aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-02-28 12:17:31 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-02-28 12:17:31 -0500
commit891003abb0db6bfffd61b76ad0ed39bb7c3db8e1 (patch)
treeba2c54bee79d46dbd7855fb6b87fa0487c761808
parentd5a74afd08738af84d51c353ac3ac200b06c51d7 (diff)
parenta365fbf354907430e6852f0c373b4b3eeff81ba3 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-3.0-fixes
* git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-3.0-fixes: GFS2: Read resource groups on mount GFS2: Ensure rindex is uptodate for fallocate GFS2: Read in rindex if necessary during unlink GFS2: Fix race between lru_list and glock ref count
-rw-r--r--fs/gfs2/glock.c14
-rw-r--r--fs/gfs2/inode.c5
-rw-r--r--fs/gfs2/ops_fstype.c5
-rw-r--r--fs/gfs2/rgrp.c13
4 files changed, 25 insertions, 12 deletions
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 376816fcd040..351a3e797789 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -167,14 +167,19 @@ void gfs2_glock_add_to_lru(struct gfs2_glock *gl)
167 spin_unlock(&lru_lock); 167 spin_unlock(&lru_lock);
168} 168}
169 169
170static void gfs2_glock_remove_from_lru(struct gfs2_glock *gl) 170static void __gfs2_glock_remove_from_lru(struct gfs2_glock *gl)
171{ 171{
172 spin_lock(&lru_lock);
173 if (!list_empty(&gl->gl_lru)) { 172 if (!list_empty(&gl->gl_lru)) {
174 list_del_init(&gl->gl_lru); 173 list_del_init(&gl->gl_lru);
175 atomic_dec(&lru_count); 174 atomic_dec(&lru_count);
176 clear_bit(GLF_LRU, &gl->gl_flags); 175 clear_bit(GLF_LRU, &gl->gl_flags);
177 } 176 }
177}
178
179static void gfs2_glock_remove_from_lru(struct gfs2_glock *gl)
180{
181 spin_lock(&lru_lock);
182 __gfs2_glock_remove_from_lru(gl);
178 spin_unlock(&lru_lock); 183 spin_unlock(&lru_lock);
179} 184}
180 185
@@ -217,11 +222,12 @@ void gfs2_glock_put(struct gfs2_glock *gl)
217 struct gfs2_sbd *sdp = gl->gl_sbd; 222 struct gfs2_sbd *sdp = gl->gl_sbd;
218 struct address_space *mapping = gfs2_glock2aspace(gl); 223 struct address_space *mapping = gfs2_glock2aspace(gl);
219 224
220 if (atomic_dec_and_test(&gl->gl_ref)) { 225 if (atomic_dec_and_lock(&gl->gl_ref, &lru_lock)) {
226 __gfs2_glock_remove_from_lru(gl);
227 spin_unlock(&lru_lock);
221 spin_lock_bucket(gl->gl_hash); 228 spin_lock_bucket(gl->gl_hash);
222 hlist_bl_del_rcu(&gl->gl_list); 229 hlist_bl_del_rcu(&gl->gl_list);
223 spin_unlock_bucket(gl->gl_hash); 230 spin_unlock_bucket(gl->gl_hash);
224 gfs2_glock_remove_from_lru(gl);
225 GLOCK_BUG_ON(gl, !list_empty(&gl->gl_holders)); 231 GLOCK_BUG_ON(gl, !list_empty(&gl->gl_holders));
226 GLOCK_BUG_ON(gl, mapping && mapping->nrpages); 232 GLOCK_BUG_ON(gl, mapping && mapping->nrpages);
227 trace_gfs2_glock_put(gl); 233 trace_gfs2_glock_put(gl);
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index a7d611b93f0f..56987460cdae 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -391,10 +391,6 @@ static int alloc_dinode(struct gfs2_inode *dip, u64 *no_addr, u64 *generation)
391 int error; 391 int error;
392 int dblocks = 1; 392 int dblocks = 1;
393 393
394 error = gfs2_rindex_update(sdp);
395 if (error)
396 fs_warn(sdp, "rindex update returns %d\n", error);
397
398 error = gfs2_inplace_reserve(dip, RES_DINODE); 394 error = gfs2_inplace_reserve(dip, RES_DINODE);
399 if (error) 395 if (error)
400 goto out; 396 goto out;
@@ -1043,6 +1039,7 @@ static int gfs2_unlink(struct inode *dir, struct dentry *dentry)
1043 rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr); 1039 rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr);
1044 if (!rgd) 1040 if (!rgd)
1045 goto out_inodes; 1041 goto out_inodes;
1042
1046 gfs2_holder_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + 2); 1043 gfs2_holder_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + 2);
1047 1044
1048 1045
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index 6aacf3f230a2..24f609c9ef91 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -800,6 +800,11 @@ static int init_inodes(struct gfs2_sbd *sdp, int undo)
800 fs_err(sdp, "can't get quota file inode: %d\n", error); 800 fs_err(sdp, "can't get quota file inode: %d\n", error);
801 goto fail_rindex; 801 goto fail_rindex;
802 } 802 }
803
804 error = gfs2_rindex_update(sdp);
805 if (error)
806 goto fail_qinode;
807
803 return 0; 808 return 0;
804 809
805fail_qinode: 810fail_qinode:
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index 981bfa32121a..49ada95209d0 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -683,16 +683,21 @@ int gfs2_rindex_update(struct gfs2_sbd *sdp)
683 struct gfs2_glock *gl = ip->i_gl; 683 struct gfs2_glock *gl = ip->i_gl;
684 struct gfs2_holder ri_gh; 684 struct gfs2_holder ri_gh;
685 int error = 0; 685 int error = 0;
686 int unlock_required = 0;
686 687
687 /* Read new copy from disk if we don't have the latest */ 688 /* Read new copy from disk if we don't have the latest */
688 if (!sdp->sd_rindex_uptodate) { 689 if (!sdp->sd_rindex_uptodate) {
689 mutex_lock(&sdp->sd_rindex_mutex); 690 mutex_lock(&sdp->sd_rindex_mutex);
690 error = gfs2_glock_nq_init(gl, LM_ST_SHARED, 0, &ri_gh); 691 if (!gfs2_glock_is_locked_by_me(gl)) {
691 if (error) 692 error = gfs2_glock_nq_init(gl, LM_ST_SHARED, 0, &ri_gh);
692 return error; 693 if (error)
694 return error;
695 unlock_required = 1;
696 }
693 if (!sdp->sd_rindex_uptodate) 697 if (!sdp->sd_rindex_uptodate)
694 error = gfs2_ri_update(ip); 698 error = gfs2_ri_update(ip);
695 gfs2_glock_dq_uninit(&ri_gh); 699 if (unlock_required)
700 gfs2_glock_dq_uninit(&ri_gh);
696 mutex_unlock(&sdp->sd_rindex_mutex); 701 mutex_unlock(&sdp->sd_rindex_mutex);
697 } 702 }
698 703