Browse Source

fix directory seek issue in FatFs.

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1448 bbd45198-f89e-11dd-88c7-29a3b14d5316
bernard.xiong@gmail.com 14 năm trước cách đây
mục cha
commit
d37f7b6100

+ 31 - 8
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);
 }
 

+ 7 - 0
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

+ 1 - 0
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 */

+ 1 - 1
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 */

+ 4 - 1
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);
 }