aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/glock.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2/glock.c')
-rw-r--r--fs/gfs2/glock.c33
1 files changed, 29 insertions, 4 deletions
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 27cb9cca9c08..4ddf3bd55dda 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -40,6 +40,7 @@
40#include "quota.h" 40#include "quota.h"
41#include "super.h" 41#include "super.h"
42#include "util.h" 42#include "util.h"
43#include "bmap.h"
43 44
44struct gfs2_gl_hash_bucket { 45struct gfs2_gl_hash_bucket {
45 struct hlist_head hb_list; 46 struct hlist_head hb_list;
@@ -289,7 +290,8 @@ static void gfs2_holder_wake(struct gfs2_holder *gh)
289 * do_promote - promote as many requests as possible on the current queue 290 * do_promote - promote as many requests as possible on the current queue
290 * @gl: The glock 291 * @gl: The glock
291 * 292 *
292 * Returns: true if there is a blocked holder at the head of the list 293 * Returns: 1 if there is a blocked holder at the head of the list, or 2
294 * if a type specific operation is underway.
293 */ 295 */
294 296
295static int do_promote(struct gfs2_glock *gl) 297static int do_promote(struct gfs2_glock *gl)
@@ -312,6 +314,8 @@ restart:
312 ret = glops->go_lock(gh); 314 ret = glops->go_lock(gh);
313 spin_lock(&gl->gl_spin); 315 spin_lock(&gl->gl_spin);
314 if (ret) { 316 if (ret) {
317 if (ret == 1)
318 return 2;
315 gh->gh_error = ret; 319 gh->gh_error = ret;
316 list_del_init(&gh->gh_list); 320 list_del_init(&gh->gh_list);
317 gfs2_holder_wake(gh); 321 gfs2_holder_wake(gh);
@@ -416,6 +420,7 @@ static void finish_xmote(struct gfs2_glock *gl, unsigned int ret)
416 const struct gfs2_glock_operations *glops = gl->gl_ops; 420 const struct gfs2_glock_operations *glops = gl->gl_ops;
417 struct gfs2_holder *gh; 421 struct gfs2_holder *gh;
418 unsigned state = ret & LM_OUT_ST_MASK; 422 unsigned state = ret & LM_OUT_ST_MASK;
423 int rv;
419 424
420 spin_lock(&gl->gl_spin); 425 spin_lock(&gl->gl_spin);
421 state_change(gl, state); 426 state_change(gl, state);
@@ -470,7 +475,6 @@ retry:
470 gfs2_demote_wake(gl); 475 gfs2_demote_wake(gl);
471 if (state != LM_ST_UNLOCKED) { 476 if (state != LM_ST_UNLOCKED) {
472 if (glops->go_xmote_bh) { 477 if (glops->go_xmote_bh) {
473 int rv;
474 spin_unlock(&gl->gl_spin); 478 spin_unlock(&gl->gl_spin);
475 rv = glops->go_xmote_bh(gl, gh); 479 rv = glops->go_xmote_bh(gl, gh);
476 if (rv == -EAGAIN) 480 if (rv == -EAGAIN)
@@ -481,10 +485,13 @@ retry:
481 goto out; 485 goto out;
482 } 486 }
483 } 487 }
484 do_promote(gl); 488 rv = do_promote(gl);
489 if (rv == 2)
490 goto out_locked;
485 } 491 }
486out: 492out:
487 clear_bit(GLF_LOCK, &gl->gl_flags); 493 clear_bit(GLF_LOCK, &gl->gl_flags);
494out_locked:
488 spin_unlock(&gl->gl_spin); 495 spin_unlock(&gl->gl_spin);
489 gfs2_glock_put(gl); 496 gfs2_glock_put(gl);
490} 497}
@@ -584,6 +591,7 @@ __releases(&gl->gl_spin)
584__acquires(&gl->gl_spin) 591__acquires(&gl->gl_spin)
585{ 592{
586 struct gfs2_holder *gh = NULL; 593 struct gfs2_holder *gh = NULL;
594 int ret;
587 595
588 if (test_and_set_bit(GLF_LOCK, &gl->gl_flags)) 596 if (test_and_set_bit(GLF_LOCK, &gl->gl_flags))
589 return; 597 return;
@@ -602,8 +610,11 @@ __acquires(&gl->gl_spin)
602 } else { 610 } else {
603 if (test_bit(GLF_DEMOTE, &gl->gl_flags)) 611 if (test_bit(GLF_DEMOTE, &gl->gl_flags))
604 gfs2_demote_wake(gl); 612 gfs2_demote_wake(gl);
605 if (do_promote(gl) == 0) 613 ret = do_promote(gl);
614 if (ret == 0)
606 goto out; 615 goto out;
616 if (ret == 2)
617 return;
607 gh = find_first_waiter(gl); 618 gh = find_first_waiter(gl);
608 gl->gl_target = gh->gh_state; 619 gl->gl_target = gh->gh_state;
609 if (!(gh->gh_flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB))) 620 if (!(gh->gh_flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB)))
@@ -1556,6 +1567,20 @@ void gfs2_gl_hash_clear(struct gfs2_sbd *sdp)
1556 } 1567 }
1557} 1568}
1558 1569
1570void gfs2_glock_finish_truncate(struct gfs2_inode *ip)
1571{
1572 struct gfs2_glock *gl = ip->i_gl;
1573 int ret;
1574
1575 ret = gfs2_truncatei_resume(ip);
1576 gfs2_assert_withdraw(gl->gl_sbd, ret == 0);
1577
1578 spin_lock(&gl->gl_spin);
1579 clear_bit(GLF_LOCK, &gl->gl_flags);
1580 run_queue(gl, 1);
1581 spin_unlock(&gl->gl_spin);
1582}
1583
1559static const char *state2str(unsigned state) 1584static const char *state2str(unsigned state)
1560{ 1585{
1561 switch(state) { 1586 switch(state) {