[PATCH 18/18] fs: fat: deletion of long file names
Heinrich Schuchardt
xypron.glpk at gmx.de
Sun Nov 29 03:02:16 CET 2020
Long file names are stored in multiple directory entries. When deleting a
file we must delete all of them.
Signed-off-by: Heinrich Schuchardt <xypron.glpk at gmx.de>
---
fs/fat/fat_write.c | 88 +++++++++++++++++++++++++++++++++++++++-------
1 file changed, 76 insertions(+), 12 deletions(-)
diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c
index c403d7d5c6..20a54a2418 100644
--- a/fs/fat/fat_write.c
+++ b/fs/fat/fat_write.c
@@ -1445,27 +1445,91 @@ exit:
return count;
}
-static int delete_dentry(fat_itr *itr)
+/**
+ * delete_single_dentry() - delete a single directory entry
+ *
+ * @itr: directory iterator
+ * Return: 0 for success
+ */
+static int delete_single_dentry(fat_itr *itr)
+{
+ struct dir_entry *dent = itr->dent;
+
+ memset(dent, 0, sizeof(*dent));
+ dent->name[0] = DELETED_FLAG;
+
+ if (!itr->remaining) {
+ if (flush_dir(itr)) {
+ printf("error: writing directory entry\n");
+ return -EIO;
+ }
+ }
+ return 0;
+}
+
+/**
+ * delete_long_name() - delete long name directory entries
+ *
+ * @itr: directory iterator
+ * Return: 0 for success
+ */
+static int delete_long_name(fat_itr *itr)
+{
+ struct dir_entry *dent = itr->dent;
+ int seqn = itr->dent->name[0] & ~LAST_LONG_ENTRY_MASK;
+
+ while (seqn--) {
+ int ret;
+
+ ret = delete_single_dentry(itr);
+ if (ret)
+ return ret;
+ dent = next_dent(itr);
+ if (!dent)
+ return -EIO;
+ }
+ return 0;
+}
+
+/**
+ * delete_dentry_long() - remove directory entry
+ *
+ * @itr: directory iterator
+ * Return: 0 for success
+ */
+static int delete_dentry_long(fat_itr *itr)
{
fsdata *mydata = itr->fsdata;
- dir_entry *dentptr = itr->dent;
+ dir_entry *dent = itr->dent;
/* free cluster blocks */
- clear_fatent(mydata, START(dentptr));
+ clear_fatent(mydata, START(dent));
if (flush_dirty_fat_buffer(mydata) < 0) {
printf("Error: flush fat buffer\n");
return -EIO;
}
+ /* Position to first directory entry for long name */
+ if (itr->clust != itr->dent_clust) {
+ int ret;
- /*
- * update a directory entry
- * TODO:
- * - long file name support
- * - find and mark the "new" first invalid entry as name[0]=0x00
- */
- memset(dentptr, 0, sizeof(*dentptr));
- dentptr->name[0] = DELETED_FLAG;
+ ret = fat_move_to_cluster(itr, itr->dent_clust);
+ if (ret)
+ return ret;
+ }
+ itr->dent = itr->dent_start;
+ itr->remaining = itr->dent_rem;
+ dent = itr->dent_start;
+ /* Delete long name */
+ if ((dent->attr & ATTR_VFAT) == ATTR_VFAT &&
+ (dent->name[0] & LAST_LONG_ENTRY_MASK)) {
+ int ret;
+ ret = delete_long_name(itr);
+ if (ret)
+ return ret;
+ }
+ /* Delete short name */
+ delete_single_dentry(itr);
if (flush_dir(itr)) {
printf("error: writing directory entry\n");
return -EIO;
@@ -1535,7 +1599,7 @@ int fat_unlink(const char *filename)
}
}
- ret = delete_dentry(itr);
+ ret = delete_dentry_long(itr);
exit:
free(fsdata.fatbuf);
--
2.29.2
More information about the U-Boot
mailing list