9
0
Fork 0

Re-architect FAT data structures to support long file names

git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@3780 7fd9a85b-ad96-42d3-883c-3090e2eb8679
This commit is contained in:
patacongo 2011-07-13 13:30:38 +00:00
parent ed3ae5b173
commit 2d10e7c352
7 changed files with 195 additions and 128 deletions

View File

@ -148,10 +148,12 @@ static ssize_t rd_read(FAR struct inode *inode, unsigned char *buffer,
{
struct rd_struct_s *dev;
fvdbg("sector: %d nsectors: %d sectorsize: %d\n");
DEBUGASSERT(inode && inode->i_private);
dev = (struct rd_struct_s *)inode->i_private;
fvdbg("sector: %d nsectors: %d sectorsize: %d\n",
start_sector, dev->rd_sectsize, nsectors);
if (start_sector < dev->rd_nsectors &&
start_sector + nsectors <= dev->rd_nsectors)
{
@ -180,10 +182,12 @@ static ssize_t rd_write(FAR struct inode *inode, const unsigned char *buffer,
{
struct rd_struct_s *dev;
fvdbg("sector: %d nsectors: %d sectorsize: %d\n");
DEBUGASSERT(inode && inode->i_private);
dev = (struct rd_struct_s *)inode->i_private;
fvdbg("sector: %d nsectors: %d sectorsize: %d\n",
start_sector, dev->rd_sectsize, nsectors);
if (!dev->rd_writeenabled)
{
return -EACCES;

View File

@ -163,12 +163,21 @@ static void uart_pollnotify(FAR uart_dev_t *dev, pollevent_t eventset)
static void uart_putxmitchar(FAR uart_dev_t *dev, int ch)
{
int nexthead = dev->xmit.head + 1;
irqstate_t flags;
int nexthead;
/* Increment to see what the next head pointer will be. We need to use the "next"
* head pointer to determine when the circular buffer would overrun
*/
nexthead = dev->xmit.head + 1;
if (nexthead >= dev->xmit.size)
{
nexthead = 0;
}
/* Loop until we are able to add the character to the TX buffer */
for (;;)
{
if (nexthead != dev->xmit.tail)
@ -179,8 +188,11 @@ static void uart_putxmitchar(FAR uart_dev_t *dev, int ch)
}
else
{
/* Inform the interrupt level logic that we are waiting */
/* Inform the interrupt level logic that we are waiting.
* This and the following steps must be atomic.
*/
flags = irqsave();
dev->xmitwaiting = true;
/* Wait for some characters to be sent from the buffer
@ -192,6 +204,7 @@ static void uart_putxmitchar(FAR uart_dev_t *dev, int ch)
uart_enabletxint(dev);
uart_takesem(&dev->xmitsem);
uart_disabletxint(dev);
irqrestore(flags);
}
}
}

View File

@ -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.
*/
/* Remove the old entry (flushing the new directory entry to disk) */
ret = fat_fscacheread(fs, oldsector);
if (ret < 0)
{
goto errout_with_semaphore;
}
/* 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;

View File

@ -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
/* TRUE if this is the root directory */
bool fd_root;
/* The following provides the sequence of directory entries used by the
* file or directory.
*/
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. */
/* 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.
*/
uint8_t *fd_entry; /* A pointer to the raw 32-byte entry */
};
/****************************************************************************
@ -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 */

View File

@ -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)

View File

@ -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;

View File

@ -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 */