diff options
| author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-12 12:14:51 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-12 12:14:51 -0400 |
| commit | f26e51f67ae6a75ffc57b96cf5fe096f75e778cb (patch) | |
| tree | 1e848187885426430cc93bffaadc539312ce636d /fs/gfs2/glock.c | |
| parent | 1462222b76a09a24b240563a51d5f9fbea8bd3e1 (diff) | |
| parent | c36258b5925e6cf6bf72904635100593573bfcff (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: (51 commits)
[DLM] block dlm_recv in recovery transition
[DLM] don't overwrite castparam if it's NULL
[GFS2] Get superblock a different way
[GFS2] Don't try to remove buffers that don't exist
[GFS2] Alternate gfs2_iget to avoid looking up inodes being freed
[GFS2] Data corruption fix
[GFS2] Clean up journaled data writing
[GFS2] GFS2: chmod hung - fix race in thread creation
[DLM] Make dlm_sendd cond_resched more
[GFS2] Move inode deletion out of blocking_cb
[GFS2] flocks from same process trip kernel BUG at fs/gfs2/glock.c:1118!
[GFS2] Clean up gfs2_trans_add_revoke()
[GFS2] Use slab operations for all gfs2_bufdata allocations
[GFS2] Replace revoke structure with bufdata structure
[GFS2] Fix ordering of dirty/journal for ordered buffer unstuffing
[GFS2] Clean up ordered write code
[GFS2] Move pin/unpin into lops.c, clean up locking
[GFS2] Don't mark jdata dirty in gfs2_unstuffer_page()
[GFS2] Introduce gfs2_remove_from_ail
[GFS2] Correct lock ordering in unlink
...
Diffstat (limited to 'fs/gfs2/glock.c')
| -rw-r--r-- | fs/gfs2/glock.c | 293 |
1 files changed, 190 insertions, 103 deletions
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 3f0974e1afef..a37efe4aae6f 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c | |||
| @@ -25,8 +25,10 @@ | |||
| 25 | #include <asm/uaccess.h> | 25 | #include <asm/uaccess.h> |
| 26 | #include <linux/seq_file.h> | 26 | #include <linux/seq_file.h> |
| 27 | #include <linux/debugfs.h> | 27 | #include <linux/debugfs.h> |
| 28 | #include <linux/module.h> | 28 | #include <linux/kthread.h> |
| 29 | #include <linux/kallsyms.h> | 29 | #include <linux/freezer.h> |
| 30 | #include <linux/workqueue.h> | ||
| 31 | #include <linux/jiffies.h> | ||
| 30 | 32 | ||
| 31 | #include "gfs2.h" | 33 | #include "gfs2.h" |
| 32 | #include "incore.h" | 34 | #include "incore.h" |
| @@ -48,7 +50,6 @@ struct glock_iter { | |||
| 48 | int hash; /* hash bucket index */ | 50 | int hash; /* hash bucket index */ |
| 49 | struct gfs2_sbd *sdp; /* incore superblock */ | 51 | struct gfs2_sbd *sdp; /* incore superblock */ |
| 50 | struct gfs2_glock *gl; /* current glock struct */ | 52 | struct gfs2_glock *gl; /* current glock struct */ |
| 51 | struct hlist_head *hb_list; /* current hash bucket ptr */ | ||
| 52 | struct seq_file *seq; /* sequence file for debugfs */ | 53 | struct seq_file *seq; /* sequence file for debugfs */ |
| 53 | char string[512]; /* scratch space */ | 54 | char string[512]; /* scratch space */ |
| 54 | }; | 55 | }; |
| @@ -59,8 +60,13 @@ static int gfs2_dump_lockstate(struct gfs2_sbd *sdp); | |||
| 59 | static int dump_glock(struct glock_iter *gi, struct gfs2_glock *gl); | 60 | static int dump_glock(struct glock_iter *gi, struct gfs2_glock *gl); |
| 60 | static void gfs2_glock_xmote_th(struct gfs2_glock *gl, struct gfs2_holder *gh); | 61 | static void gfs2_glock_xmote_th(struct gfs2_glock *gl, struct gfs2_holder *gh); |
| 61 | static void gfs2_glock_drop_th(struct gfs2_glock *gl); | 62 | static void gfs2_glock_drop_th(struct gfs2_glock *gl); |
| 63 | static void run_queue(struct gfs2_glock *gl); | ||
| 64 | |||
| 62 | static DECLARE_RWSEM(gfs2_umount_flush_sem); | 65 | static DECLARE_RWSEM(gfs2_umount_flush_sem); |
| 63 | static struct dentry *gfs2_root; | 66 | static struct dentry *gfs2_root; |
| 67 | static struct task_struct *scand_process; | ||
| 68 | static unsigned int scand_secs = 5; | ||
| 69 | static struct workqueue_struct *glock_workqueue; | ||
| 64 | 70 | ||
| 65 | #define GFS2_GL_HASH_SHIFT 15 | 71 | #define GFS2_GL_HASH_SHIFT 15 |
| 66 | #define GFS2_GL_HASH_SIZE (1 << GFS2_GL_HASH_SHIFT) | 72 | #define GFS2_GL_HASH_SIZE (1 << GFS2_GL_HASH_SHIFT) |
| @@ -276,6 +282,18 @@ static struct gfs2_glock *gfs2_glock_find(const struct gfs2_sbd *sdp, | |||
| 276 | return gl; | 282 | return gl; |
| 277 | } | 283 | } |
| 278 | 284 | ||
| 285 | static void glock_work_func(struct work_struct *work) | ||
| 286 | { | ||
| 287 | struct gfs2_glock *gl = container_of(work, struct gfs2_glock, gl_work.work); | ||
| 288 | |||
| 289 | spin_lock(&gl->gl_spin); | ||
| 290 | if (test_and_clear_bit(GLF_PENDING_DEMOTE, &gl->gl_flags)) | ||
| 291 | set_bit(GLF_DEMOTE, &gl->gl_flags); | ||
| 292 | run_queue(gl); | ||
| 293 | spin_unlock(&gl->gl_spin); | ||
| 294 | gfs2_glock_put(gl); | ||
| 295 | } | ||
| 296 | |||
| 279 | /** | 297 | /** |
| 280 | * gfs2_glock_get() - Get a glock, or create one if one doesn't exist | 298 | * gfs2_glock_get() - Get a glock, or create one if one doesn't exist |
| 281 | * @sdp: The GFS2 superblock | 299 | * @sdp: The GFS2 superblock |
| @@ -315,6 +333,7 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number, | |||
| 315 | gl->gl_name = name; | 333 | gl->gl_name = name; |
| 316 | atomic_set(&gl->gl_ref, 1); | 334 | atomic_set(&gl->gl_ref, 1); |
| 317 | gl->gl_state = LM_ST_UNLOCKED; | 335 | gl->gl_state = LM_ST_UNLOCKED; |
| 336 | gl->gl_demote_state = LM_ST_EXCLUSIVE; | ||
| 318 | gl->gl_hash = hash; | 337 | gl->gl_hash = hash; |
| 319 | gl->gl_owner_pid = 0; | 338 | gl->gl_owner_pid = 0; |
| 320 | gl->gl_ip = 0; | 339 | gl->gl_ip = 0; |
| @@ -323,10 +342,12 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number, | |||
| 323 | gl->gl_req_bh = NULL; | 342 | gl->gl_req_bh = NULL; |
| 324 | gl->gl_vn = 0; | 343 | gl->gl_vn = 0; |
| 325 | gl->gl_stamp = jiffies; | 344 | gl->gl_stamp = jiffies; |
| 345 | gl->gl_tchange = jiffies; | ||
| 326 | gl->gl_object = NULL; | 346 | gl->gl_object = NULL; |
| 327 | gl->gl_sbd = sdp; | 347 | gl->gl_sbd = sdp; |
| 328 | gl->gl_aspace = NULL; | 348 | gl->gl_aspace = NULL; |
| 329 | lops_init_le(&gl->gl_le, &gfs2_glock_lops); | 349 | lops_init_le(&gl->gl_le, &gfs2_glock_lops); |
| 350 | INIT_DELAYED_WORK(&gl->gl_work, glock_work_func); | ||
| 330 | 351 | ||
| 331 | /* If this glock protects actual on-disk data or metadata blocks, | 352 | /* If this glock protects actual on-disk data or metadata blocks, |
| 332 | create a VFS inode to manage the pages/buffers holding them. */ | 353 | create a VFS inode to manage the pages/buffers holding them. */ |
| @@ -440,6 +461,8 @@ static void wait_on_holder(struct gfs2_holder *gh) | |||
| 440 | 461 | ||
| 441 | static void gfs2_demote_wake(struct gfs2_glock *gl) | 462 | static void gfs2_demote_wake(struct gfs2_glock *gl) |
| 442 | { | 463 | { |
| 464 | BUG_ON(!spin_is_locked(&gl->gl_spin)); | ||
| 465 | gl->gl_demote_state = LM_ST_EXCLUSIVE; | ||
| 443 | clear_bit(GLF_DEMOTE, &gl->gl_flags); | 466 | clear_bit(GLF_DEMOTE, &gl->gl_flags); |
| 444 | smp_mb__after_clear_bit(); | 467 | smp_mb__after_clear_bit(); |
| 445 | wake_up_bit(&gl->gl_flags, GLF_DEMOTE); | 468 | wake_up_bit(&gl->gl_flags, GLF_DEMOTE); |
| @@ -545,12 +568,14 @@ static int rq_demote(struct gfs2_glock *gl) | |||
| 545 | return 0; | 568 | return 0; |
| 546 | } | 569 | } |
| 547 | set_bit(GLF_LOCK, &gl->gl_flags); | 570 | set_bit(GLF_LOCK, &gl->gl_flags); |
| 548 | spin_unlock(&gl->gl_spin); | ||
| 549 | if (gl->gl_demote_state == LM_ST_UNLOCKED || | 571 | if (gl->gl_demote_state == LM_ST_UNLOCKED || |
| 550 | gl->gl_state != LM_ST_EXCLUSIVE) | 572 | gl->gl_state != LM_ST_EXCLUSIVE) { |
| 573 | spin_unlock(&gl->gl_spin); | ||
| 551 | gfs2_glock_drop_th(gl); | 574 | gfs2_glock_drop_th(gl); |
| 552 | else | 575 | } else { |
| 576 | spin_unlock(&gl->gl_spin); | ||
| 553 | gfs2_glock_xmote_th(gl, NULL); | 577 | gfs2_glock_xmote_th(gl, NULL); |
| 578 | } | ||
| 554 | spin_lock(&gl->gl_spin); | 579 | spin_lock(&gl->gl_spin); |
| 555 | 580 | ||
| 556 | return 0; | 581 | return 0; |
| @@ -679,24 +704,25 @@ static void gfs2_glmutex_unlock(struct gfs2_glock *gl) | |||
| 679 | * practise: LM_ST_SHARED and LM_ST_UNLOCKED | 704 | * practise: LM_ST_SHARED and LM_ST_UNLOCKED |
| 680 | */ | 705 | */ |
| 681 | 706 | ||
| 682 | static void handle_callback(struct gfs2_glock *gl, unsigned int state, int remote) | 707 | static void handle_callback(struct gfs2_glock *gl, unsigned int state, |
| 708 | int remote, unsigned long delay) | ||
| 683 | { | 709 | { |
| 710 | int bit = delay ? GLF_PENDING_DEMOTE : GLF_DEMOTE; | ||
| 711 | |||
| 684 | spin_lock(&gl->gl_spin); | 712 | spin_lock(&gl->gl_spin); |
| 685 | if (test_and_set_bit(GLF_DEMOTE, &gl->gl_flags) == 0) { | 713 | set_bit(bit, &gl->gl_flags); |
| 714 | if (gl->gl_demote_state == LM_ST_EXCLUSIVE) { | ||
| 686 | gl->gl_demote_state = state; | 715 | gl->gl_demote_state = state; |
| 687 | gl->gl_demote_time = jiffies; | 716 | gl->gl_demote_time = jiffies; |
| 688 | if (remote && gl->gl_ops->go_type == LM_TYPE_IOPEN && | 717 | if (remote && gl->gl_ops->go_type == LM_TYPE_IOPEN && |
| 689 | gl->gl_object) { | 718 | gl->gl_object) { |
| 690 | struct inode *inode = igrab(gl->gl_object); | 719 | gfs2_glock_schedule_for_reclaim(gl); |
| 691 | spin_unlock(&gl->gl_spin); | 720 | spin_unlock(&gl->gl_spin); |
| 692 | if (inode) { | ||
| 693 | d_prune_aliases(inode); | ||
| 694 | iput(inode); | ||
| 695 | } | ||
| 696 | return; | 721 | return; |
| 697 | } | 722 | } |
| 698 | } else if (gl->gl_demote_state != LM_ST_UNLOCKED) { | 723 | } else if (gl->gl_demote_state != LM_ST_UNLOCKED && |
| 699 | gl->gl_demote_state = state; | 724 | gl->gl_demote_state != state) { |
| 725 | gl->gl_demote_state = LM_ST_UNLOCKED; | ||
| 700 | } | 726 | } |
| 701 | spin_unlock(&gl->gl_spin); | 727 | spin_unlock(&gl->gl_spin); |
| 702 | } | 728 | } |
| @@ -723,6 +749,7 @@ static void state_change(struct gfs2_glock *gl, unsigned int new_state) | |||
| 723 | } | 749 | } |
| 724 | 750 | ||
| 725 | gl->gl_state = new_state; | 751 | gl->gl_state = new_state; |
| 752 | gl->gl_tchange = jiffies; | ||
| 726 | } | 753 | } |
| 727 | 754 | ||
| 728 | /** | 755 | /** |
| @@ -760,10 +787,20 @@ static void xmote_bh(struct gfs2_glock *gl, unsigned int ret) | |||
| 760 | 787 | ||
| 761 | if (!gh) { | 788 | if (!gh) { |
| 762 | gl->gl_stamp = jiffies; | 789 | gl->gl_stamp = jiffies; |
| 763 | if (ret & LM_OUT_CANCELED) | 790 | if (ret & LM_OUT_CANCELED) { |
| 764 | op_done = 0; | 791 | op_done = 0; |
| 765 | else | 792 | } else { |
| 793 | spin_lock(&gl->gl_spin); | ||
| 794 | if (gl->gl_state != gl->gl_demote_state) { | ||
| 795 | gl->gl_req_bh = NULL; | ||
| 796 | spin_unlock(&gl->gl_spin); | ||
| 797 | gfs2_glock_drop_th(gl); | ||
| 798 | gfs2_glock_put(gl); | ||
| 799 | return; | ||
| 800 | } | ||
| 766 | gfs2_demote_wake(gl); | 801 | gfs2_demote_wake(gl); |
| 802 | spin_unlock(&gl->gl_spin); | ||
| 803 | } | ||
| 767 | } else { | 804 | } else { |
| 768 | spin_lock(&gl->gl_spin); | 805 | spin_lock(&gl->gl_spin); |
| 769 | list_del_init(&gh->gh_list); | 806 | list_del_init(&gh->gh_list); |
| @@ -799,7 +836,6 @@ out: | |||
| 799 | gl->gl_req_gh = NULL; | 836 | gl->gl_req_gh = NULL; |
| 800 | gl->gl_req_bh = NULL; | 837 | gl->gl_req_bh = NULL; |
| 801 | clear_bit(GLF_LOCK, &gl->gl_flags); | 838 | clear_bit(GLF_LOCK, &gl->gl_flags); |
| 802 | run_queue(gl); | ||
| 803 | spin_unlock(&gl->gl_spin); | 839 | spin_unlock(&gl->gl_spin); |
| 804 | } | 840 | } |
| 805 | 841 | ||
| @@ -817,7 +853,7 @@ out: | |||
| 817 | * | 853 | * |
| 818 | */ | 854 | */ |
| 819 | 855 | ||
| 820 | void gfs2_glock_xmote_th(struct gfs2_glock *gl, struct gfs2_holder *gh) | 856 | static void gfs2_glock_xmote_th(struct gfs2_glock *gl, struct gfs2_holder *gh) |
| 821 | { | 857 | { |
| 822 | struct gfs2_sbd *sdp = gl->gl_sbd; | 858 | struct gfs2_sbd *sdp = gl->gl_sbd; |
| 823 | int flags = gh ? gh->gh_flags : 0; | 859 | int flags = gh ? gh->gh_flags : 0; |
| @@ -871,7 +907,6 @@ static void drop_bh(struct gfs2_glock *gl, unsigned int ret) | |||
| 871 | gfs2_assert_warn(sdp, !ret); | 907 | gfs2_assert_warn(sdp, !ret); |
| 872 | 908 | ||
| 873 | state_change(gl, LM_ST_UNLOCKED); | 909 | state_change(gl, LM_ST_UNLOCKED); |
| 874 | gfs2_demote_wake(gl); | ||
| 875 | 910 | ||
| 876 | if (glops->go_inval) | 911 | if (glops->go_inval) |
| 877 | glops->go_inval(gl, DIO_METADATA); | 912 | glops->go_inval(gl, DIO_METADATA); |
| @@ -884,10 +919,10 @@ static void drop_bh(struct gfs2_glock *gl, unsigned int ret) | |||
| 884 | } | 919 | } |
| 885 | 920 | ||
| 886 | spin_lock(&gl->gl_spin); | 921 | spin_lock(&gl->gl_spin); |
| 922 | gfs2_demote_wake(gl); | ||
| 887 | gl->gl_req_gh = NULL; | 923 | gl->gl_req_gh = NULL; |
| 888 | gl->gl_req_bh = NULL; | 924 | gl->gl_req_bh = NULL; |
| 889 | clear_bit(GLF_LOCK, &gl->gl_flags); | 925 | clear_bit(GLF_LOCK, &gl->gl_flags); |
| 890 | run_queue(gl); | ||
| 891 | spin_unlock(&gl->gl_spin); | 926 | spin_unlock(&gl->gl_spin); |
| 892 | 927 | ||
| 893 | gfs2_glock_put(gl); | 928 | gfs2_glock_put(gl); |
| @@ -1067,24 +1102,31 @@ static void add_to_queue(struct gfs2_holder *gh) | |||
| 1067 | if (test_and_set_bit(HIF_WAIT, &gh->gh_iflags)) | 1102 | if (test_and_set_bit(HIF_WAIT, &gh->gh_iflags)) |
| 1068 | BUG(); | 1103 | BUG(); |
| 1069 | 1104 | ||
| 1070 | existing = find_holder_by_owner(&gl->gl_holders, gh->gh_owner_pid); | 1105 | if (!(gh->gh_flags & GL_FLOCK)) { |
| 1071 | if (existing) { | 1106 | existing = find_holder_by_owner(&gl->gl_holders, |
| 1072 | print_symbol(KERN_WARNING "original: %s\n", existing->gh_ip); | 1107 | gh->gh_owner_pid); |
| 1073 | printk(KERN_INFO "pid : %d\n", existing->gh_owner_pid); | 1108 | if (existing) { |
| 1074 | printk(KERN_INFO "lock type : %d lock state : %d\n", | 1109 | print_symbol(KERN_WARNING "original: %s\n", |
| 1075 | existing->gh_gl->gl_name.ln_type, existing->gh_gl->gl_state); | 1110 | existing->gh_ip); |
| 1076 | print_symbol(KERN_WARNING "new: %s\n", gh->gh_ip); | 1111 | printk(KERN_INFO "pid : %d\n", existing->gh_owner_pid); |
| 1077 | printk(KERN_INFO "pid : %d\n", gh->gh_owner_pid); | 1112 | printk(KERN_INFO "lock type : %d lock state : %d\n", |
| 1078 | printk(KERN_INFO "lock type : %d lock state : %d\n", | 1113 | existing->gh_gl->gl_name.ln_type, |
| 1079 | gl->gl_name.ln_type, gl->gl_state); | 1114 | existing->gh_gl->gl_state); |
| 1080 | BUG(); | 1115 | print_symbol(KERN_WARNING "new: %s\n", gh->gh_ip); |
| 1081 | } | 1116 | printk(KERN_INFO "pid : %d\n", gh->gh_owner_pid); |
| 1082 | 1117 | printk(KERN_INFO "lock type : %d lock state : %d\n", | |
| 1083 | existing = find_holder_by_owner(&gl->gl_waiters3, gh->gh_owner_pid); | 1118 | gl->gl_name.ln_type, gl->gl_state); |
| 1084 | if (existing) { | 1119 | BUG(); |
| 1085 | print_symbol(KERN_WARNING "original: %s\n", existing->gh_ip); | 1120 | } |
| 1086 | print_symbol(KERN_WARNING "new: %s\n", gh->gh_ip); | 1121 | |
| 1087 | BUG(); | 1122 | existing = find_holder_by_owner(&gl->gl_waiters3, |
| 1123 | gh->gh_owner_pid); | ||
| 1124 | if (existing) { | ||
| 1125 | print_symbol(KERN_WARNING "original: %s\n", | ||
| 1126 | existing->gh_ip); | ||
| 1127 | print_symbol(KERN_WARNING "new: %s\n", gh->gh_ip); | ||
| 1128 | BUG(); | ||
| 1129 | } | ||
| 1088 | } | 1130 | } |
| 1089 | 1131 | ||
| 1090 | if (gh->gh_flags & LM_FLAG_PRIORITY) | 1132 | if (gh->gh_flags & LM_FLAG_PRIORITY) |
| @@ -1195,9 +1237,10 @@ void gfs2_glock_dq(struct gfs2_holder *gh) | |||
| 1195 | { | 1237 | { |
| 1196 | struct gfs2_glock *gl = gh->gh_gl; | 1238 | struct gfs2_glock *gl = gh->gh_gl; |
| 1197 | const struct gfs2_glock_operations *glops = gl->gl_ops; | 1239 | const struct gfs2_glock_operations *glops = gl->gl_ops; |
| 1240 | unsigned delay = 0; | ||
| 1198 | 1241 | ||
| 1199 | if (gh->gh_flags & GL_NOCACHE) | 1242 | if (gh->gh_flags & GL_NOCACHE) |
| 1200 | handle_callback(gl, LM_ST_UNLOCKED, 0); | 1243 | handle_callback(gl, LM_ST_UNLOCKED, 0, 0); |
| 1201 | 1244 | ||
| 1202 | gfs2_glmutex_lock(gl); | 1245 | gfs2_glmutex_lock(gl); |
| 1203 | 1246 | ||
| @@ -1215,8 +1258,14 @@ void gfs2_glock_dq(struct gfs2_holder *gh) | |||
| 1215 | } | 1258 | } |
| 1216 | 1259 | ||
| 1217 | clear_bit(GLF_LOCK, &gl->gl_flags); | 1260 | clear_bit(GLF_LOCK, &gl->gl_flags); |
| 1218 | run_queue(gl); | ||
| 1219 | spin_unlock(&gl->gl_spin); | 1261 | spin_unlock(&gl->gl_spin); |
| 1262 | |||
| 1263 | gfs2_glock_hold(gl); | ||
| 1264 | if (test_bit(GLF_PENDING_DEMOTE, &gl->gl_flags) && | ||
| 1265 | !test_bit(GLF_DEMOTE, &gl->gl_flags)) | ||
| 1266 | delay = gl->gl_ops->go_min_hold_time; | ||
| 1267 | if (queue_delayed_work(glock_workqueue, &gl->gl_work, delay) == 0) | ||
| 1268 | gfs2_glock_put(gl); | ||
| 1220 | } | 1269 | } |
| 1221 | 1270 | ||
| 1222 | void gfs2_glock_dq_wait(struct gfs2_holder *gh) | 1271 | void gfs2_glock_dq_wait(struct gfs2_holder *gh) |
| @@ -1443,18 +1492,21 @@ static void blocking_cb(struct gfs2_sbd *sdp, struct lm_lockname *name, | |||
| 1443 | unsigned int state) | 1492 | unsigned int state) |
| 1444 | { | 1493 | { |
| 1445 | struct gfs2_glock *gl; | 1494 | struct gfs2_glock *gl; |
| 1495 | unsigned long delay = 0; | ||
| 1496 | unsigned long holdtime; | ||
| 1497 | unsigned long now = jiffies; | ||
| 1446 | 1498 | ||
| 1447 | gl = gfs2_glock_find(sdp, name); | 1499 | gl = gfs2_glock_find(sdp, name); |
| 1448 | if (!gl) | 1500 | if (!gl) |
| 1449 | return; | 1501 | return; |
| 1450 | 1502 | ||
| 1451 | handle_callback(gl, state, 1); | 1503 | holdtime = gl->gl_tchange + gl->gl_ops->go_min_hold_time; |
| 1452 | 1504 | if (time_before(now, holdtime)) | |
| 1453 | spin_lock(&gl->gl_spin); | 1505 | delay = holdtime - now; |
| 1454 | run_queue(gl); | ||
| 1455 | spin_unlock(&gl->gl_spin); | ||
| 1456 | 1506 | ||
| 1457 | gfs2_glock_put(gl); | 1507 | handle_callback(gl, state, 1, delay); |
| 1508 | if (queue_delayed_work(glock_workqueue, &gl->gl_work, delay) == 0) | ||
| 1509 | gfs2_glock_put(gl); | ||
| 1458 | } | 1510 | } |
| 1459 | 1511 | ||
| 1460 | /** | 1512 | /** |
| @@ -1495,7 +1547,8 @@ void gfs2_glock_cb(void *cb_data, unsigned int type, void *data) | |||
| 1495 | return; | 1547 | return; |
| 1496 | if (!gfs2_assert_warn(sdp, gl->gl_req_bh)) | 1548 | if (!gfs2_assert_warn(sdp, gl->gl_req_bh)) |
| 1497 | gl->gl_req_bh(gl, async->lc_ret); | 1549 | gl->gl_req_bh(gl, async->lc_ret); |
| 1498 | gfs2_glock_put(gl); | 1550 | if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0) |
| 1551 | gfs2_glock_put(gl); | ||
| 1499 | up_read(&gfs2_umount_flush_sem); | 1552 | up_read(&gfs2_umount_flush_sem); |
| 1500 | return; | 1553 | return; |
| 1501 | } | 1554 | } |
| @@ -1588,7 +1641,7 @@ void gfs2_reclaim_glock(struct gfs2_sbd *sdp) | |||
| 1588 | if (gfs2_glmutex_trylock(gl)) { | 1641 | if (gfs2_glmutex_trylock(gl)) { |
| 1589 | if (list_empty(&gl->gl_holders) && | 1642 | if (list_empty(&gl->gl_holders) && |
| 1590 | gl->gl_state != LM_ST_UNLOCKED && demote_ok(gl)) | 1643 | gl->gl_state != LM_ST_UNLOCKED && demote_ok(gl)) |
| 1591 | handle_callback(gl, LM_ST_UNLOCKED, 0); | 1644 | handle_callback(gl, LM_ST_UNLOCKED, 0, 0); |
| 1592 | gfs2_glmutex_unlock(gl); | 1645 | gfs2_glmutex_unlock(gl); |
| 1593 | } | 1646 | } |
| 1594 | 1647 | ||
| @@ -1617,7 +1670,7 @@ static int examine_bucket(glock_examiner examiner, struct gfs2_sbd *sdp, | |||
| 1617 | goto out; | 1670 | goto out; |
| 1618 | gl = list_entry(head->first, struct gfs2_glock, gl_list); | 1671 | gl = list_entry(head->first, struct gfs2_glock, gl_list); |
| 1619 | while(1) { | 1672 | while(1) { |
| 1620 | if (gl->gl_sbd == sdp) { | 1673 | if (!sdp || gl->gl_sbd == sdp) { |
| 1621 | gfs2_glock_hold(gl); | 1674 | gfs2_glock_hold(gl); |
| 1622 | read_unlock(gl_lock_addr(hash)); | 1675 | read_unlock(gl_lock_addr(hash)); |
| 1623 | if (prev) | 1676 | if (prev) |
| @@ -1635,6 +1688,7 @@ out: | |||
| 1635 | read_unlock(gl_lock_addr(hash)); | 1688 | read_unlock(gl_lock_addr(hash)); |
| 1636 | if (prev) | 1689 | if (prev) |
| 1637 | gfs2_glock_put(prev); | 1690 | gfs2_glock_put(prev); |
| 1691 | cond_resched(); | ||
| 1638 | return has_entries; | 1692 | return has_entries; |
| 1639 | } | 1693 | } |
| 1640 | 1694 | ||
| @@ -1663,20 +1717,6 @@ out_schedule: | |||
| 1663 | } | 1717 | } |
| 1664 | 1718 | ||
| 1665 | /** | 1719 | /** |
| 1666 | * gfs2_scand_internal - Look for glocks and inodes to toss from memory | ||
| 1667 | * @sdp: the filesystem | ||
| 1668 | * | ||
| 1669 | */ | ||
| 1670 | |||
| 1671 | void gfs2_scand_internal(struct gfs2_sbd *sdp) | ||
| 1672 | { | ||
| 1673 | unsigned int x; | ||
| 1674 | |||
| 1675 | for (x = 0; x < GFS2_GL_HASH_SIZE; x++) | ||
| 1676 | examine_bucket(scan_glock, sdp, x); | ||
| 1677 | } | ||
| 1678 | |||
| 1679 | /** | ||
| 1680 | * clear_glock - look at a glock and see if we can free it from glock cache | 1720 | * clear_glock - look at a glock and see if we can free it from glock cache |
| 1681 | * @gl: the glock to look at | 1721 | * @gl: the glock to look at |
| 1682 | * | 1722 | * |
| @@ -1701,7 +1741,7 @@ static void clear_glock(struct gfs2_glock *gl) | |||
| 1701 | if (gfs2_glmutex_trylock(gl)) { | 1741 | if (gfs2_glmutex_trylock(gl)) { |
| 1702 | if (list_empty(&gl->gl_holders) && | 1742 | if (list_empty(&gl->gl_holders) && |
| 1703 | gl->gl_state != LM_ST_UNLOCKED) | 1743 | gl->gl_state != LM_ST_UNLOCKED) |
| 1704 | handle_callback(gl, LM_ST_UNLOCKED, 0); | 1744 | handle_callback(gl, LM_ST_UNLOCKED, 0, 0); |
| 1705 | gfs2_glmutex_unlock(gl); | 1745 | gfs2_glmutex_unlock(gl); |
| 1706 | } | 1746 | } |
| 1707 | } | 1747 | } |
| @@ -1843,7 +1883,7 @@ static int dump_glock(struct glock_iter *gi, struct gfs2_glock *gl) | |||
| 1843 | 1883 | ||
| 1844 | spin_lock(&gl->gl_spin); | 1884 | spin_lock(&gl->gl_spin); |
| 1845 | 1885 | ||
| 1846 | print_dbg(gi, "Glock 0x%p (%u, %llu)\n", gl, gl->gl_name.ln_type, | 1886 | print_dbg(gi, "Glock 0x%p (%u, 0x%llx)\n", gl, gl->gl_name.ln_type, |
| 1847 | (unsigned long long)gl->gl_name.ln_number); | 1887 | (unsigned long long)gl->gl_name.ln_number); |
| 1848 | print_dbg(gi, " gl_flags ="); | 1888 | print_dbg(gi, " gl_flags ="); |
| 1849 | for (x = 0; x < 32; x++) { | 1889 | for (x = 0; x < 32; x++) { |
| @@ -1963,6 +2003,35 @@ static int gfs2_dump_lockstate(struct gfs2_sbd *sdp) | |||
| 1963 | return error; | 2003 | return error; |
| 1964 | } | 2004 | } |
| 1965 | 2005 | ||
| 2006 | /** | ||
| 2007 | * gfs2_scand - Look for cached glocks and inodes to toss from memory | ||
| 2008 | * @sdp: Pointer to GFS2 superblock | ||
| 2009 | * | ||
| 2010 | * One of these daemons runs, finding candidates to add to sd_reclaim_list. | ||
| 2011 | * See gfs2_glockd() | ||
| 2012 | */ | ||
| 2013 | |||
| 2014 | static int gfs2_scand(void *data) | ||
| 2015 | { | ||
| 2016 | unsigned x; | ||
| 2017 | unsigned delay; | ||
| 2018 | |||
| 2019 | while (!kthread_should_stop()) { | ||
| 2020 | for (x = 0; x < GFS2_GL_HASH_SIZE; x++) | ||
| 2021 | examine_bucket(scan_glock, NULL, x); | ||
| 2022 | if (freezing(current)) | ||
| 2023 | refrigerator(); | ||
| 2024 | delay = scand_secs; | ||
| 2025 | if (delay < 1) | ||
| 2026 | delay = 1; | ||
| 2027 | schedule_timeout_interruptible(delay * HZ); | ||
| 2028 | } | ||
| 2029 | |||
| 2030 | return 0; | ||
| 2031 | } | ||
| 2032 | |||
| 2033 | |||
| 2034 | |||
| 1966 | int __init gfs2_glock_init(void) | 2035 | int __init gfs2_glock_init(void) |
| 1967 | { | 2036 | { |
| 1968 | unsigned i; | 2037 | unsigned i; |
| @@ -1974,52 +2043,69 @@ int __init gfs2_glock_init(void) | |||
| 1974 | rwlock_init(&gl_hash_locks[i]); | 2043 | rwlock_init(&gl_hash_locks[i]); |
| 1975 | } | 2044 | } |
| 1976 | #endif | 2045 | #endif |
| 2046 | |||
| 2047 | scand_process = kthread_run(gfs2_scand, NULL, "gfs2_scand"); | ||
| 2048 | if (IS_ERR(scand_process)) | ||
| 2049 | return PTR_ERR(scand_process); | ||
| 2050 | |||
| 2051 | glock_workqueue = create_workqueue("glock_workqueue"); | ||
| 2052 | if (IS_ERR(glock_workqueue)) { | ||
| 2053 | kthread_stop(scand_process); | ||
| 2054 | return PTR_ERR(glock_workqueue); | ||
| 2055 | } | ||
| 2056 | |||
| 1977 | return 0; | 2057 | return 0; |
| 1978 | } | 2058 | } |
| 1979 | 2059 | ||
| 2060 | void gfs2_glock_exit(void) | ||
| 2061 | { | ||
| 2062 | destroy_workqueue(glock_workqueue); | ||
| 2063 | kthread_stop(scand_process); | ||
| 2064 | } | ||
| 2065 | |||
| 2066 | module_param(scand_secs, uint, S_IRUGO|S_IWUSR); | ||
| 2067 | MODULE_PARM_DESC(scand_secs, "The number of seconds between scand runs"); | ||
| 2068 | |||
| 1980 | static int gfs2_glock_iter_next(struct glock_iter *gi) | 2069 | static int gfs2_glock_iter_next(struct glock_iter *gi) |
| 1981 | { | 2070 | { |
| 2071 | struct gfs2_glock *gl; | ||
| 2072 | |||
| 2073 | restart: | ||
| 1982 | read_lock(gl_lock_addr(gi->hash)); | 2074 | read_lock(gl_lock_addr(gi->hash)); |
| 1983 | while (1) { | 2075 | gl = gi->gl; |
| 1984 | if (!gi->hb_list) { /* If we don't have a hash bucket yet */ | 2076 | if (gl) { |
| 1985 | gi->hb_list = &gl_hash_table[gi->hash].hb_list; | 2077 | gi->gl = hlist_entry(gl->gl_list.next, |
| 1986 | if (hlist_empty(gi->hb_list)) { | 2078 | struct gfs2_glock, gl_list); |
| 1987 | read_unlock(gl_lock_addr(gi->hash)); | ||
| 1988 | gi->hash++; | ||
| 1989 | read_lock(gl_lock_addr(gi->hash)); | ||
| 1990 | gi->hb_list = NULL; | ||
| 1991 | if (gi->hash >= GFS2_GL_HASH_SIZE) { | ||
| 1992 | read_unlock(gl_lock_addr(gi->hash)); | ||
| 1993 | return 1; | ||
| 1994 | } | ||
| 1995 | else | ||
| 1996 | continue; | ||
| 1997 | } | ||
| 1998 | if (!hlist_empty(gi->hb_list)) { | ||
| 1999 | gi->gl = list_entry(gi->hb_list->first, | ||
| 2000 | struct gfs2_glock, | ||
| 2001 | gl_list); | ||
| 2002 | } | ||
| 2003 | } else { | ||
| 2004 | if (gi->gl->gl_list.next == NULL) { | ||
| 2005 | read_unlock(gl_lock_addr(gi->hash)); | ||
| 2006 | gi->hash++; | ||
| 2007 | read_lock(gl_lock_addr(gi->hash)); | ||
| 2008 | gi->hb_list = NULL; | ||
| 2009 | continue; | ||
| 2010 | } | ||
| 2011 | gi->gl = list_entry(gi->gl->gl_list.next, | ||
| 2012 | struct gfs2_glock, gl_list); | ||
| 2013 | } | ||
| 2014 | if (gi->gl) | 2079 | if (gi->gl) |
| 2015 | break; | 2080 | gfs2_glock_hold(gi->gl); |
| 2016 | } | 2081 | } |
| 2017 | read_unlock(gl_lock_addr(gi->hash)); | 2082 | read_unlock(gl_lock_addr(gi->hash)); |
| 2083 | if (gl) | ||
| 2084 | gfs2_glock_put(gl); | ||
| 2085 | if (gl && gi->gl == NULL) | ||
| 2086 | gi->hash++; | ||
| 2087 | while(gi->gl == NULL) { | ||
| 2088 | if (gi->hash >= GFS2_GL_HASH_SIZE) | ||
| 2089 | return 1; | ||
| 2090 | read_lock(gl_lock_addr(gi->hash)); | ||
| 2091 | gi->gl = hlist_entry(gl_hash_table[gi->hash].hb_list.first, | ||
| 2092 | struct gfs2_glock, gl_list); | ||
| 2093 | if (gi->gl) | ||
| 2094 | gfs2_glock_hold(gi->gl); | ||
| 2095 | read_unlock(gl_lock_addr(gi->hash)); | ||
| 2096 | gi->hash++; | ||
| 2097 | } | ||
| 2098 | |||
| 2099 | if (gi->sdp != gi->gl->gl_sbd) | ||
| 2100 | goto restart; | ||
| 2101 | |||
| 2018 | return 0; | 2102 | return 0; |
| 2019 | } | 2103 | } |
| 2020 | 2104 | ||
| 2021 | static void gfs2_glock_iter_free(struct glock_iter *gi) | 2105 | static void gfs2_glock_iter_free(struct glock_iter *gi) |
| 2022 | { | 2106 | { |
| 2107 | if (gi->gl) | ||
| 2108 | gfs2_glock_put(gi->gl); | ||
| 2023 | kfree(gi); | 2109 | kfree(gi); |
| 2024 | } | 2110 | } |
| 2025 | 2111 | ||
| @@ -2033,9 +2119,8 @@ static struct glock_iter *gfs2_glock_iter_init(struct gfs2_sbd *sdp) | |||
| 2033 | 2119 | ||
| 2034 | gi->sdp = sdp; | 2120 | gi->sdp = sdp; |
| 2035 | gi->hash = 0; | 2121 | gi->hash = 0; |
| 2036 | gi->gl = NULL; | ||
| 2037 | gi->hb_list = NULL; | ||
| 2038 | gi->seq = NULL; | 2122 | gi->seq = NULL; |
| 2123 | gi->gl = NULL; | ||
| 2039 | memset(gi->string, 0, sizeof(gi->string)); | 2124 | memset(gi->string, 0, sizeof(gi->string)); |
| 2040 | 2125 | ||
| 2041 | if (gfs2_glock_iter_next(gi)) { | 2126 | if (gfs2_glock_iter_next(gi)) { |
| @@ -2055,7 +2140,7 @@ static void *gfs2_glock_seq_start(struct seq_file *file, loff_t *pos) | |||
| 2055 | if (!gi) | 2140 | if (!gi) |
| 2056 | return NULL; | 2141 | return NULL; |
| 2057 | 2142 | ||
| 2058 | while (n--) { | 2143 | while(n--) { |
| 2059 | if (gfs2_glock_iter_next(gi)) { | 2144 | if (gfs2_glock_iter_next(gi)) { |
| 2060 | gfs2_glock_iter_free(gi); | 2145 | gfs2_glock_iter_free(gi); |
| 2061 | return NULL; | 2146 | return NULL; |
| @@ -2082,7 +2167,9 @@ static void *gfs2_glock_seq_next(struct seq_file *file, void *iter_ptr, | |||
| 2082 | 2167 | ||
| 2083 | static void gfs2_glock_seq_stop(struct seq_file *file, void *iter_ptr) | 2168 | static void gfs2_glock_seq_stop(struct seq_file *file, void *iter_ptr) |
| 2084 | { | 2169 | { |
| 2085 | /* nothing for now */ | 2170 | struct glock_iter *gi = iter_ptr; |
| 2171 | if (gi) | ||
| 2172 | gfs2_glock_iter_free(gi); | ||
| 2086 | } | 2173 | } |
| 2087 | 2174 | ||
| 2088 | static int gfs2_glock_seq_show(struct seq_file *file, void *iter_ptr) | 2175 | static int gfs2_glock_seq_show(struct seq_file *file, void *iter_ptr) |
| @@ -2095,7 +2182,7 @@ static int gfs2_glock_seq_show(struct seq_file *file, void *iter_ptr) | |||
| 2095 | return 0; | 2182 | return 0; |
| 2096 | } | 2183 | } |
| 2097 | 2184 | ||
| 2098 | static struct seq_operations gfs2_glock_seq_ops = { | 2185 | static const struct seq_operations gfs2_glock_seq_ops = { |
| 2099 | .start = gfs2_glock_seq_start, | 2186 | .start = gfs2_glock_seq_start, |
| 2100 | .next = gfs2_glock_seq_next, | 2187 | .next = gfs2_glock_seq_next, |
| 2101 | .stop = gfs2_glock_seq_stop, | 2188 | .stop = gfs2_glock_seq_stop, |
