gfs2: Don't release and reacquire local statfs bh
authorBob Peterson <rpeterso@redhat.com>
Wed, 30 Jun 2021 16:46:17 +0000 (11:46 -0500)
committerBob Peterson <rpeterso@redhat.com>
Fri, 20 Aug 2021 14:03:46 +0000 (09:03 -0500)
Before this patch, several functions in gfs2 related to the updating
of the statfs file used a newly acquired/read buffer_head for the
local statfs file. This is completely unnecessary, because other nodes
should never update it. Recreating the buffer is a waste of time.

This patch allows gfs2 to read in the local statefs buffer_head at
mount time and keep it around until unmount time.

Signed-off-by: Bob Peterson <rpeterso@redhat.com>
fs/gfs2/aops.c
fs/gfs2/incore.h
fs/gfs2/ops_fstype.c
fs/gfs2/super.c
fs/gfs2/super.h

index 81d8f06..005e920 100644 (file)
@@ -574,10 +574,9 @@ void adjust_fs_space(struct inode *inode)
 {
        struct gfs2_sbd *sdp = GFS2_SB(inode);
        struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode);
-       struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode);
        struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master;
        struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local;
-       struct buffer_head *m_bh, *l_bh;
+       struct buffer_head *m_bh;
        u64 fs_total, new_free;
 
        if (gfs2_trans_begin(sdp, 2 * RES_STATFS, 0) != 0)
@@ -600,11 +599,7 @@ void adjust_fs_space(struct inode *inode)
                (unsigned long long)new_free);
        gfs2_statfs_change(sdp, new_free, new_free, 0);
 
-       if (gfs2_meta_inode_buffer(l_ip, &l_bh) != 0)
-               goto out2;
-       update_statfs(sdp, m_bh, l_bh);
-       brelse(l_bh);
-out2:
+       update_statfs(sdp, m_bh);
        brelse(m_bh);
 out:
        sdp->sd_rindex_uptodate = 0;
index e6f820f..397b091 100644 (file)
@@ -768,6 +768,7 @@ struct gfs2_sbd {
        struct gfs2_glock *sd_jinode_gl;
 
        struct gfs2_holder sd_sc_gh;
+       struct buffer_head *sd_sc_bh;
        struct gfs2_holder sd_qc_gh;
 
        struct completion sd_journal_ready;
index ca76e3b..5b90d2b 100644 (file)
@@ -696,8 +696,16 @@ static int init_statfs(struct gfs2_sbd *sdp)
                fs_err(sdp, "can't lock local \"sc\" file: %d\n", error);
                goto free_local;
        }
+       /* read in the local statfs buffer - other nodes don't change it. */
+       error = gfs2_meta_inode_buffer(ip, &sdp->sd_sc_bh);
+       if (error) {
+               fs_err(sdp, "Cannot read in local statfs: %d\n", error);
+               goto unlock_sd_gh;
+       }
        return 0;
 
+unlock_sd_gh:
+       gfs2_glock_dq_uninit(&sdp->sd_sc_gh);
 free_local:
        free_local_statfs_inodes(sdp);
        iput(pn);
@@ -711,6 +719,7 @@ out:
 static void uninit_statfs(struct gfs2_sbd *sdp)
 {
        if (!sdp->sd_args.ar_spectator) {
+               brelse(sdp->sd_sc_bh);
                gfs2_glock_dq_uninit(&sdp->sd_sc_gh);
                free_local_statfs_inodes(sdp);
        }
index 2bdbba5..0a5b7df 100644 (file)
@@ -178,9 +178,8 @@ int gfs2_statfs_init(struct gfs2_sbd *sdp)
 {
        struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode);
        struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master;
-       struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode);
        struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local;
-       struct buffer_head *m_bh, *l_bh;
+       struct buffer_head *m_bh;
        struct gfs2_holder gh;
        int error;
 
