aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-07-14 13:20:42 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-07-14 13:20:42 -0400
commit5dcd07b9f39ca3e9be5bcc387d193fc0674e1c81 (patch)
tree8cd651b2743b8af4805e0ae45b660ce8758960ae /fs
parent51414d41084496aaefd06d7f19eb8206e8bfac2d (diff)
parent380f7c65a7eb3288e4b6812acf3474a1de230707 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-fixes
* git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-fixes: GFS2: Resolve inode eviction and ail list interaction bug GFS2: Fix race during filesystem mount GFS2: force a log flush when invalidating the rindex glock
Diffstat (limited to 'fs')
-rw-r--r--fs/gfs2/aops.c3
-rw-r--r--fs/gfs2/glops.c8
-rw-r--r--fs/gfs2/incore.h2
-rw-r--r--fs/gfs2/log.c1
-rw-r--r--fs/gfs2/ops_fstype.c3
-rw-r--r--fs/gfs2/super.c36
-rw-r--r--fs/gfs2/sys.c7
7 files changed, 50 insertions, 10 deletions
diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c
index 802ac5eeba28..f9fbbe96c222 100644
--- a/fs/gfs2/aops.c
+++ b/fs/gfs2/aops.c
@@ -1069,6 +1069,7 @@ int gfs2_releasepage(struct page *page, gfp_t gfp_mask)
1069 return 0; 1069 return 0;
1070 1070
1071 gfs2_log_lock(sdp); 1071 gfs2_log_lock(sdp);
1072 spin_lock(&sdp->sd_ail_lock);
1072 head = bh = page_buffers(page); 1073 head = bh = page_buffers(page);
1073 do { 1074 do {
1074 if (atomic_read(&bh->b_count)) 1075 if (atomic_read(&bh->b_count))
@@ -1080,6 +1081,7 @@ int gfs2_releasepage(struct page *page, gfp_t gfp_mask)
1080 goto not_possible; 1081 goto not_possible;
1081 bh = bh->b_this_page; 1082 bh = bh->b_this_page;
1082 } while(bh != head); 1083 } while(bh != head);
1084 spin_unlock(&sdp->sd_ail_lock);
1083 gfs2_log_unlock(sdp); 1085 gfs2_log_unlock(sdp);
1084 1086
1085 head = bh = page_buffers(page); 1087 head = bh = page_buffers(page);
@@ -1112,6 +1114,7 @@ not_possible: /* Should never happen */
1112 WARN_ON(buffer_dirty(bh)); 1114 WARN_ON(buffer_dirty(bh));
1113 WARN_ON(buffer_pinned(bh)); 1115 WARN_ON(buffer_pinned(bh));
1114cannot_release: 1116cannot_release:
1117 spin_unlock(&sdp->sd_ail_lock);
1115 gfs2_log_unlock(sdp); 1118 gfs2_log_unlock(sdp);
1116 return 0; 1119 return 0;
1117} 1120}
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c
index 8ef70f464731..2cca29316bd6 100644
--- a/fs/gfs2/glops.c
+++ b/fs/gfs2/glops.c
@@ -47,10 +47,10 @@ static void __gfs2_ail_flush(struct gfs2_glock *gl)
47 bd_ail_gl_list); 47 bd_ail_gl_list);
48 bh = bd->bd_bh; 48 bh = bd->bd_bh;
49 gfs2_remove_from_ail(bd); 49 gfs2_remove_from_ail(bd);
50 spin_unlock(&sdp->sd_ail_lock);
51
52 bd->bd_bh = NULL; 50 bd->bd_bh = NULL;
53 bh->b_private = NULL; 51 bh->b_private = NULL;
52 spin_unlock(&sdp->sd_ail_lock);
53
54 bd->bd_blkno = bh->b_blocknr; 54 bd->bd_blkno = bh->b_blocknr;
55 gfs2_log_lock(sdp); 55 gfs2_log_lock(sdp);
56 gfs2_assert_withdraw(sdp, !buffer_busy(bh)); 56 gfs2_assert_withdraw(sdp, !buffer_busy(bh));
@@ -221,8 +221,10 @@ static void inode_go_inval(struct gfs2_glock *gl, int flags)
221 } 221 }
222 } 222 }
223 223
224 if (ip == GFS2_I(gl->gl_sbd->sd_rindex)) 224 if (ip == GFS2_I(gl->gl_sbd->sd_rindex)) {
225 gfs2_log_flush(gl->gl_sbd, NULL);
225 gl->gl_sbd->sd_rindex_uptodate = 0; 226 gl->gl_sbd->sd_rindex_uptodate = 0;
227 }
226 if (ip && S_ISREG(ip->i_inode.i_mode)) 228 if (ip && S_ISREG(ip->i_inode.i_mode))
227 truncate_inode_pages(ip->i_inode.i_mapping, 0); 229 truncate_inode_pages(ip->i_inode.i_mapping, 0);
228} 230}
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index 0a064e91ac70..81206e70cbf6 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -17,6 +17,7 @@
17#include <linux/buffer_head.h> 17#include <linux/buffer_head.h>
18#include <linux/rcupdate.h> 18#include <linux/rcupdate.h>
19#include <linux/rculist_bl.h> 19#include <linux/rculist_bl.h>
20#include <linux/completion.h>
20 21
21#define DIO_WAIT 0x00000010 22#define DIO_WAIT 0x00000010
22#define DIO_METADATA 0x00000020 23#define DIO_METADATA 0x00000020
@@ -546,6 +547,7 @@ struct gfs2_sbd {
546 struct gfs2_glock *sd_trans_gl; 547 struct gfs2_glock *sd_trans_gl;
547 wait_queue_head_t sd_glock_wait; 548 wait_queue_head_t sd_glock_wait;
548 atomic_t sd_glock_disposal; 549 atomic_t sd_glock_disposal;
550 struct completion sd_locking_init;
549 551
550 /* Inode Stuff */ 552 /* Inode Stuff */
551 553
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c
index 903115f2bb34..85c62923ee29 100644
--- a/fs/gfs2/log.c
+++ b/fs/gfs2/log.c
@@ -903,6 +903,7 @@ void gfs2_meta_syncfs(struct gfs2_sbd *sdp)
903 if (gfs2_ail1_empty(sdp)) 903 if (gfs2_ail1_empty(sdp))
904 break; 904 break;
905 } 905 }
906 gfs2_log_flush(sdp, NULL);
906} 907}
907 908
908static inline int gfs2_jrnl_flush_reqd(struct gfs2_sbd *sdp) 909static inline int gfs2_jrnl_flush_reqd(struct gfs2_sbd *sdp)
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index 8ac9ae189b53..2a77071fb7b6 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -72,6 +72,7 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb)
72 72
73 init_waitqueue_head(&sdp->sd_glock_wait); 73 init_waitqueue_head(&sdp->sd_glock_wait);
74 atomic_set(&sdp->sd_glock_disposal, 0); 74 atomic_set(&sdp->sd_glock_disposal, 0);
75 init_completion(&sdp->sd_locking_init);
75 spin_lock_init(&sdp->sd_statfs_spin); 76 spin_lock_init(&sdp->sd_statfs_spin);
76 77
77 spin_lock_init(&sdp->sd_rindex_spin); 78 spin_lock_init(&sdp->sd_rindex_spin);
@@ -1017,11 +1018,13 @@ hostdata_error:
1017 fsname++; 1018 fsname++;
1018 if (lm->lm_mount == NULL) { 1019 if (lm->lm_mount == NULL) {
1019 fs_info(sdp, "Now mounting FS...\n"); 1020 fs_info(sdp, "Now mounting FS...\n");
1021 complete(&sdp->sd_locking_init);
1020 return 0; 1022 return 0;
1021 } 1023 }
1022 ret = lm->lm_mount(sdp, fsname); 1024 ret = lm->lm_mount(sdp, fsname);
1023 if (ret == 0) 1025 if (ret == 0)
1024 fs_info(sdp, "Joined cluster. Now mounting FS...\n"); 1026 fs_info(sdp, "Joined cluster. Now mounting FS...\n");
1027 complete(&sdp->sd_locking_init);
1025 return ret; 1028 return ret;
1026} 1029}
1027 1030
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index ed540e7018be..fb0edf735483 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -757,13 +757,17 @@ static int gfs2_write_inode(struct inode *inode, struct writeback_control *wbc)
757 struct timespec atime; 757 struct timespec atime;
758 struct gfs2_dinode *di; 758 struct gfs2_dinode *di;
759 int ret = -EAGAIN; 759 int ret = -EAGAIN;
760 int unlock_required = 0;
760 761
761 /* Skip timestamp update, if this is from a memalloc */ 762 /* Skip timestamp update, if this is from a memalloc */
762 if (current->flags & PF_MEMALLOC) 763 if (current->flags & PF_MEMALLOC)
763 goto do_flush; 764 goto do_flush;
764 ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); 765 if (!gfs2_glock_is_locked_by_me(ip->i_gl)) {
765 if (ret) 766 ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
766 goto do_flush; 767 if (ret)
768 goto do_flush;
769 unlock_required = 1;
770 }
767 ret = gfs2_trans_begin(sdp, RES_DINODE, 0); 771 ret = gfs2_trans_begin(sdp, RES_DINODE, 0);
768 if (ret) 772 if (ret)
769 goto do_unlock; 773 goto do_unlock;
@@ -780,7 +784,8 @@ static int gfs2_write_inode(struct inode *inode, struct writeback_control *wbc)
780 } 784 }
781 gfs2_trans_end(sdp); 785 gfs2_trans_end(sdp);
782do_unlock: 786do_unlock:
783 gfs2_glock_dq_uninit(&gh); 787 if (unlock_required)
788 gfs2_glock_dq_uninit(&gh);
784do_flush: 789do_flush:
785 if (wbc->sync_mode == WB_SYNC_ALL) 790 if (wbc->sync_mode == WB_SYNC_ALL)
786 gfs2_log_flush(GFS2_SB(inode), ip->i_gl); 791 gfs2_log_flush(GFS2_SB(inode), ip->i_gl);
@@ -1427,7 +1432,20 @@ out:
1427 return error; 1432 return error;
1428} 1433}
1429 1434
1430/* 1435/**
1436 * gfs2_evict_inode - Remove an inode from cache
1437 * @inode: The inode to evict
1438 *
1439 * There are three cases to consider:
1440 * 1. i_nlink == 0, we are final opener (and must deallocate)
1441 * 2. i_nlink == 0, we are not the final opener (and cannot deallocate)
1442 * 3. i_nlink > 0
1443 *
1444 * If the fs is read only, then we have to treat all cases as per #3
1445 * since we are unable to do any deallocation. The inode will be
1446 * deallocated by the next read/write node to attempt an allocation
1447 * in the same resource group
1448 *
1431 * We have to (at the moment) hold the inodes main lock to cover 1449 * We have to (at the moment) hold the inodes main lock to cover
1432 * the gap between unlocking the shared lock on the iopen lock and 1450 * the gap between unlocking the shared lock on the iopen lock and
1433 * taking the exclusive lock. I'd rather do a shared -> exclusive 1451 * taking the exclusive lock. I'd rather do a shared -> exclusive
@@ -1470,6 +1488,8 @@ static void gfs2_evict_inode(struct inode *inode)
1470 if (error) 1488 if (error)
1471 goto out_truncate; 1489 goto out_truncate;
1472 1490
1491 /* Case 1 starts here */
1492
1473 if (S_ISDIR(inode->i_mode) && 1493 if (S_ISDIR(inode->i_mode) &&
1474 (ip->i_diskflags & GFS2_DIF_EXHASH)) { 1494 (ip->i_diskflags & GFS2_DIF_EXHASH)) {
1475 error = gfs2_dir_exhash_dealloc(ip); 1495 error = gfs2_dir_exhash_dealloc(ip);
@@ -1493,13 +1513,16 @@ static void gfs2_evict_inode(struct inode *inode)
1493 goto out_unlock; 1513 goto out_unlock;
1494 1514
1495out_truncate: 1515out_truncate:
1516 /* Case 2 starts here */
1496 error = gfs2_trans_begin(sdp, 0, sdp->sd_jdesc->jd_blocks); 1517 error = gfs2_trans_begin(sdp, 0, sdp->sd_jdesc->jd_blocks);
1497 if (error) 1518 if (error)
1498 goto out_unlock; 1519 goto out_unlock;
1499 gfs2_final_release_pages(ip); 1520 /* Needs to be done before glock release & also in a transaction */
1521 truncate_inode_pages(&inode->i_data, 0);
1500 gfs2_trans_end(sdp); 1522 gfs2_trans_end(sdp);
1501 1523
1502out_unlock: 1524out_unlock:
1525 /* Error path for case 1 */
1503 if (test_bit(HIF_HOLDER, &ip->i_iopen_gh.gh_iflags)) 1526 if (test_bit(HIF_HOLDER, &ip->i_iopen_gh.gh_iflags))
1504 gfs2_glock_dq(&ip->i_iopen_gh); 1527 gfs2_glock_dq(&ip->i_iopen_gh);
1505 gfs2_holder_uninit(&ip->i_iopen_gh); 1528 gfs2_holder_uninit(&ip->i_iopen_gh);
@@ -1507,6 +1530,7 @@ out_unlock:
1507 if (error && error != GLR_TRYFAILED && error != -EROFS) 1530 if (error && error != GLR_TRYFAILED && error != -EROFS)
1508 fs_warn(sdp, "gfs2_evict_inode: %d\n", error); 1531 fs_warn(sdp, "gfs2_evict_inode: %d\n", error);
1509out: 1532out:
1533 /* Case 3 starts here */
1510 truncate_inode_pages(&inode->i_data, 0); 1534 truncate_inode_pages(&inode->i_data, 0);
1511 end_writeback(inode); 1535 end_writeback(inode);
1512 1536
diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c
index e20eab37bc80..443cabcfcd23 100644
--- a/fs/gfs2/sys.c
+++ b/fs/gfs2/sys.c
@@ -338,6 +338,9 @@ static ssize_t lkfirst_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
338 rv = sscanf(buf, "%u", &first); 338 rv = sscanf(buf, "%u", &first);
339 if (rv != 1 || first > 1) 339 if (rv != 1 || first > 1)
340 return -EINVAL; 340 return -EINVAL;
341 rv = wait_for_completion_killable(&sdp->sd_locking_init);
342 if (rv)
343 return rv;
341 spin_lock(&sdp->sd_jindex_spin); 344 spin_lock(&sdp->sd_jindex_spin);
342 rv = -EBUSY; 345 rv = -EBUSY;
343 if (test_bit(SDF_NOJOURNALID, &sdp->sd_flags) == 0) 346 if (test_bit(SDF_NOJOURNALID, &sdp->sd_flags) == 0)
@@ -414,7 +417,9 @@ static ssize_t jid_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
414 rv = sscanf(buf, "%d", &jid); 417 rv = sscanf(buf, "%d", &jid);
415 if (rv != 1) 418 if (rv != 1)
416 return -EINVAL; 419 return -EINVAL;
417 420 rv = wait_for_completion_killable(&sdp->sd_locking_init);
421 if (rv)
422 return rv;
418 spin_lock(&sdp->sd_jindex_spin); 423 spin_lock(&sdp->sd_jindex_spin);
419 rv = -EINVAL; 424 rv = -EINVAL;
420 if (sdp->sd_lockstruct.ls_ops->lm_mount == NULL) 425 if (sdp->sd_lockstruct.ls_ops->lm_mount == NULL)