Fix a FAT error when trying to create file in a non-existent directory. Reported by Andrew Tridgell.

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5764 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2013-03-20 15:26:50 +00:00
parent 7f8958d651
commit d5d9fa89ab
3 changed files with 48 additions and 12 deletions

View file

@ -4389,3 +4389,9 @@
build different objects in the first and second pass kernel builds need
to keep those objects in separate directories so that they are not
constantly rebuilt (2013-93-19).
* fs/fat: Create an error in FAT file creation. The FAT logic was
not making a distinction between directory non-existence and file
non-existence so when it you try to create a file in a non-existent
directory, it would create a file with the nameof the missing
directory. Reported by Andrew Tridgell.

View file

@ -260,6 +260,12 @@ static int fat_open(FAR struct file *filep, const char *relpath,
/* fall through to finish the file open operations */
}
/* ENOENT would be returned by fat_finddirentry() if the full
* directory path was found, but the file was not found in the
* final directory.
*/
else if (ret == -ENOENT)
{
/* The file does not exist. Were we asked to create it? */
@ -284,6 +290,9 @@ static int fat_open(FAR struct file *filep, const char *relpath,
direntry = &fs->fs_buffer[dirinfo.fd_seq.ds_offset];
}
/* No other error is handled */
else
{
/* An error occurred while checking for file existence --
@ -1406,6 +1415,7 @@ static int fat_opendir(struct inode *mountpt, const char *relpath, struct fs_dir
{
goto errout_with_semaphore;
}
direntry = &fs->fs_buffer[dirinfo.fd_seq.ds_offset];
/* Check if this is the root directory */
@ -1942,11 +1952,20 @@ static int fat_mkdir(struct inode *mountpt, const char *relpath, mode_t mode)
ret = fat_finddirentry(fs, &dirinfo, relpath);
/* If anything exists at this location, then we fail with EEXIST */
/* Or if any error occurs other -ENOENT, then return the error. For
* example, if one of the earlier directory path segments was not found
* then ENOTDIR will be returned.
*/
if (ret == OK)
if (ret != -ENOENT)
{
ret = -EEXIST;
/* If anything exists at this location, then we fail with EEXIST */
if (ret == OK)
{
ret = -EEXIST;
}
goto errout_with_semaphore;
}
@ -2224,13 +2243,6 @@ int fat_rename(struct inode *mountpt, const char *oldrelpath,
/* Now find the directory where we should create the newpath object */
ret = fat_finddirentry(fs, &dirinfo, newrelpath);
if (ret == OK)
{
/* It is an error if the object at newrelpath already exists */
ret = -EEXIST;
goto errout_with_semaphore;
}
/* What we expect is -ENOENT mean that the full directory path was
* followed but that the object does not exists in the terminal directory.
@ -2238,6 +2250,13 @@ int fat_rename(struct inode *mountpt, const char *oldrelpath,
if (ret != -ENOENT)
{
if (ret == OK)
{
/* It is an error if the object at newrelpath already exists */
ret = -EEXIST;
}
goto errout_with_semaphore;
}

View file

@ -2343,6 +2343,17 @@ int fat_finddirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo,
if (ret < 0)
{
/* A return value of -ENOENT would mean that the path segement
* was not found. Let's distinguish to cases: (1) the final
* file was not found in the directory (-ENOENT), or (2) one
* of the directory path segments does not exist (-ENOTDIR)
*/
if (ret == -ENOENT && terminator != '\0')
{
return -ENOTDIR;
}
return ret;
}
@ -2351,7 +2362,7 @@ int fat_finddirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo,
* the path.
*/
if (!terminator)
if (terminator == '\0')
{
/* Return success meaning that the description the matching
* directory entry is in dirinfo.
@ -2795,7 +2806,7 @@ int fat_remove(struct fat_mountpt_s *fs, const char *relpath, bool directory)
ret = fat_finddirentry(fs, &dirinfo, relpath);
if (ret != OK)
{
/* No such path */
/* Most likely, some element of the path does not exist. */
return -ENOENT;
}