Patchwork [U-Boot,v3,15/17] fs: Add support for saving data to filesystems

login
register
mail settings
Submitter Simon Glass
Date April 20, 2013, 6:42 p.m.
Message ID <1366483372-16523-16-git-send-email-sjg@chromium.org>
Download mbox | patch
Permalink /patch/238170/
State Accepted, archived
Delegated to: Simon Glass
Headers show

Comments

Simon Glass - April 20, 2013, 6:42 p.m.
Add a new method for saving that filesystems can implement. This mirrors the
existing load method.

Signed-off-by: Simon Glass <sjg@chromium.org>
---
Changes in v3: None
Changes in v2: None

 fs/fs.c      | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/fs.h |  2 ++
 2 files changed, 76 insertions(+)

Patch

diff --git a/fs/fs.c b/fs/fs.c
index 6f5063c..eee7e23 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -47,6 +47,12 @@  static inline int fs_read_unsupported(const char *filename, void *buf,
 	return -1;
 }
 
+static inline int fs_write_unsupported(const char *filename, void *buf,
+				      int offset, int len)
+{
+	return -1;
+}
+
 static inline void fs_close_unsupported(void)
 {
 }
@@ -57,6 +63,7 @@  struct fstype_info {
 		     disk_partition_t *fs_partition);
 	int (*ls)(const char *dirname);
 	int (*read)(const char *filename, void *buf, int offset, int len);
+	int (*write)(const char *filename, void *buf, int offset, int len);
 	void (*close)(void);
 };
 
@@ -94,6 +101,7 @@  static struct fstype_info fstypes[] = {
 		.close = fs_close_unsupported,
 		.ls = fs_ls_unsupported,
 		.read = fs_read_unsupported,
+		.write = fs_write_unsupported,
 	},
 };
 
@@ -125,6 +133,7 @@  int fs_set_blk_dev(const char *ifname, const char *dev_part_str, int fstype)
 			info->close += gd->reloc_off;
 			info->ls += gd->reloc_off;
 			info->read += gd->reloc_off;
+			info->write += gd->reloc_off;
 		}
 		relocated = 1;
 	}
@@ -196,6 +205,30 @@  int fs_read(const char *filename, ulong addr, int offset, int len)
 	return ret;
 }
 
+int fs_write(const char *filename, ulong addr, int offset, int len)
+{
+	struct fstype_info *info = fs_get_info(fs_type);
+	void *buf;
+	int ret;
+
+	/*
+	 * We don't actually know how many bytes are being read, since len==0
+	 * means read the whole file.
+	 */
+	buf = map_sysmem(addr, len);
+	ret = info->write(filename, buf, offset, len);
+	unmap_sysmem(buf);
+
+	/* If we requested a specific number of bytes, check we got it */
+	if (ret >= 0 && len && ret != len) {
+		printf("** Unable to write file %s **\n", filename);
+		ret = -1;
+	}
+	fs_close();
+
+	return ret;
+}
+
 int do_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
 		int fstype, int cmdline_base)
 {
@@ -277,3 +310,44 @@  int do_ls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
 
 	return 0;
 }
+
+int do_save(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
+		int fstype, int cmdline_base)
+{
+	unsigned long addr;
+	const char *filename;
+	unsigned long bytes;
+	unsigned long pos;
+	int len;
+	unsigned long time;
+
+	if (argc < 6 || argc > 7)
+		return CMD_RET_USAGE;
+
+	if (fs_set_blk_dev(argv[1], argv[2], fstype))
+		return 1;
+
+	filename = argv[3];
+	addr = simple_strtoul(argv[4], NULL, cmdline_base);
+	bytes = simple_strtoul(argv[5], NULL, cmdline_base);
+	if (argc >= 7)
+		pos = simple_strtoul(argv[6], NULL, cmdline_base);
+	else
+		pos = 0;
+
+	time = get_timer(0);
+	len = fs_write(filename, addr, pos, bytes);
+	time = get_timer(time);
+	if (len <= 0)
+		return 1;
+
+	printf("%d bytes written in %lu ms", len, time);
+	if (time > 0) {
+		puts(" (");
+		print_size(len / time * 1000, "/s");
+		puts(")");
+	}
+	puts("\n");
+
+	return 0;
+}
diff --git a/include/fs.h b/include/fs.h
index b6d69e5..c837bae 100644
--- a/include/fs.h
+++ b/include/fs.h
@@ -62,5 +62,7 @@  int do_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
 		int fstype, int cmdline_base);
 int do_ls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
 		int fstype);
+int do_save(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
+		int fstype, int cmdline_base);
 
 #endif /* _FS_H */