Blame view

fs/fs.c 13.7 KB
045fa1e11   Stephen Warren   fs: add filesyste...
1
2
3
  /*
   * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.
   *
5b8031ccb   Tom Rini   Add more SPDX-Lic...
4
   * SPDX-License-Identifier:	GPL-2.0
045fa1e11   Stephen Warren   fs: add filesyste...
5
6
7
   */
  
  #include <config.h>
59e890ef7   Christian Gmeiner   fs: make it possi...
8
  #include <errno.h>
045fa1e11   Stephen Warren   fs: add filesyste...
9
  #include <common.h>
0eb25b619   Joe Hershberger   common: Make sure...
10
  #include <mapmem.h>
045fa1e11   Stephen Warren   fs: add filesyste...
11
12
13
14
  #include <part.h>
  #include <ext4fs.h>
  #include <fat.h>
  #include <fs.h>
92ccc96bf   Simon Glass   sandbox: Add host...
15
  #include <sandboxfs.h>
251cee0db   Hans de Goede   ubifs: Add generi...
16
  #include <ubifs_uboot.h>
0c936ee31   Marek Behún   fs: btrfs: Add U-...
17
  #include <btrfs.h>
117e05072   Simon Glass   fs: Use map_sysme...
18
  #include <asm/io.h>
9e374e7b7   Tom Rini   fs/ext4/ext4fs.c,...
19
20
  #include <div64.h>
  #include <linux/math64.h>
045fa1e11   Stephen Warren   fs: add filesyste...
21

a1b231cef   Stephen Warren   fs: handle CONFIG...
22
  DECLARE_GLOBAL_DATA_PTR;
4101f6879   Simon Glass   dm: Drop the bloc...
23
  static struct blk_desc *fs_dev_desc;
4bbcc965f   Rob Clark   fs: add fs_readdir()
24
  static int fs_dev_part;
045fa1e11   Stephen Warren   fs: add filesyste...
25
26
  static disk_partition_t fs_partition;
  static int fs_type = FS_TYPE_ANY;
4101f6879   Simon Glass   dm: Drop the bloc...
27
  static inline int fs_probe_unsupported(struct blk_desc *fs_dev_desc,
2ded0d471   Simon Glass   fs: Tell probe fu...
28
  				      disk_partition_t *fs_partition)
