aboutsummaryrefslogtreecommitdiff
path: root/fs/fat
diff options
context:
space:
mode:
authorHeinrich Schuchardt <xypron.glpk@gmx.de>2020-11-22 09:58:44 +0100
committerHeinrich Schuchardt <xypron.glpk@gmx.de>2020-12-10 09:14:59 +0100
commit32a5f887c48e54d0842eef6af63534fd1f6001d7 (patch)
tree3d2bcfcc785a90cc7243103b4246d802d926b9f9 /fs/fat
parent569b0e1938a5c78b6f4152704ef8c8a4e04fcb09 (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>
Diffstat (limited to 'fs/fat')
-rw-r--r--fs/fat/fat_write.c62
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);
/**