diff --git a/fs/fat/misc.c b/fs/fat/misc.c index c44296756eae..0a1ee9035327 100644 --- a/fs/fat/misc.c +++ b/fs/fat/misc.c @@ -62,6 +62,7 @@ void _fat_msg(struct super_block *sb, const char *level, const char *fmt, ...) _printk(FAT_PRINTK_PREFIX "%pV\n", level, sb->s_id, &vaf); va_end(args); } +EXPORT_SYMBOL_GPL(_fat_msg); /* Flushes the number of free clusters on FAT32 */ /* XXX: Need to write one per FSINFO block. Currently only writes 1 */ diff --git a/fs/fat/namei_msdos.c b/fs/fat/namei_msdos.c index d46d1a3851f2..7f2c68149efd 100644 --- a/fs/fat/namei_msdos.c +++ b/fs/fat/namei_msdos.c @@ -292,11 +292,17 @@ static int msdos_create(struct mnt_idmap *idmap, struct inode *dir, if (err) goto out; inode = fat_build_inode(sb, sinfo.de, sinfo.i_pos); - brelse(sinfo.bh); if (IS_ERR(inode)) { + int err2; + err = PTR_ERR(inode); + err2 = fat_remove_entries(dir, &sinfo); + if (err2) + fat_msg(sb, KERN_WARNING, + "failed to roll back new entry (%d)", err2); goto out; } + brelse(sinfo.bh); fat_truncate_time(inode, &ts, FAT_UPDATE_ATIME | FAT_UPDATE_CMTIME); /* timestamp is already written, so mark_inode_dirty() is unneeded. */ @@ -381,12 +387,20 @@ static struct dentry *msdos_mkdir(struct mnt_idmap *idmap, struct inode *dir, inc_nlink(dir); inode = fat_build_inode(sb, sinfo.de, sinfo.i_pos); - brelse(sinfo.bh); if (IS_ERR(inode)) { + int err2; + err = PTR_ERR(inode); - /* the directory was completed, just return a error */ - goto out; + err2 = fat_remove_entries(dir, &sinfo); + if (err2) { + fat_msg(sb, KERN_WARNING, + "failed to roll back new entry (%d)", err2); + goto out; + } + drop_nlink(dir); + goto out_free; } + brelse(sinfo.bh); set_nlink(inode, 2); fat_truncate_time(inode, &ts, FAT_UPDATE_ATIME | FAT_UPDATE_CMTIME); /* timestamp is already written, so mark_inode_dirty() is unneeded. */ diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c index da3e89c0b16a..b366e0163272 100644 --- a/fs/fat/namei_vfat.c +++ b/fs/fat/namei_vfat.c @@ -771,11 +771,17 @@ static int vfat_create(struct mnt_idmap *idmap, struct inode *dir, inode_inc_iversion(dir); inode = fat_build_inode(sb, sinfo.de, sinfo.i_pos); - brelse(sinfo.bh); if (IS_ERR(inode)) { + int err2; + err = PTR_ERR(inode); + err2 = fat_remove_entries(dir, &sinfo); + if (err2) + fat_msg(sb, KERN_WARNING, + "failed to roll back new entry (%d)", err2); goto out; } + brelse(sinfo.bh); inode_inc_iversion(inode); d_instantiate(dentry, inode); @@ -870,12 +876,20 @@ static struct dentry *vfat_mkdir(struct mnt_idmap *idmap, struct inode *dir, inc_nlink(dir); inode = fat_build_inode(sb, sinfo.de, sinfo.i_pos); - brelse(sinfo.bh); if (IS_ERR(inode)) { + int err2; + err = PTR_ERR(inode); - /* the directory was completed, just return a error */ - goto out; + err2 = fat_remove_entries(dir, &sinfo); + if (err2) { + fat_msg(sb, KERN_WARNING, + "failed to roll back new entry (%d)", err2); + goto out; + } + drop_nlink(dir); + goto out_free; } + brelse(sinfo.bh); inode_inc_iversion(inode); set_nlink(inode, 2);