Acked-by: Steven Whitehouse <swhit...@redhat.com>

Looks good. Thanks,

Steve.


On 27/02/18 11:50, Andreas Gruenbacher wrote:
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

Signed-off-by: Andreas Gruenbacher <agrue...@redhat.com>
---
  fs/gfs2/dir.c   | 13 ++-----------
  fs/gfs2/inode.c | 10 +---------
  2 files changed, 3 insertions(+), 20 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,
  {
        struct buffer_head *bh;
        struct gfs2_dirent *dent;
-       int error;
dent = gfs2_dirent_search(&dip->i_inode, filename, gfs2_dirent_find, &bh);
        if (!dent) {
@@ -1953,18 +1952,10 @@ int gfs2_dir_mvino(struct gfs2_inode *dip, const struct 
qstr *filename,
        gfs2_trans_add_meta(dip->i_gl, bh);
        gfs2_inum_out(nip, dent);
        dent->de_type = cpu_to_be16(new_type);
-
-       if (dip->i_diskflags & GFS2_DIF_EXHASH) {
-               brelse(bh);
-               error = gfs2_meta_inode_buffer(dip, &bh);
-               if (error)
-                       return error;
-               gfs2_trans_add_meta(dip->i_gl, bh);
-       }
+       brelse(bh);
dip->i_inode.i_mtime = dip->i_inode.i_ctime = current_time(&dip->i_inode);
-       gfs2_dinode_out(dip, bh->b_data);
-       brelse(bh);
+       mark_inode_dirty_sync(&dip->i_inode);
        return 0;
  }
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)
  static int update_moved_ino(struct gfs2_inode *ip, struct gfs2_inode *ndip,
                            int dir_rename)
  {
-       int error;
-       struct buffer_head *dibh;
-
        if (dir_rename)
                return gfs2_dir_mvino(ip, &gfs2_qdotdot, ndip, DT_DIR);
- error = gfs2_meta_inode_buffer(ip, &dibh);
-       if (error)
-               return error;
        ip->i_inode.i_ctime = current_time(&ip->i_inode);
-       gfs2_trans_add_meta(ip->i_gl, dibh);
-       gfs2_dinode_out(ip, dibh->b_data);
-       brelse(dibh);
+       mark_inode_dirty_sync(&ip->i_inode);
        return 0;
  }

Reply via email to