summaryrefslogtreecommitdiffstats
path: root/nuttx/fs
diff options
context:
space:
mode:
authorpatacongo <patacongo@7fd9a85b-ad96-42d3-883c-3090e2eb8679>2008-11-16 14:54:03 +0000
committerpatacongo <patacongo@7fd9a85b-ad96-42d3-883c-3090e2eb8679>2008-11-16 14:54:03 +0000
commit5b3b08e98252873aa8acb135b5978c9712d35813 (patch)
tree285d4324e62a9f0a9dc4543b7577a23bcef12058 /nuttx/fs
parent0ef1633c37f69c7f772c71bc032427b105b72324 (diff)
Fix some lseek to zero problems
git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@1251 7fd9a85b-ad96-42d3-883c-3090e2eb8679
Diffstat (limited to 'nuttx/fs')
-rw-r--r--nuttx/fs/fat/fs_fat32.c235
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. */