diff options
Diffstat (limited to 'fs/gfs2')
-rw-r--r-- | fs/gfs2/glock.c | 233 | ||||
-rw-r--r-- | fs/gfs2/glock.h | 2 | ||||
-rw-r--r-- | fs/gfs2/incore.h | 8 | ||||
-rw-r--r-- | fs/gfs2/main.c | 1 | ||||
-rw-r--r-- | fs/gfs2/ops_super.c | 28 |
5 files changed, 93 insertions, 179 deletions
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index a3a24f2e99d2..e7075945b051 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c | |||
@@ -54,7 +54,7 @@ struct glock_iter { | |||
54 | typedef void (*glock_examiner) (struct gfs2_glock * gl); | 54 | typedef void (*glock_examiner) (struct gfs2_glock * gl); |
55 | 55 | ||
56 | static int gfs2_dump_lockstate(struct gfs2_sbd *sdp); | 56 | static int gfs2_dump_lockstate(struct gfs2_sbd *sdp); |
57 | static void gfs2_glock_xmote_th(struct gfs2_holder *gh); | 57 | static void gfs2_glock_xmote_th(struct gfs2_glock *gl, struct gfs2_holder *gh); |
58 | static void gfs2_glock_drop_th(struct gfs2_glock *gl); | 58 | static void gfs2_glock_drop_th(struct gfs2_glock *gl); |
59 | static DECLARE_RWSEM(gfs2_umount_flush_sem); | 59 | static DECLARE_RWSEM(gfs2_umount_flush_sem); |
60 | static struct dentry *gfs2_root; | 60 | static struct dentry *gfs2_root; |
@@ -212,7 +212,6 @@ int gfs2_glock_put(struct gfs2_glock *gl) | |||
212 | gfs2_assert(sdp, list_empty(&gl->gl_reclaim)); | 212 | gfs2_assert(sdp, list_empty(&gl->gl_reclaim)); |
213 | gfs2_assert(sdp, list_empty(&gl->gl_holders)); | 213 | gfs2_assert(sdp, list_empty(&gl->gl_holders)); |
214 | gfs2_assert(sdp, list_empty(&gl->gl_waiters1)); | 214 | gfs2_assert(sdp, list_empty(&gl->gl_waiters1)); |
215 | gfs2_assert(sdp, list_empty(&gl->gl_waiters2)); | ||
216 | gfs2_assert(sdp, list_empty(&gl->gl_waiters3)); | 215 | gfs2_assert(sdp, list_empty(&gl->gl_waiters3)); |
217 | glock_free(gl); | 216 | glock_free(gl); |
218 | rv = 1; | 217 | rv = 1; |
@@ -399,7 +398,7 @@ void gfs2_holder_reinit(unsigned int state, unsigned flags, struct gfs2_holder * | |||
399 | { | 398 | { |
400 | gh->gh_state = state; | 399 | gh->gh_state = state; |
401 | gh->gh_flags = flags; | 400 | gh->gh_flags = flags; |
402 | gh->gh_iflags &= 1 << HIF_ALLOCED; | 401 | gh->gh_iflags = 0; |
403 | gh->gh_ip = (unsigned long)__builtin_return_address(0); | 402 | gh->gh_ip = (unsigned long)__builtin_return_address(0); |
404 | } | 403 | } |
405 | 404 | ||
@@ -416,54 +415,8 @@ void gfs2_holder_uninit(struct gfs2_holder *gh) | |||
416 | gh->gh_ip = 0; | 415 | gh->gh_ip = 0; |
417 | } | 416 | } |
418 | 417 | ||
419 | /** | 418 | static void gfs2_holder_wake(struct gfs2_holder *gh) |
420 | * gfs2_holder_get - get a struct gfs2_holder structure | ||
421 | * @gl: the glock | ||
422 | * @state: the state we're requesting | ||
423 | * @flags: the modifier flags | ||
424 | * @gfp_flags: | ||
425 | * | ||
426 | * Figure out how big an impact this function has. Either: | ||
427 | * 1) Replace it with a cache of structures hanging off the struct gfs2_sbd | ||
428 | * 2) Leave it like it is | ||
429 | * | ||
430 | * Returns: the holder structure, NULL on ENOMEM | ||
431 | */ | ||
432 | |||
433 | static struct gfs2_holder *gfs2_holder_get(struct gfs2_glock *gl, | ||
434 | unsigned int state, | ||
435 | int flags, gfp_t gfp_flags) | ||
436 | { | ||
437 | struct gfs2_holder *gh; | ||
438 | |||
439 | gh = kmalloc(sizeof(struct gfs2_holder), gfp_flags); | ||
440 | if (!gh) | ||
441 | return NULL; | ||
442 | |||
443 | gfs2_holder_init(gl, state, flags, gh); | ||
444 | set_bit(HIF_ALLOCED, &gh->gh_iflags); | ||
445 | gh->gh_ip = (unsigned long)__builtin_return_address(0); | ||
446 | return gh; | ||
447 | } | ||
448 | |||
449 | /** | ||
450 | * gfs2_holder_put - get rid of a struct gfs2_holder structure | ||
451 | * @gh: the holder structure | ||
452 | * | ||
453 | */ | ||
454 | |||
455 | static void gfs2_holder_put(struct gfs2_holder *gh) | ||
456 | { | ||
457 | gfs2_holder_uninit(gh); | ||
458 | kfree(gh); | ||
459 | } | ||
460 | |||
461 | static void gfs2_holder_dispose_or_wake(struct gfs2_holder *gh) | ||
462 | { | 419 | { |
463 | if (test_bit(HIF_DEALLOC, &gh->gh_iflags)) { | ||
464 | gfs2_holder_put(gh); | ||
465 | return; | ||
466 | } | ||
467 | clear_bit(HIF_WAIT, &gh->gh_iflags); | 420 | clear_bit(HIF_WAIT, &gh->gh_iflags); |
468 | smp_mb(); | 421 | smp_mb(); |
469 | wake_up_bit(&gh->gh_iflags, HIF_WAIT); | 422 | wake_up_bit(&gh->gh_iflags, HIF_WAIT); |
@@ -529,7 +482,7 @@ static int rq_promote(struct gfs2_holder *gh) | |||
529 | gfs2_reclaim_glock(sdp); | 482 | gfs2_reclaim_glock(sdp); |
530 | } | 483 | } |
531 | 484 | ||
532 | gfs2_glock_xmote_th(gh); | 485 | gfs2_glock_xmote_th(gh->gh_gl, gh); |
533 | spin_lock(&gl->gl_spin); | 486 | spin_lock(&gl->gl_spin); |
534 | } | 487 | } |
535 | return 1; | 488 | return 1; |
@@ -552,7 +505,7 @@ static int rq_promote(struct gfs2_holder *gh) | |||
552 | gh->gh_error = 0; | 505 | gh->gh_error = 0; |
553 | set_bit(HIF_HOLDER, &gh->gh_iflags); | 506 | set_bit(HIF_HOLDER, &gh->gh_iflags); |
554 | 507 | ||
555 | gfs2_holder_dispose_or_wake(gh); | 508 | gfs2_holder_wake(gh); |
556 | 509 | ||
557 | return 0; | 510 | return 0; |
558 | } | 511 | } |
@@ -564,32 +517,24 @@ static int rq_promote(struct gfs2_holder *gh) | |||
564 | * Returns: 1 if the queue is blocked | 517 | * Returns: 1 if the queue is blocked |
565 | */ | 518 | */ |
566 | 519 | ||
567 | static int rq_demote(struct gfs2_holder *gh) | 520 | static int rq_demote(struct gfs2_glock *gl) |
568 | { | 521 | { |
569 | struct gfs2_glock *gl = gh->gh_gl; | ||
570 | |||
571 | if (!list_empty(&gl->gl_holders)) | 522 | if (!list_empty(&gl->gl_holders)) |
572 | return 1; | 523 | return 1; |
573 | 524 | ||
574 | if (gl->gl_state == gh->gh_state || gl->gl_state == LM_ST_UNLOCKED) { | 525 | if (gl->gl_state == gl->gl_demote_state || |
575 | list_del_init(&gh->gh_list); | 526 | gl->gl_state == LM_ST_UNLOCKED) { |
576 | gh->gh_error = 0; | 527 | clear_bit(GLF_DEMOTE, &gl->gl_flags); |
577 | spin_unlock(&gl->gl_spin); | 528 | return 0; |
578 | gfs2_holder_dispose_or_wake(gh); | ||
579 | spin_lock(&gl->gl_spin); | ||
580 | } else { | ||
581 | gl->gl_req_gh = gh; | ||
582 | set_bit(GLF_LOCK, &gl->gl_flags); | ||
583 | spin_unlock(&gl->gl_spin); | ||
584 | |||
585 | if (gh->gh_state == LM_ST_UNLOCKED || | ||
586 | gl->gl_state != LM_ST_EXCLUSIVE) | ||
587 | gfs2_glock_drop_th(gl); | ||
588 | else | ||
589 | gfs2_glock_xmote_th(gh); | ||
590 | |||
591 | spin_lock(&gl->gl_spin); | ||
592 | } | 529 | } |
530 | set_bit(GLF_LOCK, &gl->gl_flags); | ||
531 | spin_unlock(&gl->gl_spin); | ||
532 | if (gl->gl_demote_state == LM_ST_UNLOCKED || | ||
533 | gl->gl_state != LM_ST_EXCLUSIVE) | ||
534 | gfs2_glock_drop_th(gl); | ||
535 | else | ||
536 | gfs2_glock_xmote_th(gl, NULL); | ||
537 | spin_lock(&gl->gl_spin); | ||
593 | 538 | ||
594 | return 0; | 539 | return 0; |
595 | } | 540 | } |
@@ -617,16 +562,8 @@ static void run_queue(struct gfs2_glock *gl) | |||
617 | else | 562 | else |
618 | gfs2_assert_warn(gl->gl_sbd, 0); | 563 | gfs2_assert_warn(gl->gl_sbd, 0); |
619 | 564 | ||
620 | } else if (!list_empty(&gl->gl_waiters2) && | 565 | } else if (test_bit(GLF_DEMOTE, &gl->gl_flags)) { |
621 | !test_bit(GLF_SKIP_WAITERS2, &gl->gl_flags)) { | 566 | blocked = rq_demote(gl); |
622 | gh = list_entry(gl->gl_waiters2.next, | ||
623 | struct gfs2_holder, gh_list); | ||
624 | |||
625 | if (test_bit(HIF_DEMOTE, &gh->gh_iflags)) | ||
626 | blocked = rq_demote(gh); | ||
627 | else | ||
628 | gfs2_assert_warn(gl->gl_sbd, 0); | ||
629 | |||
630 | } else if (!list_empty(&gl->gl_waiters3)) { | 567 | } else if (!list_empty(&gl->gl_waiters3)) { |
631 | gh = list_entry(gl->gl_waiters3.next, | 568 | gh = list_entry(gl->gl_waiters3.next, |
632 | struct gfs2_holder, gh_list); | 569 | struct gfs2_holder, gh_list); |
@@ -717,50 +654,24 @@ static void gfs2_glmutex_unlock(struct gfs2_glock *gl) | |||
717 | } | 654 | } |
718 | 655 | ||
719 | /** | 656 | /** |
720 | * handle_callback - add a demote request to a lock's queue | 657 | * handle_callback - process a demote request |
721 | * @gl: the glock | 658 | * @gl: the glock |
722 | * @state: the state the caller wants us to change to | 659 | * @state: the state the caller wants us to change to |
723 | * | 660 | * |
724 | * Note: This may fail sliently if we are out of memory. | 661 | * There are only two requests that we are going to see in actual |
662 | * practise: LM_ST_SHARED and LM_ST_UNLOCKED | ||
725 | */ | 663 | */ |
726 | 664 | ||
727 | static void handle_callback(struct gfs2_glock *gl, unsigned int state) | 665 | static void handle_callback(struct gfs2_glock *gl, unsigned int state) |
728 | { | 666 | { |
729 | struct gfs2_holder *gh, *new_gh = NULL; | ||
730 | |||
731 | restart: | ||
732 | spin_lock(&gl->gl_spin); | 667 | spin_lock(&gl->gl_spin); |
733 | 668 | if (test_and_set_bit(GLF_DEMOTE, &gl->gl_flags) == 0) { | |
734 | list_for_each_entry(gh, &gl->gl_waiters2, gh_list) { | 669 | gl->gl_demote_state = state; |
735 | if (test_bit(HIF_DEMOTE, &gh->gh_iflags) && | 670 | gl->gl_demote_time = jiffies; |
736 | gl->gl_req_gh != gh) { | 671 | } else if (gl->gl_demote_state != LM_ST_UNLOCKED) { |
737 | if (gh->gh_state != state) | 672 | gl->gl_demote_state = state; |
738 | gh->gh_state = LM_ST_UNLOCKED; | ||
739 | goto out; | ||
740 | } | ||
741 | } | ||
742 | |||
743 | if (new_gh) { | ||
744 | list_add_tail(&new_gh->gh_list, &gl->gl_waiters2); | ||
745 | new_gh = NULL; | ||
746 | } else { | ||
747 | spin_unlock(&gl->gl_spin); | ||
748 | |||
749 | new_gh = gfs2_holder_get(gl, state, LM_FLAG_TRY, GFP_NOFS); | ||
750 | if (!new_gh) | ||
751 | return; | ||
752 | set_bit(HIF_DEMOTE, &new_gh->gh_iflags); | ||
753 | set_bit(HIF_DEALLOC, &new_gh->gh_iflags); | ||
754 | set_bit(HIF_WAIT, &new_gh->gh_iflags); | ||
755 | |||
756 | goto restart; | ||
757 | } | 673 | } |
758 | |||
759 | out: | ||
760 | spin_unlock(&gl->gl_spin); | 674 | spin_unlock(&gl->gl_spin); |
761 | |||
762 | if (new_gh) | ||
763 | gfs2_holder_put(new_gh); | ||
764 | } | 675 | } |
765 | 676 | ||
766 | /** | 677 | /** |
@@ -820,56 +731,37 @@ static void xmote_bh(struct gfs2_glock *gl, unsigned int ret) | |||
820 | 731 | ||
821 | /* Deal with each possible exit condition */ | 732 | /* Deal with each possible exit condition */ |
822 | 733 | ||
823 | if (!gh) | 734 | if (!gh) { |
824 | gl->gl_stamp = jiffies; | 735 | gl->gl_stamp = jiffies; |
825 | else if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) { | 736 | if (ret & LM_OUT_CANCELED) |
737 | op_done = 0; | ||
738 | else | ||
739 | clear_bit(GLF_DEMOTE, &gl->gl_flags); | ||
740 | } else { | ||
826 | spin_lock(&gl->gl_spin); | 741 | spin_lock(&gl->gl_spin); |
827 | list_del_init(&gh->gh_list); | 742 | list_del_init(&gh->gh_list); |
828 | gh->gh_error = -EIO; | 743 | gh->gh_error = -EIO; |
829 | spin_unlock(&gl->gl_spin); | 744 | if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) |
830 | } else if (test_bit(HIF_DEMOTE, &gh->gh_iflags)) { | 745 | goto out; |
831 | spin_lock(&gl->gl_spin); | 746 | gh->gh_error = GLR_CANCELED; |
832 | list_del_init(&gh->gh_list); | 747 | if (ret & LM_OUT_CANCELED) |
833 | if (gl->gl_state == gh->gh_state || | 748 | goto out; |
834 | gl->gl_state == LM_ST_UNLOCKED) { | 749 | if (relaxed_state_ok(gl->gl_state, gh->gh_state, gh->gh_flags)) { |
750 | list_add_tail(&gh->gh_list, &gl->gl_holders); | ||
835 | gh->gh_error = 0; | 751 | gh->gh_error = 0; |
836 | } else { | 752 | set_bit(HIF_HOLDER, &gh->gh_iflags); |
837 | if (gfs2_assert_warn(sdp, gh->gh_flags & | 753 | set_bit(HIF_FIRST, &gh->gh_iflags); |
838 | (LM_FLAG_TRY | LM_FLAG_TRY_1CB)) == -1) | 754 | op_done = 0; |
839 | fs_warn(sdp, "ret = 0x%.8X\n", ret); | 755 | goto out; |
840 | gh->gh_error = GLR_TRYFAILED; | ||
841 | } | 756 | } |
842 | spin_unlock(&gl->gl_spin); | ||
843 | |||
844 | if (ret & LM_OUT_CANCELED) | ||
845 | handle_callback(gl, LM_ST_UNLOCKED); | ||
846 | |||
847 | } else if (ret & LM_OUT_CANCELED) { | ||
848 | spin_lock(&gl->gl_spin); | ||
849 | list_del_init(&gh->gh_list); | ||
850 | gh->gh_error = GLR_CANCELED; | ||
851 | spin_unlock(&gl->gl_spin); | ||
852 | |||
853 | } else if (relaxed_state_ok(gl->gl_state, gh->gh_state, gh->gh_flags)) { | ||
854 | spin_lock(&gl->gl_spin); | ||
855 | list_move_tail(&gh->gh_list, &gl->gl_holders); | ||
856 | gh->gh_error = 0; | ||
857 | set_bit(HIF_HOLDER, &gh->gh_iflags); | ||
858 | spin_unlock(&gl->gl_spin); | ||
859 | |||
860 | set_bit(HIF_FIRST, &gh->gh_iflags); | ||
861 | |||
862 | op_done = 0; | ||
863 | |||
864 | } else if (gh->gh_flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB)) { | ||
865 | spin_lock(&gl->gl_spin); | ||
866 | list_del_init(&gh->gh_list); | ||
867 | gh->gh_error = GLR_TRYFAILED; | 757 | gh->gh_error = GLR_TRYFAILED; |
868 | spin_unlock(&gl->gl_spin); | 758 | if (gh->gh_flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB)) |
869 | 759 | goto out; | |
870 | } else { | 760 | gh->gh_error = -EINVAL; |
871 | if (gfs2_assert_withdraw(sdp, 0) == -1) | 761 | if (gfs2_assert_withdraw(sdp, 0) == -1) |
872 | fs_err(sdp, "ret = 0x%.8X\n", ret); | 762 | fs_err(sdp, "ret = 0x%.8X\n", ret); |
763 | out: | ||
764 | spin_unlock(&gl->gl_spin); | ||
873 | } | 765 | } |
874 | 766 | ||
875 | if (glops->go_xmote_bh) | 767 | if (glops->go_xmote_bh) |
@@ -887,7 +779,7 @@ static void xmote_bh(struct gfs2_glock *gl, unsigned int ret) | |||
887 | gfs2_glock_put(gl); | 779 | gfs2_glock_put(gl); |
888 | 780 | ||
889 | if (gh) | 781 | if (gh) |
890 | gfs2_holder_dispose_or_wake(gh); | 782 | gfs2_holder_wake(gh); |
891 | } | 783 | } |
892 | 784 | ||
893 | /** | 785 | /** |
@@ -898,12 +790,11 @@ static void xmote_bh(struct gfs2_glock *gl, unsigned int ret) | |||
898 | * | 790 | * |
899 | */ | 791 | */ |
900 | 792 | ||
901 | void gfs2_glock_xmote_th(struct gfs2_holder *gh) | 793 | void gfs2_glock_xmote_th(struct gfs2_glock *gl, struct gfs2_holder *gh) |
902 | { | 794 | { |
903 | struct gfs2_glock *gl = gh->gh_gl; | ||
904 | struct gfs2_sbd *sdp = gl->gl_sbd; | 795 | struct gfs2_sbd *sdp = gl->gl_sbd; |
905 | int flags = gh->gh_flags; | 796 | int flags = gh ? gh->gh_flags : 0; |
906 | unsigned state = gh->gh_state; | 797 | unsigned state = gh ? gh->gh_state : gl->gl_demote_state; |
907 | const struct gfs2_glock_operations *glops = gl->gl_ops; | 798 | const struct gfs2_glock_operations *glops = gl->gl_ops; |
908 | int lck_flags = flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB | | 799 | int lck_flags = flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB | |
909 | LM_FLAG_NOEXP | LM_FLAG_ANY | | 800 | LM_FLAG_NOEXP | LM_FLAG_ANY | |
@@ -953,6 +844,7 @@ static void drop_bh(struct gfs2_glock *gl, unsigned int ret) | |||
953 | gfs2_assert_warn(sdp, !ret); | 844 | gfs2_assert_warn(sdp, !ret); |
954 | 845 | ||
955 | state_change(gl, LM_ST_UNLOCKED); | 846 | state_change(gl, LM_ST_UNLOCKED); |
847 | clear_bit(GLF_DEMOTE, &gl->gl_flags); | ||
956 | 848 | ||
957 | if (glops->go_inval) | 849 | if (glops->go_inval) |
958 | glops->go_inval(gl, DIO_METADATA); | 850 | glops->go_inval(gl, DIO_METADATA); |
@@ -974,7 +866,7 @@ static void drop_bh(struct gfs2_glock *gl, unsigned int ret) | |||
974 | gfs2_glock_put(gl); | 866 | gfs2_glock_put(gl); |
975 | 867 | ||
976 | if (gh) | 868 | if (gh) |
977 | gfs2_holder_dispose_or_wake(gh); | 869 | gfs2_holder_wake(gh); |
978 | } | 870 | } |
979 | 871 | ||
980 | /** | 872 | /** |
@@ -1291,9 +1183,8 @@ void gfs2_glock_dq(struct gfs2_holder *gh) | |||
1291 | if (glops->go_unlock) | 1183 | if (glops->go_unlock) |
1292 | glops->go_unlock(gh); | 1184 | glops->go_unlock(gh); |
1293 | 1185 | ||
1294 | gl->gl_stamp = jiffies; | ||
1295 | |||
1296 | spin_lock(&gl->gl_spin); | 1186 | spin_lock(&gl->gl_spin); |
1187 | gl->gl_stamp = jiffies; | ||
1297 | } | 1188 | } |
1298 | 1189 | ||
1299 | clear_bit(GLF_LOCK, &gl->gl_flags); | 1190 | clear_bit(GLF_LOCK, &gl->gl_flags); |
@@ -1981,16 +1872,16 @@ static int dump_glock(struct glock_iter *gi, struct gfs2_glock *gl) | |||
1981 | if (error) | 1872 | if (error) |
1982 | goto out; | 1873 | goto out; |
1983 | } | 1874 | } |
1984 | list_for_each_entry(gh, &gl->gl_waiters2, gh_list) { | ||
1985 | error = dump_holder(gi, "Waiter2", gh); | ||
1986 | if (error) | ||
1987 | goto out; | ||
1988 | } | ||
1989 | list_for_each_entry(gh, &gl->gl_waiters3, gh_list) { | 1875 | list_for_each_entry(gh, &gl->gl_waiters3, gh_list) { |
1990 | error = dump_holder(gi, "Waiter3", gh); | 1876 | error = dump_holder(gi, "Waiter3", gh); |
1991 | if (error) | 1877 | if (error) |
1992 | goto out; | 1878 | goto out; |
1993 | } | 1879 | } |
1880 | if (test_bit(GLF_DEMOTE, &gl->gl_flags)) { | ||
1881 | print_dbg(gi, " Demotion req to state %u (%llu uS ago)\n", | ||
1882 | gl->gl_demote_state, | ||
1883 | (u64)(jiffies - gl->gl_demote_time)*1000000/HZ); | ||
1884 | } | ||
1994 | if (gl->gl_ops == &gfs2_inode_glops && gl->gl_object) { | 1885 | if (gl->gl_ops == &gfs2_inode_glops && gl->gl_object) { |
1995 | if (!test_bit(GLF_LOCK, &gl->gl_flags) && | 1886 | if (!test_bit(GLF_LOCK, &gl->gl_flags) && |
1996 | list_empty(&gl->gl_holders)) { | 1887 | list_empty(&gl->gl_holders)) { |
diff --git a/fs/gfs2/glock.h b/fs/gfs2/glock.h index d7cef7408728..5e662eadc6f2 100644 --- a/fs/gfs2/glock.h +++ b/fs/gfs2/glock.h | |||
@@ -67,7 +67,7 @@ static inline int gfs2_glock_is_blocking(struct gfs2_glock *gl) | |||
67 | { | 67 | { |
68 | int ret; | 68 | int ret; |
69 | spin_lock(&gl->gl_spin); | 69 | spin_lock(&gl->gl_spin); |
70 | ret = !list_empty(&gl->gl_waiters2) || !list_empty(&gl->gl_waiters3); | 70 | ret = test_bit(GLF_DEMOTE, &gl->gl_flags) || !list_empty(&gl->gl_waiters3); |
71 | spin_unlock(&gl->gl_spin); | 71 | spin_unlock(&gl->gl_spin); |
72 | return ret; | 72 | return ret; |
73 | } | 73 | } |
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 7555261d911f..9c125823d760 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h | |||
@@ -115,11 +115,8 @@ enum { | |||
115 | /* Actions */ | 115 | /* Actions */ |
116 | HIF_MUTEX = 0, | 116 | HIF_MUTEX = 0, |
117 | HIF_PROMOTE = 1, | 117 | HIF_PROMOTE = 1, |
118 | HIF_DEMOTE = 2, | ||
119 | 118 | ||
120 | /* States */ | 119 | /* States */ |
121 | HIF_ALLOCED = 4, | ||
122 | HIF_DEALLOC = 5, | ||
123 | HIF_HOLDER = 6, | 120 | HIF_HOLDER = 6, |
124 | HIF_FIRST = 7, | 121 | HIF_FIRST = 7, |
125 | HIF_ABORTED = 9, | 122 | HIF_ABORTED = 9, |
@@ -142,8 +139,8 @@ struct gfs2_holder { | |||
142 | enum { | 139 | enum { |
143 | GLF_LOCK = 1, | 140 | GLF_LOCK = 1, |
144 | GLF_STICKY = 2, | 141 | GLF_STICKY = 2, |
142 | GLF_DEMOTE = 3, | ||
145 | GLF_DIRTY = 5, | 143 | GLF_DIRTY = 5, |
146 | GLF_SKIP_WAITERS2 = 6, | ||
147 | }; | 144 | }; |
148 | 145 | ||
149 | struct gfs2_glock { | 146 | struct gfs2_glock { |
@@ -156,11 +153,12 @@ struct gfs2_glock { | |||
156 | 153 | ||
157 | unsigned int gl_state; | 154 | unsigned int gl_state; |
158 | unsigned int gl_hash; | 155 | unsigned int gl_hash; |
156 | unsigned int gl_demote_state; /* state requested by remote node */ | ||
157 | unsigned long gl_demote_time; /* time of first demote request */ | ||
159 | struct task_struct *gl_owner; | 158 | struct task_struct *gl_owner; |
160 | unsigned long gl_ip; | 159 | unsigned long gl_ip; |
161 | struct list_head gl_holders; | 160 | struct list_head gl_holders; |
162 | struct list_head gl_waiters1; /* HIF_MUTEX */ | 161 | struct list_head gl_waiters1; /* HIF_MUTEX */ |
163 | struct list_head gl_waiters2; /* HIF_DEMOTE */ | ||
164 | struct list_head gl_waiters3; /* HIF_PROMOTE */ | 162 | struct list_head gl_waiters3; /* HIF_PROMOTE */ |
165 | 163 | ||
166 | const struct gfs2_glock_operations *gl_ops; | 164 | const struct gfs2_glock_operations *gl_ops; |
diff --git a/fs/gfs2/main.c b/fs/gfs2/main.c index 218395371dbe..c4bb374eaf92 100644 --- a/fs/gfs2/main.c +++ b/fs/gfs2/main.c | |||
@@ -45,7 +45,6 @@ static void gfs2_init_glock_once(void *foo, struct kmem_cache *cachep, unsigned | |||
45 | spin_lock_init(&gl->gl_spin); | 45 | spin_lock_init(&gl->gl_spin); |
46 | INIT_LIST_HEAD(&gl->gl_holders); | 46 | INIT_LIST_HEAD(&gl->gl_holders); |
47 | INIT_LIST_HEAD(&gl->gl_waiters1); | 47 | INIT_LIST_HEAD(&gl->gl_waiters1); |
48 | INIT_LIST_HEAD(&gl->gl_waiters2); | ||
49 | INIT_LIST_HEAD(&gl->gl_waiters3); | 48 | INIT_LIST_HEAD(&gl->gl_waiters3); |
50 | gl->gl_lvb = NULL; | 49 | gl->gl_lvb = NULL; |
51 | atomic_set(&gl->gl_lvb_count, 0); | 50 | atomic_set(&gl->gl_lvb_count, 0); |
diff --git a/fs/gfs2/ops_super.c b/fs/gfs2/ops_super.c index b89999d3a767..485ce3d49923 100644 --- a/fs/gfs2/ops_super.c +++ b/fs/gfs2/ops_super.c | |||
@@ -284,6 +284,31 @@ static int gfs2_remount_fs(struct super_block *sb, int *flags, char *data) | |||
284 | } | 284 | } |
285 | 285 | ||
286 | /** | 286 | /** |
287 | * gfs2_drop_inode - Drop an inode (test for remote unlink) | ||
288 | * @inode: The inode to drop | ||
289 | * | ||
290 | * If we've received a callback on an iopen lock then its because a | ||
291 | * remote node tried to deallocate the inode but failed due to this node | ||
292 | * still having the inode open. Here we mark the link count zero | ||
293 | * since we know that it must have reached zero if the GLF_DEMOTE flag | ||
294 | * is set on the iopen glock. If we didn't do a disk read since the | ||
295 | * remote node removed the final link then we might otherwise miss | ||
296 | * this event. This check ensures that this node will deallocate the | ||
297 | * inode's blocks, or alternatively pass the baton on to another | ||
298 | * node for later deallocation. | ||
299 | */ | ||
300 | static void gfs2_drop_inode(struct inode *inode) | ||
301 | { | ||
302 | if (inode->i_private && inode->i_nlink) { | ||
303 | struct gfs2_inode *ip = GFS2_I(inode); | ||
304 | struct gfs2_glock *gl = ip->i_iopen_gh.gh_gl; | ||
305 | if (gl && test_bit(GLF_DEMOTE, &gl->gl_flags)) | ||
306 | clear_nlink(inode); | ||
307 | } | ||
308 | generic_drop_inode(inode); | ||
309 | } | ||
310 | |||
311 | /** | ||
287 | * gfs2_clear_inode - Deallocate an inode when VFS is done with it | 312 | * gfs2_clear_inode - Deallocate an inode when VFS is done with it |
288 | * @inode: The VFS inode | 313 | * @inode: The VFS inode |
289 | * | 314 | * |
@@ -441,7 +466,7 @@ out_unlock: | |||
441 | out_uninit: | 466 | out_uninit: |
442 | gfs2_holder_uninit(&ip->i_iopen_gh); | 467 | gfs2_holder_uninit(&ip->i_iopen_gh); |
443 | gfs2_glock_dq_uninit(&gh); | 468 | gfs2_glock_dq_uninit(&gh); |
444 | if (error) | 469 | if (error && error != GLR_TRYFAILED) |
445 | fs_warn(sdp, "gfs2_delete_inode: %d\n", error); | 470 | fs_warn(sdp, "gfs2_delete_inode: %d\n", error); |
446 | out: | 471 | out: |
447 | truncate_inode_pages(&inode->i_data, 0); | 472 | truncate_inode_pages(&inode->i_data, 0); |
@@ -481,6 +506,7 @@ const struct super_operations gfs2_super_ops = { | |||
481 | .statfs = gfs2_statfs, | 506 | .statfs = gfs2_statfs, |
482 | .remount_fs = gfs2_remount_fs, | 507 | .remount_fs = gfs2_remount_fs, |
483 | .clear_inode = gfs2_clear_inode, | 508 | .clear_inode = gfs2_clear_inode, |
509 | .drop_inode = gfs2_drop_inode, | ||
484 | .show_options = gfs2_show_options, | 510 | .show_options = gfs2_show_options, |
485 | }; | 511 | }; |
486 | 512 | ||