[PATCH 12/18] fs: fat: flush new directory cluster
Heinrich Schuchardt
xypron.glpk at gmx.de
Sun Nov 29 03:02:10 CET 2020
When handling long file names directory entries may be split over multiple
clusters. We must make sure that new clusters are zero filled on disk.
When allocating a new cluster for a directory flush it.
The flushing should be executed before updating the FAT. This way if
flushing fails, we still have a valid directory structure.
Signed-off-by: Heinrich Schuchardt <xypron.glpk at gmx.de>
---
fs/fat/fat_write.c | 28 +++++++++++++++++++---------
1 file changed, 19 insertions(+), 9 deletions(-)
diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c
index 0746d73f8d..941f8789ab 100644
--- a/fs/fat/fat_write.c
+++ b/fs/fat/fat_write.c
@@ -738,17 +738,32 @@ static int find_empty_cluster(fsdata *mydata)
return entry;
}
-/*
- * Allocate a cluster for additional directory entries
+/**
+ * new_dir_table() - allocate a cluster for additional directory entries
+ *
+ * @itr: directory iterator
+ * Return: 0 on success, -EIO otherwise
*/
static int new_dir_table(fat_itr *itr)
{
fsdata *mydata = itr->fsdata;
int dir_newclust = 0;
+ int dir_oldclust = itr->clust;
unsigned int bytesperclust = mydata->clust_size * mydata->sect_size;
dir_newclust = find_empty_cluster(mydata);
- set_fatent_value(mydata, itr->clust, dir_newclust);
+
+ /*
+ * Flush before updating FAT to ensure valid directory structure
+ * in case of failure.
+ */
+ itr->clust = dir_newclust;
+ itr->next_clust = dir_newclust;
+ memset(itr->block, 0x00, bytesperclust);
+ if (flush_dir(itr))
+ return -EIO;
+
+ set_fatent_value(mydata, dir_oldclust, dir_newclust);
if (mydata->fatsize == 32)
set_fatent_value(mydata, dir_newclust, 0xffffff8);
else if (mydata->fatsize == 16)
@@ -756,13 +771,8 @@ static int new_dir_table(fat_itr *itr)
else if (mydata->fatsize == 12)
set_fatent_value(mydata, dir_newclust, 0xff8);
- itr->clust = dir_newclust;
- itr->next_clust = dir_newclust;
-
if (flush_dirty_fat_buffer(mydata) < 0)
- return -1;
-
- memset(itr->block, 0x00, bytesperclust);
+ return -EIO;
itr->dent = (dir_entry *)itr->block;
itr->last_cluster = 1;
--
2.29.2
More information about the U-Boot
mailing list