From: "Brüns, Stefan" <Stefan.Bruens@rwth-aachen.de>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH v2 3/8] fat/fs: convert to directory iterators
Date: Mon, 14 Aug 2017 13:47:48 +0000 [thread overview]
Message-ID: <8714069.Dt7qGlXCB0@sbruens-linux> (raw)
In-Reply-To: <20170814131623.9830-4-robdclark@gmail.com>
On Montag, 14. August 2017 15:16:15 CEST Rob Clark wrote:
> And drop a whole lot of ugly code!
>
> Signed-off-by: Rob Clark <robdclark@gmail.com>
> ---
> fs/fat/fat.c | 723
> ++++++---------------------------------------------------- include/fat.h |
> 6 -
> 2 files changed, 75 insertions(+), 654 deletions(-)
Nice, even after accounting for the ~300 lines added for the iterators :-)
Two comments inline ...
> diff --git a/fs/fat/fat.c b/fs/fat/fat.c
> index 69fa7f4cab..a50a10ba47 100644
> --- a/fs/fat/fat.c
> +++ b/fs/fat/fat.c
> @@ -119,22 +119,6 @@ int fat_register_device(struct blk_desc *dev_desc, int
> part_no) }
>
[...]
> -
> -/*
> * Extract zero terminated short name from a directory entry.
> */
> static void get_name(dir_entry *dirent, char *s_name)
> @@ -468,95 +452,6 @@ static int slot2str(dir_slot *slotptr, char *l_name,
> int *idx) return 0;
> }
[...]
> -}
> -
> /* Calculate short name checksum */
> static __u8 mkcksum(const char name[8], const char ext[3])
> {
> @@ -572,170 +467,11 @@ static __u8 mkcksum(const char name[8], const char
> ext[3]) return ret;
[...]
>
> /*
> * Read boot sector and volume info from a FAT filesystem
> @@ -877,374 +613,6 @@ static int get_fs_info(fsdata *mydata)
> return 0;
> }
[...]
> -
> - while (isdir) {
> - int startsect = mydata->data_begin
> - + START(dentptr) * mydata->clust_size;
> - dir_entry dent;
> - char *nextname = NULL;
> -
> - dent = *dentptr;
> - dentptr = &dent;
> -
> - idx = dirdelim(subname);
> -
> - if (idx >= 0) {
> - subname[idx] = '\0';
> - nextname = subname + idx + 1;
> - /* Handle multiple delimiters */
> - while (ISDIRDELIM(*nextname))
> - nextname++;
> - if (dols && *nextname == '\0')
> - firsttime = 0;
> - } else {
> - if (dols && firsttime) {
> - firsttime = 0;
> - } else {
> - isdir = 0;
> - }
> - }
> -
> - if (get_dentfromdir(mydata, startsect, subname, dentptr,
> - isdir ? 0 : dols) == NULL) {
> - if (dols && !isdir)
> - *size = 0;
> - goto exit;
> - }
> -
> - if (isdir && !(dentptr->attr & ATTR_DIR))
> - goto exit;
> -
> - /*
> - * If we are looking for a directory, and found a directory
> - * type entry, and the entry is for the root directory (as
> - * denoted by a cluster number of 0), jump back to the start
> - * of the function, since at least on FAT12/16, the root dir
> - * lives in a hard-coded location and needs special handling
> - * to parse, rather than simply following the cluster linked
> - * list in the FAT, like other directories.
> - */
Have you checked this case still works? AFAICS this is not covered in fs-
test.sh. Examples of suitables sandbox commands are given in the commit
message of:
18a10d46f267057ede0490ddba71c106475b4eb1 (fat: handle paths that include ../)
> - if (isdir && (dentptr->attr & ATTR_DIR) && !START(dentptr)) {
> - /*
> - * Modify the filename to remove the prefix that gets
> - * back to the root directory, so the initial root dir
> - * parsing code can continue from where we are without
> - * confusion.
> - */
> - strcpy(fnamecopy, nextname ?: "");
> - /*
> - * Set up state the same way as the function does when
> - * first started. This is required for the root dir
> - * parsing code operates in its expected environment.
> - */
> - subname = "";
> - cursect = mydata->rootdir_sect;
> - isdir = 0;
> - goto root_reparse;
> - }
> -
> - if (idx >= 0)
> - subname = nextname;
> - }
> -
> - if (dogetsize) {
> - *size = FAT2CPU32(dentptr->size);
> - ret = 0;
> - } else {
> - ret = get_contents(mydata, dentptr, pos, buffer, maxsize, size);
> - }
> - debug("Size: %u, got: %llu\n", FAT2CPU32(dentptr->size), *size);
> -
> -exit:
> - free(mydata->fatbuf);
> - return ret;
> -}
> -
>
> /*
> * Directory iterator, to simplify filesystem traversal
> @@ -1571,12 +939,6 @@ static int fat_itr_resolve(fat_itr *itr, const char
> *path, unsigned type) return -ENOENT;
> }
>
> -int do_fat_read(const char *filename, void *buffer, loff_t maxsize, int
> dols, - loff_t *actread)
> -{
> - return do_fat_read_at(filename, 0, buffer, maxsize, dols, 0, actread);
> -}
> -
> int file_fat_detectfs(void)
> {
> boot_sector bs;
> @@ -1641,31 +1003,96 @@ int file_fat_detectfs(void)
>
> int file_fat_ls(const char *dir)
> {
> - loff_t size;
> + fsdata fsdata;
> + fat_itr itrblock, *itr = &itrblock;
> + int files = 0, dirs = 0;
> + int ret;
> +
> + ret = fat_itr_root(itr, &fsdata);
> + if (ret)
> + return ret;
> +
> + ret = fat_itr_resolve(itr, dir, TYPE_DIR);
> + if (ret)
> + return ret;
> +
> + while (fat_itr_next(itr)) {
> + if (fat_itr_isdir(itr)) {
> + printf(" %s/\n", itr->name);
> + dirs++;
> + } else {
> + printf(" %8u %s\n",
> + FAT2CPU32(itr->dent->size),
> + itr->name);
> + files++;
> + }
> + }
> +
> + printf("\n%d file(s), %d dir(s)\n\n", files, dirs);
>
> - return do_fat_read(dir, NULL, 0, LS_YES, &size);
> + return 0;
> }
>
> int fat_exists(const char *filename)
> {
> + fsdata fsdata;
> + fat_itr itrblock, *itr = &itrblock;
> int ret;
> - loff_t size;
>
> - ret = do_fat_read_at(filename, 0, NULL, 0, LS_NO, 1, &size);
> + ret = fat_itr_root(itr, &fsdata);
> + if (ret)
> + return ret;
> +
> + ret = fat_itr_resolve(itr, filename, TYPE_ANY);
> return ret == 0;
> }
>
> int fat_size(const char *filename, loff_t *size)
> {
> - return do_fat_read_at(filename, 0, NULL, 0, LS_NO, 1, size);
> + fsdata fsdata;
> + fat_itr itrblock, *itr = &itrblock;
> + int ret;
> +
> + ret = fat_itr_root(itr, &fsdata);
> + if (ret)
> + return ret;
> +
> + ret = fat_itr_resolve(itr, filename, TYPE_FILE);
> + if (ret) {
> + /*
> + * Directories don't have size, but fs_size() is not
> + * expected to fail if passed a directory path:
> + */
> + fat_itr_root(itr, &fsdata);
> + if (!fat_itr_resolve(itr, filename, TYPE_DIR)) {
> + *size = 0;
> + return 0;
> + }
It might be simpler to resolve with (TYPE_ANY) and check the TYPE of the
returned iterator.
> + return ret;
> + }
> +
> + *size = FAT2CPU32(itr->dent->size);
> +
> + return 0;
> }
>
> int file_fat_read_at(const char *filename, loff_t pos, void *buffer,
> loff_t maxsize, loff_t *actread)
> {
> + fsdata fsdata;
> + fat_itr itrblock, *itr = &itrblock;
> + int ret;
> +
> + ret = fat_itr_root(itr, &fsdata);
> + if (ret)
> + return ret;
> +
> + ret = fat_itr_resolve(itr, filename, TYPE_FILE);
> + if (ret)
> + return ret;
> +
> printf("reading %s\n", filename);
> - return do_fat_read_at(filename, pos, buffer, maxsize, LS_NO, 0,
> - actread);
> + return get_contents(&fsdata, itr->dent, pos, buffer, maxsize, actread);
> }
>
> int file_fat_read(const char *filename, void *buffer, int maxsize)
> diff --git a/include/fat.h b/include/fat.h
> index 6d3fc8e4a6..3e7ab9ea8d 100644
> --- a/include/fat.h
> +++ b/include/fat.h
> @@ -58,12 +58,6 @@
> */
> #define LAST_LONG_ENTRY_MASK 0x40
>
> -/* Flags telling whether we should read a file or list a directory */
> -#define LS_NO 0
> -#define LS_YES 1
> -#define LS_DIR 1
> -#define LS_ROOT 2
> -
> #define ISDIRDELIM(c) ((c) == '/' || (c) == '\\')
>
> #define FSTYPE_NONE (-1)
next prev parent reply other threads:[~2017-08-14 13:47 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-08-14 13:16 [U-Boot] [PATCH v2 0/8] fs/fat: cleanups + readdir implementation Rob Clark
2017-08-14 13:16 ` [U-Boot] [PATCH v2 1/8] fs/fat: split out helper to init fsdata Rob Clark
2017-08-14 13:16 ` [U-Boot] [PATCH v2 2/8] fs/fat: introduce new director iterators Rob Clark
2017-08-14 13:16 ` [U-Boot] [PATCH v2 3/8] fat/fs: convert to directory iterators Rob Clark
2017-08-14 13:47 ` Brüns, Stefan [this message]
2017-08-14 14:39 ` Rob Clark
2017-08-14 14:56 ` Rob Clark
2017-08-14 13:16 ` [U-Boot] [PATCH v2 4/8] fs: add fs_readdir() Rob Clark
2017-08-14 13:16 ` [U-Boot] [PATCH v2 5/8] fs/fat: implement opendir/readdir/closedir Rob Clark
2017-08-14 13:16 ` [U-Boot] [PATCH v2 6/8] fat/fs: remove a bunch of dead code Rob Clark
2017-08-14 13:16 ` [U-Boot] [PATCH v2 7/8] fat/fs: move ls to generic implementation Rob Clark
2017-08-14 13:16 ` [U-Boot] [PATCH v2 8/8] fs/fat: fix case for FAT shortnames Rob Clark
-- strict thread matches above, loose matches on Subject: below --
2017-09-02 16:37 [U-Boot] [PATCH v2 0/8] fs/fat: cleanups + readdir implementation Rob Clark
2017-09-02 16:37 ` [U-Boot] [PATCH v2 3/8] fat/fs: convert to directory iterators Rob Clark
2017-09-03 15:08 ` Łukasz Majewski
2017-09-05 8:56 ` Simon Glass
2017-09-06 2:18 ` Rob Clark
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=8714069.Dt7qGlXCB0@sbruens-linux \
--to=stefan.bruens@rwth-aachen.de \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox