diff options
author | Heinrich Schuchardt | 2020-11-22 09:19:52 +0100 |
---|---|---|
committer | Heinrich Schuchardt | 2020-12-10 09:14:58 +0100 |
commit | d236e825a214a5684598fa7a7b919af332c43390 (patch) | |
tree | b4068142ae945949d73ba0bbdecaf9ea18214300 | |
parent | c5924118c03dc8db30d633de98afe6ad6eb7f277 (diff) |
fs: fat: export fat_next_cluster()
Rename function next_cluster() to fat_next_cluster() and export it.
When creating a new directory entries we should reuse deleted entries.
This requires re-scanning the directory.
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
-rw-r--r-- | fs/fat/fat.c | 106 | ||||
-rw-r--r-- | include/fat.h | 7 |
2 files changed, 80 insertions, 33 deletions
diff --git a/fs/fat/fat.c b/fs/fat/fat.c index fb6ba894664..674236d68a6 100644 --- a/fs/fat/fat.c +++ b/fs/fat/fat.c @@ -621,7 +621,7 @@ static int get_fs_info(fsdata *mydata) /* * The root directory is not cluster-aligned and may be on a * "negative" cluster, this will be handled specially in - * next_cluster(). + * fat_next_cluster(). */ mydata->root_cluster = 0; } @@ -647,44 +647,76 @@ static int get_fs_info(fsdata *mydata) return 0; } - -/* - * Directory iterator, to simplify filesystem traversal +/** + * struct fat_itr - directory iterator, to simplify filesystem traversal * * Implements an iterator pattern to traverse directory tables, * transparently handling directory tables split across multiple * clusters, and the difference between FAT12/FAT16 root directory * (contiguous) and subdirectories + FAT32 root (chained). * - * Rough usage: + * Rough usage * - * for (fat_itr_root(&itr, fsdata); fat_itr_next(&itr); ) { - * // to traverse down to a subdirectory pointed to by - * // current iterator position: - * fat_itr_child(&itr, &itr); - * } + * .. code-block:: c * - * For more complete example, see fat_itr_resolve() + * for (fat_itr_root(&itr, fsdata); fat_itr_next(&itr); ) { + * // to traverse down to a subdirectory pointed to by + * // current iterator position: + * fat_itr_child(&itr, &itr); + * } + * + * For a more complete example, see fat_itr_resolve(). */ - -typedef struct { - fsdata *fsdata; /* filesystem parameters */ - unsigned start_clust; /* first cluster */ - unsigned clust; /* current cluster */ - unsigned next_clust; /* next cluster if remaining == 0 */ - int last_cluster; /* set once we've read last cluster */ - int is_root; /* is iterator at root directory */ - int remaining; /* remaining dent's in current cluster */ - - /* current iterator position values: */ - dir_entry *dent; /* current directory entry */ - char l_name[VFAT_MAXLEN_BYTES]; /* long (vfat) name */ - char s_name[14]; /* short 8.3 name */ - char *name; /* l_name if there is one, else s_name */ - - /* storage for current cluster in memory: */ - u8 block[MAX_CLUSTSIZE] __aligned(ARCH_DMA_MINALIGN); -} fat_itr; +struct fat_itr { + /** + * @fsdata: filesystem parameters + */ + fsdata *fsdata; + /** + * @start_clust: first cluster + */ + unsigned int start_clust; + /** + * @clust: current cluster + */ + unsigned int clust; + /** + * @next_clust: next cluster if remaining == 0 + */ + unsigned int next_clust; + /** + * @last_cluster: set if last cluster of directory reached + */ + int last_cluster; + /** + * @is_root: is iterator at root directory + */ + int is_root; + /** + * @remaining: remaining directory entries in current cluster + */ + int remaining; + /** + * @dent: current directory entry + */ + dir_entry *dent; + /** + * @l_name: long name of current directory entry + */ + char l_name[VFAT_MAXLEN_BYTES]; + /** + * @s_name: short 8.3 name of current directory entry + */ + char s_name[14]; + /** + * @name: l_name if there is one, else s_name + */ + char *name; + /** + * @block: buffer for current cluster + */ + u8 block[MAX_CLUSTSIZE] __aligned(ARCH_DMA_MINALIGN); +}; static int fat_itr_isdir(fat_itr *itr); @@ -753,7 +785,17 @@ static void fat_itr_child(fat_itr *itr, fat_itr *parent) itr->last_cluster = 0; } -static void *next_cluster(fat_itr *itr, unsigned *nbytes) +/** + * fat_next_cluster() - load next FAT cluster + * + * The function is used when iterating through directories. It loads the + * next cluster with directory entries + * + * @itr: directory iterator + * @nbytes: number of bytes read, 0 on error + * Return: first directory entry, NULL on error + */ +void *fat_next_cluster(fat_itr *itr, unsigned int *nbytes) { fsdata *mydata = itr->fsdata; /* for silly macros */ int ret; @@ -825,7 +867,7 @@ static dir_entry *next_dent(fat_itr *itr) { if (itr->remaining == 0) { unsigned nbytes; - struct dir_entry *dent = next_cluster(itr, &nbytes); + struct dir_entry *dent = fat_next_cluster(itr, &nbytes); /* have we reached the last cluster? */ if (!dent) { diff --git a/include/fat.h b/include/fat.h index 02742f92a5c..3c29a4484d4 100644 --- a/include/fat.h +++ b/include/fat.h @@ -9,8 +9,9 @@ #ifndef _FAT_H_ #define _FAT_H_ -#include <asm/byteorder.h> #include <fs.h> +#include <asm/byteorder.h> +#include <asm/cache.h> struct disk_partition; @@ -179,6 +180,9 @@ typedef struct { int fats; /* Number of FATs */ } fsdata; +struct fat_itr; +typedef struct fat_itr fat_itr; + static inline u32 clust_to_sect(fsdata *fsdata, u32 clust) { return fsdata->data_begin + clust * fsdata->clust_size; @@ -208,4 +212,5 @@ void fat_closedir(struct fs_dir_stream *dirs); int fat_unlink(const char *filename); int fat_mkdir(const char *dirname); void fat_close(void); +void *fat_next_cluster(fat_itr *itr, unsigned int *nbytes); #endif /* _FAT_H_ */ |