From 6adab3df7c6be815071b8162c2b5a1330a3d6334 Mon Sep 17 00:00:00 2001 From: patacongo Date: Sun, 17 Aug 2008 16:19:13 +0000 Subject: [PATCH] Fix error in FAT FS when file opened for O_APPEND git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@827 42af7a65-404d-4744-a932-0658087f49c3 --- ChangeLog | 6 +++++ Documentation/NuttX.html | 8 ++++++- TODO | 2 +- fs/fat/fs_fat32.c | 48 +++++++++++++++++++++++++--------------- 4 files changed, 44 insertions(+), 20 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7e7ce7c6c6..1c828cf7ec 100644 --- a/ChangeLog +++ b/ChangeLog @@ -406,4 +406,10 @@ int and unsigned int. * Add support for redirection of command output in NSH * NSH can now use both telnet and serial front ends together + * $variable can be used for any command value in NSH. + * Fixed an error in opendir() that could cause an assertion to fail + inappropriately. + * Correct an error in the FAT that caused files opened for writing with + O_APPEND to fail. The file was not being properly positioned to the + end of the file in that case. diff --git a/Documentation/NuttX.html b/Documentation/NuttX.html index fdf88f3af6..c4bbf8b420 100644 --- a/Documentation/NuttX.html +++ b/Documentation/NuttX.html @@ -8,7 +8,7 @@

NuttX RTOS

-

Last Updated: August 16, 2008

+

Last Updated: August 17, 2008

@@ -1040,6 +1040,12 @@ nuttx-0.3.13 2008-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr> int and unsigned int. * Add support for redirection of command output in NSH * NSH can now use both telnet and serial front ends together + * $variable can be used for any command value in NSH. + * Fixed an error in opendir() that could cause an assertion to fail + inappropriately. + * Correct an error in the FAT that caused files opened for writing with + O_APPEND to fail. The file was not being properly positioned to the + end of the file in that case. pascal-0.1.3 2008-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr> diff --git a/TODO b/TODO index a19239b54e..1c307d6f1d 100644 --- a/TODO +++ b/TODO @@ -10,7 +10,7 @@ NuttX TODO List (Last updated July 31, 2008) (11) Network (net/, netutils/) (2) USB (drivers/usbdev) (3) Libraries (lib/) - (5) File system/Generic drivers (fs/, drivers/) + (4) File system/Generic drivers (fs/, drivers/) (1) Pascal add-on (pcode/) (2) Documentation (Documentation/) (3) Build system diff --git a/fs/fat/fs_fat32.c b/fs/fat/fs_fat32.c index a54298bcec..d4be115fd0 100644 --- a/fs/fat/fs_fat32.c +++ b/fs/fat/fs_fat32.c @@ -318,13 +318,6 @@ static int fat_open(FAR struct file *filp, const char *relpath, ff->ff_size = DIR_GETFILESIZE(dirinfo.fd_entry); - /* In write/append mode, we need to set the file pointer to the end of the file */ - - if ((oflags & (O_APPEND|O_WRONLY)) == (O_APPEND|O_WRONLY)) - { - ff->ff_position = ff->ff_size; - } - /* Attach the private date to the struct file instance */ filp->f_priv = ff; @@ -339,6 +332,19 @@ static int fat_open(FAR struct file *filp, const char *relpath, fs->fs_head = ff->ff_next; fat_semgive(fs); + + /* In write/append mode, we need to set the file pointer to the end of the file */ + + if ((oflags & (O_APPEND|O_WRONLY)) == (O_APPEND|O_WRONLY)) + { + ssize_t offset = (ssize_t)fat_seek(filp, ff->ff_size, SEEK_SET); + if (offset < 0) + { + free(ff); + return (int)offset; + } + } + return OK; /* Error exits -- goto's are nasty things, but they sure can make error @@ -670,7 +676,7 @@ static ssize_t fat_write(FAR struct file *filp, const char *buffer, */ byteswritten = 0; - writesector = ff->ff_currentsector; + writesector = ff->ff_currentsector; while (buflen > 0) { /* Get offset into the sector where we begin the read */ @@ -727,11 +733,11 @@ static ssize_t fat_write(FAR struct file *filp, const char *buffer, else { - /* Extend the chain by adding a new cluster after - * the last one - */ + /* Extend the chain by adding a new cluster after + * the last one + */ - cluster = fat_extendchain(fs, ff->ff_currentcluster); + cluster = fat_extendchain(fs, ff->ff_currentcluster); } /* Verify the cluster number */ @@ -768,7 +774,7 @@ static ssize_t fat_write(FAR struct file *filp, const char *buffer, */ nsectors = buflen / fs->fs_hwsectorsize; - if (nsectors > 0) + if (nsectors > 0 && sectorindex == 0) { /* Write maximum contiguous sectors directly from the user's * buffer without using our tiny read buffer. @@ -804,12 +810,18 @@ static ssize_t fat_write(FAR struct file *filp, const char *buffer, } else { - /* We are write a partial sector. We will first have to - * read the full sector in memory as part of a read-modify-write - * operation. + /* We are writing a partial sector -OR- the current sector + * has not yet been filled. + * + * We will first have to read the full sector in memory as + * part of a read-modify-write operation. NOTE we don't + * have to read the data on a rare case: When we are extending + * the file (ff->ff_position == ff->ff_size) -AND- the new data + * happens to be aligned at the beginning of the sector + * (sectorindex == 0). */ - if (ff->ff_position < ff->ff_size) + if (ff->ff_position < ff->ff_size || sectorindex != 0) { ff->ff_currentsector = writesector; ret = fat_ffcacheread(fs, ff, writesector); @@ -997,7 +1009,7 @@ static off_t fat_seek(FAR struct file *filp, off_t offset, int whence) } else { - /* Other we can only follong the existing chain */ + /* Otherwise we can only follong the existing chain */ cluster = fat_getcluster(fs, cluster); }