All of lore.kernel.org
 help / color / mirror / Atom feed
From: AKASHI Takahiro <takahiro.akashi@linaro.org>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH] fs: fat: handle deleted directory entries correctly
Date: Wed, 27 Nov 2019 13:34:13 +0900	[thread overview]
Message-ID: <20191127043412.GM22427@linaro.org> (raw)
In-Reply-To: <20191126082931.23698-1-takahiro.akashi@linaro.org>

On Tue, Nov 26, 2019 at 05:29:31PM +0900, AKASHI Takahiro wrote:
> Unlink test for FAT file system seems to fail at test_unlink2.
> (When I added this test, I haven't seen any errors though.)

FYI, once the following patches are merged, file system pytests
under /test/py/tests/test_fs will start to be invoked for sandbox build
on Travis CI.

[1] https://lists.denx.de/pipermail/u-boot/2019-November/391743.html
[2] https://lists.denx.de/pipermail/u-boot/2019-November/391742.html

Thanks,
-Takahiro Akashi


> for example,
> ===8<===
> fs_obj_unlink = ['fat', '/home/akashi/tmp/uboot_sandbox_test/128MB.fat32.img']
> 
>     def test_unlink2(self, u_boot_console, fs_obj_unlink):
>         """
>         Test Case 2 - delete many files
>         """
>         fs_type,fs_img = fs_obj_unlink
>         with u_boot_console.log.section('Test Case 2 - unlink (many)'):
>             output = u_boot_console.run_command('host bind 0 %s' % fs_img)
> 
>             for i in range(0, 20):
>                 output = u_boot_console.run_command_list([
>                     '%srm host 0:0 dir2/0123456789abcdef%02x' % (fs_type, i),
>                     '%sls host 0:0 dir2/0123456789abcdef%02x' % (fs_type, i)])
>                 assert('' == ''.join(output))
> 
>             output = u_boot_console.run_command(
>                 '%sls host 0:0 dir2' % fs_type)
> >           assert('0 file(s), 2 dir(s)' in output)
> E           AssertionError: assert '0 file(s), 2 dir(s)' in '            ./\r\r\n            ../\r\r\n        0   0123456789abcdef11\r\r\n\r\r\n1 file(s), 2 dir(s)'
> 
> test/py/tests/test_fs/test_unlink.py:52: AssertionError
> ===>8===
> 
> This can happen when fat_itr_next() wrongly detects an already-
> deleted directory entry.
> 
> File deletion, which was added in the commit f8240ce95d64 ("fs: fat:
> support unlink"), is implemented by marking its entry for a short name
> with DELETED_FLAG, but related entry slots for a long file name are kept
> unmodified. (So entries will never be actually deleted from media.)
> 
> To handle this case correctly, an additional check for a directory slot
> will be needed in fat_itr_next().
> 
> In addition, I added extra comments about long file name and short file
> name format in FAT file system. Although they are not directly related
> to the issue, I hope it will be helpful for better understandings
> in general.
> 
> Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
> ---
>  fs/fat/fat.c | 33 ++++++++++++++++++++++++++++++++-
>  1 file changed, 32 insertions(+), 1 deletion(-)
> 
> diff --git a/fs/fat/fat.c b/fs/fat/fat.c
> index 9e1b842dac6b..68ce65838678 100644
> --- a/fs/fat/fat.c
> +++ b/fs/fat/fat.c
> @@ -869,6 +869,14 @@ static dir_entry *extract_vfat_name(fat_itr *itr)
>  			return NULL;
>  	}
>  
> +	/*
> +	 * We are now at the short file name entry.
> +	 * If it is marked as deleted, just skip it.
> +	 */
> +	if (dent->name[0] == DELETED_FLAG ||
> +	    dent->name[0] == aRING)
> +		return NULL;
> +
>  	itr->l_name[n] = '\0';
>  
>  	chksum = mkcksum(dent->name, dent->ext);
> @@ -898,6 +906,16 @@ static int fat_itr_next(fat_itr *itr)
>  
>  	itr->name = NULL;
>  
> +	/*
> +	 * One logical directory entry consist of following slots:
> +	 *				name[0]	Attributes
> +	 *   dent[N - N]: LFN[N - 1]	N|0x40	ATTR_VFAT
> +	 *   ...
> +	 *   dent[N - 2]: LFN[1]	2	ATTR_VFAT
> +	 *   dent[N - 1]: LFN[0]	1	ATTR_VFAT
> +	 *   dent[N]:     SFN			ATTR_ARCH
> +	 */
> +
>  	while (1) {
>  		dent = next_dent(itr);
>  		if (!dent)
> @@ -910,7 +928,17 @@ static int fat_itr_next(fat_itr *itr)
>  		if (dent->attr & ATTR_VOLUME) {
>  			if ((dent->attr & ATTR_VFAT) == ATTR_VFAT &&
>  			    (dent->name[0] & LAST_LONG_ENTRY_MASK)) {
> +				/* long file name */
>  				dent = extract_vfat_name(itr);
> +				/*
> +				 * If succeeded, dent has a valid short file
> +				 * name entry for the current entry.
> +				 * If failed, itr points to a current bogus
> +				 * entry. So after fetching a next one,
> +				 * it may have a short file name entry
> +				 * for this bogus entry so that we can still
> +				 * check for a short name.
> +				 */
>  				if (!dent)
>  					continue;
>  				itr->name = itr->l_name;
> @@ -919,8 +947,11 @@ static int fat_itr_next(fat_itr *itr)
>  				/* Volume label or VFAT entry, skip */
>  				continue;
>  			}
> -		}
> +		} else if (!(dent->attr & ATTR_ARCH) &&
> +			   !(dent->attr & ATTR_DIR))
> +			continue;
>  
> +		/* short file name */
>  		break;
>  	}
>  
> -- 
> 2.24.0
> 

  reply	other threads:[~2019-11-27  4:34 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-11-26  8:29 [U-Boot] [PATCH] fs: fat: handle deleted directory entries correctly AKASHI Takahiro
2019-11-27  4:34 ` AKASHI Takahiro [this message]
2019-12-05 22:09 ` Tom Rini
2020-01-13 10:52   ` fat: handle Windows formatted partition (thru USB Mass Storage) Andy Shevchenko
2020-01-13 10:53     ` Fwd: " Andy Shevchenko
2020-01-13 16:34     ` Tom Rini
2020-01-13 17:55       ` Heinrich Schuchardt
2020-01-13 19:15         ` Andy Shevchenko
2020-01-13 19:22           ` Andy Shevchenko
2020-01-13 20:58             ` Andy Shevchenko
2020-01-13 21:05               ` Heinrich Schuchardt
2020-01-13 21:52                 ` Andy Shevchenko
2020-01-13 23:14                   ` Heinrich Schuchardt
2020-01-14  8:21                     ` Andy Shevchenko
2020-01-14  8:23                       ` Andy Shevchenko
2020-01-14 12:43                         ` Andy Shevchenko
2020-01-14 13:16                           ` Andy Shevchenko
2020-01-15  0:12                           ` AKASHI Takahiro
2020-01-16  2:01                             ` AKASHI Takahiro
2020-01-16 10:39                               ` Andy Shevchenko
2020-01-16 19:20                                 ` Heinrich Schuchardt
2020-01-16 20:31                                   ` Andy Shevchenko
2020-01-17  6:12                                     ` AKASHI Takahiro
2020-01-17  9:47                                       ` Andy Shevchenko
2020-01-17 14:51                                         ` Tom Rini
2020-01-21  0:39                                         ` AKASHI Takahiro
2020-01-21 16:13                                           ` Andy Shevchenko

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=20191127043412.GM22427@linaro.org \
    --to=takahiro.akashi@linaro.org \
    --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.