Commit 70c11ba8 authored by Bob Peterson's avatar Bob Peterson

gfs2: Don't release and reacquire local statfs bh

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: default avatarBob Peterson <rpeterso@redhat.com>
parent a28dc123
...@@ -574,10 +574,9 @@ void adjust_fs_space(struct inode *inode) ...@@ -574,10 +574,9 @@ void adjust_fs_space(struct inode *inode)
{ {
struct gfs2_sbd *sdp = GFS2_SB(inode); struct gfs2_sbd *sdp = GFS2_SB(inode);
struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_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 *m_sc = &sdp->sd_statfs_master;
struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; 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; u64 fs_total, new_free;
if (gfs2_trans_begin(sdp, 2 * RES_STATFS, 0) != 0) if (gfs2_trans_begin(sdp, 2 * RES_STATFS, 0) != 0)
...@@ -600,11 +599,7 @@ void adjust_fs_space(struct inode *inode) ...@@ -600,11 +599,7 @@ void adjust_fs_space(struct inode *inode)
(unsigned long long)new_free); (unsigned long long)new_free);
gfs2_statfs_change(sdp, new_free, new_free, 0); gfs2_statfs_change(sdp, new_free, new_free, 0);
if (gfs2_meta_inode_buffer(l_ip, &l_bh) != 0) update_statfs(sdp, m_bh);
goto out2;
update_statfs(sdp, m_bh, l_bh);
brelse(l_bh);
out2:
brelse(m_bh); brelse(m_bh);
out: out:
sdp->sd_rindex_uptodate = 0; sdp->sd_rindex_uptodate = 0;
......
...@@ -768,6 +768,7 @@ struct gfs2_sbd { ...@@ -768,6 +768,7 @@ struct gfs2_sbd {
struct gfs2_glock *sd_jinode_gl; struct gfs2_glock *sd_jinode_gl;
struct gfs2_holder sd_sc_gh; struct gfs2_holder sd_sc_gh;
struct buffer_head *sd_sc_bh;
struct gfs2_holder sd_qc_gh; struct gfs2_holder sd_qc_gh;
struct completion sd_journal_ready; struct completion sd_journal_ready;
......
...@@ -696,8 +696,16 @@ static int init_statfs(struct gfs2_sbd *sdp) ...@@ -696,8 +696,16 @@ static int init_statfs(struct gfs2_sbd *sdp)
fs_err(sdp, "can't lock local \"sc\" file: %d\n", error); fs_err(sdp, "can't lock local \"sc\" file: %d\n", error);
goto free_local; 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; return 0;
unlock_sd_gh:
gfs2_glock_dq_uninit(&sdp->sd_sc_gh);
free_local: free_local:
free_local_statfs_inodes(sdp); free_local_statfs_inodes(sdp);
iput(pn); iput(pn);
...@@ -711,6 +719,7 @@ static int init_statfs(struct gfs2_sbd *sdp) ...@@ -711,6 +719,7 @@ static int init_statfs(struct gfs2_sbd *sdp)
static void uninit_statfs(struct gfs2_sbd *sdp) static void uninit_statfs(struct gfs2_sbd *sdp)
{ {
if (!sdp->sd_args.ar_spectator) { if (!sdp->sd_args.ar_spectator) {
brelse(sdp->sd_sc_bh);
gfs2_glock_dq_uninit(&sdp->sd_sc_gh); gfs2_glock_dq_uninit(&sdp->sd_sc_gh);
free_local_statfs_inodes(sdp); free_local_statfs_inodes(sdp);
} }
......
...@@ -178,9 +178,8 @@ int gfs2_statfs_init(struct gfs2_sbd *sdp) ...@@ -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_inode *m_ip = GFS2_I(sdp->sd_statfs_inode);
struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master; 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 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; struct gfs2_holder gh;
int error; int error;
...@@ -199,21 +198,15 @@ int gfs2_statfs_init(struct gfs2_sbd *sdp) ...@@ -199,21 +198,15 @@ int gfs2_statfs_init(struct gfs2_sbd *sdp)
sizeof(struct gfs2_dinode)); sizeof(struct gfs2_dinode));
spin_unlock(&sdp->sd_statfs_spin); spin_unlock(&sdp->sd_statfs_spin);
} else { } else {
error = gfs2_meta_inode_buffer(l_ip, &l_bh);
if (error)
goto out_m_bh;
spin_lock(&sdp->sd_statfs_spin); spin_lock(&sdp->sd_statfs_spin);
gfs2_statfs_change_in(m_sc, m_bh->b_data + gfs2_statfs_change_in(m_sc, m_bh->b_data +
sizeof(struct gfs2_dinode)); 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)); sizeof(struct gfs2_dinode));
spin_unlock(&sdp->sd_statfs_spin); spin_unlock(&sdp->sd_statfs_spin);
brelse(l_bh);
} }
out_m_bh:
brelse(m_bh); brelse(m_bh);
out: out:
gfs2_glock_dq_uninit(&gh); gfs2_glock_dq_uninit(&gh);
...@@ -226,22 +219,17 @@ void gfs2_statfs_change(struct gfs2_sbd *sdp, s64 total, s64 free, ...@@ -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_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 *l_sc = &sdp->sd_statfs_local;
struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master; struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master;
struct buffer_head *l_bh;
s64 x, y; s64 x, y;
int need_sync = 0; 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); spin_lock(&sdp->sd_statfs_spin);
l_sc->sc_total += total; l_sc->sc_total += total;
l_sc->sc_free += free; l_sc->sc_free += free;
l_sc->sc_dinodes += dinodes; 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) { if (sdp->sd_args.ar_statfs_percent) {
x = 100 * l_sc->sc_free; x = 100 * l_sc->sc_free;
y = m_sc->sc_free * sdp->sd_args.ar_statfs_percent; 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, ...@@ -250,20 +238,18 @@ void gfs2_statfs_change(struct gfs2_sbd *sdp, s64 total, s64 free,
} }
spin_unlock(&sdp->sd_statfs_spin); spin_unlock(&sdp->sd_statfs_spin);
brelse(l_bh);
if (need_sync) if (need_sync)
gfs2_wake_up_statfs(sdp); gfs2_wake_up_statfs(sdp);
} }
void update_statfs(struct gfs2_sbd *sdp, struct buffer_head *m_bh, void update_statfs(struct gfs2_sbd *sdp, struct buffer_head *m_bh)
struct buffer_head *l_bh)
{ {
struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_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_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 *m_sc = &sdp->sd_statfs_master;
struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; 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); gfs2_trans_add_meta(m_ip->i_gl, m_bh);
spin_lock(&sdp->sd_statfs_spin); spin_lock(&sdp->sd_statfs_spin);
...@@ -271,7 +257,7 @@ void update_statfs(struct gfs2_sbd *sdp, struct buffer_head *m_bh, ...@@ -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_free += l_sc->sc_free;
m_sc->sc_dinodes += l_sc->sc_dinodes; m_sc->sc_dinodes += l_sc->sc_dinodes;
memset(l_sc, 0, sizeof(struct gfs2_statfs_change)); 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)); 0, sizeof(struct gfs2_statfs_change));
gfs2_statfs_change_out(m_sc, m_bh->b_data + sizeof(struct gfs2_dinode)); gfs2_statfs_change_out(m_sc, m_bh->b_data + sizeof(struct gfs2_dinode));
spin_unlock(&sdp->sd_statfs_spin); spin_unlock(&sdp->sd_statfs_spin);
...@@ -281,11 +267,10 @@ int gfs2_statfs_sync(struct super_block *sb, int type) ...@@ -281,11 +267,10 @@ int gfs2_statfs_sync(struct super_block *sb, int type)
{ {
struct gfs2_sbd *sdp = sb->s_fs_info; struct gfs2_sbd *sdp = sb->s_fs_info;
struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_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 *m_sc = &sdp->sd_statfs_master;
struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local;
struct gfs2_holder gh; struct gfs2_holder gh;
struct buffer_head *m_bh, *l_bh; struct buffer_head *m_bh;
int error; int error;
error = gfs2_glock_nq_init(m_ip->i_gl, LM_ST_EXCLUSIVE, GL_NOCACHE, 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) ...@@ -306,21 +291,15 @@ int gfs2_statfs_sync(struct super_block *sb, int type)
} }
spin_unlock(&sdp->sd_statfs_spin); 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); error = gfs2_trans_begin(sdp, 2 * RES_DINODE, 0);
if (error) 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; sdp->sd_statfs_force_sync = 0;
gfs2_trans_end(sdp); gfs2_trans_end(sdp);
out_bh2:
brelse(l_bh);
out_bh: out_bh:
brelse(m_bh); brelse(m_bh);
out_unlock: out_unlock:
...@@ -626,6 +605,7 @@ static void gfs2_put_super(struct super_block *sb) ...@@ -626,6 +605,7 @@ static void gfs2_put_super(struct super_block *sb)
gfs2_glock_dq_uninit(&sdp->sd_journal_gh); gfs2_glock_dq_uninit(&sdp->sd_journal_gh);
if (gfs2_holder_initialized(&sdp->sd_jinode_gh)) if (gfs2_holder_initialized(&sdp->sd_jinode_gh))
gfs2_glock_dq_uninit(&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_sc_gh);
gfs2_glock_dq_uninit(&sdp->sd_qc_gh); gfs2_glock_dq_uninit(&sdp->sd_qc_gh);
free_local_statfs_inodes(sdp); free_local_statfs_inodes(sdp);
......
...@@ -43,8 +43,7 @@ extern void gfs2_statfs_change_in(struct gfs2_statfs_change_host *sc, ...@@ -43,8 +43,7 @@ extern void gfs2_statfs_change_in(struct gfs2_statfs_change_host *sc,
const void *buf); const void *buf);
extern void gfs2_statfs_change_out(const struct gfs2_statfs_change_host *sc, extern void gfs2_statfs_change_out(const struct gfs2_statfs_change_host *sc,
void *buf); void *buf);
extern void update_statfs(struct gfs2_sbd *sdp, struct buffer_head *m_bh, extern void update_statfs(struct gfs2_sbd *sdp, struct buffer_head *m_bh);
struct buffer_head *l_bh);
extern int gfs2_statfs_sync(struct super_block *sb, int type); extern int gfs2_statfs_sync(struct super_block *sb, int type);
extern void gfs2_freeze_func(struct work_struct *work); extern void gfs2_freeze_func(struct work_struct *work);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment