aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/glock.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-01-25 11:39:18 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2008-01-25 11:39:18 -0500
commite07dd2ad305f6b29b47d713600aa8b722ef2a9f7 (patch)
tree4815808e538ec625bf2766b1eb9d91c7b3beaead /fs/gfs2/glock.c
parenteba0e319c12fb098d66316a8eafbaaa9174a07c3 (diff)
parent7bc5c414fe6627ec518c82d154c796f0981f5b02 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-nmw
* git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-nmw: (56 commits) [GFS2] Allow journal recovery on read-only mount [GFS2] Lockup on error [GFS2] Fix page_mkwrite truncation race path [GFS2] Fix typo [GFS2] Fix write alloc required shortcut calculation [GFS2] gfs2_alloc_required performance [GFS2] Remove unneeded i_spin [GFS2] Reduce inode size by moving i_alloc out of line [GFS2] Fix assert in log code [GFS2] Fix problems relating to execution of files on GFS2 [GFS2] Initialize extent_list earlier [GFS2] Allow page migration for writeback and ordered pages [GFS2] Remove unused variable [GFS2] Fix log block mapper [GFS2] Minor correction [GFS2] Eliminate the no longer needed sd_statfs_mutex [GFS2] Incremental patch to fix compiler warning [GFS2] Function meta_read optimization [GFS2] Only fetch the dinode once in block_map [GFS2] Reorganize function gfs2_glmutex_lock ...
Diffstat (limited to 'fs/gfs2/glock.c')
-rw-r--r--fs/gfs2/glock.c83
1 files changed, 31 insertions, 52 deletions
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index a37efe4aae6f..80e09c50590a 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. 2 * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
3 * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. 3 * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
4 * 4 *
5 * This copyrighted material is made available to anyone wishing to use, 5 * This copyrighted material is made available to anyone wishing to use,
6 * modify, copy, or redistribute it subject to the terms and conditions 6 * modify, copy, or redistribute it subject to the terms and conditions
@@ -217,7 +217,6 @@ int gfs2_glock_put(struct gfs2_glock *gl)
217 if (atomic_dec_and_test(&gl->gl_ref)) { 217 if (atomic_dec_and_test(&gl->gl_ref)) {
218 hlist_del(&gl->gl_list); 218 hlist_del(&gl->gl_list);
219 write_unlock(gl_lock_addr(gl->gl_hash)); 219 write_unlock(gl_lock_addr(gl->gl_hash));
220 BUG_ON(spin_is_locked(&gl->gl_spin));
221 gfs2_assert(sdp, gl->gl_state == LM_ST_UNLOCKED); 220 gfs2_assert(sdp, gl->gl_state == LM_ST_UNLOCKED);
222 gfs2_assert(sdp, list_empty(&gl->gl_reclaim)); 221 gfs2_assert(sdp, list_empty(&gl->gl_reclaim));
223 gfs2_assert(sdp, list_empty(&gl->gl_holders)); 222 gfs2_assert(sdp, list_empty(&gl->gl_holders));
@@ -346,7 +345,6 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
346 gl->gl_object = NULL; 345 gl->gl_object = NULL;
347 gl->gl_sbd = sdp; 346 gl->gl_sbd = sdp;
348 gl->gl_aspace = NULL; 347 gl->gl_aspace = NULL;
349 lops_init_le(&gl->gl_le, &gfs2_glock_lops);
350 INIT_DELAYED_WORK(&gl->gl_work, glock_work_func); 348 INIT_DELAYED_WORK(&gl->gl_work, glock_work_func);
351 349
352 /* If this glock protects actual on-disk data or metadata blocks, 350 /* If this glock protects actual on-disk data or metadata blocks,
@@ -461,7 +459,6 @@ static void wait_on_holder(struct gfs2_holder *gh)
461 459
462static void gfs2_demote_wake(struct gfs2_glock *gl) 460static void gfs2_demote_wake(struct gfs2_glock *gl)
463{ 461{
464 BUG_ON(!spin_is_locked(&gl->gl_spin));
465 gl->gl_demote_state = LM_ST_EXCLUSIVE; 462 gl->gl_demote_state = LM_ST_EXCLUSIVE;
466 clear_bit(GLF_DEMOTE, &gl->gl_flags); 463 clear_bit(GLF_DEMOTE, &gl->gl_flags);
467 smp_mb__after_clear_bit(); 464 smp_mb__after_clear_bit();
@@ -507,21 +504,12 @@ static int rq_mutex(struct gfs2_holder *gh)
507static int rq_promote(struct gfs2_holder *gh) 504static int rq_promote(struct gfs2_holder *gh)
508{ 505{
509 struct gfs2_glock *gl = gh->gh_gl; 506 struct gfs2_glock *gl = gh->gh_gl;
510 struct gfs2_sbd *sdp = gl->gl_sbd;
511 507
512 if (!relaxed_state_ok(gl->gl_state, gh->gh_state, gh->gh_flags)) { 508 if (!relaxed_state_ok(gl->gl_state, gh->gh_state, gh->gh_flags)) {
513 if (list_empty(&gl->gl_holders)) { 509 if (list_empty(&gl->gl_holders)) {
514 gl->gl_req_gh = gh; 510 gl->gl_req_gh = gh;
515 set_bit(GLF_LOCK, &gl->gl_flags); 511 set_bit(GLF_LOCK, &gl->gl_flags);
516 spin_unlock(&gl->gl_spin); 512 spin_unlock(&gl->gl_spin);
517
518 if (atomic_read(&sdp->sd_reclaim_count) >
519 gfs2_tune_get(sdp, gt_reclaim_limit) &&
520 !(gh->gh_flags & LM_FLAG_PRIORITY)) {
521 gfs2_reclaim_glock(sdp);
522 gfs2_reclaim_glock(sdp);
523 }
524
525 gfs2_glock_xmote_th(gh->gh_gl, gh); 513 gfs2_glock_xmote_th(gh->gh_gl, gh);
526 spin_lock(&gl->gl_spin); 514 spin_lock(&gl->gl_spin);
527 } 515 }
@@ -567,7 +555,10 @@ static int rq_demote(struct gfs2_glock *gl)
567 gfs2_demote_wake(gl); 555 gfs2_demote_wake(gl);
568 return 0; 556 return 0;
569 } 557 }
558
570 set_bit(GLF_LOCK, &gl->gl_flags); 559 set_bit(GLF_LOCK, &gl->gl_flags);
560 set_bit(GLF_DEMOTE_IN_PROGRESS, &gl->gl_flags);
561
571 if (gl->gl_demote_state == LM_ST_UNLOCKED || 562 if (gl->gl_demote_state == LM_ST_UNLOCKED ||
572 gl->gl_state != LM_ST_EXCLUSIVE) { 563 gl->gl_state != LM_ST_EXCLUSIVE) {
573 spin_unlock(&gl->gl_spin); 564 spin_unlock(&gl->gl_spin);
@@ -576,7 +567,9 @@ static int rq_demote(struct gfs2_glock *gl)
576 spin_unlock(&gl->gl_spin); 567 spin_unlock(&gl->gl_spin);
577 gfs2_glock_xmote_th(gl, NULL); 568 gfs2_glock_xmote_th(gl, NULL);
578 } 569 }
570
579 spin_lock(&gl->gl_spin); 571 spin_lock(&gl->gl_spin);
572 clear_bit(GLF_DEMOTE_IN_PROGRESS, &gl->gl_flags);
580 573
581 return 0; 574 return 0;
582} 575}
@@ -598,23 +591,18 @@ static void run_queue(struct gfs2_glock *gl)
598 if (!list_empty(&gl->gl_waiters1)) { 591 if (!list_empty(&gl->gl_waiters1)) {
599 gh = list_entry(gl->gl_waiters1.next, 592 gh = list_entry(gl->gl_waiters1.next,
600 struct gfs2_holder, gh_list); 593 struct gfs2_holder, gh_list);
601 594 blocked = rq_mutex(gh);
602 if (test_bit(HIF_MUTEX, &gh->gh_iflags))
603 blocked = rq_mutex(gh);
604 else
605 gfs2_assert_warn(gl->gl_sbd, 0);
606
607 } else if (test_bit(GLF_DEMOTE, &gl->gl_flags)) { 595 } else if (test_bit(GLF_DEMOTE, &gl->gl_flags)) {
608 blocked = rq_demote(gl); 596 blocked = rq_demote(gl);
597 if (gl->gl_waiters2 && !blocked) {
598 set_bit(GLF_DEMOTE, &gl->gl_flags);
599 gl->gl_demote_state = LM_ST_UNLOCKED;
600 }
601 gl->gl_waiters2 = 0;
609 } else if (!list_empty(&gl->gl_waiters3)) { 602 } else if (!list_empty(&gl->gl_waiters3)) {
610 gh = list_entry(gl->gl_waiters3.next, 603 gh = list_entry(gl->gl_waiters3.next,
611 struct gfs2_holder, gh_list); 604 struct gfs2_holder, gh_list);
612 605 blocked = rq_promote(gh);
613 if (test_bit(HIF_PROMOTE, &gh->gh_iflags))
614 blocked = rq_promote(gh);
615 else
616 gfs2_assert_warn(gl->gl_sbd, 0);
617
618 } else 606 } else
619 break; 607 break;
620 608
@@ -632,27 +620,21 @@ static void run_queue(struct gfs2_glock *gl)
632 620
633static void gfs2_glmutex_lock(struct gfs2_glock *gl) 621static void gfs2_glmutex_lock(struct gfs2_glock *gl)
634{ 622{
635 struct gfs2_holder gh;
636
637 gfs2_holder_init(gl, 0, 0, &gh);
638 set_bit(HIF_MUTEX, &gh.gh_iflags);
639 if (test_and_set_bit(HIF_WAIT, &gh.gh_iflags))
640 BUG();
641
642 spin_lock(&gl->gl_spin); 623 spin_lock(&gl->gl_spin);
643 if (test_and_set_bit(GLF_LOCK, &gl->gl_flags)) { 624 if (test_and_set_bit(GLF_LOCK, &gl->gl_flags)) {
625 struct gfs2_holder gh;
626
627 gfs2_holder_init(gl, 0, 0, &gh);
628 set_bit(HIF_WAIT, &gh.gh_iflags);
644 list_add_tail(&gh.gh_list, &gl->gl_waiters1); 629 list_add_tail(&gh.gh_list, &gl->gl_waiters1);
630 spin_unlock(&gl->gl_spin);
631 wait_on_holder(&gh);
632 gfs2_holder_uninit(&gh);
645 } else { 633 } else {
646 gl->gl_owner_pid = current->pid; 634 gl->gl_owner_pid = current->pid;
647 gl->gl_ip = (unsigned long)__builtin_return_address(0); 635 gl->gl_ip = (unsigned long)__builtin_return_address(0);
648 clear_bit(HIF_WAIT, &gh.gh_iflags); 636 spin_unlock(&gl->gl_spin);
649 smp_mb();
650 wake_up_bit(&gh.gh_iflags, HIF_WAIT);
651 } 637 }
652 spin_unlock(&gl->gl_spin);
653
654 wait_on_holder(&gh);
655 gfs2_holder_uninit(&gh);
656} 638}
657 639
658/** 640/**
@@ -691,7 +673,6 @@ static void gfs2_glmutex_unlock(struct gfs2_glock *gl)
691 gl->gl_owner_pid = 0; 673 gl->gl_owner_pid = 0;
692 gl->gl_ip = 0; 674 gl->gl_ip = 0;
693 run_queue(gl); 675 run_queue(gl);
694 BUG_ON(!spin_is_locked(&gl->gl_spin));
695 spin_unlock(&gl->gl_spin); 676 spin_unlock(&gl->gl_spin);
696} 677}
697 678
@@ -722,7 +703,10 @@ static void handle_callback(struct gfs2_glock *gl, unsigned int state,
722 } 703 }
723 } else if (gl->gl_demote_state != LM_ST_UNLOCKED && 704 } else if (gl->gl_demote_state != LM_ST_UNLOCKED &&
724 gl->gl_demote_state != state) { 705 gl->gl_demote_state != state) {
725 gl->gl_demote_state = LM_ST_UNLOCKED; 706 if (test_bit(GLF_DEMOTE_IN_PROGRESS, &gl->gl_flags))
707 gl->gl_waiters2 = 1;
708 else
709 gl->gl_demote_state = LM_ST_UNLOCKED;
726 } 710 }
727 spin_unlock(&gl->gl_spin); 711 spin_unlock(&gl->gl_spin);
728} 712}
@@ -943,8 +927,8 @@ static void gfs2_glock_drop_th(struct gfs2_glock *gl)
943 const struct gfs2_glock_operations *glops = gl->gl_ops; 927 const struct gfs2_glock_operations *glops = gl->gl_ops;
944 unsigned int ret; 928 unsigned int ret;
945 929
946 if (glops->go_drop_th) 930 if (glops->go_xmote_th)
947 glops->go_drop_th(gl); 931 glops->go_xmote_th(gl);
948 932
949 gfs2_assert_warn(sdp, test_bit(GLF_LOCK, &gl->gl_flags)); 933 gfs2_assert_warn(sdp, test_bit(GLF_LOCK, &gl->gl_flags));
950 gfs2_assert_warn(sdp, list_empty(&gl->gl_holders)); 934 gfs2_assert_warn(sdp, list_empty(&gl->gl_holders));
@@ -1156,8 +1140,6 @@ restart:
1156 return -EIO; 1140 return -EIO;
1157 } 1141 }
1158 1142
1159 set_bit(HIF_PROMOTE, &gh->gh_iflags);
1160
1161 spin_lock(&gl->gl_spin); 1143 spin_lock(&gl->gl_spin);
1162 add_to_queue(gh); 1144 add_to_queue(gh);
1163 run_queue(gl); 1145 run_queue(gl);
@@ -1248,12 +1230,11 @@ void gfs2_glock_dq(struct gfs2_holder *gh)
1248 list_del_init(&gh->gh_list); 1230 list_del_init(&gh->gh_list);
1249 1231
1250 if (list_empty(&gl->gl_holders)) { 1232 if (list_empty(&gl->gl_holders)) {
1251 spin_unlock(&gl->gl_spin); 1233 if (glops->go_unlock) {
1252 1234 spin_unlock(&gl->gl_spin);
1253 if (glops->go_unlock)
1254 glops->go_unlock(gh); 1235 glops->go_unlock(gh);
1255 1236 spin_lock(&gl->gl_spin);
1256 spin_lock(&gl->gl_spin); 1237 }
1257 gl->gl_stamp = jiffies; 1238 gl->gl_stamp = jiffies;
1258 } 1239 }
1259 1240
@@ -1910,8 +1891,6 @@ static int dump_glock(struct glock_iter *gi, struct gfs2_glock *gl)
1910 print_dbg(gi, " req_bh = %s\n", (gl->gl_req_bh) ? "yes" : "no"); 1891 print_dbg(gi, " req_bh = %s\n", (gl->gl_req_bh) ? "yes" : "no");
1911 print_dbg(gi, " lvb_count = %d\n", atomic_read(&gl->gl_lvb_count)); 1892 print_dbg(gi, " lvb_count = %d\n", atomic_read(&gl->gl_lvb_count));
1912 print_dbg(gi, " object = %s\n", (gl->gl_object) ? "yes" : "no"); 1893 print_dbg(gi, " object = %s\n", (gl->gl_object) ? "yes" : "no");
1913 print_dbg(gi, " le = %s\n",
1914 (list_empty(&gl->gl_le.le_list)) ? "no" : "yes");
1915 print_dbg(gi, " reclaim = %s\n", 1894 print_dbg(gi, " reclaim = %s\n",
1916 (list_empty(&gl->gl_reclaim)) ? "no" : "yes"); 1895 (list_empty(&gl->gl_reclaim)) ? "no" : "yes");
1917 if (gl->gl_aspace) 1896 if (gl->gl_aspace)