aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/inode.c
diff options
context:
space:
mode:
authorAndreas Gruenbacher <agruenba@redhat.com>2018-02-28 14:48:53 -0500
committerBob Peterson <rpeterso@redhat.com>2018-03-08 11:26:20 -0500
commit83998ccd9bfff881f04ce03f6964f8a83e6c5b54 (patch)
tree0d7ce75cf2531a013e58d0681daa596c5b36fe32 /fs/gfs2/inode.c
parent174d1232ebc84fcde8f5889d1171c9c7e74a10a7 (diff)
gfs2: Dirty source inode during rename
Mark the source inode dirty during a rename instead of just updating the underlying buffer head. Otherwise, fsync may find the inode clean and will then skip flushing the journal. A subsequent power failure will cause the rename to be lost. This happens in command sequences like: xfs_io -f -c 'pwrite 0 4096' -c 'fsync' foo mv foo bar xfs_io -c 'fsync' bar # power failure Fixes xfstests generic/322, generic/376. Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> Signed-off-by: Bob Peterson <rpeterso@redhat.com>
Diffstat (limited to 'fs/gfs2/inode.c')
-rw-r--r--fs/gfs2/inode.c10
1 files changed, 1 insertions, 9 deletions
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index 59e0560180ec..8700eb815638 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -1326,19 +1326,11 @@ static int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to)
1326static int update_moved_ino(struct gfs2_inode *ip, struct gfs2_inode *ndip, 1326static int update_moved_ino(struct gfs2_inode *ip, struct gfs2_inode *ndip,
1327 int dir_rename) 1327 int dir_rename)
1328{ 1328{
1329 int error;
1330 struct buffer_head *dibh;
1331
1332 if (dir_rename) 1329 if (dir_rename)
1333 return gfs2_dir_mvino(ip, &gfs2_qdotdot, ndip, DT_DIR); 1330 return gfs2_dir_mvino(ip, &gfs2_qdotdot, ndip, DT_DIR);
1334 1331
1335 error = gfs2_meta_inode_buffer(ip, &dibh);
1336 if (error)
1337 return error;
1338 ip->i_inode.i_ctime = current_time(&ip->i_inode); 1332 ip->i_inode.i_ctime = current_time(&ip->i_inode);
1339 gfs2_trans_add_meta(ip->i_gl, dibh); 1333 mark_inode_dirty_sync(&ip->i_inode);
1340 gfs2_dinode_out(ip, dibh->b_data);
1341 brelse(dibh);
1342 return 0; 1334 return 0;
1343} 1335}
1344 1336