summaryrefslogtreecommitdiff
path: root/nuttx/fs/fat
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2011-07-13 13:30:38 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2011-07-13 13:30:38 +0000
commitedeffa28c526825510f7ff35024ea242f82252e5 (patch)
tree6e73fb2151408160fea483c4c143ef6cf95c00ed /nuttx/fs/fat
parent286a4141b552e05aa782b1fafa192426af2f42a2 (diff)
downloadpx4-nuttx-edeffa28c526825510f7ff35024ea242f82252e5.tar.gz
px4-nuttx-edeffa28c526825510f7ff35024ea242f82252e5.tar.bz2
px4-nuttx-edeffa28c526825510f7ff35024ea242f82252e5.zip
Re-architect FAT data structures to support long file names
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3780 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/fs/fat')
-rw-r--r--nuttx/fs/fat/fs_fat32.c88
-rw-r--r--nuttx/fs/fat/fs_fat32.h64
-rw-r--r--nuttx/fs/fat/fs_fat32attrib.c8
-rw-r--r--nuttx/fs/fat/fs_fat32dirent.c111
-rw-r--r--nuttx/fs/fat/fs_fat32util.c21
5 files changed, 171 insertions, 121 deletions
diff --git a/nuttx/fs/fat/fs_fat32.c b/nuttx/fs/fat/fs_fat32.c
index 098f3be31..09db4766b 100644
--- a/nuttx/fs/fat/fs_fat32.c
+++ b/nuttx/fs/fat/fs_fat32.c
@@ -160,6 +160,7 @@ static int fat_open(FAR struct file *filep, const char *relpath,
struct inode *inode;
struct fat_mountpt_s *fs;
struct fat_file_s *ff;
+ uint8_t *direntry;
int ret;
/* Sanity checks */
@@ -203,10 +204,12 @@ static int fat_open(FAR struct file *filep, const char *relpath,
/* The name exists -- but is it a file or a directory? */
- if (dirinfo.fd_entry == NULL ||
- (DIR_GETATTRIBUTES(dirinfo.fd_entry) & FATATTR_DIRECTORY))
+ direntry = &fs->fs_buffer[dirinfo.fd_seq.ds_offset];
+ if (dirinfo.fd_root ||
+ (DIR_GETATTRIBUTES(direntry) & FATATTR_DIRECTORY))
{
/* It is a directory */
+
ret = -EISDIR;
goto errout_with_semaphore;
}
@@ -227,7 +230,7 @@ static int fat_open(FAR struct file *filep, const char *relpath,
/* Check if the caller has sufficient privileges to open the file */
- readonly = ((DIR_GETATTRIBUTES(dirinfo.fd_entry) & FATATTR_READONLY) != 0);
+ readonly = ((DIR_GETATTRIBUTES(direntry) & FATATTR_READONLY) != 0);
if (((oflags & O_WRONLY) != 0) && readonly)
{
ret = -EACCES;
@@ -273,6 +276,8 @@ static int fat_open(FAR struct file *filep, const char *relpath,
}
/* Fall through to finish the file open operation */
+
+ direntry = &fs->fs_buffer[dirinfo.fd_seq.ds_offset];
}
else
{
@@ -316,12 +321,12 @@ static int fat_open(FAR struct file *filep, const char *relpath,
/* File cluster/size info */
ff->ff_startcluster =
- ((uint32_t)DIR_GETFSTCLUSTHI(dirinfo.fd_entry) << 16) |
- DIR_GETFSTCLUSTLO(dirinfo.fd_entry);
+ ((uint32_t)DIR_GETFSTCLUSTHI(direntry) << 16) |
+ DIR_GETFSTCLUSTLO(direntry);
ff->ff_currentcluster = ff->ff_startcluster;
ff->ff_sectorsincluster = fs->fs_fatsecperclus;
- ff->ff_size = DIR_GETFILESIZE(dirinfo.fd_entry);
+ ff->ff_size = DIR_GETFILESIZE(direntry);
/* Attach the private date to the struct file instance */
@@ -1224,7 +1229,8 @@ static int fat_opendir(struct inode *mountpt, const char *relpath, struct fs_dir
{
struct fat_mountpt_s *fs;
struct fat_dirinfo_s dirinfo;
- int ret;
+ uint8_t *direntry;
+ int ret;
/* Sanity checks */
@@ -1250,10 +1256,11 @@ 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 */
- if (dirinfo.fd_entry == NULL)
+ if (dirinfo.fd_root)
{
/* Handle the FAT12/16/32 root directory using the values setup by
* fat_finddirentry() above.
@@ -1267,7 +1274,7 @@ static int fat_opendir(struct inode *mountpt, const char *relpath, struct fs_dir
/* This is not the root directory. Verify that it is some kind of directory */
- else if ((DIR_GETATTRIBUTES(dirinfo.fd_entry) & FATATTR_DIRECTORY) == 0)
+ else if ((DIR_GETATTRIBUTES(direntry) & FATATTR_DIRECTORY) == 0)
{
/* The entry is not a directory */
ret = -ENOTDIR;
@@ -1278,8 +1285,8 @@ static int fat_opendir(struct inode *mountpt, const char *relpath, struct fs_dir
/* The entry is a directory */
dir->u.fat.fd_startcluster =
- ((uint32_t)DIR_GETFSTCLUSTHI(dirinfo.fd_entry) << 16) |
- DIR_GETFSTCLUSTLO(dirinfo.fd_entry);
+ ((uint32_t)DIR_GETFSTCLUSTHI(direntry) << 16) |
+ DIR_GETFSTCLUSTLO(direntry);
dir->u.fat.fd_currcluster = dir->u.fat.fd_startcluster;
dir->u.fat.fd_currsector = fat_cluster2sector(fs, dir->u.fat.fd_currcluster);
dir->u.fat.fd_index = 2;
@@ -1819,7 +1826,7 @@ static int fat_mkdir(struct inode *mountpt, const char *relpath, mode_t mode)
* management routines.
*/
- memset(&direntry[DIR_NAME], ' ', 8+3);
+ memset(&direntry[DIR_NAME], ' ', DIR_MAXFNAME);
direntry[DIR_NAME] = '.';
DIR_PUTATTRIBUTES(direntry, FATATTR_DIRECTORY);
@@ -1875,8 +1882,9 @@ static int fat_mkdir(struct inode *mountpt, const char *relpath, mode_t mode)
* change the sector in the cache.
*/
- DIR_PUTFSTCLUSTLO(dirinfo.fd_entry, dircluster);
- DIR_PUTFSTCLUSTHI(dirinfo.fd_entry, dircluster >> 16);
+ direntry = &fs->fs_buffer[dirinfo.fd_seq.ds_offset];
+ DIR_PUTFSTCLUSTLO(direntry, dircluster);
+ DIR_PUTFSTCLUSTHI(direntry, dircluster >> 16);
fs->fs_dirty = true;
/* Now update the FAT32 FSINFO sector */
@@ -1951,9 +1959,8 @@ int fat_rename(struct inode *mountpt, const char *oldrelpath,
{
struct fat_mountpt_s *fs;
struct fat_dirinfo_s dirinfo;
- off_t oldsector;
- uint8_t *olddirentry;
- uint8_t *newdirentry;
+ struct fat_dirseq_s dirseq;
+ uint8_t *direntry;
uint8_t dirstate[DIR_SIZE-DIR_ATTRIBUTES];
int ret;
@@ -1988,7 +1995,7 @@ int fat_rename(struct inode *mountpt, const char *oldrelpath,
* root directory. We can't rename the root directory.
*/
- if (!dirinfo.fd_entry)
+ if (dirinfo.fd_root)
{
ret = -EXDEV;
goto errout_with_semaphore;
@@ -1998,9 +2005,10 @@ int fat_rename(struct inode *mountpt, const char *oldrelpath,
* directory entry offset to the old directory.
*/
- olddirentry = dirinfo.fd_entry;
- oldsector = fs->fs_currentsector;
- memcpy(dirstate, &olddirentry[DIR_ATTRIBUTES], DIR_SIZE-DIR_ATTRIBUTES);
+ memcpy(&dirseq, &dirinfo.fd_seq, sizeof(struct fat_dirseq_s));
+
+ direntry = &fs->fs_buffer[dirinfo.fd_seq.ds_offset];
+ memcpy(dirstate, &direntry[DIR_ATTRIBUTES], DIR_SIZE-DIR_ATTRIBUTES);
/* No find the directory where we should create the newpath object */
@@ -2032,8 +2040,8 @@ int fat_rename(struct inode *mountpt, const char *oldrelpath,
/* Write the new directory entry */
- newdirentry = dirinfo.fd_entry;
- memcpy(&newdirentry[DIR_ATTRIBUTES], dirstate, DIR_SIZE-DIR_ATTRIBUTES);
+ direntry = &fs->fs_buffer[dirinfo.fd_seq.ds_offset];
+ memcpy(&direntry[DIR_ATTRIBUTES], dirstate, DIR_SIZE-DIR_ATTRIBUTES);
fs->fs_dirty = true;
ret = fat_dirnamewrite(fs, &dirinfo);
@@ -2042,19 +2050,9 @@ int fat_rename(struct inode *mountpt, const char *oldrelpath,
goto errout_with_semaphore;
}
- /* Now flush the new directory entry to disk and read the sector
- * containing the old directory entry.
- */
-
- ret = fat_fscacheread(fs, oldsector);
- if (ret < 0)
- {
- goto errout_with_semaphore;
- }
+ /* Remove the old entry (flushing the new directory entry to disk) */
- /* Remove the old entry */
-
- ret = fat_freedirentry(fs, olddirentry);
+ ret = fat_freedirentry(fs, &dirseq);
if (ret < 0)
{
goto errout_with_semaphore;
@@ -2090,6 +2088,7 @@ static int fat_stat(struct inode *mountpt, const char *relpath, struct stat *buf
uint16_t fatdate;
uint16_t date2;
uint16_t fattime;
+ uint8_t *direntry;
uint8_t attribute;
int ret;
@@ -2122,9 +2121,9 @@ static int fat_stat(struct inode *mountpt, const char *relpath, struct stat *buf
}
memset(buf, 0, sizeof(struct stat));
- if (!dirinfo.fd_entry)
+ if (dirinfo.fd_root)
{
- /* It's directory name of mount point */
+ /* It's directory name of the mount point */
buf->st_mode = S_IFDIR|S_IROTH|S_IRGRP|S_IRUSR|S_IWOTH|S_IWGRP|S_IWUSR;
ret = OK;
@@ -2133,7 +2132,8 @@ static int fat_stat(struct inode *mountpt, const char *relpath, struct stat *buf
/* Get the FAT attribute and map it so some meaningful mode_t values */
- attribute = DIR_GETATTRIBUTES(dirinfo.fd_entry);
+ direntry = &fs->fs_buffer[dirinfo.fd_seq.ds_offset];
+ attribute = DIR_GETATTRIBUTES(direntry);
if ((attribute & FATATTR_VOLUMEID) != 0)
{
ret = -ENOENT;
@@ -2163,17 +2163,17 @@ static int fat_stat(struct inode *mountpt, const char *relpath, struct stat *buf
/* File/directory size, access block size */
- buf->st_size = DIR_GETFILESIZE(dirinfo.fd_entry);
+ buf->st_size = DIR_GETFILESIZE(direntry);
buf->st_blksize = fs->fs_fatsecperclus * fs->fs_hwsectorsize;
buf->st_blocks = (buf->st_size + buf->st_blksize - 1) / buf->st_blksize;
/* Times */
- fatdate = DIR_GETWRTDATE(dirinfo.fd_entry);
- fattime = DIR_GETWRTTIME(dirinfo.fd_entry);
+ fatdate = DIR_GETWRTDATE(direntry);
+ fattime = DIR_GETWRTTIME(direntry);
buf->st_mtime = fat_fattime2systime(fattime, fatdate);
- date2 = DIR_GETLASTACCDATE(dirinfo.fd_entry);
+ date2 = DIR_GETLASTACCDATE(direntry);
if (fatdate == date2)
{
buf->st_atime = buf->st_mtime;
@@ -2183,8 +2183,8 @@ static int fat_stat(struct inode *mountpt, const char *relpath, struct stat *buf
buf->st_atime = fat_fattime2systime(0, date2);
}
- fatdate = DIR_GETCRDATE(dirinfo.fd_entry);
- fattime = DIR_GETCRTIME(dirinfo.fd_entry);
+ fatdate = DIR_GETCRDATE(direntry);
+ fattime = DIR_GETCRTIME(direntry);
buf->st_ctime = fat_fattime2systime(fattime, fatdate);
ret = OK;
diff --git a/nuttx/fs/fat/fs_fat32.h b/nuttx/fs/fat/fs_fat32.h
index 89c42e2a5..3d3db644c 100644
--- a/nuttx/fs/fat/fs_fat32.h
+++ b/nuttx/fs/fat/fs_fat32.h
@@ -148,8 +148,15 @@
#define PART_SIZE 12 /* 4@12: Partition size (in sectors) */
/****************************************************************************
- * Each FAT "short" 8.3 file name directory entry is 32-bytes long. The
- * following define offsets relative to the beginning of a directory entry.
+ * Each FAT "short" 8.3 file name directory entry is 32-bytes long.
+ *
+ * Sizes and limits
+ */
+
+#define DIR_MAXFNAME 11 /* Max short name size is 8+3 = 11 */
+
+/* The following define offsets relative to the beginning of a directory
+ * entry.
*/
#define DIR_NAME 0 /* 11@ 0: NAME: 8 bytes + 3 byte extension */
@@ -687,6 +694,37 @@ struct fat_file_s
uint8_t *ff_buffer; /* File buffer (for partial sector accesses) */
};
+/* This structure holds the sequency of directory entries used by one
+ * file element (directory or file). For short file names, this is
+ * single diretory entry. But for long file names, the is a sequence
+ * of directory entries. Long directory name entries appear in reverse
+ * order: Last, next-to-last, ..., first. The "first" long file name
+ * directory is then following by the short directory name entry. The
+ * short file name entry contains the real meat of the file data.
+ *
+ * So it takes the sector number and entry offset of the last long
+ * file name entry and of the short file name entry to define the
+ * sequence. In the case of short file names, the sector number and
+ * offset will be the same.
+ */
+
+struct fat_dirseq_s
+{
+ /* Sector offsets */
+
+ uint16_t ds_offset; /* Sector offset to short file name entry */
+#ifdef CONFIG_FAT_LFN
+ uint16_t ds_lfnoffset; /* Sector offset to last long file name entry */
+#endif
+
+ /* Sector numbers */
+
+ off_t ds_sector; /* Sector of the short file name entry */
+#ifdef CONFIG_FAT_LFN
+ off_t ds_lfnsector; /* Sector of the last long name entry */
+#endif
+};
+
/* This structure is used internally for describing directory entries */
struct fat_dirinfo_s
@@ -694,10 +732,9 @@ struct fat_dirinfo_s
/* The file/directory name */
#ifdef CONFIG_FAT_LFN
- uint8_t fd_name[LDIR_MAXFNAME]; /* Filename -- directory format */
-#else
- uint8_t fd_name[8+3]; /* Filename -- directory format */
+ uint8_t fd_lfname[LDIR_MAXFNAME]; /* Long filename */
#endif
+ uint8_t fd_name[DIR_MAXFNAME]; /* Short 8.3 alias filename */
/* NT flags are not used */
@@ -705,16 +742,19 @@ struct fat_dirinfo_s
uint8_t fd_ntflags; /* NTRes lower case flags */
#endif
- /* This is part of the opendir, readdir, ... logic */
+ /* TRUE if this is the root directory */
- struct fs_fatdir_s dir; /* Used with opendir, readdir, etc. */
+ bool fd_root;
- /* The following points the standard, short file name directory
- * entry that contains the real meat of the file data. Several
- * 32-byte long fine name records may have preceded this.
+ /* The following provides the sequence of directory entries used by the
+ * file or directory.
*/
- uint8_t *fd_entry; /* A pointer to the raw 32-byte entry */
+ struct fat_dirseq_s fd_seq; /* Directory sequence */
+
+ /* This is part of the opendir, readdir, ... logic */
+
+ struct fs_fatdir_s dir; /* Used with opendir, readdir, etc. */
};
/****************************************************************************
@@ -782,7 +822,7 @@ EXTERN int fat_dirnamewrite(struct fat_mountpt_s *fs, struct fat_dirinfo_s *d
EXTERN int fat_dirwrite(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo,
uint8_t attributes, uint32_t fattime);
EXTERN int fat_allocatedirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo);
-EXTERN int fat_freedirentry(struct fat_mountpt_s *fs, FAR uint8_t *direntry);
+EXTERN int fat_freedirentry(struct fat_mountpt_s *fs, struct fat_dirseq_s *seq);
EXTERN int fat_dirname2path(char *path, uint8_t *direntry);
/* File creation and removal helpers */
diff --git a/nuttx/fs/fat/fs_fat32attrib.c b/nuttx/fs/fat/fs_fat32attrib.c
index 77495d5e0..d97001ef2 100644
--- a/nuttx/fs/fat/fs_fat32attrib.c
+++ b/nuttx/fs/fat/fs_fat32attrib.c
@@ -63,6 +63,7 @@ static int fat_attrib(const char *path, fat_attrib_t *retattrib,
struct fat_dirinfo_s dirinfo;
FAR struct inode *inode;
const char *relpath = NULL;
+ uint8_t *direntry;
uint8_t oldattributes;
uint8_t newattributes;
int ret;
@@ -111,7 +112,7 @@ static int fat_attrib(const char *path, fat_attrib_t *retattrib,
/* Make sure that we found some valid file or directory */
- if (!dirinfo.fd_entry)
+ if (dirinfo.fd_root)
{
/* Ooops.. we found the root directory */
@@ -121,7 +122,8 @@ static int fat_attrib(const char *path, fat_attrib_t *retattrib,
/* Get the current attributes */
- oldattributes = DIR_GETATTRIBUTES(dirinfo.fd_entry);
+ direntry = &fs->fs_buffer[dirinfo.fd_seq.ds_offset];
+ oldattributes = DIR_GETATTRIBUTES(direntry);
newattributes = oldattributes;
/* Set or clear any bits as requested */
@@ -133,7 +135,7 @@ static int fat_attrib(const char *path, fat_attrib_t *retattrib,
if (newattributes != oldattributes)
{
- DIR_PUTATTRIBUTES(dirinfo.fd_entry, newattributes);
+ DIR_PUTATTRIBUTES(direntry, newattributes);
fs->fs_dirty = true;
ret = fat_updatefsinfo(fs);
if (ret != OK)
diff --git a/nuttx/fs/fat/fs_fat32dirent.c b/nuttx/fs/fat/fs_fat32dirent.c
index 58d08e33c..f98d75a9d 100644
--- a/nuttx/fs/fat/fs_fat32dirent.c
+++ b/nuttx/fs/fat/fs_fat32dirent.c
@@ -154,7 +154,7 @@ static inline int fat_path2dirname(const char **path, struct fat_dirinfo_s *diri
/* Initialized the name with all spaces */
- memset(dirinfo->fd_name, ' ', 8+3);
+ memset(dirinfo->fd_name, ' ', DIR_MAXFNAME);
/* Loop until the name is successfully parsed or an error occurs */
@@ -294,10 +294,11 @@ static inline int fat_path2dirname(const char **path, struct fat_dirinfo_s *diri
int fat_finddirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo,
const char *path)
{
- off_t cluster;
+ off_t cluster;
+ uint16_t diroffset;
uint8_t *direntry = NULL;
- char terminator;
- int ret;
+ char terminator;
+ int ret;
/* Initialize to traverse the chain. Set it to the cluster of
* the root directory
@@ -336,7 +337,7 @@ int fat_finddirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo,
if (*path == '\0')
{
- dirinfo->fd_entry = NULL;
+ dirinfo->fd_root = true;
return OK;
}
@@ -374,7 +375,8 @@ int fat_finddirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo,
/* Get a pointer to the directory entry */
- direntry = &fs->fs_buffer[DIRSEC_BYTENDX(fs, dirinfo->dir.fd_index)];
+ diroffset = DIRSEC_BYTENDX(fs, dirinfo->dir.fd_index);
+ direntry = &fs->fs_buffer[diroffset];
/* Check if we are at the end of the directory */
@@ -387,7 +389,7 @@ int fat_finddirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo,
if (direntry[DIR_NAME] != DIR0_EMPTY &&
!(DIR_GETATTRIBUTES(direntry) & FATATTR_VOLUMEID) &&
- !memcmp(&direntry[DIR_NAME], dirinfo->fd_name, 8+3) )
+ !memcmp(&direntry[DIR_NAME], dirinfo->fd_name, DIR_MAXFNAME) )
{
/* Yes.. break out of the loop */
@@ -412,9 +414,10 @@ int fat_finddirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo,
if (!terminator)
{
- /* Return the pointer to the matching directory entry */
+ /* Return the sector and offset to the matching directory entry */
- dirinfo->fd_entry = direntry;
+ dirinfo->fd_seq.ds_sector = fs->fs_currentsector;
+ dirinfo->fd_seq.ds_offset = diroffset;
return OK;
}
@@ -453,12 +456,13 @@ int fat_finddirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo,
int fat_allocatedirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo)
{
- int32_t cluster;
- off_t sector;
+ int32_t cluster;
+ off_t sector;
+ uint16_t diroffset;
uint8_t *direntry;
- uint8_t ch;
- int ret;
- int i;
+ uint8_t ch;
+ int ret;
+ int i;
/* Re-initialize directory object */
@@ -480,8 +484,6 @@ int fat_allocatedirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo
for (;;)
{
- unsigned int dirindex;
-
/* Read the directory sector into fs_buffer */
ret = fat_fscacheread(fs, dirinfo->dir.fd_currsector);
@@ -492,8 +494,8 @@ int fat_allocatedirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo
/* Get a pointer to the entry at fd_index */
- dirindex = (dirinfo->dir.fd_index & DIRSEC_NDXMASK(fs)) * DIR_SIZE;
- direntry = &fs->fs_buffer[dirindex];
+ diroffset = (dirinfo->dir.fd_index & DIRSEC_NDXMASK(fs)) * DIR_SIZE;
+ direntry = &fs->fs_buffer[diroffset];
/* Check if this directory entry is empty */
@@ -502,7 +504,8 @@ int fat_allocatedirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo
{
/* It is empty -- we have found a directory entry */
- dirinfo->fd_entry = direntry;
+ dirinfo->fd_seq.ds_sector = fs->fs_currentsector;
+ dirinfo->fd_seq.ds_offset = diroffset;
return OK;
}
@@ -535,7 +538,7 @@ int fat_allocatedirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo
return cluster;
}
- /* Flush out any cached date in fs_buffer.. we are going to use
+ /* Flush out any cached data in fs_buffer.. we are going to use
* it to initialize the new directory cluster.
*/
@@ -561,7 +564,8 @@ int fat_allocatedirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo
sector++;
}
- dirinfo->fd_entry = fs->fs_buffer;
+ dirinfo->fd_seq.ds_sector = fs->fs_currentsector;
+ dirinfo->fd_seq.ds_offset = 0;
return OK;
}
@@ -570,17 +574,28 @@ int fat_allocatedirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo
*
* Desciption: Free the directory entry.
*
- * Assumptions: (1) the directory enty is in the cache and (2) direntry
- * points to the directory entry to be deleted. This obvioulsy needs
- * to be re-designed to support long file names!
- *
****************************************************************************/
-int fat_freedirentry(struct fat_mountpt_s *fs, FAR uint8_t *direntry)
+int fat_freedirentry(struct fat_mountpt_s *fs, struct fat_dirseq_s *seq)
{
- direntry[DIR_NAME] = DIR0_EMPTY;
- fs->fs_dirty = true;
- return OK;
+ uint8_t *direntry;
+ int ret;
+
+ /* Make sure that the sector containing the directory entry is in the
+ * cache.
+ */
+
+ ret = fat_fscacheread(fs, seq->ds_sector);
+ if (ret == OK)
+ {
+ /* Then mark the entry as deleted */
+
+ direntry = &fs->fs_buffer[seq->ds_offset];
+ direntry[DIR_NAME] = DIR0_EMPTY;
+ fs->fs_dirty = true;
+ }
+
+ return ret;
}
/****************************************************************************
@@ -703,9 +718,9 @@ int fat_dirname2path(char *path, uint8_t *direntry)
int fat_dirnamewrite(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo)
{
- uint8_t *direntry = dirinfo->fd_entry;
+ uint8_t *direntry = &fs->fs_buffer[dirinfo->fd_seq.ds_offset];
- memcpy(&direntry[DIR_NAME], dirinfo->fd_name, 8+3);
+ memcpy(&direntry[DIR_NAME], dirinfo->fd_name, DIR_MAXFNAME);
#ifdef CONFIG_FLAT_LCNAMES
DIR_PUTNTRES(direntry, dirinfo->fd_ntflags);
#else
@@ -732,7 +747,7 @@ int fat_dirwrite(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo,
/* Initialize the 32-byte directory entry */
- direntry = dirinfo->fd_entry;
+ direntry = &fs->fs_buffer[dirinfo->fd_seq.ds_offset];
memset(direntry, 0, DIR_SIZE);
/* Directory name info */
@@ -793,9 +808,9 @@ int fat_dircreate(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo)
int fat_remove(struct fat_mountpt_s *fs, const char *relpath, bool directory)
{
struct fat_dirinfo_s dirinfo;
- uint32_t dircluster;
- off_t dirsector;
- int ret;
+ uint32_t dircluster;
+ uint8_t *direntry;
+ int ret;
/* Find the directory entry referring to the entry to be deleted */
@@ -809,7 +824,7 @@ int fat_remove(struct fat_mountpt_s *fs, const char *relpath, bool directory)
/* Check if this is a FAT12/16 root directory */
- if (dirinfo.fd_entry == NULL)
+ if (dirinfo.fd_root)
{
/* The root directory cannot be removed */
@@ -818,7 +833,8 @@ int fat_remove(struct fat_mountpt_s *fs, const char *relpath, bool directory)
/* The object has to have write access to be deleted */
- if ((DIR_GETATTRIBUTES(dirinfo.fd_entry) & FATATTR_READONLY) != 0)
+ direntry = &fs->fs_buffer[dirinfo.fd_seq.ds_offset];
+ if ((DIR_GETATTRIBUTES(direntry) & FATATTR_READONLY) != 0)
{
/* It is a read-only entry */
@@ -829,14 +845,13 @@ int fat_remove(struct fat_mountpt_s *fs, const char *relpath, bool directory)
* entry to be deleted
*/
- dirsector = fs->fs_currentsector;
dircluster =
- ((uint32_t)DIR_GETFSTCLUSTHI(dirinfo.fd_entry) << 16) |
- DIR_GETFSTCLUSTLO(dirinfo.fd_entry);
+ ((uint32_t)DIR_GETFSTCLUSTHI(direntry) << 16) |
+ DIR_GETFSTCLUSTLO(direntry);
/* Is this entry a directory? */
- if (DIR_GETATTRIBUTES(dirinfo.fd_entry) & FATATTR_DIRECTORY)
+ if (DIR_GETATTRIBUTES(direntry) & FATATTR_DIRECTORY)
{
/* It is a sub-directory. Check if we are be asked to remove
* a directory or a file.
@@ -903,7 +918,7 @@ int fat_remove(struct fat_mountpt_s *fs, const char *relpath, bool directory)
return -ENOTEMPTY;
}
- /* Get the next directgory entry */
+ /* Get the next directory entry */
ret = fat_nextdirentry(fs, &dirinfo.dir);
if (ret < 0)
@@ -926,19 +941,9 @@ int fat_remove(struct fat_mountpt_s *fs, const char *relpath, bool directory)
}
}
- /* Make sure that the directory containing the entry to be deleted is
- * in the cache.
- */
-
- ret = fat_fscacheread(fs, dirsector);
- if (ret < 0)
- {
- return ret;
- }
-
/* Mark the directory entry 'deleted' */
- ret = fat_freedirentry(fs, dirinfo.fd_entry);
+ ret = fat_freedirentry(fs, &dirinfo.fd_seq);
if (ret < 0)
{
return ret;
diff --git a/nuttx/fs/fat/fs_fat32util.c b/nuttx/fs/fat/fs_fat32util.c
index e54206aff..a8c745e71 100644
--- a/nuttx/fs/fat/fs_fat32util.c
+++ b/nuttx/fs/fat/fs_fat32util.c
@@ -1273,7 +1273,8 @@ int fat_nextdirentry(struct fat_mountpt_s *fs, struct fs_fatdir_s *dir)
* Desciption: Truncate an existing file to zero length
*
* Assumptions: The caller holds mountpoint semaphore, fs_buffer holds
- * the directory entry, dirinfo refers to the current fs_buffer content.
+ * the directory entry, the directory entry sector (fd_sector) is
+ * currently in the sector cache.
*
****************************************************************************/
@@ -1281,31 +1282,33 @@ int fat_dirtruncate(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo)
{
unsigned int startcluster;
uint32_t writetime;
+ uint8_t *direntry;
off_t savesector;
int ret;
/* Get start cluster of the file to truncate */
+ direntry = &fs->fs_buffer[dirinfo->fd_seq.ds_offset];
startcluster =
- ((uint32_t)DIR_GETFSTCLUSTHI(dirinfo->fd_entry) << 16) |
- DIR_GETFSTCLUSTLO(dirinfo->fd_entry);
+ ((uint32_t)DIR_GETFSTCLUSTHI(direntry) << 16) |
+ DIR_GETFSTCLUSTLO(direntry);
/* Clear the cluster start value in the directory and set the file size
* to zero. This makes the file look empty but also have to dispose of
* all of the clusters in the chain.
*/
- DIR_PUTFSTCLUSTHI(dirinfo->fd_entry, 0);
- DIR_PUTFSTCLUSTLO(dirinfo->fd_entry, 0);
- DIR_PUTFILESIZE(dirinfo->fd_entry, 0);
+ DIR_PUTFSTCLUSTHI(direntry, 0);
+ DIR_PUTFSTCLUSTLO(direntry, 0);
+ DIR_PUTFILESIZE(direntry, 0);
/* Set the ARCHIVE attribute and update the write time */
- DIR_PUTATTRIBUTES(dirinfo->fd_entry, FATATTR_ARCHIVE);
+ DIR_PUTATTRIBUTES(direntry, FATATTR_ARCHIVE);
writetime = fat_systime2fattime();
- DIR_PUTWRTTIME(dirinfo->fd_entry, writetime & 0xffff);
- DIR_PUTWRTDATE(dirinfo->fd_entry, writetime > 16);
+ DIR_PUTWRTTIME(direntry, writetime & 0xffff);
+ DIR_PUTWRTDATE(direntry, writetime > 16);
/* This sector needs to be written back to disk eventually */