diff options
author | Heinrich Schuchardt | 2020-11-22 09:58:44 +0100 |
---|---|---|
committer | Heinrich Schuchardt | 2020-12-10 09:14:59 +0100 |
commit | 32a5f887c48e54d0842eef6af63534fd1f6001d7 (patch) | |
tree | 3d2bcfcc785a90cc7243103b4246d802d926b9f9 | |
parent | 569b0e1938a5c78b6f4152704ef8c8a4e04fcb09 (diff) |
fs: fat: fat_find_empty_dentries()
Provide a function to find a series of empty directory entries.
The current directory is scanned for deleted entries.
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
-rw-r--r-- | fs/fat/fat_write.c | 62 |
1 files changed, 61 insertions, 1 deletions
diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c index 941f8789ab8..d560b94b60a 100644 --- a/fs/fat/fat_write.c +++ b/fs/fat/fat_write.c @@ -21,6 +21,7 @@ #include "fat.c" static dir_entry *find_directory_entry(fat_itr *itr, char *filename); +static int new_dir_table(fat_itr *itr); /* Characters that may only be used in long file names */ static const char LONG_ONLY_CHARS[] = "+,;=[]"; @@ -250,6 +251,66 @@ static int flush_dirty_fat_buffer(fsdata *mydata) return 0; } +/** + * fat_find_empty_dentries() - find a sequence of available directory entries + * + * @itr: directory iterator + * @count: number of directory entries to find + * Return: 0 on success or negative error number + */ +static int __maybe_unused fat_find_empty_dentries(fat_itr *itr, int count) +{ + unsigned int cluster; + dir_entry *dent; + int remaining; + unsigned int n = 0; + int ret; + + ret = fat_move_to_cluster(itr, itr->start_clust); + if (ret) + return ret; + + for (;;) { + if (!itr->dent) { + log_debug("Not enough directory entries available\n"); + return -ENOSPC; + } + switch (itr->dent->name[0]) { + case 0x00: + case DELETED_FLAG: + if (!n) { + /* Remember first deleted directory entry */ + cluster = itr->clust; + dent = itr->dent; + remaining = itr->remaining; + } + ++n; + if (n == count) + goto out; + break; + default: + n = 0; + break; + } + + next_dent(itr); + if (!itr->dent && + (!itr->is_root || itr->fsdata->fatsize == 32) && + new_dir_table(itr)) + return -ENOSPC; + } +out: + /* Position back to first directory entry */ + if (itr->clust != cluster) { + ret = fat_move_to_cluster(itr, cluster); + if (ret) + return ret; + } + itr->dent = dent; + itr->remaining = remaining; + return 0; +} + /* * Set the file name information from 'name' into 'slotptr', */ @@ -319,7 +380,6 @@ name11_12: return 1; } -static int new_dir_table(fat_itr *itr); static int flush_dir(fat_itr *itr); /** |