diff options
Diffstat (limited to 'fs/gfs2/glock.c')
-rw-r--r-- | fs/gfs2/glock.c | 75 |
1 files changed, 24 insertions, 51 deletions
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index f42663325931..454d4b4eb36b 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/list.h> | 19 | #include <linux/list.h> |
20 | #include <linux/wait.h> | 20 | #include <linux/wait.h> |
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/rwsem.h> | ||
23 | #include <asm/uaccess.h> | 22 | #include <asm/uaccess.h> |
24 | #include <linux/seq_file.h> | 23 | #include <linux/seq_file.h> |
25 | #include <linux/debugfs.h> | 24 | #include <linux/debugfs.h> |
@@ -60,7 +59,6 @@ static int __dump_glock(struct seq_file *seq, const struct gfs2_glock *gl); | |||
60 | #define GLOCK_BUG_ON(gl,x) do { if (unlikely(x)) { __dump_glock(NULL, gl); BUG(); } } while(0) | 59 | #define GLOCK_BUG_ON(gl,x) do { if (unlikely(x)) { __dump_glock(NULL, gl); BUG(); } } while(0) |
61 | static void do_xmote(struct gfs2_glock *gl, struct gfs2_holder *gh, unsigned int target); | 60 | static void do_xmote(struct gfs2_glock *gl, struct gfs2_holder *gh, unsigned int target); |
62 | 61 | ||
63 | static DECLARE_RWSEM(gfs2_umount_flush_sem); | ||
64 | static struct dentry *gfs2_root; | 62 | static struct dentry *gfs2_root; |
65 | static struct workqueue_struct *glock_workqueue; | 63 | static struct workqueue_struct *glock_workqueue; |
66 | struct workqueue_struct *gfs2_delete_workqueue; | 64 | struct workqueue_struct *gfs2_delete_workqueue; |
@@ -154,12 +152,14 @@ static unsigned int gl_hash(const struct gfs2_sbd *sdp, | |||
154 | static void glock_free(struct gfs2_glock *gl) | 152 | static void glock_free(struct gfs2_glock *gl) |
155 | { | 153 | { |
156 | struct gfs2_sbd *sdp = gl->gl_sbd; | 154 | struct gfs2_sbd *sdp = gl->gl_sbd; |
157 | struct inode *aspace = gl->gl_aspace; | 155 | struct address_space *mapping = gfs2_glock2aspace(gl); |
156 | struct kmem_cache *cachep = gfs2_glock_cachep; | ||
158 | 157 | ||
159 | if (aspace) | 158 | GLOCK_BUG_ON(gl, mapping && mapping->nrpages); |
160 | gfs2_aspace_put(aspace); | ||
161 | trace_gfs2_glock_put(gl); | 159 | trace_gfs2_glock_put(gl); |
162 | sdp->sd_lockstruct.ls_ops->lm_put_lock(gfs2_glock_cachep, gl); | 160 | if (mapping) |
161 | cachep = gfs2_glock_aspace_cachep; | ||
162 | sdp->sd_lockstruct.ls_ops->lm_put_lock(cachep, gl); | ||
163 | } | 163 | } |
164 | 164 | ||
165 | /** | 165 | /** |
@@ -712,7 +712,6 @@ static void glock_work_func(struct work_struct *work) | |||
712 | finish_xmote(gl, gl->gl_reply); | 712 | finish_xmote(gl, gl->gl_reply); |
713 | drop_ref = 1; | 713 | drop_ref = 1; |
714 | } | 714 | } |
715 | down_read(&gfs2_umount_flush_sem); | ||
716 | spin_lock(&gl->gl_spin); | 715 | spin_lock(&gl->gl_spin); |
717 | if (test_and_clear_bit(GLF_PENDING_DEMOTE, &gl->gl_flags) && | 716 | if (test_and_clear_bit(GLF_PENDING_DEMOTE, &gl->gl_flags) && |
718 | gl->gl_state != LM_ST_UNLOCKED && | 717 | gl->gl_state != LM_ST_UNLOCKED && |
@@ -725,7 +724,6 @@ static void glock_work_func(struct work_struct *work) | |||
725 | } | 724 | } |
726 | run_queue(gl, 0); | 725 | run_queue(gl, 0); |
727 | spin_unlock(&gl->gl_spin); | 726 | spin_unlock(&gl->gl_spin); |
728 | up_read(&gfs2_umount_flush_sem); | ||
729 | if (!delay || | 727 | if (!delay || |
730 | queue_delayed_work(glock_workqueue, &gl->gl_work, delay) == 0) | 728 | queue_delayed_work(glock_workqueue, &gl->gl_work, delay) == 0) |
731 | gfs2_glock_put(gl); | 729 | gfs2_glock_put(gl); |
@@ -750,10 +748,11 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number, | |||
750 | const struct gfs2_glock_operations *glops, int create, | 748 | const struct gfs2_glock_operations *glops, int create, |
751 | struct gfs2_glock **glp) | 749 | struct gfs2_glock **glp) |
752 | { | 750 | { |
751 | struct super_block *s = sdp->sd_vfs; | ||
753 | struct lm_lockname name = { .ln_number = number, .ln_type = glops->go_type }; | 752 | struct lm_lockname name = { .ln_number = number, .ln_type = glops->go_type }; |
754 | struct gfs2_glock *gl, *tmp; | 753 | struct gfs2_glock *gl, *tmp; |
755 | unsigned int hash = gl_hash(sdp, &name); | 754 | unsigned int hash = gl_hash(sdp, &name); |
756 | int error; | 755 | struct address_space *mapping; |
757 | 756 | ||
758 | read_lock(gl_lock_addr(hash)); | 757 | read_lock(gl_lock_addr(hash)); |
759 | gl = search_bucket(hash, sdp, &name); | 758 | gl = search_bucket(hash, sdp, &name); |
@@ -765,7 +764,10 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number, | |||
765 | if (!create) | 764 | if (!create) |
766 | return -ENOENT; | 765 | return -ENOENT; |
767 | 766 | ||
768 | gl = kmem_cache_alloc(gfs2_glock_cachep, GFP_KERNEL); | 767 | if (glops->go_flags & GLOF_ASPACE) |
768 | gl = kmem_cache_alloc(gfs2_glock_aspace_cachep, GFP_KERNEL); | ||
769 | else | ||
770 | gl = kmem_cache_alloc(gfs2_glock_cachep, GFP_KERNEL); | ||
769 | if (!gl) | 771 | if (!gl) |
770 | return -ENOMEM; | 772 | return -ENOMEM; |
771 | 773 | ||
@@ -784,18 +786,18 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number, | |||
784 | gl->gl_tchange = jiffies; | 786 | gl->gl_tchange = jiffies; |
785 | gl->gl_object = NULL; | 787 | gl->gl_object = NULL; |
786 | gl->gl_sbd = sdp; | 788 | gl->gl_sbd = sdp; |
787 | gl->gl_aspace = NULL; | ||
788 | INIT_DELAYED_WORK(&gl->gl_work, glock_work_func); | 789 | INIT_DELAYED_WORK(&gl->gl_work, glock_work_func); |
789 | INIT_WORK(&gl->gl_delete, delete_work_func); | 790 | INIT_WORK(&gl->gl_delete, delete_work_func); |
790 | 791 | ||
791 | /* If this glock protects actual on-disk data or metadata blocks, | 792 | mapping = gfs2_glock2aspace(gl); |
792 | create a VFS inode to manage the pages/buffers holding them. */ | 793 | if (mapping) { |
793 | if (glops == &gfs2_inode_glops || glops == &gfs2_rgrp_glops) { | 794 | mapping->a_ops = &gfs2_meta_aops; |
794 | gl->gl_aspace = gfs2_aspace_get(sdp); | 795 | mapping->host = s->s_bdev->bd_inode; |
795 | if (!gl->gl_aspace) { | 796 | mapping->flags = 0; |
796 | error = -ENOMEM; | 797 | mapping_set_gfp_mask(mapping, GFP_NOFS); |
797 | goto fail; | 798 | mapping->assoc_mapping = NULL; |
798 | } | 799 | mapping->backing_dev_info = s->s_bdi; |
800 | mapping->writeback_index = 0; | ||
799 | } | 801 | } |
800 | 802 | ||
801 | write_lock(gl_lock_addr(hash)); | 803 | write_lock(gl_lock_addr(hash)); |
@@ -812,10 +814,6 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number, | |||
812 | *glp = gl; | 814 | *glp = gl; |
813 | 815 | ||
814 | return 0; | 816 | return 0; |
815 | |||
816 | fail: | ||
817 | kmem_cache_free(gfs2_glock_cachep, gl); | ||
818 | return error; | ||
819 | } | 817 | } |
820 | 818 | ||
821 | /** | 819 | /** |
@@ -1510,35 +1508,10 @@ void gfs2_glock_thaw(struct gfs2_sbd *sdp) | |||
1510 | 1508 | ||
1511 | void gfs2_gl_hash_clear(struct gfs2_sbd *sdp) | 1509 | void gfs2_gl_hash_clear(struct gfs2_sbd *sdp) |
1512 | { | 1510 | { |
1513 | unsigned long t; | ||
1514 | unsigned int x; | 1511 | unsigned int x; |
1515 | int cont; | ||
1516 | 1512 | ||
1517 | t = jiffies; | 1513 | for (x = 0; x < GFS2_GL_HASH_SIZE; x++) |
1518 | 1514 | examine_bucket(clear_glock, sdp, x); | |
1519 | for (;;) { | ||
1520 | cont = 0; | ||
1521 | for (x = 0; x < GFS2_GL_HASH_SIZE; x++) { | ||
1522 | if (examine_bucket(clear_glock, sdp, x)) | ||
1523 | cont = 1; | ||
1524 | } | ||
1525 | |||
1526 | if (!cont) | ||
1527 | break; | ||
1528 | |||
1529 | if (time_after_eq(jiffies, | ||
1530 | t + gfs2_tune_get(sdp, gt_stall_secs) * HZ)) { | ||
1531 | fs_warn(sdp, "Unmount seems to be stalled. " | ||
1532 | "Dumping lock state...\n"); | ||
1533 | gfs2_dump_lockstate(sdp); | ||
1534 | t = jiffies; | ||
1535 | } | ||
1536 | |||
1537 | down_write(&gfs2_umount_flush_sem); | ||
1538 | invalidate_inodes(sdp->sd_vfs); | ||
1539 | up_write(&gfs2_umount_flush_sem); | ||
1540 | msleep(10); | ||
1541 | } | ||
1542 | flush_workqueue(glock_workqueue); | 1515 | flush_workqueue(glock_workqueue); |
1543 | wait_event(sdp->sd_glock_wait, atomic_read(&sdp->sd_glock_disposal) == 0); | 1516 | wait_event(sdp->sd_glock_wait, atomic_read(&sdp->sd_glock_disposal) == 0); |
1544 | gfs2_dump_lockstate(sdp); | 1517 | gfs2_dump_lockstate(sdp); |
@@ -1685,7 +1658,7 @@ static int __dump_glock(struct seq_file *seq, const struct gfs2_glock *gl) | |||
1685 | dtime *= 1000000/HZ; /* demote time in uSec */ | 1658 | dtime *= 1000000/HZ; /* demote time in uSec */ |
1686 | if (!test_bit(GLF_DEMOTE, &gl->gl_flags)) | 1659 | if (!test_bit(GLF_DEMOTE, &gl->gl_flags)) |
1687 | dtime = 0; | 1660 | dtime = 0; |
1688 | gfs2_print_dbg(seq, "G: s:%s n:%u/%llu f:%s t:%s d:%s/%llu a:%d r:%d\n", | 1661 | gfs2_print_dbg(seq, "G: s:%s n:%u/%llx f:%s t:%s d:%s/%llu a:%d r:%d\n", |
1689 | state2str(gl->gl_state), | 1662 | state2str(gl->gl_state), |
1690 | gl->gl_name.ln_type, | 1663 | gl->gl_name.ln_type, |
1691 | (unsigned long long)gl->gl_name.ln_number, | 1664 | (unsigned long long)gl->gl_name.ln_number, |