gfs2: Split up gfs2_meta_sync into inode and rgrp versions
authorBob Peterson <rpeterso@redhat.com>
Tue, 27 Oct 2020 17:29:37 +0000 (12:29 -0500)
committerAndreas Gruenbacher <agruenba@redhat.com>
Thu, 29 Oct 2020 21:16:46 +0000 (22:16 +0100)
Before this patch, function gfs2_meta_sync called filemap_fdatawrite to write
the address space for the metadata being synced. That's great for inodes, but
resource groups all point to the same superblock-address space, sdp->sd_aspace.
Each rgrp has its own range of blocks on which it should operate. That meant
every time an rgrp's metadata was synced, it would write all of them instead
of just the range.

This patch eliminates function gfs2_meta_sync and tailors specific metasync
functions for inodes and rgrps.

Signed-off-by: Bob Peterson <rpeterso@redhat.com>
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
fs/gfs2/glops.c
fs/gfs2/glops.h
fs/gfs2/lops.c
fs/gfs2/lops.h
fs/gfs2/recovery.c

index aa3f5236befb4d5b23a59c8f4384812118756cbb..6c1432d78dce656fc1eec8b49bece5fd452a47c9 100644 (file)
@@ -164,6 +164,31 @@ void gfs2_ail_flush(struct gfs2_glock *gl, bool fsync)
                       GFS2_LFC_AIL_FLUSH);
 }
 
+/**
+ * gfs2_rgrp_metasync - sync out the metadata of a resource group
+ * @gl: the glock protecting the resource group
+ *
+ */
+
+static int gfs2_rgrp_metasync(struct gfs2_glock *gl)
+{
+       struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
+       struct address_space *metamapping = &sdp->sd_aspace;
+       struct gfs2_rgrpd *rgd = gfs2_glock2rgrp(gl);
+       const unsigned bsize = sdp->sd_sb.sb_bsize;
+       loff_t start = (rgd->rd_addr * bsize) & PAGE_MASK;
+       loff_t end = PAGE_ALIGN((rgd->rd_addr + rgd->rd_length) * bsize) - 1;
+       int error;
+
+       filemap_fdatawrite_range(metamapping, start, end);
+       error = filemap_fdatawait_range(metamapping, start, end);
+       WARN_ON_ONCE(error && !gfs2_withdrawn(sdp));
+       mapping_set_error(metamapping, error);
+       if (error)
+               gfs2_io_error(sdp);
+       return error;
+}
+
 /**
  * rgrp_go_sync - sync out the metadata for this glock
  * @gl: the glock
@@ -176,11 +201,7 @@ void gfs2_ail_flush(struct gfs2_glock *gl, bool fsync)
 static int rgrp_go_sync(struct gfs2_glock *gl)
 {
        struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
-       struct address_space *mapping = &sdp->sd_aspace;
        struct gfs2_rgrpd *rgd = gfs2_glock2rgrp(gl);
-       const unsigned bsize = sdp->sd_sb.sb_bsize;
-       loff_t start = (rgd->rd_addr * bsize) & PAGE_MASK;
-       loff_t end = PAGE_ALIGN((rgd->rd_addr + rgd->rd_length) * bsize) - 1;
        int error;
 
        if (!test_and_clear_bit(GLF_DIRTY, &gl->gl_flags))
@@ -189,10 +210,7 @@ static int rgrp_go_sync(struct gfs2_glock *gl)
 
        gfs2_log_flush(sdp, gl, GFS2_LOG_HEAD_FLUSH_NORMAL |
                       GFS2_LFC_RGRP_GO_SYNC);
-       filemap_fdatawrite_range(mapping, start, end);
-       error = filemap_fdatawait_range(mapping, start, end);
-       WARN_ON_ONCE(error && !gfs2_withdrawn(sdp));
-       mapping_set_error(mapping, error);
+       error = gfs2_rgrp_metasync(gl);
        if (!error)
                error = gfs2_ail_empty_gl(gl);
        gfs2_free_clones(rgd);
@@ -266,7 +284,24 @@ static void gfs2_clear_glop_pending(struct gfs2_inode *ip)
 }
 
 /**
- * inode_go_sync - Sync the dirty data and/or metadata for an inode glock
+ * gfs2_inode_metasync - sync out the metadata of an inode
+ * @gl: the glock protecting the inode
+ *
+ */
+int gfs2_inode_metasync(struct gfs2_glock *gl)
+{
+       struct address_space *metamapping = gfs2_glock2aspace(gl);
+       int error;
+
+       filemap_fdatawrite(metamapping);
+       error = filemap_fdatawait(metamapping);
+       if (error)
+               gfs2_io_error(gl->gl_name.ln_sbd);
+       return error;
+}
+
+/**
+ * inode_go_sync - Sync the dirty metadata of an inode
  * @gl: the glock protecting the inode
  *
  */
