diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-01-25 11:39:18 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-01-25 11:39:18 -0500 |
commit | e07dd2ad305f6b29b47d713600aa8b722ef2a9f7 (patch) | |
tree | 4815808e538ec625bf2766b1eb9d91c7b3beaead /fs/gfs2/glock.c | |
parent | eba0e319c12fb098d66316a8eafbaaa9174a07c3 (diff) | |
parent | 7bc5c414fe6627ec518c82d154c796f0981f5b02 (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.c | 83 |
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 | ||
462 | static void gfs2_demote_wake(struct gfs2_glock *gl) | 460 | static 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) | |||
507 | static int rq_promote(struct gfs2_holder *gh) | 504 | static 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 | ||
633 | static void gfs2_glmutex_lock(struct gfs2_glock *gl) | 621 | static 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) |