diff --git a/fs/exfat/namei.c b/fs/exfat/namei.c index 8725dfc6467c..f26f987a34cf 100644 --- a/fs/exfat/namei.c +++ b/fs/exfat/namei.c @@ -471,6 +471,7 @@ static int exfat_add_entry(struct inode *inode, const char *path, struct exfat_entry_set_cache es; int clu_size = 0; unsigned int start_clu = EXFAT_FREE_CLUSTER; + bool dir_allocated = false; ret = exfat_resolve_path(inode, path, &uniname); if (ret) @@ -497,6 +498,7 @@ static int exfat_add_entry(struct inode *inode, const char *path, } start_clu = clu.dir; clu_size = sbi->cluster_size; + dir_allocated = true; } /* update the directory entry */ @@ -507,8 +509,21 @@ static int exfat_add_entry(struct inode *inode, const char *path, exfat_init_ext_entry(&es, num_entries, &uniname, NULL, 0); ret = exfat_put_dentry_set(&es, IS_DIRSYNC(inode)); - if (ret) + if (ret) { + int cleanup_ret; + + cleanup_ret = exfat_get_dentry_set(&es, sb, &info->dir, + dentry, ES_ALL_ENTRIES); + if (!cleanup_ret) { + exfat_remove_entries(inode, &es, ES_IDX_FILE, false); + cleanup_ret = exfat_put_dentry_set(&es, + IS_DIRSYNC(inode)); + } + + if (!cleanup_ret && dir_allocated) + exfat_free_cluster(inode, &clu); goto out; + } info->entry = dentry; info->flags = ALLOC_NO_FAT_CHAIN;