summaryrefslogtreecommitdiff
path: root/fs/fat
diff options
context:
space:
mode:
authorHeinrich Schuchardt <xypron.glpk@gmx.de>2020-11-22 13:54:22 +0300
committerHeinrich Schuchardt <xypron.glpk@gmx.de>2020-12-10 11:14:59 +0300
commit3049a5106c95781663202c626d2e0f56fa2c6646 (patch)
tree3671fd2cd9a064841562113bbd49172be433cf45 /fs/fat
parent32a5f887c48e54d0842eef6af63534fd1f6001d7 (diff)
downloadu-boot-3049a5106c95781663202c626d2e0f56fa2c6646.tar.xz
fs: fat: reuse deleted directory entries
When creating new directory entries try to reuse entries marked as deleted. In fill_dir_slot() do not allocate new clusters as this has already been done in fat_find_empty_dentries(). Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Diffstat (limited to 'fs/fat')
-rw-r--r--fs/fat/fat_write.c34
1 files changed, 22 insertions, 12 deletions
diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c
index d560b94b60..a029ef8ed6 100644
--- a/fs/fat/fat_write.c
+++ b/fs/fat/fat_write.c
@@ -258,7 +258,7 @@ static int flush_dirty_fat_buffer(fsdata *mydata)
* @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)
+static int fat_find_empty_dentries(fat_itr *itr, int count)
{
unsigned int cluster;
dir_entry *dent;
@@ -421,11 +421,9 @@ fill_dir_slot(fat_itr *itr, const char *l_name, const char *shortname)
if (itr->remaining == 0)
flush_dir(itr);
- /* allocate a cluster for more entries */
- if (!next_dent(itr) && !itr->dent)
- if ((itr->is_root && itr->fsdata->fatsize != 32) ||
- new_dir_table(itr))
- return -EIO;
+ next_dent(itr);
+ if (!itr->dent)
+ return -EIO;
}
return 0;
@@ -1339,6 +1337,7 @@ int file_fat_write_at(const char *filename, loff_t pos, void *buffer,
} else {
/* Create a new file */
char shortname[SHORT_NAME_SIZE];
+ int ndent;
if (itr->is_root) {
/* root dir cannot have "." or ".." */
@@ -1362,10 +1361,15 @@ int file_fat_write_at(const char *filename, loff_t pos, void *buffer,
}
/* Check if long name is needed */
- ret = set_name(itr, filename, shortname);
- if (ret < 0)
+ ndent = set_name(itr, filename, shortname);
+ if (ndent < 0) {
+ ret = ndent;
+ goto exit;
+ }
+ ret = fat_find_empty_dentries(itr, ndent);
+ if (ret)
goto exit;
- if (ret > 1) {
+ if (ndent > 1) {
/* Set long name entries */
ret = fill_dir_slot(itr, filename, shortname);
if (ret)
@@ -1607,6 +1611,7 @@ int fat_mkdir(const char *new_dirname)
goto exit;
} else {
char shortname[SHORT_NAME_SIZE];
+ int ndent;
if (itr->is_root) {
/* root dir cannot have "." or ".." */
@@ -1624,10 +1629,15 @@ int fat_mkdir(const char *new_dirname)
}
/* Check if long name is needed */
- ret = set_name(itr, dirname, shortname);
- if (ret < 0)
+ ndent = set_name(itr, dirname, shortname);
+ if (ndent < 0) {
+ ret = ndent;
+ goto exit;
+ }
+ ret = fat_find_empty_dentries(itr, ndent);
+ if (ret)
goto exit;
- if (ret > 1) {
+ if (ndent > 1) {
/* Set long name entries */
ret = fill_dir_slot(itr, dirname, shortname);
if (ret)