aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/dir.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/dir.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/dir.c')
-rw-r--r--fs/gfs2/dir.c13
1 files changed, 2 insertions, 11 deletions
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c
index 7c21aea0266b..d9fb0ad6cc30 100644
--- a/fs/gfs2/dir.c
+++ b/fs/gfs2/dir.c
@@ -1940,7 +1940,6 @@ int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename,
1940{ 1940{
1941 struct buffer_head *bh; 1941 struct buffer_head *bh;
1942 struct gfs2_dirent *dent; 1942 struct gfs2_dirent *dent;
1943 int error;
1944 1943
1945 dent = gfs2_dirent_search(&dip->i_inode, filename, gfs2_dirent_find, &bh); 1944 dent = gfs2_dirent_search(&dip->i_inode, filename, gfs2_dirent_find, &bh);
1946 if (!dent) { 1945 if (!dent) {
@@ -1953,18 +1952,10 @@ int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename,
1953 gfs2_trans_add_meta(dip->i_gl, bh); 1952 gfs2_trans_add_meta(dip->i_gl, bh);
1954 gfs2_inum_out(nip, dent); 1953 gfs2_inum_out(nip, dent);
1955 dent->de_type = cpu_to_be16(new_type); 1954 dent->de_type = cpu_to_be16(new_type);
1956 1955 brelse(bh);
1957 if (dip->i_diskflags & GFS2_DIF_EXHASH) {
1958 brelse(bh);
1959 error = gfs2_meta_inode_buffer(dip, &bh);
1960 if (error)
1961 return error;
1962 gfs2_trans_add_meta(dip->i_gl, bh);
1963 }
1964 1956
1965 dip->i_inode.i_mtime = dip->i_inode.i_ctime = current_time(&dip->i_inode); 1957 dip->i_inode.i_mtime = dip->i_inode.i_ctime = current_time(&dip->i_inode);
1966 gfs2_dinode_out(dip, bh->b_data); 1958 mark_inode_dirty_sync(&dip->i_inode);
1967 brelse(bh);
1968 return 0; 1959 return 0;
1969} 1960}
1970 1961