[Cluster-devel] [PATCH 2/8] gfs2: Protect gl->gl_object by spin lock
Andreas Gruenbacher
agruenba at redhat.com
Wed May 31 15:03:06 UTC 2017
Put all remaining accesses to gl->gl_object under the
gl->gl_lockref.lock spinlock to prevent races.
Signed-off-by: Andreas Gruenbacher <agruenba at redhat.com>
---
fs/gfs2/bmap.c | 7 ++++++-
fs/gfs2/dir.c | 6 +++++-
fs/gfs2/glops.c | 10 ++++++++--
fs/gfs2/inode.c | 8 ++++----
fs/gfs2/lops.c | 9 +++++++--
fs/gfs2/rgrp.c | 6 ++----
fs/gfs2/super.c | 11 ++++++++---
fs/gfs2/xattr.c | 6 +++++-
8 files changed, 45 insertions(+), 18 deletions(-)
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
index 4d810be..e43decb 100644
--- a/fs/gfs2/bmap.c
+++ b/fs/gfs2/bmap.c
@@ -970,7 +970,12 @@ static int sweep_bh_for_rgrps(struct gfs2_inode *ip, struct gfs2_holder *rd_gh,
continue;
bn = be64_to_cpu(*p);
if (gfs2_holder_initialized(rd_gh)) {
- rgd = (struct gfs2_rgrpd *)rd_gh->gh_gl->gl_object;
+ struct gfs2_glock *gl = rd_gh->gh_gl;
+
+ spin_lock(&gl->gl_lockref.lock);
+ rgd = rd_gh->gh_gl->gl_object;
+ spin_unlock(&gl->gl_lockref.lock);
+
gfs2_assert_withdraw(sdp,
gfs2_glock_is_locked_by_me(rd_gh->gh_gl));
} else {
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c
index 7911321..965f1c7 100644
--- a/fs/gfs2/dir.c
+++ b/fs/gfs2/dir.c
@@ -2031,9 +2031,13 @@ static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len,
gfs2_rlist_alloc(&rlist, LM_ST_EXCLUSIVE);
for (x = 0; x < rlist.rl_rgrps; x++) {
+ struct gfs2_glock *gl = rlist.rl_ghs[x].gh_gl;
struct gfs2_rgrpd *rgd;
- rgd = rlist.rl_ghs[x].gh_gl->gl_object;
+
+ spin_lock(&gl->gl_lockref.lock);
+ rgd = gl->gl_object;
rg_blocks += rgd->rd_length;
+ spin_unlock(&gl->gl_lockref.lock);
}
error = gfs2_glock_nq_m(rlist.rl_rgrps, rlist.rl_ghs);
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c
index 7449b19..238a78c 100644
--- a/fs/gfs2/glops.c
+++ b/fs/gfs2/glops.c
@@ -184,17 +184,23 @@ static void rgrp_go_inval(struct gfs2_glock *gl, int flags)
{
struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
struct address_space *mapping = &sdp->sd_aspace;
- struct gfs2_rgrpd *rgd = gl->gl_object;
+ struct gfs2_rgrpd *rgd;
+ spin_lock(&gl->gl_lockref.lock);
+ rgd = gl->gl_object;
if (rgd)
gfs2_rgrp_brelse(rgd);
+ spin_unlock(&gl->gl_lockref.lock);
WARN_ON_ONCE(!(flags & DIO_METADATA));
gfs2_assert_withdraw(sdp, !atomic_read(&gl->gl_ail_count));
truncate_inode_pages_range(mapping, gl->gl_vm.start, gl->gl_vm.end);
+ spin_lock(&gl->gl_lockref.lock);
+ rgd = gl->gl_object;
if (rgd)
rgd->rd_flags &= ~GFS2_RDF_UPTODATE;
+ spin_unlock(&gl->gl_lockref.lock);
}
static struct gfs2_inode *gfs2_glock2inode(struct gfs2_glock *gl)
@@ -566,7 +572,7 @@ static int freeze_go_demote_ok(const struct gfs2_glock *gl)
*/
static void iopen_go_callback(struct gfs2_glock *gl, bool remote)
{
- struct gfs2_inode *ip = (struct gfs2_inode *)gl->gl_object;
+ struct gfs2_inode *ip = gl->gl_object;
struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
if (!remote || (sdp->sd_vfs->s_flags & MS_RDONLY))
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index 912d4e6..50108fa 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -202,14 +202,14 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type,
fail_refresh:
ip->i_iopen_gh.gh_flags |= GL_NOCACHE;
- ip->i_iopen_gh.gh_gl->gl_object = NULL;
+ glock_set_object(ip->i_iopen_gh.gh_gl, NULL);
gfs2_glock_dq_uninit(&ip->i_iopen_gh);
fail_put:
if (io_gl)
gfs2_glock_put(io_gl);
if (gfs2_holder_initialized(&i_gh))
gfs2_glock_dq_uninit(&i_gh);
- ip->i_gl->gl_object = NULL;
+ glock_set_object(ip->i_gl, NULL);
fail:
iget_failed(inode);
return ERR_PTR(error);
@@ -706,7 +706,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
if (error)
goto fail_free_inode;
- ip->i_gl->gl_object = ip;
+ glock_set_object(ip->i_gl, ip);
error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_SKIP, ghs + 1);
if (error)
goto fail_free_inode;
@@ -732,7 +732,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
if (error)
goto fail_gunlock2;
- ip->i_iopen_gh.gh_gl->gl_object = ip;
+ glock_set_object(ip->i_iopen_gh.gh_gl, ip);
gfs2_glock_put(io_gl);
gfs2_set_iop(inode);
insert_inode_hash(inode);
diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c
index b1f9144..93c1074 100644
--- a/fs/gfs2/lops.c
+++ b/fs/gfs2/lops.c
@@ -71,10 +71,15 @@ static void maybe_release_space(struct gfs2_bufdata *bd)
{
struct gfs2_glock *gl = bd->bd_gl;
struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
- struct gfs2_rgrpd *rgd = gl->gl_object;
+ struct gfs2_rgrpd *rgd;
unsigned int index = bd->bd_bh->b_blocknr - gl->gl_name.ln_number;
- struct gfs2_bitmap *bi = rgd->rd_bits + index;
+ struct gfs2_bitmap *bi;
+ spin_lock(&gl->gl_lockref.lock);
+ rgd = gl->gl_object;
+ spin_unlock(&gl->gl_lockref.lock);
+
+ bi = rgd->rd_bits + index;
if (bi->bi_clone == NULL)
return;
if (sdp->sd_args.ar_discard)
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index 83c9909..836e38b 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -705,9 +705,7 @@ void gfs2_clear_rgrpd(struct gfs2_sbd *sdp)
rb_erase(n, &sdp->sd_rindex_tree);
if (gl) {
- spin_lock(&gl->gl_lockref.lock);
- gl->gl_object = NULL;
- spin_unlock(&gl->gl_lockref.lock);
+ glock_set_object(gl, NULL);
gfs2_glock_add_to_lru(gl);
gfs2_glock_put(gl);
}
@@ -917,7 +915,7 @@ static int read_rindex_entry(struct gfs2_inode *ip)
error = rgd_insert(rgd);
spin_unlock(&sdp->sd_rindex_spin);
if (!error) {
- rgd->rd_gl->gl_object = rgd;
+ glock_set_object(rgd->rd_gl, rgd);
rgd->rd_gl->gl_vm.start = (rgd->rd_addr * bsize) & PAGE_MASK;
rgd->rd_gl->gl_vm.end = PAGE_ALIGN((rgd->rd_addr +
rgd->rd_length) * bsize) - 1;
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index 7d12c12..554bd0c 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -1105,9 +1105,14 @@ static int gfs2_statfs_slow(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host
gfs2_holder_uninit(gh);
error = err;
} else {
+ struct gfs2_glock *gl = gh->gh_gl;
+ struct gfs2_rgrpd *rgd;
+
+ spin_lock(&gl->gl_lockref.lock);
+ rgd = gl->gl_object;
+ spin_unlock(&gl->gl_lockref.lock);
if (!error)
- error = statfs_slow_fill(
- gh->gh_gl->gl_object, sc);
+ error = statfs_slow_fill(rgd, sc);
gfs2_glock_dq_uninit(gh);
}
}
@@ -1637,7 +1642,7 @@ static void gfs2_evict_inode(struct inode *inode)
gfs2_glock_put(ip->i_gl);
ip->i_gl = NULL;
if (gfs2_holder_initialized(&ip->i_iopen_gh)) {
- ip->i_iopen_gh.gh_gl->gl_object = NULL;
+ glock_set_object(ip->i_iopen_gh.gh_gl, NULL);
ip->i_iopen_gh.gh_flags |= GL_NOCACHE;
gfs2_glock_dq_uninit(&ip->i_iopen_gh);
}
diff --git a/fs/gfs2/xattr.c b/fs/gfs2/xattr.c
index d87721a..4774584 100644
--- a/fs/gfs2/xattr.c
+++ b/fs/gfs2/xattr.c
@@ -1327,9 +1327,13 @@ static int ea_dealloc_indirect(struct gfs2_inode *ip)
gfs2_rlist_alloc(&rlist, LM_ST_EXCLUSIVE);
for (x = 0; x < rlist.rl_rgrps; x++) {
+ struct gfs2_glock *gl = rlist.rl_ghs[x].gh_gl;
struct gfs2_rgrpd *rgd;
- rgd = rlist.rl_ghs[x].gh_gl->gl_object;
+
+ spin_lock(&gl->gl_lockref.lock);
+ rgd = gl->gl_object;
rg_blocks += rgd->rd_length;
+ spin_unlock(&gl->gl_lockref.lock);
}
error = gfs2_glock_nq_m(rlist.rl_rgrps, rlist.rl_ghs);
--
2.7.4
More information about the Cluster-devel
mailing list