Now that fat_sync_inode() ends up writing all metadata buffers associated with the inode, it isn't necessary to write them out explicitely using sync_dirty_buffer(). Remove the unnecessary calls. To maintain proper detection of IO errors when writing buffers, make sure errors from fat_sync_inode() get propagated to the callers. Signed-off-by: Jan Kara --- fs/fat/dir.c | 23 +++-------------------- fs/fat/namei_msdos.c | 28 +++++++++++----------------- fs/fat/namei_vfat.c | 21 ++++++++++++--------- 3 files changed, 26 insertions(+), 46 deletions(-) diff --git a/fs/fat/dir.c b/fs/fat/dir.c index c6cca5d00ffd..60f16154224b 100644 --- a/fs/fat/dir.c +++ b/fs/fat/dir.c @@ -1053,11 +1053,7 @@ static int __fat_remove_entries(struct inode *dir, loff_t pos, int nr_slots) nr_slots--; } mmb_mark_buffer_dirty(bh, &MSDOS_I(dir)->i_metadata_bhs); - if (IS_DIRSYNC(dir)) - err = sync_dirty_buffer(bh); brelse(bh); - if (err) - break; /* pos is *next* de's position, so this does `- sizeof(de)' */ pos += ((orig_slots - nr_slots) * sizeof(*de)) - sizeof(*de); @@ -1088,11 +1084,7 @@ int fat_remove_entries(struct inode *dir, struct fat_slot_info *sinfo) nr_slots--; } mmb_mark_buffer_dirty(bh, &MSDOS_I(dir)->i_metadata_bhs); - if (IS_DIRSYNC(dir)) - err = sync_dirty_buffer(bh); brelse(bh); - if (err) - return err; inode_inc_iversion(dir); if (nr_slots) { @@ -1109,12 +1101,13 @@ int fat_remove_entries(struct inode *dir, struct fat_slot_info *sinfo) } fat_truncate_time(dir, NULL, FAT_UPDATE_ATIME | FAT_UPDATE_CMTIME); + err = 0; if (IS_DIRSYNC(dir)) - (void)fat_sync_inode(dir); + err = fat_sync_inode(dir); else mark_inode_dirty(dir); - return 0; + return err; } EXPORT_SYMBOL_GPL(fat_remove_entries); @@ -1144,21 +1137,11 @@ static int fat_zeroed_cluster(struct inode *dir, sector_t blknr, int nr_used, n++; blknr++; if (n == nr_bhs) { - if (IS_DIRSYNC(dir)) { - err = fat_sync_bhs(bhs, n); - if (err) - goto error; - } for (i = 0; i < n; i++) brelse(bhs[i]); n = 0; } } - if (IS_DIRSYNC(dir)) { - err = fat_sync_bhs(bhs, n); - if (err) - goto error; - } for (i = 0; i < n; i++) brelse(bhs[i]); diff --git a/fs/fat/namei_msdos.c b/fs/fat/namei_msdos.c index 0fd2971ad4b1..55095c172f0a 100644 --- a/fs/fat/namei_msdos.c +++ b/fs/fat/namei_msdos.c @@ -253,11 +253,11 @@ static int msdos_add_entry(struct inode *dir, const unsigned char *name, fat_truncate_time(dir, ts, FAT_UPDATE_CMTIME); if (IS_DIRSYNC(dir)) - (void)fat_sync_inode(dir); + err = fat_sync_inode(dir); else mark_inode_dirty(dir); - return 0; + return err; } /***** Create a file */ @@ -485,7 +485,7 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name, inode_inc_iversion(old_dir); fat_truncate_time(old_dir, NULL, FAT_UPDATE_CMTIME); if (IS_DIRSYNC(old_dir)) - (void)fat_sync_inode(old_dir); + err = fat_sync_inode(old_dir); else mark_inode_dirty(old_dir); goto out; @@ -518,26 +518,21 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name, MSDOS_I(old_inode)->i_attrs |= ATTR_HIDDEN; else MSDOS_I(old_inode)->i_attrs &= ~ATTR_HIDDEN; - if (IS_DIRSYNC(new_dir)) { - err = fat_sync_inode(old_inode); - if (err) - goto error_inode; - } else - mark_inode_dirty(old_inode); - if (update_dotdot) { fat_set_start(dotdot_de, MSDOS_I(new_dir)->i_logstart); mmb_mark_buffer_dirty(dotdot_bh, &MSDOS_I(old_inode)->i_metadata_bhs); - if (IS_DIRSYNC(new_dir)) { - err = sync_dirty_buffer(dotdot_bh); - if (err) - goto error_dotdot; - } drop_nlink(old_dir); if (!new_inode) inc_nlink(new_dir); } + if (IS_DIRSYNC(new_dir)) { + err = fat_sync_inode(old_inode); + if (err) + goto error_dotdot; + } else + mark_inode_dirty(old_inode); + err = fat_remove_entries(old_dir, &old_sinfo); /* and releases bh */ old_sinfo.bh = NULL; @@ -546,7 +541,7 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name, inode_inc_iversion(old_dir); fat_truncate_time(old_dir, &ts, FAT_UPDATE_CMTIME); if (IS_DIRSYNC(old_dir)) - (void)fat_sync_inode(old_dir); + err = fat_sync_inode(old_dir); else mark_inode_dirty(old_dir); @@ -571,7 +566,6 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name, &MSDOS_I(old_inode)->i_metadata_bhs); corrupt |= sync_dirty_buffer(dotdot_bh); } -error_inode: fat_detach(old_inode); fat_attach(old_inode, old_sinfo.i_pos); MSDOS_I(old_inode)->i_attrs = old_attrs; diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c index e909447873e3..e7b7d7c887fa 100644 --- a/fs/fat/namei_vfat.c +++ b/fs/fat/namei_vfat.c @@ -679,7 +679,7 @@ static int vfat_add_entry(struct inode *dir, const struct qstr *qname, /* update timestamp */ fat_truncate_time(dir, ts, FAT_UPDATE_CMTIME); if (IS_DIRSYNC(dir)) - (void)fat_sync_inode(dir); + err = fat_sync_inode(dir); else mark_inode_dirty(dir); cleanup: @@ -921,14 +921,14 @@ static int vfat_update_dotdot_de(struct inode *dir, struct inode *inode, return 0; } -static void vfat_update_dir_metadata(struct inode *dir, struct timespec64 *ts) +static int vfat_update_dir_metadata(struct inode *dir, struct timespec64 *ts) { inode_inc_iversion(dir); fat_truncate_time(dir, ts, FAT_UPDATE_CMTIME); if (IS_DIRSYNC(dir)) - (void)fat_sync_inode(dir); - else - mark_inode_dirty(dir); + return fat_sync_inode(dir); + mark_inode_dirty(dir); + return 0; } static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry, @@ -996,7 +996,7 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry, old_sinfo.bh = NULL; if (err) goto error_dotdot; - vfat_update_dir_metadata(old_dir, &ts); + err = vfat_update_dir_metadata(old_dir, &ts); if (new_inode) { drop_nlink(new_inode); @@ -1123,10 +1123,13 @@ static int vfat_rename_exchange(struct inode *old_dir, struct dentry *old_dentry vfat_move_nlink(new_dir, old_dir); } - vfat_update_dir_metadata(old_dir, &ts); + err = vfat_update_dir_metadata(old_dir, &ts); /* if directories are not the same, update new_dir as well */ - if (old_dir != new_dir) - vfat_update_dir_metadata(new_dir, &ts); + if (old_dir != new_dir) { + int err2 = vfat_update_dir_metadata(new_dir, &ts); + if (!err) + err = err2; + } out: brelse(old_dotdot_bh); -- 2.51.0