@@ -297,8 +332,7 @@ static int inode_go_sync(struct gfs2_glock *gl)
                error = filemap_fdatawait(mapping);
                mapping_set_error(mapping, error);
        }
-       ret = filemap_fdatawait(metamapping);
-       mapping_set_error(metamapping, ret);
+       ret = gfs2_inode_metasync(gl);
        if (!error)
                error = ret;
        gfs2_ail_empty_gl(gl);
index 2dd192e8561825920ac24d9b4931e9f3fcc71104..695898afcaf1fbf6c9d3be048a1cfa90ce11e225 100644 (file)
@@ -22,6 +22,7 @@ extern const struct gfs2_glock_operations gfs2_quota_glops;
 extern const struct gfs2_glock_operations gfs2_journal_glops;
 extern const struct gfs2_glock_operations *gfs2_glops_list[];
 
+extern int gfs2_inode_metasync(struct gfs2_glock *gl);
 extern void gfs2_ail_flush(struct gfs2_glock *gl, bool fsync);
 
 #endif /* __GLOPS_DOT_H__ */
index ed69298dd824a23c53cf6a83e7dad64c011ecf3c..3922b26264f5a87cec611ab2e6b01cf4827cde44 100644 (file)
@@ -22,6 +22,7 @@
 #include "incore.h"
 #include "inode.h"
 #include "glock.h"
+#include "glops.h"
 #include "log.h"
 #include "lops.h"
 #include "meta_io.h"
@@ -817,41 +818,19 @@ static int buf_lo_scan_elements(struct gfs2_jdesc *jd, u32 start,
        return error;
 }
 
-/**
- * gfs2_meta_sync - Sync all buffers associated with a glock
- * @gl: The glock
- *
- */
-
-void gfs2_meta_sync(struct gfs2_glock *gl)
-{
-       struct address_space *mapping = gfs2_glock2aspace(gl);
-       struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
-       int error;
-
-       if (mapping == NULL)
-               mapping = &sdp->sd_aspace;
-
-       filemap_fdatawrite(mapping);
-       error = filemap_fdatawait(mapping);
-
-       if (error)
-               gfs2_io_error(gl->gl_name.ln_sbd);
-}
-
 static void buf_lo_after_scan(struct gfs2_jdesc *jd, int error, int pass)
 {
        struct gfs2_inode *ip = GFS2_I(jd->jd_inode);
        struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
 
        if (error) {
-               gfs2_meta_sync(ip->i_gl);
+               gfs2_inode_metasync(ip->i_gl);
                return;
        }
        if (pass != 1)
                return;
 
-       gfs2_meta_sync(ip->i_gl);
+       gfs2_inode_metasync(ip->i_gl);
 
        fs_info(sdp, "jid=%u: Replayed %u of %u blocks\n",
                jd->jd_jid, jd->jd_replayed_blocks, jd->jd_found_blocks);
@@ -1060,14 +1039,14 @@ static void databuf_lo_after_scan(struct gfs2_jdesc *jd, int error, int pass)
        struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
 
        if (error) {
-               gfs2_meta_sync(ip->i_gl);
+               gfs2_inode_metasync(ip->i_gl);
                return;
        }
        if (pass != 1)
                return;
 
        /* data sync? */
-       gfs2_meta_sync(ip->i_gl);
+       gfs2_inode_metasync(ip->i_gl);
 
        fs_info(sdp, "jid=%u: Replayed %u of %u data blocks\n",
                jd->jd_jid, jd->jd_replayed_blocks, jd->jd_found_blocks);
index 4a3d8aecdf82765a22dd655c7e8913ff8a3a289d..fbdbb08dcec6af19057a4f4181e10f2441295c11 100644 (file)
@@ -27,8 +27,6 @@ extern void gfs2_log_submit_bio(struct bio **biop, int opf);
 extern void gfs2_pin(struct gfs2_sbd *sdp, struct buffer_head *bh);
 extern int gfs2_find_jhead(struct gfs2_jdesc *jd,
                           struct gfs2_log_header_host *head, bool keep_cache);
-extern void gfs2_meta_sync(struct gfs2_glock *gl);
-
 static inline unsigned int buf_limit(struct gfs2_sbd *sdp)
 {
        unsigned int limit;
index b5cbe21efdfb3b5608b1fb35dd8fc5329604c051..c26c68ebd29d4be67b3015838fca25068e6c0641 100644 (file)
@@ -349,7 +349,7 @@ static int update_statfs_inode(struct gfs2_jdesc *jd,
 
        mark_buffer_dirty(bh);
        brelse(bh);
-       gfs2_meta_sync(ip->i_gl);
+       gfs2_inode_metasync(ip->i_gl);
 
 out:
        return error;