FAT long support is code complete (but untested)
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3783 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
718738cb62
commit
65d19ae3dc
|
@ -1314,6 +1314,7 @@ static int fat_readdir(struct inode *mountpt, struct fs_dirent_s *dir)
|
|||
uint8_t *direntry;
|
||||
uint8_t ch;
|
||||
uint8_t attribute;
|
||||
bool found;
|
||||
int ret = OK;
|
||||
|
||||
/* Sanity checks */
|
||||
|
@ -1336,7 +1337,9 @@ static int fat_readdir(struct inode *mountpt, struct fs_dirent_s *dir)
|
|||
/* Read the next directory entry */
|
||||
|
||||
dir->fd_dir.d_name[0] = '\0';
|
||||
while (dir->u.fat.fd_currsector && dir->fd_dir.d_name[0] == '\0')
|
||||
found = false;
|
||||
|
||||
while (dir->u.fat.fd_currsector && !found)
|
||||
{
|
||||
ret = fat_fscacheread(fs, dir->u.fat.fd_currsector);
|
||||
if (ret < 0)
|
||||
|
@ -1365,21 +1368,39 @@ static int fat_readdir(struct inode *mountpt, struct fs_dirent_s *dir)
|
|||
/* No, is the current entry a valid entry? */
|
||||
|
||||
attribute = DIR_GETATTRIBUTES(direntry);
|
||||
|
||||
#ifdef CONFIG_FAT_LFN
|
||||
if (ch != DIR0_EMPTY &&
|
||||
((attribute & FATATTR_VOLUMEID) == 0) ||
|
||||
((ch & LDIR0_LAST) != 0 && attribute == LDDIR_LFNATTR))
|
||||
#else
|
||||
if (ch != DIR0_EMPTY && (attribute & FATATTR_VOLUMEID) == 0)
|
||||
#endif
|
||||
{
|
||||
/* Yes.. get the name from the directory info */
|
||||
/* Yes.. get the name from the directory entry. NOTE: For the case
|
||||
* of the long file name entry, this will advance the several
|
||||
* several directory entries.
|
||||
*/
|
||||
|
||||
(void)fat_dirname2path(dir->fd_dir.d_name, direntry);
|
||||
|
||||
/* And the file type */
|
||||
|
||||
if ((attribute & FATATTR_DIRECTORY) == 0)
|
||||
ret = fat_dirname2path(dir, direntry);
|
||||
if (ret == OK)
|
||||
{
|
||||
dir->fd_dir.d_type = DTYPE_FILE;
|
||||
}
|
||||
else
|
||||
{
|
||||
dir->fd_dir.d_type = DTYPE_DIRECTORY;
|
||||
/* The name was successfully extracted. Now save the file type */
|
||||
|
||||
if ((attribute & FATATTR_DIRECTORY) == 0)
|
||||
{
|
||||
dir->fd_dir.d_type = DTYPE_FILE;
|
||||
}
|
||||
else
|
||||
{
|
||||
dir->fd_dir.d_type = DTYPE_DIRECTORY;
|
||||
}
|
||||
|
||||
/* Mark the entry found. We will set up the next directory index,
|
||||
* and then exit with success.
|
||||
*/
|
||||
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1981,7 +2002,9 @@ int fat_rename(struct inode *mountpt, const char *oldrelpath,
|
|||
goto errout_with_semaphore;
|
||||
}
|
||||
|
||||
/* Find the directory entry for the oldrelpath */
|
||||
/* Find the directory entry for the oldrelpath (there may be multiple
|
||||
* directory entries if long file name support is enabled).
|
||||
*/
|
||||
|
||||
ret = fat_finddirentry(fs, &dirinfo, oldrelpath);
|
||||
if (ret != OK)
|
||||
|
@ -2003,14 +2026,18 @@ int fat_rename(struct inode *mountpt, const char *oldrelpath,
|
|||
|
||||
/* Save the information that will need to recover the directory sector and
|
||||
* directory entry offset to the old directory.
|
||||
*
|
||||
* Save the positional information of the old directory entry.
|
||||
*/
|
||||
|
||||
memcpy(&dirseq, &dirinfo.fd_seq, sizeof(struct fat_dirseq_s));
|
||||
|
||||
|
||||
/* Save the non-name-related portion of the directory entry intact */
|
||||
|
||||
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 */
|
||||
/* Now find the directory where we should create the newpath object */
|
||||
|
||||
ret = fat_finddirentry(fs, &dirinfo, newrelpath);
|
||||
if (ret == OK)
|
||||
|
@ -2030,7 +2057,11 @@ int fat_rename(struct inode *mountpt, const char *oldrelpath,
|
|||
goto errout_with_semaphore;
|
||||
}
|
||||
|
||||
/* Reserve a directory entry */
|
||||
/* Reserve a directory entry. If long file name support is enabled, then
|
||||
* this might, in fact, allocate a sequence of directory entries. A side
|
||||
* effect of fat_allocatedirentry() in either case is that it leaves the
|
||||
* short file name entry in the sector cache.
|
||||
*/
|
||||
|
||||
ret = fat_allocatedirentry(fs, &dirinfo);
|
||||
if (ret != OK)
|
||||
|
@ -2038,19 +2069,28 @@ int fat_rename(struct inode *mountpt, const char *oldrelpath,
|
|||
goto errout_with_semaphore;
|
||||
}
|
||||
|
||||
/* Write the new directory entry */
|
||||
/* Then write the new file name into the directory entry. This, of course,
|
||||
* may involve writing multiple directory entries if long file name
|
||||
* support is enabled. A side effect of fat_allocatedirentry() in either
|
||||
* case is that it leaves the short file name entry in the sector cache.
|
||||
*/
|
||||
|
||||
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);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_with_semaphore;
|
||||
}
|
||||
|
||||
/* Remove the old entry (flushing the new directory entry to disk) */
|
||||
/* Copy the unchanged information into the new short file name entry. */
|
||||
|
||||
direntry = &fs->fs_buffer[dirinfo.fd_seq.ds_offset];
|
||||
memcpy(&direntry[DIR_ATTRIBUTES], dirstate, DIR_SIZE-DIR_ATTRIBUTES);
|
||||
fs->fs_dirty = true;
|
||||
|
||||
/* Remove the old entry, flushing the new directory entry to disk. If
|
||||
* the old file name was a long file name, then multiple directory
|
||||
* entries may be freed.
|
||||
*/
|
||||
|
||||
ret = fat_freedirentry(fs, &dirseq);
|
||||
if (ret < 0)
|
||||
|
|
|
@ -829,7 +829,7 @@ EXTERN int fat_dirwrite(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirin
|
|||
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, struct fat_dirseq_s *seq);
|
||||
EXTERN int fat_dirname2path(char *path, uint8_t *direntry);
|
||||
EXTERN int fat_dirname2path(struct fs_dirent_s *dir, uint8_t *direntry);
|
||||
|
||||
/* File creation and removal helpers */
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue