diff options
Diffstat (limited to 'fs/fs.c')
| -rw-r--r-- | fs/fs.c | 57 | 
1 files changed, 51 insertions, 6 deletions
@@ -41,6 +41,11 @@ static inline int fs_ls_unsupported(const char *dirname)  	return -1;  } +static inline int fs_exists_unsupported(const char *filename) +{ +	return 0; +} +  static inline int fs_read_unsupported(const char *filename, void *buf,  				      int offset, int len)  { @@ -59,9 +64,19 @@ static inline void fs_close_unsupported(void)  struct fstype_info {  	int fstype; +	/* +	 * Is it legal to pass NULL as .probe()'s  fs_dev_desc parameter? This +	 * should be false in most cases. For "virtual" filesystems which +	 * aren't based on a U-Boot block device (e.g. sandbox), this can be +	 * set to true. This should also be true for the dumm entry at the end +	 * of fstypes[], since that is essentially a "virtual" (non-existent) +	 * filesystem. +	 */ +	bool null_dev_desc_ok;  	int (*probe)(block_dev_desc_t *fs_dev_desc,  		     disk_partition_t *fs_partition);  	int (*ls)(const char *dirname); +	int (*exists)(const char *filename);  	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); @@ -71,36 +86,46 @@ static struct fstype_info fstypes[] = {  #ifdef CONFIG_FS_FAT  	{  		.fstype = FS_TYPE_FAT, +		.null_dev_desc_ok = false,  		.probe = fat_set_blk_dev,  		.close = fat_close,  		.ls = file_fat_ls, +		.exists = fat_exists,  		.read = fat_read_file, +		.write = fs_write_unsupported,  	},  #endif  #ifdef CONFIG_FS_EXT4  	{  		.fstype = FS_TYPE_EXT, +		.null_dev_desc_ok = false,  		.probe = ext4fs_probe,  		.close = ext4fs_close,  		.ls = ext4fs_ls, +		.exists = ext4fs_exists,  		.read = ext4_read_file, +		.write = fs_write_unsupported,  	},  #endif  #ifdef CONFIG_SANDBOX  	{  		.fstype = FS_TYPE_SANDBOX, +		.null_dev_desc_ok = true,  		.probe = sandbox_fs_set_blk_dev,  		.close = sandbox_fs_close,  		.ls = sandbox_fs_ls, +		.exists = sandbox_fs_exists,  		.read = fs_read_sandbox,  		.write = fs_write_sandbox,  	},  #endif  	{  		.fstype = FS_TYPE_ANY, +		.null_dev_desc_ok = true,  		.probe = fs_probe_unsupported,  		.close = fs_close_unsupported,  		.ls = fs_ls_unsupported, +		.exists = fs_exists_unsupported,  		.read = fs_read_unsupported,  		.write = fs_write_unsupported,  	}, @@ -150,6 +175,9 @@ int fs_set_blk_dev(const char *ifname, const char *dev_part_str, int fstype)  				fstype != info->fstype)  			continue; +		if (!fs_dev_desc && !info->null_dev_desc_ok) +			continue; +  		if (!info->probe(fs_dev_desc, &fs_partition)) {  			fs_type = info->fstype;  			return 0; @@ -182,6 +210,19 @@ int fs_ls(const char *dirname)  	return ret;  } +int fs_exists(const char *filename) +{ +	int ret; + +	struct fstype_info *info = fs_get_info(fs_type); + +	ret = info->exists(filename); + +	fs_close(); + +	return ret; +} +  int fs_read(const char *filename, ulong addr, int offset, int len)  {  	struct fstype_info *info = fs_get_info(fs_type); @@ -212,16 +253,11 @@ int fs_write(const char *filename, ulong addr, int offset, int len)  	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) { +	if (ret >= 0 && ret != len) {  		printf("** Unable to write file %s **\n", filename);  		ret = -1;  	} @@ -312,6 +348,15 @@ int do_ls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],  	return 0;  } +int file_exists(const char *dev_type, const char *dev_part, const char *file, +		int fstype) +{ +	if (fs_set_blk_dev(dev_type, dev_part, fstype)) +		return 0; + +	return fs_exists(file); +} +  int do_save(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],  		int fstype)  {  |