diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-02-28 12:17:31 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-02-28 12:17:31 -0500 |
commit | 891003abb0db6bfffd61b76ad0ed39bb7c3db8e1 (patch) | |
tree | ba2c54bee79d46dbd7855fb6b87fa0487c761808 | |
parent | d5a74afd08738af84d51c353ac3ac200b06c51d7 (diff) | |
parent | a365fbf354907430e6852f0c373b4b3eeff81ba3 (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.c | 14 | ||||
-rw-r--r-- | fs/gfs2/inode.c | 5 | ||||
-rw-r--r-- | fs/gfs2/ops_fstype.c | 5 | ||||
-rw-r--r-- | fs/gfs2/rgrp.c | 13 |
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 | ||
170 | static void gfs2_glock_remove_from_lru(struct gfs2_glock *gl) | 170 | static 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 | |||
179 | static 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 | ||
805 | fail_qinode: | 810 | fail_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 | ||