@@ -199,21 +198,15 @@ int gfs2_statfs_init(struct gfs2_sbd *sdp)
                                      sizeof(struct gfs2_dinode));
                spin_unlock(&sdp->sd_statfs_spin);
        } else {
-               error = gfs2_meta_inode_buffer(l_ip, &l_bh);
-               if (error)
-                       goto out_m_bh;
-
                spin_lock(&sdp->sd_statfs_spin);
                gfs2_statfs_change_in(m_sc, m_bh->b_data +
                                      sizeof(struct gfs2_dinode));
-               gfs2_statfs_change_in(l_sc, l_bh->b_data +
+               gfs2_statfs_change_in(l_sc, sdp->sd_sc_bh->b_data +
                                      sizeof(struct gfs2_dinode));
                spin_unlock(&sdp->sd_statfs_spin);
 
-               brelse(l_bh);
        }
 
-out_m_bh:
        brelse(m_bh);
 out:
        gfs2_glock_dq_uninit(&gh);
@@ -226,22 +219,17 @@ void gfs2_statfs_change(struct gfs2_sbd *sdp, s64 total, s64 free,
        struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode);
        struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local;
        struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master;
-       struct buffer_head *l_bh;
        s64 x, y;
        int need_sync = 0;
-       int error;
-
-       error = gfs2_meta_inode_buffer(l_ip, &l_bh);
-       if (error)
-               return;
 
-       gfs2_trans_add_meta(l_ip->i_gl, l_bh);
+       gfs2_trans_add_meta(l_ip->i_gl, sdp->sd_sc_bh);
 
        spin_lock(&sdp->sd_statfs_spin);
        l_sc->sc_total += total;
        l_sc->sc_free += free;
        l_sc->sc_dinodes += dinodes;
-       gfs2_statfs_change_out(l_sc, l_bh->b_data + sizeof(struct gfs2_dinode));
+       gfs2_statfs_change_out(l_sc, sdp->sd_sc_bh->b_data +
+                              sizeof(struct gfs2_dinode));
        if (sdp->sd_args.ar_statfs_percent) {
                x = 100 * l_sc->sc_free;
                y = m_sc->sc_free * sdp->sd_args.ar_statfs_percent;
@@ -250,20 +238,18 @@ void gfs2_statfs_change(struct gfs2_sbd *sdp, s64 total, s64 free,
        }
        spin_unlock(&sdp->sd_statfs_spin);
 
-       brelse(l_bh);
        if (need_sync)
                gfs2_wake_up_statfs(sdp);
 }
 
-void update_statfs(struct gfs2_sbd *sdp, struct buffer_head *m_bh,
-                  struct buffer_head *l_bh)
+void update_statfs(struct gfs2_sbd *sdp, struct buffer_head *m_bh)
 {
        struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode);
        struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode);
        struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master;
        struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local;
 
-       gfs2_trans_add_meta(l_ip->i_gl, l_bh);
+       gfs2_trans_add_meta(l_ip->i_gl, sdp->sd_sc_bh);
        gfs2_trans_add_meta(m_ip->i_gl, m_bh);
 
        spin_lock(&sdp->sd_statfs_spin);
@@ -271,7 +257,7 @@ void update_statfs(struct gfs2_sbd *sdp, struct buffer_head *m_bh,
        m_sc->sc_free += l_sc->sc_free;
        m_sc->sc_dinodes += l_sc->sc_dinodes;
        memset(l_sc, 0, sizeof(struct gfs2_statfs_change));
-       memset(l_bh->b_data + sizeof(struct gfs2_dinode),
+       memset(sdp->sd_sc_bh->b_data + sizeof(struct gfs2_dinode),
               0, sizeof(struct gfs2_statfs_change));
        gfs2_statfs_change_out(m_sc, m_bh->b_data + sizeof(struct gfs2_dinode));
        spin_unlock(&sdp->sd_statfs_spin);
@@ -281,11 +267,10 @@ int gfs2_statfs_sync(struct super_block *sb, int type)
 {
        struct gfs2_sbd *sdp = sb->s_fs_info;
        struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode);
-       struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode);
        struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master;
        struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local;
        struct gfs2_holder gh;
-       struct buffer_head *m_bh, *l_bh;
+       struct buffer_head *m_bh;
        int error;
 
        error = gfs2_glock_nq_init(m_ip->i_gl, LM_ST_EXCLUSIVE, GL_NOCACHE,
@@ -306,21 +291,15 @@ int gfs2_statfs_sync(struct super_block *sb, int type)
        }
        spin_unlock(&sdp->sd_statfs_spin);
 
-       error = gfs2_meta_inode_buffer(l_ip, &l_bh);
-       if (error)
-               goto out_bh;
-
        error = gfs2_trans_begin(sdp, 2 * RES_DINODE, 0);
        if (error)
-               goto out_bh2;
+               goto out_bh;
 
-       update_statfs(sdp, m_bh, l_bh);
+       update_statfs(sdp, m_bh);
        sdp->sd_statfs_force_sync = 0;
 
        gfs2_trans_end(sdp);
 
-out_bh2:
-       brelse(l_bh);
 out_bh:
        brelse(m_bh);
 out_unlock:
@@ -626,6 +605,7 @@ restart:
                        gfs2_glock_dq_uninit(&sdp->sd_journal_gh);
                if (gfs2_holder_initialized(&sdp->sd_jinode_gh))
                        gfs2_glock_dq_uninit(&sdp->sd_jinode_gh);
+               brelse(sdp->sd_sc_bh);
                gfs2_glock_dq_uninit(&sdp->sd_sc_gh);
                gfs2_glock_dq_uninit(&sdp->sd_qc_gh);
                free_local_statfs_inodes(sdp);
index ec4affb..58d13fd 100644 (file)
@@ -43,8 +43,7 @@ extern void gfs2_statfs_change_in(struct gfs2_statfs_change_host *sc,
                                  const void *buf);
 extern void gfs2_statfs_change_out(const struct gfs2_statfs_change_host *sc,
                                   void *buf);
-extern void update_statfs(struct gfs2_sbd *sdp, struct buffer_head *m_bh,
-                         struct buffer_head *l_bh);
+extern void update_statfs(struct gfs2_sbd *sdp, struct buffer_head *m_bh);
 extern int gfs2_statfs_sync(struct super_block *sb, int type);
 extern void gfs2_freeze_func(struct work_struct *work);