[U-Boot] [PATCH 02/17] fs: fat: handle "." and ".." of root dir correctly with fat_itr_resolve()

AKASHI Takahiro takahiro.akashi at linaro.org
Mon Jul 23 07:55:02 UTC 2018


On Fri, Jul 20, 2018 at 08:09:00PM +0200, Heinrich Schuchardt wrote:
> On 07/20/2018 04:57 AM, AKASHI Takahiro wrote:
> > FAT's root directory does not have "." nor ".."
> > So care must be taken when scanning root directory with fat_itr_resolve().
> > Without this patch, any file path starting with "." or ".." will not be
> > resolved at all.
> > 
> > Signed-off-by: AKASHI Takahiro <takahiro.akashi at linaro.org>
> > ---
> >  fs/fat/fat.c | 21 +++++++++++++++++++++
> >  1 file changed, 21 insertions(+)
> > 
> > diff --git a/fs/fat/fat.c b/fs/fat/fat.c
> > index b48f48a751..fd6523c66b 100644
> > --- a/fs/fat/fat.c
> > +++ b/fs/fat/fat.c
> > @@ -927,6 +927,27 @@ static int fat_itr_resolve(fat_itr *itr, const char *path, unsigned type)
> >  	while (next[0] && !ISDIRDELIM(next[0]))
> >  		next++;
> >  
> > +	if (itr->is_root) {
> > +		/* root dir doesn't have "." nor ".." */
> 
> I understand why root has no ../ but  /./ should be valid.

What I meant here is that, according to FAT specification, the root
directory has neither "." directory entry nor ".." in its associated
clusters in contrast to ordinary directories.
So when user specifies "." or ".." (and other variants), we will have to
take special care to handle them correctly.

> On Linux 'ls /./' displays the root directory.

My code works with any of the following paths:
 * .
 * ..
 * /
 * /.
 * /.., or
 * even any combination of above, like
     ./.././.././

Note that "ls /.." on linux also shows the root directory.

Please try.

-Takahiro AKASHI


> Best regards
> 
> Heinrich
> 
> > +		if ((((next - path) == 1) && !strncmp(path, ".", 1)) ||
> > +		    (((next - path) == 2) && !strncmp(path, "..", 2))) {
> > +			/* point back to itself */
> > +			itr->clust = itr->fsdata->root_cluster;
> > +			itr->dent = NULL;
> > +			itr->remaining = 0;
> > +			itr->last_cluster = 0;
> > +
> > +			if (next[0] == 0) {
> > +				if (type & TYPE_DIR)
> > +					return 0;
> > +				else
> > +					return -ENOENT;
> > +			}
> > +
> > +			return fat_itr_resolve(itr, next, type);
> > +		}
> > +	}
> > +
> >  	while (fat_itr_next(itr)) {
> >  		int match = 0;
> >  		unsigned n = max(strlen(itr->name), (size_t)(next - path));
> > 
> 


More information about the U-Boot mailing list