diff options
author | patacongo <patacongo@7fd9a85b-ad96-42d3-883c-3090e2eb8679> | 2008-11-16 14:54:03 +0000 |
---|---|---|
committer | patacongo <patacongo@7fd9a85b-ad96-42d3-883c-3090e2eb8679> | 2008-11-16 14:54:03 +0000 |
commit | 5b3b08e98252873aa8acb135b5978c9712d35813 (patch) | |
tree | 285d4324e62a9f0a9dc4543b7577a23bcef12058 | |
parent | 0ef1633c37f69c7f772c71bc032427b105b72324 (diff) |
Fix some lseek to zero problems
git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@1251 7fd9a85b-ad96-42d3-883c-3090e2eb8679
-rw-r--r-- | nuttx/fs/fat/fs_fat32.c | 235 |
1 files changed, 118 insertions, 117 deletions
diff --git a/nuttx/fs/fat/fs_fat32.c b/nuttx/fs/fat/fs_fat32.c index 1f8acd4fdb..bd22a61e5c 100644 --- a/nuttx/fs/fat/fs_fat32.c +++ b/nuttx/fs/fat/fs_fat32.c @@ -304,7 +304,6 @@ static int fat_open(FAR struct file *filep, const char *relpath, ff->ff_open = TRUE; ff->ff_oflags = oflags; - ff->ff_sectorsincluster = 1; /* Save information that can be used later to recover the directory entry */ @@ -925,135 +924,137 @@ static off_t fat_seek(FAR struct file *filep, off_t offset, int whence) position = ff->ff_size; } - /* Set file position to the beginning of the file */ + /* Set file position to the beginning of the file (first cluster, + * first sector in cluster) + */ filep->f_pos = 0; - ff->ff_sectorsincluster = 1; + ff->ff_sectorsincluster = fs->fs_fatsecperclus; + + /* Get the start cluster of the file */ + + cluster = ff->ff_startcluster; + + /* Create a new cluster chain if the file does not have one (and + * if we are seeking beyond zero + */ + + if (!cluster && position > 0) + { + cluster = fat_createchain(fs); + if (cluster < 0) + { + ret = cluster; + goto errout_with_semaphore; + } + ff->ff_startcluster = cluster; + } /* Move file position if necessary */ - if (position) + if (cluster) { - /* Get the start cluster of the file */ + /* If the file has a cluster chain, follow it to the + * requested position. + */ - cluster = ff->ff_startcluster; - if (!cluster) + clustersize = fs->fs_fatsecperclus * fs->fs_hwsectorsize; + for (;;) { - /* Create a new cluster chain if the file does not have one */ + /* Skip over clusters prior to the one containing + * the requested position. + */ + + ff->ff_currentcluster = cluster; + if (position < clustersize) + { + break; + } + + /* Extend the cluster chain if write in enabled. NOTE: + * this is not consistent with the lseek description: + * "The lseek() function allows the file offset to be + * set beyond the end of the file (but this does not + * change the size of the file). If data is later written + * at this point, subsequent reads of the data in the + * gap (a "hole") return null bytes ('\0') until data + * is actually written into the gap." + */ + + if ((ff->ff_oflags & O_WROK) != 0) + { + /* Extend the cluster chain (fat_extendchain + * will follow the existing chain or add new + * clusters as needed. + */ + + cluster = fat_extendchain(fs, cluster); + } + else + { + /* Otherwise we can only follong the existing chain */ + + cluster = fat_getcluster(fs, cluster); + } + + if (cluster < 0) + { + /* An error occurred getting the cluster */ + + ret = cluster; + goto errout_with_semaphore; + } + + /* Zero means that there is no further clusters available + * in the chain. + */ - cluster = fat_createchain(fs); - if (cluster < 0) + if (cluster == 0) { - ret = cluster; - goto errout_with_semaphore; + /* At the position to the current locaiton and + * break out. + */ + + position = clustersize; + break; } - ff->ff_startcluster = cluster; + + if (cluster >= fs->fs_nclusters) + { + ret = -ENOSPC; + goto errout_with_semaphore; + } + + /* Otherwise, update the position and continue looking */ + + filep->f_pos += clustersize; + position -= clustersize; } - if (cluster) - { - /* If the file has a cluster chain, follow it to the - * requested position. - */ - - clustersize = fs->fs_fatsecperclus * fs->fs_hwsectorsize; - for (;;) - { - /* Skip over clusters prior to the one containing - * the requested position. - */ - - ff->ff_currentcluster = cluster; - if (position < clustersize) - { - break; - } - - /* Extend the cluster chain if write in enabled. NOTE: - * this is not consistent with the lseek description: - * "The lseek() function allows the file offset to be - * set beyond the end of the file (but this does not - * change the size of the file). If data is later written - * at this point, subsequent reads of the data in the - * gap (a "hole") return null bytes ('\0') until data - * is actually written into the gap." - */ - - if ((ff->ff_oflags & O_WROK) != 0) - { - /* Extend the cluster chain (fat_extendchain - * will follow the existing chain or add new - * clusters as needed. - */ - - cluster = fat_extendchain(fs, cluster); - } - else - { - /* Otherwise we can only follong the existing chain */ - - cluster = fat_getcluster(fs, cluster); - } - - if (cluster < 0) - { - /* An error occurred getting the cluster */ - - ret = cluster; - goto errout_with_semaphore; - } - - /* Zero means that there is no further clusters available - * in the chain. - */ - - if (cluster == 0) - { - /* At the position to the current locaiton and - * break out. - */ - - position = clustersize; - break; - } - - if (cluster >= fs->fs_nclusters) - { - ret = -ENOSPC; - goto errout_with_semaphore; - } - - /* Otherwise, update the position and continue looking */ - - filep->f_pos += clustersize; - position -= clustersize; - } - - /* We get here after we have found the sector containing - * the requested position. - * - * Save the new file position - */ - - filep->f_pos += position; - - /* Then get the current sector from the cluster and the offset - * into the cluster from the position - */ - - (void)fat_currentsector(fs, ff, filep->f_pos); - - /* Load the sector corresponding to the position */ - - if ((position & SEC_NDXMASK(fs)) != 0) - { - ret = fat_ffcacheread(fs, ff, ff->ff_currentsector); - if (ret < 0) - { - goto errout_with_semaphore; - } - } - } + /* We get here after we have found the sector containing + * the requested position. + * + * Save the new file position + */ + + filep->f_pos += position; + + /* Then get the current sector from the cluster and the offset + * into the cluster from the position + */ + + (void)fat_currentsector(fs, ff, filep->f_pos); + + /* Load the sector corresponding to the position */ + + if ((position & SEC_NDXMASK(fs)) != 0) + { + ret = fat_ffcacheread(fs, ff, ff->ff_currentsector); + if (ret < 0) + { + goto errout_with_semaphore; + } + } } /* If we extended the size of the file, then mark the file as modified. */ |