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: Bob Peterson <rpeterso@redhat.com>
This commit is contained in:
@ -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)
|
|||||||
(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 {
|
|||||||
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)
|
|||||||
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 @@ out:
|
|||||||
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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
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,
|
|||||||
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);
|
gfs2_trans_add_meta(l_ip->i_gl, sdp->sd_sc_bh);
|
||||||
if (error)
|
|
||||||
return;
|
|
||||||
|
|
||||||
gfs2_trans_add_meta(l_ip->i_gl, l_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,
|
|||||||
}
|
}
|
||||||
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,
|
|||||||
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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
}
|
}
|
||||||
spin_unlock(&sdp->sd_statfs_spin);
|
spin_unlock(&sdp->sd_statfs_spin);
|
||||||
|
|
||||||
error = gfs2_meta_inode_buffer(l_ip, &l_bh);
|
error = gfs2_trans_begin(sdp, 2 * RES_DINODE, 0);
|
||||||
if (error)
|
if (error)
|
||||||
goto out_bh;
|
goto out_bh;
|
||||||
|
|
||||||
error = gfs2_trans_begin(sdp, 2 * RES_DINODE, 0);
|
update_statfs(sdp, m_bh);
|
||||||
if (error)
|
|
||||||
goto out_bh2;
|
|
||||||
|
|
||||||
update_statfs(sdp, m_bh, l_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 @@ restart:
|
|||||||
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,
|
|||||||
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);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user