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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.