From d37f7b610074448e30bc35e5820e3831620a9edb Mon Sep 17 00:00:00 2001 From: "bernard.xiong@gmail.com" Date: Sat, 4 Jun 2011 13:02:57 +0000 Subject: fix directory seek issue in FatFs. git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1448 bbd45198-f89e-11dd-88c7-29a3b14d5316 --- components/dfs/filesystems/elmfat/dfs_elm.c | 39 +++++++++++++++++++++++------ components/dfs/filesystems/elmfat/ff.c | 7 ++++++ components/dfs/filesystems/elmfat/ff.h | 1 + components/dfs/filesystems/elmfat/ffconf.h | 2 +- components/dfs/src/dfs_posix.c | 5 +++- 5 files changed, 44 insertions(+), 10 deletions(-) diff --git a/components/dfs/filesystems/elmfat/dfs_elm.c b/components/dfs/filesystems/elmfat/dfs_elm.c index ffdf483d20..79180d5337 100644 --- a/components/dfs/filesystems/elmfat/dfs_elm.c +++ b/components/dfs/filesystems/elmfat/dfs_elm.c @@ -385,18 +385,39 @@ int dfs_elm_flush(struct dfs_fd* file) int dfs_elm_lseek(struct dfs_fd* file, rt_off_t offset) { - FIL* fd; FRESULT result; + if (file->type == DFS_DT_REG) + { + FIL* fd; - fd = (FIL*)(file->data); - RT_ASSERT(fd != RT_NULL); - - result = f_lseek(fd, offset); - if (result == FR_OK) + /* regular file type */ + fd = (FIL*)(file->data); + RT_ASSERT(fd != RT_NULL); + + result = f_lseek(fd, offset); + if (result == FR_OK) + { + /* return current position */ + return fd->fptr; + } + } + else if (file->type == DFS_DT_DIR) { - /* return current position */ - return fd->fptr; + /* which is a directory */ + DIR* dir; + + dir = (DIR*)(file->data); + RT_ASSERT(dir != RT_NULL); + + result = f_seekdir(dir, offset / sizeof(struct dirent)); + if (result == FR_OK) + { + /* update file position */ + file->pos = offset; + return file->pos; + } } + return elm_result_to_dfs(result); } @@ -457,6 +478,8 @@ int dfs_elm_getdents(struct dfs_fd* file, struct dirent* dirp, rt_uint32_t count if (index == 0) return elm_result_to_dfs(result); + file->pos += index * sizeof(struct dirent); + return index * sizeof(struct dirent); } diff --git a/components/dfs/filesystems/elmfat/ff.c b/components/dfs/filesystems/elmfat/ff.c index 3fc2513d63..fc759a38d7 100644 --- a/components/dfs/filesystems/elmfat/ff.c +++ b/components/dfs/filesystems/elmfat/ff.c @@ -3028,6 +3028,13 @@ FRESULT f_readdir ( LEAVE_FF(dj->fs, res); } +FRESULT f_seekdir( + DIR *dj, /* Pointer to the open directory object */ + int offset /* the seek offset */ +) +{ + return dir_sdi(dj, offset); /* seek directory index to offset */ +} #if _FS_MINIMIZE == 0 diff --git a/components/dfs/filesystems/elmfat/ff.h b/components/dfs/filesystems/elmfat/ff.h index 191e3a4838..8f4a4e4e46 100644 --- a/components/dfs/filesystems/elmfat/ff.h +++ b/components/dfs/filesystems/elmfat/ff.h @@ -209,6 +209,7 @@ FRESULT f_lseek (FIL*, DWORD); /* Move file pointer of a file object */ FRESULT f_close (FIL*); /* Close an open file object */ FRESULT f_opendir (DIR*, const TCHAR*); /* Open an existing directory */ FRESULT f_readdir (DIR*, FILINFO*); /* Read a directory item */ +FRESULT f_seekdir(DIR *dj, int offset); /* Seek in directory */ FRESULT f_stat (const TCHAR*, FILINFO*); /* Get file status */ FRESULT f_write (FIL*, const void*, UINT, UINT*); /* Write data to a file */ FRESULT f_getfree (const TCHAR*, DWORD*, FATFS**); /* Get number of free clusters on the drive */ diff --git a/components/dfs/filesystems/elmfat/ffconf.h b/components/dfs/filesystems/elmfat/ffconf.h index 615a79fa8e..284ff2eb2e 100644 --- a/components/dfs/filesystems/elmfat/ffconf.h +++ b/components/dfs/filesystems/elmfat/ffconf.h @@ -91,7 +91,7 @@ #ifdef RT_DFS_ELM_USE_LFN -#define _USE_LFN RT_DFS_ELM_USE_LFN +#define _USE_LFN 1 #define _MAX_LFN RT_DFS_ELM_MAX_LFN #else #define _USE_LFN 0 /* 0 to 3 */ diff --git a/components/dfs/src/dfs_posix.c b/components/dfs/src/dfs_posix.c index 4241bbb774..c1e80a3d9d 100644 --- a/components/dfs/src/dfs_posix.c +++ b/components/dfs/src/dfs_posix.c @@ -468,6 +468,7 @@ struct dirent* readdir(DIR *d) if (!d->num || (d->cur += ((struct dirent*)(d->buf + d->cur))->d_reclen) >= d->num) { + /* get a new entry */ result = dfs_file_getdents(fd, (struct dirent*)d->buf, sizeof(d->buf) - 1); if (result <= 0) { @@ -478,7 +479,7 @@ struct dirent* readdir(DIR *d) } d->num = result; - d->cur = 0; + d->cur = 0; /* current entry index */ } fd_put(fd); @@ -529,6 +530,7 @@ void seekdir(DIR *d, off_t offset) return ; } + /* seek to the offset position of directory */ if (dfs_file_lseek(fd, offset) >= 0) d->num = d->cur = 0; fd_put(fd); } @@ -549,6 +551,7 @@ void rewinddir(DIR *d) return ; } + /* seek to the beginning of directory */ if (dfs_file_lseek(fd, 0) >= 0) d->num = d->cur = 0; fd_put(fd); } -- cgit v1.3.1