aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/gfs2/glock.c94
-rw-r--r--fs/gfs2/glock.h6
-rw-r--r--fs/gfs2/incore.h1
-rw-r--r--fs/gfs2/inode.c34
-rw-r--r--fs/gfs2/ops_fstype.c1
5 files changed, 123 insertions, 13 deletions
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 661350989e98..0290a22ebccf 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -305,6 +305,11 @@ static void gfs2_holder_wake(struct gfs2_holder *gh)
305 clear_bit(HIF_WAIT, &gh->gh_iflags); 305 clear_bit(HIF_WAIT, &gh->gh_iflags);
306 smp_mb__after_atomic(); 306 smp_mb__after_atomic();
307 wake_up_bit(&gh->gh_iflags, HIF_WAIT); 307 wake_up_bit(&gh->gh_iflags, HIF_WAIT);
308 if (gh->gh_flags & GL_ASYNC) {
309 struct gfs2_sbd *sdp = gh->gh_gl->gl_name.ln_sbd;
310
311 wake_up(&sdp->sd_async_glock_wait);
312 }
308} 313}
309 314
310/** 315/**
@@ -959,6 +964,91 @@ int gfs2_glock_wait(struct gfs2_holder *gh)
959 return gh->gh_error; 964 return gh->gh_error;
960} 965}
961 966
967static int glocks_pending(unsigned int num_gh, struct gfs2_holder *ghs)
968{
969 int i;
970
971 for (i = 0; i < num_gh; i++)
972 if (test_bit(HIF_WAIT, &ghs[i].gh_iflags))
973 return 1;
974 return 0;
975}
976
977/**
978 * gfs2_glock_async_wait - wait on multiple asynchronous glock acquisitions
979 * @num_gh: the number of holders in the array
980 * @ghs: the glock holder array
981 *
982 * Returns: 0 on success, meaning all glocks have been granted and are held.
983 * -ESTALE if the request timed out, meaning all glocks were released,
984 * and the caller should retry the operation.
985 */
986
987int gfs2_glock_async_wait(unsigned int num_gh, struct gfs2_holder *ghs)
988{
989 struct gfs2_sbd *sdp = ghs[0].gh_gl->gl_name.ln_sbd;
990 int i, ret = 0, timeout = 0;
991 unsigned long start_time = jiffies;
992 bool keep_waiting;
993
994 might_sleep();
995 /*
996 * Total up the (minimum hold time * 2) of all glocks and use that to
997 * determine the max amount of time we should wait.
998 */
999 for (i = 0; i < num_gh; i++)
1000 timeout += ghs[i].gh_gl->gl_hold_time << 1;
1001
1002wait_for_dlm:
1003 if (!wait_event_timeout(sdp->sd_async_glock_wait,
1004 !glocks_pending(num_gh, ghs), timeout))
1005 ret = -ESTALE; /* request timed out. */
1006
1007 /*
1008 * If dlm granted all our requests, we need to adjust the glock
1009 * minimum hold time values according to how long we waited.
1010 *
1011 * If our request timed out, we need to repeatedly release any held
1012 * glocks we acquired thus far to allow dlm to acquire the remaining
1013 * glocks without deadlocking. We cannot currently cancel outstanding
1014 * glock acquisitions.
1015 *
1016 * The HIF_WAIT bit tells us which requests still need a response from
1017 * dlm.
1018 *
1019 * If dlm sent us any errors, we return the first error we find.
1020 */
1021 keep_waiting = false;
1022 for (i = 0; i < num_gh; i++) {
1023 /* Skip holders we have already dequeued below. */
1024 if (!gfs2_holder_queued(&ghs[i]))
1025 continue;
1026 /* Skip holders with a pending DLM response. */
1027 if (test_bit(HIF_WAIT, &ghs[i].gh_iflags)) {
1028 keep_waiting = true;
1029 continue;
1030 }
1031
1032 if (test_bit(HIF_HOLDER, &ghs[i].gh_iflags)) {
1033 if (ret == -ESTALE)
1034 gfs2_glock_dq(&ghs[i]);
1035 else
1036 gfs2_glock_update_hold_time(ghs[i].gh_gl,
1037 start_time);
1038 }
1039 if (!ret)
1040 ret = ghs[i].gh_error;
1041 }
1042
1043 if (keep_waiting)
1044 goto wait_for_dlm;
1045
1046 /*
1047 * At this point, we've either acquired all locks or released them all.
1048 */
1049 return ret;
1050}
1051
962/** 1052/**
963 * handle_callback - process a demote request 1053 * handle_callback - process a demote request
964 * @gl: the glock 1054 * @gl: the glock
@@ -1025,9 +1115,9 @@ __acquires(&gl->gl_lockref.lock)
1025 struct gfs2_holder *gh2; 1115 struct gfs2_holder *gh2;
1026 int try_futile = 0; 1116 int try_futile = 0;
1027 1117
1028 BUG_ON(gh->gh_owner_pid == NULL); 1118 GLOCK_BUG_ON(gl, gh->gh_owner_pid == NULL);
1029 if (test_and_set_bit(HIF_WAIT, &gh->gh_iflags)) 1119 if (test_and_set_bit(HIF_WAIT, &gh->gh_iflags))
1030 BUG(); 1120 GLOCK_BUG_ON(gl, true);
1031 1121
1032 if (gh->gh_flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB)) { 1122 if (gh->gh_flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB)) {
1033 if (test_bit(GLF_LOCK, &gl->gl_flags)) 1123 if (test_bit(GLF_LOCK, &gl->gl_flags))
diff --git a/fs/gfs2/glock.h b/fs/gfs2/glock.h
index e4e0bed5257c..b8adaf80e4c5 100644
--- a/fs/gfs2/glock.h
+++ b/fs/gfs2/glock.h
@@ -190,6 +190,7 @@ extern void gfs2_holder_uninit(struct gfs2_holder *gh);
190extern int gfs2_glock_nq(struct gfs2_holder *gh); 190extern int gfs2_glock_nq(struct gfs2_holder *gh);
191extern int gfs2_glock_poll(struct gfs2_holder *gh); 191extern int gfs2_glock_poll(struct gfs2_holder *gh);
192extern int gfs2_glock_wait(struct gfs2_holder *gh); 192extern int gfs2_glock_wait(struct gfs2_holder *gh);
193extern int gfs2_glock_async_wait(unsigned int num_gh, struct gfs2_holder *ghs);
193extern void gfs2_glock_dq(struct gfs2_holder *gh); 194extern void gfs2_glock_dq(struct gfs2_holder *gh);
194extern void gfs2_glock_dq_wait(struct gfs2_holder *gh); 195extern void gfs2_glock_dq_wait(struct gfs2_holder *gh);
195extern void gfs2_glock_dq_uninit(struct gfs2_holder *gh); 196extern void gfs2_glock_dq_uninit(struct gfs2_holder *gh);
@@ -260,6 +261,11 @@ static inline bool gfs2_holder_initialized(struct gfs2_holder *gh)
260 return gh->gh_gl; 261 return gh->gh_gl;
261} 262}
262 263
264static inline bool gfs2_holder_queued(struct gfs2_holder *gh)
265{
266 return !list_empty(&gh->gh_list);
267}
268
263/** 269/**
264 * glock_set_object - set the gl_object field of a glock 270 * glock_set_object - set the gl_object field of a glock
265 * @gl: the glock 271 * @gl: the glock
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index 7a993d7c022e..6b450065b9d5 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -725,6 +725,7 @@ struct gfs2_sbd {
725 struct gfs2_glock *sd_freeze_gl; 725 struct gfs2_glock *sd_freeze_gl;
726 struct work_struct sd_freeze_work; 726 struct work_struct sd_freeze_work;
727 wait_queue_head_t sd_glock_wait; 727 wait_queue_head_t sd_glock_wait;
728 wait_queue_head_t sd_async_glock_wait;
728 atomic_t sd_glock_disposal; 729 atomic_t sd_glock_disposal;
729 struct completion sd_locking_init; 730 struct completion sd_locking_init;
730 struct completion sd_wdack; 731 struct completion sd_wdack;
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index 50eeb15c6f4f..e1e18fb587eb 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -1388,16 +1388,18 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
1388 } 1388 }
1389 1389
1390 num_gh = 1; 1390 num_gh = 1;
1391 gfs2_holder_init(odip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); 1391 gfs2_holder_init(odip->i_gl, LM_ST_EXCLUSIVE, GL_ASYNC, ghs);
1392 if (odip != ndip) { 1392 if (odip != ndip) {
1393 gfs2_holder_init(ndip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh); 1393 gfs2_holder_init(ndip->i_gl, LM_ST_EXCLUSIVE,GL_ASYNC,
1394 ghs + num_gh);
1394 num_gh++; 1395 num_gh++;
1395 } 1396 }
1396 gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh); 1397 gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_ASYNC, ghs + num_gh);
1397 num_gh++; 1398 num_gh++;
1398 1399
1399 if (nip) { 1400 if (nip) {
1400 gfs2_holder_init(nip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh); 1401 gfs2_holder_init(nip->i_gl, LM_ST_EXCLUSIVE, GL_ASYNC,
1402 ghs + num_gh);
1401 num_gh++; 1403 num_gh++;
1402 } 1404 }
1403 1405
@@ -1406,6 +1408,9 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
1406 if (error) 1408 if (error)
1407 goto out_gunlock; 1409 goto out_gunlock;
1408 } 1410 }
1411 error = gfs2_glock_async_wait(num_gh, ghs);
1412 if (error)
1413 goto out_gunlock;
1409 1414
1410 if (nip) { 1415 if (nip) {
1411 /* Grab the resource group glock for unlink flag twiddling. 1416 /* Grab the resource group glock for unlink flag twiddling.
@@ -1555,7 +1560,8 @@ out_gunlock:
1555 gfs2_glock_dq_uninit(&rd_gh); 1560 gfs2_glock_dq_uninit(&rd_gh);
1556 1561
1557 while (x--) { 1562 while (x--) {
1558 gfs2_glock_dq(ghs + x); 1563 if (gfs2_holder_queued(ghs + x))
1564 gfs2_glock_dq(ghs + x);
1559 gfs2_holder_uninit(ghs + x); 1565 gfs2_holder_uninit(ghs + x);
1560 } 1566 }
1561out_gunlock_r: 1567out_gunlock_r:
@@ -1585,7 +1591,7 @@ static int gfs2_exchange(struct inode *odir, struct dentry *odentry,
1585 struct gfs2_inode *oip = GFS2_I(odentry->d_inode); 1591 struct gfs2_inode *oip = GFS2_I(odentry->d_inode);
1586 struct gfs2_inode *nip = GFS2_I(ndentry->d_inode); 1592 struct gfs2_inode *nip = GFS2_I(ndentry->d_inode);
1587 struct gfs2_sbd *sdp = GFS2_SB(odir); 1593 struct gfs2_sbd *sdp = GFS2_SB(odir);
1588 struct gfs2_holder ghs[5], r_gh; 1594 struct gfs2_holder ghs[4], r_gh;
1589 unsigned int num_gh; 1595 unsigned int num_gh;
1590 unsigned int x; 1596 unsigned int x;
1591 umode_t old_mode = oip->i_inode.i_mode; 1597 umode_t old_mode = oip->i_inode.i_mode;
@@ -1619,15 +1625,16 @@ static int gfs2_exchange(struct inode *odir, struct dentry *odentry,
1619 } 1625 }
1620 1626
1621 num_gh = 1; 1627 num_gh = 1;
1622 gfs2_holder_init(odip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); 1628 gfs2_holder_init(odip->i_gl, LM_ST_EXCLUSIVE, GL_ASYNC, ghs);
1623 if (odip != ndip) { 1629 if (odip != ndip) {
1624 gfs2_holder_init(ndip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh); 1630 gfs2_holder_init(ndip->i_gl, LM_ST_EXCLUSIVE, GL_ASYNC,
1631 ghs + num_gh);
1625 num_gh++; 1632 num_gh++;
1626 } 1633 }
1627 gfs2_holder_init(oip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh); 1634 gfs2_holder_init(oip->i_gl, LM_ST_EXCLUSIVE, GL_ASYNC, ghs + num_gh);
1628 num_gh++; 1635 num_gh++;
1629 1636
1630 gfs2_holder_init(nip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh); 1637 gfs2_holder_init(nip->i_gl, LM_ST_EXCLUSIVE, GL_ASYNC, ghs + num_gh);
1631 num_gh++; 1638 num_gh++;
1632 1639
1633 for (x = 0; x < num_gh; x++) { 1640 for (x = 0; x < num_gh; x++) {
@@ -1636,6 +1643,10 @@ static int gfs2_exchange(struct inode *odir, struct dentry *odentry,
1636 goto out_gunlock; 1643 goto out_gunlock;
1637 } 1644 }
1638 1645
1646 error = gfs2_glock_async_wait(num_gh, ghs);
1647 if (error)
1648 goto out_gunlock;
1649
1639 error = -ENOENT; 1650 error = -ENOENT;
1640 if (oip->i_inode.i_nlink == 0 || nip->i_inode.i_nlink == 0) 1651 if (oip->i_inode.i_nlink == 0 || nip->i_inode.i_nlink == 0)
1641 goto out_gunlock; 1652 goto out_gunlock;
@@ -1696,7 +1707,8 @@ out_end_trans:
1696 gfs2_trans_end(sdp); 1707 gfs2_trans_end(sdp);
1697out_gunlock: 1708out_gunlock:
1698 while (x--) { 1709 while (x--) {
1699 gfs2_glock_dq(ghs + x); 1710 if (gfs2_holder_queued(ghs + x))
1711 gfs2_glock_dq(ghs + x);
1700 gfs2_holder_uninit(ghs + x); 1712 gfs2_holder_uninit(ghs + x);
1701 } 1713 }
1702out_gunlock_r: 1714out_gunlock_r:
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index 4a8e5a7310f0..f3fd5cd9d43f 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -87,6 +87,7 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb)
87 gfs2_tune_init(&sdp->sd_tune); 87 gfs2_tune_init(&sdp->sd_tune);
88 88
89 init_waitqueue_head(&sdp->sd_glock_wait); 89 init_waitqueue_head(&sdp->sd_glock_wait);
90 init_waitqueue_head(&sdp->sd_async_glock_wait);
90 atomic_set(&sdp->sd_glock_disposal, 0); 91 atomic_set(&sdp->sd_glock_disposal, 0);
91 init_completion(&sdp->sd_locking_init); 92 init_completion(&sdp->sd_locking_init);
92 init_completion(&sdp->sd_wdack); 93 init_completion(&sdp->sd_wdack);