fs: fat: deletion of long file names

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@gmx.de>
This commit is contained in:
Heinrich Schuchardt 2020-11-19 07:31:18 +01:00
parent 89735b44c4
commit 3d20d212cf

View File

@ -1445,27 +1445,91 @@ exit:
return count; 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; fsdata *mydata = itr->fsdata;
dir_entry *dentptr = itr->dent; dir_entry *dent = itr->dent;
/* free cluster blocks */ /* free cluster blocks */
clear_fatent(mydata, START(dentptr)); clear_fatent(mydata, START(dent));
if (flush_dirty_fat_buffer(mydata) < 0) { if (flush_dirty_fat_buffer(mydata) < 0) {
printf("Error: flush fat buffer\n"); printf("Error: flush fat buffer\n");
return -EIO; return -EIO;
} }
/* Position to first directory entry for long name */
if (itr->clust != itr->dent_clust) {
int ret;
/* ret = fat_move_to_cluster(itr, itr->dent_clust);
* update a directory entry if (ret)
* TODO: return ret;
* - long file name support }
* - find and mark the "new" first invalid entry as name[0]=0x00 itr->dent = itr->dent_start;
*/ itr->remaining = itr->dent_rem;
memset(dentptr, 0, sizeof(*dentptr)); dent = itr->dent_start;
dentptr->name[0] = DELETED_FLAG; /* 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)) { if (flush_dir(itr)) {
printf("error: writing directory entry\n"); printf("error: writing directory entry\n");
return -EIO; return -EIO;
@ -1535,7 +1599,7 @@ int fat_unlink(const char *filename)
} }
} }
ret = delete_dentry(itr); ret = delete_dentry_long(itr);
exit: exit:
free(fsdata.fatbuf); free(fsdata.fatbuf);