436e2b731   Simon Glass   fs: Fully populat...
29
30
31
32
33
  {
  	printf("** Unrecognized filesystem type **
  ");
  	return -1;
  }
045fa1e11   Stephen Warren   fs: add filesyste...
34
35
  static inline int fs_ls_unsupported(const char *dirname)
  {
045fa1e11   Stephen Warren   fs: add filesyste...
36
37
  	return -1;
  }
89191d626   Rob Clark   fat/fs: move ls t...
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
  /* generic implementation of ls in terms of opendir/readdir/closedir */
  __maybe_unused
  static int fs_ls_generic(const char *dirname)
  {
  	struct fs_dir_stream *dirs;
  	struct fs_dirent *dent;
  	int nfiles = 0, ndirs = 0;
  
  	dirs = fs_opendir(dirname);
  	if (!dirs)
  		return -errno;
  
  	while ((dent = fs_readdir(dirs))) {
  		if (dent->type == FS_DT_DIR) {
  			printf("            %s/
  ", dent->name);
  			ndirs++;
  		} else {
  			printf(" %8lld   %s
  ", dent->size, dent->name);
  			nfiles++;
  		}
  	}
  
  	fs_closedir(dirs);
  
  	printf("
  %d file(s), %d dir(s)
  
  ", nfiles, ndirs);
  
  	return 0;
  }
6152916a9   Stephen Warren   fs: implement inf...
71
72
73
74
  static inline int fs_exists_unsupported(const char *filename)
  {
  	return 0;
  }
d455d8789   Suriyan Ramasami   fs: API changes e...
75
  static inline int fs_size_unsupported(const char *filename, loff_t *size)
cf6598193   Stephen Warren   fs: implement siz...
76
77
78
  {
  	return -1;
  }
117e05072   Simon Glass   fs: Use map_sysme...
79
  static inline int fs_read_unsupported(const char *filename, void *buf,
d455d8789   Suriyan Ramasami   fs: API changes e...
80
81
  				      loff_t offset, loff_t len,
  				      loff_t *actread)
045fa1e11   Stephen Warren   fs: add filesyste...
82
  {
045fa1e11   Stephen Warren   fs: add filesyste...
83
84
  	return -1;
  }
a8f6ab522   Simon Glass   fs: Add support f...
85
  static inline int fs_write_unsupported(const char *filename, void *buf,
d455d8789   Suriyan Ramasami   fs: API changes e...
86
87
  				      loff_t offset, loff_t len,
  				      loff_t *actwrite)
a8f6ab522   Simon Glass   fs: Add support f...
88
89
90
  {
  	return -1;
  }
436e2b731   Simon Glass   fs: Fully populat...
91
92
93
  static inline void fs_close_unsupported(void)
  {
  }
59e890ef7   Christian Gmeiner   fs: make it possi...
94
95
96
97
  static inline int fs_uuid_unsupported(char *uuid_str)
  {
  	return -1;
  }
4bbcc965f   Rob Clark   fs: add fs_readdir()
98
99
100
101
102
  static inline int fs_opendir_unsupported(const char *filename,
  					 struct fs_dir_stream **dirs)
  {
  	return -EACCES;
  }
436e2b731   Simon Glass   fs: Fully populat...
103
  struct fstype_info {
045fa1e11   Stephen Warren   fs: add filesyste...
104
  	int fstype;
1a1ad8e09   Sjoerd Simons   fs: Add command t...
105
  	char *name;
377202b56   Stephen Warren   fs: don't pass NU...
106
107
108
109
110
111
112
113
114
  	/*
  	 * 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;
4101f6879   Simon Glass   dm: Drop the bloc...
115
  	int (*probe)(struct blk_desc *fs_dev_desc,
2ded0d471   Simon Glass   fs: Tell probe fu...
116
  		     disk_partition_t *fs_partition);
436e2b731   Simon Glass   fs: Fully populat...
117
  	int (*ls)(const char *dirname);
6152916a9   Stephen Warren   fs: implement inf...
118
  	int (*exists)(const char *filename);
d455d8789   Suriyan Ramasami   fs: API changes e...
119
120
121
122
123
  	int (*size)(const char *filename, loff_t *size);
  	int (*read)(const char *filename, void *buf, loff_t offset,
  		    loff_t len, loff_t *actread);
  	int (*write)(const char *filename, void *buf, loff_t offset,
  		     loff_t len, loff_t *actwrite);
436e2b731   Simon Glass   fs: Fully populat...
124
  	void (*close)(void);
59e890ef7   Christian Gmeiner   fs: make it possi...
125
  	int (*uuid)(char *uuid_str);
4bbcc965f   Rob Clark   fs: add fs_readdir()
126
127
128
129
130
131
132
133
134
135
136
137
138
139
  	/*
  	 * Open a directory stream.  On success return 0 and directory
  	 * stream pointer via 'dirsp'.  On error, return -errno.  See
  	 * fs_opendir().
  	 */
  	int (*opendir)(const char *filename, struct fs_dir_stream **dirsp);
  	/*
  	 * Read next entry from directory stream.  On success return 0
  	 * and directory entry pointer via 'dentp'.  On error return
  	 * -errno.  See fs_readdir().
  	 */
  	int (*readdir)(struct fs_dir_stream *dirs, struct fs_dirent **dentp);
  	/* see fs_closedir() */
  	void (*closedir)(struct fs_dir_stream *dirs);
436e2b731   Simon Glass   fs: Fully populat...
140
141
142
143
  };
  
  static struct fstype_info fstypes[] = {
  #ifdef CONFIG_FS_FAT
045fa1e11   Stephen Warren   fs: add filesyste...
144
145
  	{
  		.fstype = FS_TYPE_FAT,
1a1ad8e09   Sjoerd Simons   fs: Add command t...
146
  		.name = "fat",
377202b56   Stephen Warren   fs: don't pass NU...
147
  		.null_dev_desc_ok = false,
e6d524153   Simon Glass   fs: Move ls and r...
148
149
  		.probe = fat_set_blk_dev,
  		.close = fat_close,
89191d626   Rob Clark   fat/fs: move ls t...
150
  		.ls = fs_ls_generic,
b7b5f3195   Stephen Warren   fat: implement ex...
151
  		.exists = fat_exists,
cf6598193   Stephen Warren   fs: implement siz...
152
  		.size = fat_size,
e6d524153   Simon Glass   fs: Move ls and r...
153
  		.read = fat_read_file,
d455d8789   Suriyan Ramasami   fs: API changes e...
154
155
156
  #ifdef CONFIG_FAT_WRITE
  		.write = file_fat_write,
  #else
bd6fb31fa   Stephen Warren   fs: fix generic s...
157
  		.write = fs_write_unsupported,
d455d8789   Suriyan Ramasami   fs: API changes e...
158
  #endif
59e890ef7   Christian Gmeiner   fs: make it possi...
159
  		.uuid = fs_uuid_unsupported,
89191d626   Rob Clark   fat/fs: move ls t...
160
161
162
  		.opendir = fat_opendir,
  		.readdir = fat_readdir,
  		.closedir = fat_closedir,
045fa1e11   Stephen Warren   fs: add filesyste...
163
  	},
436e2b731   Simon Glass   fs: Fully populat...
164
165
  #endif
  #ifdef CONFIG_FS_EXT4
045fa1e11   Stephen Warren   fs: add filesyste...
166
167
  	{
  		.fstype = FS_TYPE_EXT,
1a1ad8e09   Sjoerd Simons   fs: Add command t...
168
  		.name = "ext4",
377202b56   Stephen Warren   fs: don't pass NU...
169
  		.null_dev_desc_ok = false,
e6d524153   Simon Glass   fs: Move ls and r...
170
171
  		.probe = ext4fs_probe,
  		.close = ext4fs_close,
436e2b731   Simon Glass   fs: Fully populat...
172
  		.ls = ext4fs_ls,
55af5c931   Stephen Warren   ext4: implement e...
173
  		.exists = ext4fs_exists,
cf6598193   Stephen Warren   fs: implement siz...
174
  		.size = ext4fs_size,
e6d524153   Simon Glass   fs: Move ls and r...
175
  		.read = ext4_read_file,
d455d8789   Suriyan Ramasami   fs: API changes e...
176
177
178
  #ifdef CONFIG_CMD_EXT4_WRITE
  		.write = ext4_write_file,
  #else
bd6fb31fa   Stephen Warren   fs: fix generic s...
179
  		.write = fs_write_unsupported,
d455d8789   Suriyan Ramasami   fs: API changes e...
180
  #endif
59e890ef7   Christian Gmeiner   fs: make it possi...
181
  		.uuid = ext4fs_uuid,
4bbcc965f   Rob Clark   fs: add fs_readdir()
182
  		.opendir = fs_opendir_unsupported,
436e2b731   Simon Glass   fs: Fully populat...
183
184
  	},
  #endif
92ccc96bf   Simon Glass   sandbox: Add host...
185
186
187
  #ifdef CONFIG_SANDBOX
  	{
  		.fstype = FS_TYPE_SANDBOX,
1a1ad8e09   Sjoerd Simons   fs: Add command t...
188
  		.name = "sandbox",
377202b56   Stephen Warren   fs: don't pass NU...
189
  		.null_dev_desc_ok = true,
92ccc96bf   Simon Glass   sandbox: Add host...
190
191
192
  		.probe = sandbox_fs_set_blk_dev,
  		.close = sandbox_fs_close,
  		.ls = sandbox_fs_ls,
0a30aa1e7   Stephen Warren   sandbox: implemen...
193
  		.exists = sandbox_fs_exists,
cf6598193   Stephen Warren   fs: implement siz...
194
  		.size = sandbox_fs_size,
92ccc96bf   Simon Glass   sandbox: Add host...
195
  		.read = fs_read_sandbox,
7eb2c8d57   Simon Glass   sandbox: fs: Add ...
196
  		.write = fs_write_sandbox,
59e890ef7   Christian Gmeiner   fs: make it possi...
197
  		.uuid = fs_uuid_unsupported,
4bbcc965f   Rob Clark   fs: add fs_readdir()
198
  		.opendir = fs_opendir_unsupported,
92ccc96bf   Simon Glass   sandbox: Add host...
199
200
  	},
  #endif
251cee0db   Hans de Goede   ubifs: Add generi...
201
202
203
204
205
206
207
208
209
210
211
212
213
  #ifdef CONFIG_CMD_UBIFS
  	{
  		.fstype = FS_TYPE_UBIFS,
  		.name = "ubifs",
  		.null_dev_desc_ok = true,
  		.probe = ubifs_set_blk_dev,
  		.close = ubifs_close,
  		.ls = ubifs_ls,
  		.exists = ubifs_exists,
  		.size = ubifs_size,
  		.read = ubifs_read,
  		.write = fs_write_unsupported,
  		.uuid = fs_uuid_unsupported,
4bbcc965f   Rob Clark   fs: add fs_readdir()
214
  		.opendir = fs_opendir_unsupported,
251cee0db   Hans de Goede   ubifs: Add generi...
215
216
  	},
  #endif
0c936ee31   Marek Behún   fs: btrfs: Add U-...
217
218
219
220
221
222
223
224
225
226
227
228
229
  #ifdef CONFIG_FS_BTRFS
  	{
  		.fstype = FS_TYPE_BTRFS,
  		.name = "btrfs",
  		.null_dev_desc_ok = false,
  		.probe = btrfs_probe,
  		.close = btrfs_close,
  		.ls = btrfs_ls,
  		.exists = btrfs_exists,
  		.size = btrfs_size,
  		.read = btrfs_read,
  		.write = fs_write_unsupported,
  		.uuid = btrfs_uuid,
38fc683d3   Marek Behún   fs: Set .opendir ...
230
  		.opendir = fs_opendir_unsupported,
0c936ee31   Marek Behún   fs: btrfs: Add U-...
231
232
  	},
  #endif
436e2b731   Simon Glass   fs: Fully populat...
233
234
  	{
  		.fstype = FS_TYPE_ANY,
1a1ad8e09   Sjoerd Simons   fs: Add command t...
235
  		.name = "unsupported",
377202b56   Stephen Warren   fs: don't pass NU...
236
  		.null_dev_desc_ok = true,
436e2b731   Simon Glass   fs: Fully populat...
237
238
239
  		.probe = fs_probe_unsupported,
  		.close = fs_close_unsupported,
  		.ls = fs_ls_unsupported,
6152916a9   Stephen Warren   fs: implement inf...
240
  		.exists = fs_exists_unsupported,
cf6598193   Stephen Warren   fs: implement siz...
241
  		.size = fs_size_unsupported,
436e2b731   Simon Glass   fs: Fully populat...
242
  		.read = fs_read_unsupported,
a8f6ab522   Simon Glass   fs: Add support f...
243
  		.write = fs_write_unsupported,
59e890ef7   Christian Gmeiner   fs: make it possi...
244
  		.uuid = fs_uuid_unsupported,
4bbcc965f   Rob Clark   fs: add fs_readdir()
245
  		.opendir = fs_opendir_unsupported,
045fa1e11   Stephen Warren   fs: add filesyste...
246
247
  	},
  };
c6f548d23   Simon Glass   fs: Use filesyste...
248
249
250
251
252
253
254
255
256
257
258
259
260
  static struct fstype_info *fs_get_info(int fstype)
  {
  	struct fstype_info *info;
  	int i;
  
  	for (i = 0, info = fstypes; i < ARRAY_SIZE(fstypes) - 1; i++, info++) {
  		if (fstype == info->fstype)
  			return info;
  	}
  
  	/* Return the 'unsupported' sentinel */
  	return info;
  }
045fa1e11   Stephen Warren   fs: add filesyste...
261
262
  int fs_set_blk_dev(const char *ifname, const char *dev_part_str, int fstype)
  {
436e2b731   Simon Glass   fs: Fully populat...
263
  	struct fstype_info *info;
045fa1e11   Stephen Warren   fs: add filesyste...
264
  	int part, i;
a1b231cef   Stephen Warren   fs: handle CONFIG...
265
266
267
268
  #ifdef CONFIG_NEEDS_MANUAL_RELOC
  	static int relocated;
  
  	if (!relocated) {
436e2b731   Simon Glass   fs: Fully populat...
269
270
  		for (i = 0, info = fstypes; i < ARRAY_SIZE(fstypes);
  				i++, info++) {
1a1ad8e09   Sjoerd Simons   fs: Add command t...
271
  			info->name += gd->reloc_off;
436e2b731   Simon Glass   fs: Fully populat...
272
273
274
275
  			info->probe += gd->reloc_off;
  			info->close += gd->reloc_off;
  			info->ls += gd->reloc_off;
  			info->read += gd->reloc_off;
a8f6ab522   Simon Glass   fs: Add support f...
276
  			info->write += gd->reloc_off;
436e2b731   Simon Glass   fs: Fully populat...
277
  		}
a1b231cef   Stephen Warren   fs: handle CONFIG...
278
279
280
  		relocated = 1;
  	}
  #endif
045fa1e11   Stephen Warren   fs: add filesyste...
281

e35929e4a   Simon Glass   dm: blk: Rename g...
282
  	part = blk_get_device_part_str(ifname, dev_part_str, &fs_dev_desc,
045fa1e11   Stephen Warren   fs: add filesyste...
283
284
285
  					&fs_partition, 1);
  	if (part < 0)
  		return -1;
436e2b731   Simon Glass   fs: Fully populat...
286
287
288
  	for (i = 0, info = fstypes; i < ARRAY_SIZE(fstypes); i++, info++) {
  		if (fstype != FS_TYPE_ANY && info->fstype != FS_TYPE_ANY &&
  				fstype != info->fstype)
045fa1e11   Stephen Warren   fs: add filesyste...
289
  			continue;
377202b56   Stephen Warren   fs: don't pass NU...
290
291
  		if (!fs_dev_desc && !info->null_dev_desc_ok)
  			continue;
2ded0d471   Simon Glass   fs: Tell probe fu...
292
  		if (!info->probe(fs_dev_desc, &fs_partition)) {
436e2b731   Simon Glass   fs: Fully populat...
293
  			fs_type = info->fstype;
4bbcc965f   Rob Clark   fs: add fs_readdir()
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
  			fs_dev_part = part;
  			return 0;
  		}
  	}
  
  	return -1;
  }
  
  /* set current blk device w/ blk_desc + partition # */
  int fs_set_blk_dev_with_part(struct blk_desc *desc, int part)
  {
  	struct fstype_info *info;
  	int ret, i;
  
  	if (part >= 1)
  		ret = part_get_info(desc, part, &fs_partition);
  	else
  		ret = part_get_info_whole_disk(desc, &fs_partition);
  	if (ret)
  		return ret;
  	fs_dev_desc = desc;
  
  	for (i = 0, info = fstypes; i < ARRAY_SIZE(fstypes); i++, info++) {
  		if (!info->probe(fs_dev_desc, &fs_partition)) {
  			fs_type = info->fstype;
045fa1e11   Stephen Warren   fs: add filesyste...
319
320
321
  			return 0;
  		}
  	}
045fa1e11   Stephen Warren   fs: add filesyste...
322
323
324
325
326
  	return -1;
  }
  
  static void fs_close(void)
  {
c6f548d23   Simon Glass   fs: Use filesyste...
327
  	struct fstype_info *info = fs_get_info(fs_type);
045fa1e11   Stephen Warren   fs: add filesyste...
328

c6f548d23   Simon Glass   fs: Use filesyste...
329
  	info->close();
e6d524153   Simon Glass   fs: Move ls and r...
330

045fa1e11   Stephen Warren   fs: add filesyste...
331
332
  	fs_type = FS_TYPE_ANY;
  }
59e890ef7   Christian Gmeiner   fs: make it possi...
333
334
335
336
337
338
  int fs_uuid(char *uuid_str)
  {
  	struct fstype_info *info = fs_get_info(fs_type);
  
  	return info->uuid(uuid_str);
  }
045fa1e11   Stephen Warren   fs: add filesyste...
339
340
341
  int fs_ls(const char *dirname)
  {
  	int ret;
c6f548d23   Simon Glass   fs: Use filesyste...
342
343
344
  	struct fstype_info *info = fs_get_info(fs_type);
  
  	ret = info->ls(dirname);
045fa1e11   Stephen Warren   fs: add filesyste...
345

e6d524153   Simon Glass   fs: Move ls and r...
346
  	fs_type = FS_TYPE_ANY;
045fa1e11   Stephen Warren   fs: add filesyste...
347
348
349
350
  	fs_close();
  
  	return ret;
  }
6152916a9   Stephen Warren   fs: implement inf...
351
352
353
354
355
356
357
358
359
360
361
362
  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;
  }
d455d8789   Suriyan Ramasami   fs: API changes e...
363
  int fs_size(const char *filename, loff_t *size)
cf6598193   Stephen Warren   fs: implement siz...
364
365
366
367
  {
  	int ret;
  
  	struct fstype_info *info = fs_get_info(fs_type);
d455d8789   Suriyan Ramasami   fs: API changes e...
368
  	ret = info->size(filename, size);
cf6598193   Stephen Warren   fs: implement siz...
369
370
371
372
373
  
  	fs_close();
  
  	return ret;
  }
d455d8789   Suriyan Ramasami   fs: API changes e...
374
375
  int fs_read(const char *filename, ulong addr, loff_t offset, loff_t len,
  	    loff_t *actread)
045fa1e11   Stephen Warren   fs: add filesyste...
376
  {
c6f548d23   Simon Glass   fs: Use filesyste...
377
  	struct fstype_info *info = fs_get_info(fs_type);
117e05072   Simon Glass   fs: Use map_sysme...
378
  	void *buf;
045fa1e11   Stephen Warren   fs: add filesyste...
379
  	int ret;
117e05072   Simon Glass   fs: Use map_sysme...
380
381
382
383
384
  	/*
  	 * We don't actually know how many bytes are being read, since len==0
  	 * means read the whole file.
  	 */
  	buf = map_sysmem(addr, len);
d455d8789   Suriyan Ramasami   fs: API changes e...
385
  	ret = info->read(filename, buf, offset, len, actread);
117e05072   Simon Glass   fs: Use map_sysme...
386
  	unmap_sysmem(buf);
045fa1e11   Stephen Warren   fs: add filesyste...
387

c6f548d23   Simon Glass   fs: Use filesyste...
388
  	/* If we requested a specific number of bytes, check we got it */
7a3e70cfd   Max Krummenacher   fs/fs.c: read up ...
389
  	if (ret == 0 && len && *actread != len)
a327bde78   Heinrich Schuchardt   fs: remove distra...
390
391
  		debug("** %s shorter than offset + len **
  ", filename);
045fa1e11   Stephen Warren   fs: add filesyste...
392
393
394
395
  	fs_close();
  
  	return ret;
  }
d455d8789   Suriyan Ramasami   fs: API changes e...
396
397
  int fs_write(const char *filename, ulong addr, loff_t offset, loff_t len,
  	     loff_t *actwrite)
a8f6ab522   Simon Glass   fs: Add support f...
398
399
400
401
  {
  	struct fstype_info *info = fs_get_info(fs_type);
  	void *buf;
  	int ret;
a8f6ab522   Simon Glass   fs: Add support f...
402
  	buf = map_sysmem(addr, len);
d455d8789   Suriyan Ramasami   fs: API changes e...
403
  	ret = info->write(filename, buf, offset, len, actwrite);
a8f6ab522   Simon Glass   fs: Add support f...
404
  	unmap_sysmem(buf);
d455d8789   Suriyan Ramasami   fs: API changes e...
405
  	if (ret < 0 && len != *actwrite) {
a8f6ab522   Simon Glass   fs: Add support f...
406
407
408
409
410
411
412
413
  		printf("** Unable to write file %s **
  ", filename);
  		ret = -1;
  	}
  	fs_close();
  
  	return ret;
  }
4bbcc965f   Rob Clark   fs: add fs_readdir()
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
  struct fs_dir_stream *fs_opendir(const char *filename)
  {
  	struct fstype_info *info = fs_get_info(fs_type);
  	struct fs_dir_stream *dirs = NULL;
  	int ret;
  
  	ret = info->opendir(filename, &dirs);
  	fs_close();
  	if (ret) {
  		errno = -ret;
  		return NULL;
  	}
  
  	dirs->desc = fs_dev_desc;
  	dirs->part = fs_dev_part;
  
  	return dirs;
  }
  
  struct fs_dirent *fs_readdir(struct fs_dir_stream *dirs)
  {
  	struct fstype_info *info;
  	struct fs_dirent *dirent;
  	int ret;
  
  	fs_set_blk_dev_with_part(dirs->desc, dirs->part);
  	info = fs_get_info(fs_type);
  
  	ret = info->readdir(dirs, &dirent);
  	fs_close();
  	if (ret) {
  		errno = -ret;
  		return NULL;
  	}
  
  	return dirent;
  }
  
  void fs_closedir(struct fs_dir_stream *dirs)
  {
  	struct fstype_info *info;
  
  	if (!dirs)
  		return;
  
  	fs_set_blk_dev_with_part(dirs->desc, dirs->part);
  	info = fs_get_info(fs_type);
  
  	info->closedir(dirs);
  	fs_close();
  }
cf6598193   Stephen Warren   fs: implement siz...
465
466
467
  int do_size(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
  		int fstype)
  {
d455d8789   Suriyan Ramasami   fs: API changes e...
468
  	loff_t size;
cf6598193   Stephen Warren   fs: implement siz...
469
470
471
472
473
474
  
  	if (argc != 4)
  		return CMD_RET_USAGE;
  
  	if (fs_set_blk_dev(argv[1], argv[2], fstype))
  		return 1;
d455d8789   Suriyan Ramasami   fs: API changes e...
475
  	if (fs_size(argv[3], &size) < 0)
cf6598193   Stephen Warren   fs: implement siz...
476
  		return CMD_RET_FAILURE;
018f53032   Simon Glass   env: Rename commo...
477
  	env_set_hex("filesize", size);
cf6598193   Stephen Warren   fs: implement siz...
478
479
480
  
  	return 0;
  }
f9b55e228   Stephen Warren   fs: rename fsload...
481
  int do_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
b770e88a6   Wolfgang Denk   Fix number base h...
482
  		int fstype)
045fa1e11   Stephen Warren   fs: add filesyste...
483
484
485
486
  {
  	unsigned long addr;
  	const char *addr_str;
  	const char *filename;
d455d8789   Suriyan Ramasami   fs: API changes e...
487
488
489
490
  	loff_t bytes;
  	loff_t pos;
  	loff_t len_read;
  	int ret;
da1fd96ce   Andreas Bießmann   fs/fs.c: do_fsloa...
491
  	unsigned long time;
949bbd7c8   Pavel Machek   catch wrong load ...
492
  	char *ep;
045fa1e11   Stephen Warren   fs: add filesyste...
493

e9b0f99e8   Stephen Warren   fs: fix do_fsload...
494
495
496
  	if (argc < 2)
  		return CMD_RET_USAGE;
  	if (argc > 7)
045fa1e11   Stephen Warren   fs: add filesyste...
497
  		return CMD_RET_USAGE;
e9b0f99e8   Stephen Warren   fs: fix do_fsload...
498
  	if (fs_set_blk_dev(argv[1], (argc >= 3) ? argv[2] : NULL, fstype))
045fa1e11   Stephen Warren   fs: add filesyste...
499
500
501
  		return 1;
  
  	if (argc >= 4) {
949bbd7c8   Pavel Machek   catch wrong load ...
502
503
504
  		addr = simple_strtoul(argv[3], &ep, 16);
  		if (ep == argv[3] || *ep != '\0')
  			return CMD_RET_USAGE;
045fa1e11   Stephen Warren   fs: add filesyste...
505
  	} else {
00caae6d4   Simon Glass   env: Rename geten...
506
  		addr_str = env_get("loadaddr");
045fa1e11   Stephen Warren   fs: add filesyste...
507
508
509
510
511
512
513
514
  		if (addr_str != NULL)
  			addr = simple_strtoul(addr_str, NULL, 16);
  		else
  			addr = CONFIG_SYS_LOAD_ADDR;
  	}
  	if (argc >= 5) {
  		filename = argv[4];
  	} else {
00caae6d4   Simon Glass   env: Rename geten...
515
  		filename = env_get("bootfile");
045fa1e11   Stephen Warren   fs: add filesyste...
516
517
518
519
520
521
522
  		if (!filename) {
  			puts("** No boot file defined **
  ");
  			return 1;
  		}
  	}
  	if (argc >= 6)
b770e88a6   Wolfgang Denk   Fix number base h...
523
  		bytes = simple_strtoul(argv[5], NULL, 16);
045fa1e11   Stephen Warren   fs: add filesyste...
524
525
526
  	else
  		bytes = 0;
  	if (argc >= 7)
b770e88a6   Wolfgang Denk   Fix number base h...
527
  		pos = simple_strtoul(argv[6], NULL, 16);
045fa1e11   Stephen Warren   fs: add filesyste...
528
529
  	else
  		pos = 0;
da1fd96ce   Andreas Bießmann   fs/fs.c: do_fsloa...
530
  	time = get_timer(0);
d455d8789   Suriyan Ramasami   fs: API changes e...
531
  	ret = fs_read(filename, addr, pos, bytes, &len_read);
da1fd96ce   Andreas Bießmann   fs/fs.c: do_fsloa...
532
  	time = get_timer(time);
d455d8789   Suriyan Ramasami   fs: API changes e...
533
  	if (ret < 0)
045fa1e11   Stephen Warren   fs: add filesyste...
534
  		return 1;
d455d8789   Suriyan Ramasami   fs: API changes e...
535
  	printf("%llu bytes read in %lu ms", len_read, time);
da1fd96ce   Andreas Bießmann   fs/fs.c: do_fsloa...
536
537
  	if (time > 0) {
  		puts(" (");
9e374e7b7   Tom Rini   fs/ext4/ext4fs.c,...
538
  		print_size(div_u64(len_read, time) * 1000, "/s");
da1fd96ce   Andreas Bießmann   fs/fs.c: do_fsloa...
539
540
541
542
  		puts(")");
  	}
  	puts("
  ");
045fa1e11   Stephen Warren   fs: add filesyste...
543

018f53032   Simon Glass   env: Rename commo...
544
545
  	env_set_hex("fileaddr", addr);
  	env_set_hex("filesize", len_read);
045fa1e11   Stephen Warren   fs: add filesyste...
546
547
548
549
550
551
552
553
554
  
  	return 0;
  }
  
  int do_ls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
  	int fstype)
  {
  	if (argc < 2)
  		return CMD_RET_USAGE;
e9b0f99e8   Stephen Warren   fs: fix do_fsload...
555
556
  	if (argc > 4)
  		return CMD_RET_USAGE;
045fa1e11   Stephen Warren   fs: add filesyste...
557
558
559
  
  	if (fs_set_blk_dev(argv[1], (argc >= 3) ? argv[2] : NULL, fstype))
  		return 1;
e9b0f99e8   Stephen Warren   fs: fix do_fsload...
560
  	if (fs_ls(argc >= 4 ? argv[3] : "/"))
045fa1e11   Stephen Warren   fs: add filesyste...
561
562
563
564
  		return 1;
  
  	return 0;
  }
a8f6ab522   Simon Glass   fs: Add support f...
565

6152916a9   Stephen Warren   fs: implement inf...
566
567
568
569
570
571
572
573
  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);
  }
a8f6ab522   Simon Glass   fs: Add support f...
574
  int do_save(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
b770e88a6   Wolfgang Denk   Fix number base h...
575
  		int fstype)
a8f6ab522   Simon Glass   fs: Add support f...
576
577
578
  {
  	unsigned long addr;
  	const char *filename;
d455d8789   Suriyan Ramasami   fs: API changes e...
579
580
581
582
  	loff_t bytes;
  	loff_t pos;
  	loff_t len;
  	int ret;
a8f6ab522   Simon Glass   fs: Add support f...
583
584
585
586
587
588
589
  	unsigned long time;
  
  	if (argc < 6 || argc > 7)
  		return CMD_RET_USAGE;
  
  	if (fs_set_blk_dev(argv[1], argv[2], fstype))
  		return 1;
d455d8789   Suriyan Ramasami   fs: API changes e...
590
591
  	addr = simple_strtoul(argv[3], NULL, 16);
  	filename = argv[4];
b770e88a6   Wolfgang Denk   Fix number base h...
592
  	bytes = simple_strtoul(argv[5], NULL, 16);
a8f6ab522   Simon Glass   fs: Add support f...
593
  	if (argc >= 7)
b770e88a6   Wolfgang Denk   Fix number base h...
594
  		pos = simple_strtoul(argv[6], NULL, 16);
a8f6ab522   Simon Glass   fs: Add support f...
595
596
597
598
  	else
  		pos = 0;
  
  	time = get_timer(0);
d455d8789   Suriyan Ramasami   fs: API changes e...
599
  	ret = fs_write(filename, addr, pos, bytes, &len);
a8f6ab522   Simon Glass   fs: Add support f...
600
  	time = get_timer(time);
d455d8789   Suriyan Ramasami   fs: API changes e...
601
  	if (ret < 0)
a8f6ab522   Simon Glass   fs: Add support f...
602
  		return 1;
d455d8789   Suriyan Ramasami   fs: API changes e...
603
  	printf("%llu bytes written in %lu ms", len, time);
a8f6ab522   Simon Glass   fs: Add support f...
604
605
  	if (time > 0) {
  		puts(" (");
9e374e7b7   Tom Rini   fs/ext4/ext4fs.c,...
606
  		print_size(div_u64(len, time) * 1000, "/s");
a8f6ab522   Simon Glass   fs: Add support f...
607
608
609
610
611
612
613
  		puts(")");
  	}
  	puts("
  ");
  
  	return 0;
  }
59e890ef7   Christian Gmeiner   fs: make it possi...
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
  
  int do_fs_uuid(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
  		int fstype)
  {
  	int ret;
  	char uuid[37];
  	memset(uuid, 0, sizeof(uuid));
  
  	if (argc < 3 || argc > 4)
  		return CMD_RET_USAGE;
  
  	if (fs_set_blk_dev(argv[1], argv[2], fstype))
  		return 1;
  
  	ret = fs_uuid(uuid);
  	if (ret)
  		return CMD_RET_FAILURE;
  
  	if (argc == 4)
382bee57f   Simon Glass   env: Rename seten...
633
  		env_set(argv[3], uuid);
59e890ef7   Christian Gmeiner   fs: make it possi...
634
635
636
637
638
639
  	else
  		printf("%s
  ", uuid);
  
  	return CMD_RET_SUCCESS;
  }
1a1ad8e09   Sjoerd Simons   fs: Add command t...
640
641
642
643
644
645
646
647
648
649
650
651
652
653
  
  int do_fs_type(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
  {
  	struct fstype_info *info;
  
  	if (argc < 3 || argc > 4)
  		return CMD_RET_USAGE;
  
  	if (fs_set_blk_dev(argv[1], argv[2], FS_TYPE_ANY))
  		return 1;
  
  	info = fs_get_info(fs_type);
  
  	if (argc == 4)
382bee57f   Simon Glass   env: Rename seten...
654
  		env_set(argv[3], info->name);
1a1ad8e09   Sjoerd Simons   fs: Add command t...
655
656
657
658
659
660
  	else
  		printf("%s
  ", info->name);
  
  	return CMD_RET_SUCCESS;
  }