From edeffa28c526825510f7ff35024ea242f82252e5 Mon Sep 17 00:00:00 2001 From: patacongo Date: Wed, 13 Jul 2011 13:30:38 +0000 Subject: 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 --- nuttx/fs/fat/fs_fat32.c | 88 ++++++++++++++++----------------- nuttx/fs/fat/fs_fat32.h | 64 +++++++++++++++++++----- nuttx/fs/fat/fs_fat32attrib.c | 8 +-- nuttx/fs/fat/fs_fat32dirent.c | 111 ++++++++++++++++++++++-------------------- nuttx/fs/fat/fs_fat32util.c | 21 ++++---- 5 files changed, 171 insertions(+), 121 deletions(-) (limited to 'nuttx/fs/fat') 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 */ -- cgit v1.2.3