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>
This commit is contained in:
parent
c5924118c0
commit
d236e825a2
106
fs/fat/fat.c
106
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) {
|
||||
|
@ -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_ */
|
||||
|
Loading…
Reference in New Issue
Block a user