diff options
Diffstat (limited to 'fs/gfs2')
-rw-r--r-- | fs/gfs2/glock.c | 75 | ||||
-rw-r--r-- | fs/gfs2/glock.h | 2 | ||||
-rw-r--r-- | fs/gfs2/incore.h | 4 |
3 files changed, 59 insertions, 22 deletions
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index b8aa816bb6eb..d2e3094c40f8 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c | |||
@@ -25,6 +25,8 @@ | |||
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> | ||
29 | #include <linux/kallsyms.h> | ||
28 | 30 | ||
29 | #include "gfs2.h" | 31 | #include "gfs2.h" |
30 | #include "incore.h" | 32 | #include "incore.h" |
@@ -54,6 +56,7 @@ struct glock_iter { | |||
54 | typedef void (*glock_examiner) (struct gfs2_glock * gl); | 56 | typedef void (*glock_examiner) (struct gfs2_glock * gl); |
55 | 57 | ||
56 | static int gfs2_dump_lockstate(struct gfs2_sbd *sdp); | 58 | static int gfs2_dump_lockstate(struct gfs2_sbd *sdp); |
59 | static int dump_glock(struct glock_iter *gi, struct gfs2_glock *gl); | ||
57 | static void gfs2_glock_xmote_th(struct gfs2_glock *gl, struct gfs2_holder *gh); | 60 | 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); | 61 | static void gfs2_glock_drop_th(struct gfs2_glock *gl); |
59 | static DECLARE_RWSEM(gfs2_umount_flush_sem); | 62 | static DECLARE_RWSEM(gfs2_umount_flush_sem); |
@@ -64,6 +67,7 @@ static struct dentry *gfs2_root; | |||
64 | #define GFS2_GL_HASH_MASK (GFS2_GL_HASH_SIZE - 1) | 67 | #define GFS2_GL_HASH_MASK (GFS2_GL_HASH_SIZE - 1) |
65 | 68 | ||
66 | static struct gfs2_gl_hash_bucket gl_hash_table[GFS2_GL_HASH_SIZE]; | 69 | static struct gfs2_gl_hash_bucket gl_hash_table[GFS2_GL_HASH_SIZE]; |
70 | static struct dentry *gfs2_root; | ||
67 | 71 | ||
68 | /* | 72 | /* |
69 | * Despite what you might think, the numbers below are not arbitrary :-) | 73 | * Despite what you might think, the numbers below are not arbitrary :-) |
@@ -312,7 +316,7 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number, | |||
312 | atomic_set(&gl->gl_ref, 1); | 316 | atomic_set(&gl->gl_ref, 1); |
313 | gl->gl_state = LM_ST_UNLOCKED; | 317 | gl->gl_state = LM_ST_UNLOCKED; |
314 | gl->gl_hash = hash; | 318 | gl->gl_hash = hash; |
315 | gl->gl_owner = NULL; | 319 | gl->gl_owner_pid = 0; |
316 | gl->gl_ip = 0; | 320 | gl->gl_ip = 0; |
317 | gl->gl_ops = glops; | 321 | gl->gl_ops = glops; |
318 | gl->gl_req_gh = NULL; | 322 | gl->gl_req_gh = NULL; |
@@ -376,7 +380,7 @@ void gfs2_holder_init(struct gfs2_glock *gl, unsigned int state, unsigned flags, | |||
376 | INIT_LIST_HEAD(&gh->gh_list); | 380 | INIT_LIST_HEAD(&gh->gh_list); |
377 | gh->gh_gl = gl; | 381 | gh->gh_gl = gl; |
378 | gh->gh_ip = (unsigned long)__builtin_return_address(0); | 382 | gh->gh_ip = (unsigned long)__builtin_return_address(0); |
379 | gh->gh_owner = current; | 383 | gh->gh_owner_pid = current->pid; |
380 | gh->gh_state = state; | 384 | gh->gh_state = state; |
381 | gh->gh_flags = flags; | 385 | gh->gh_flags = flags; |
382 | gh->gh_error = 0; | 386 | gh->gh_error = 0; |
@@ -601,7 +605,7 @@ static void gfs2_glmutex_lock(struct gfs2_glock *gl) | |||
601 | if (test_and_set_bit(GLF_LOCK, &gl->gl_flags)) { | 605 | if (test_and_set_bit(GLF_LOCK, &gl->gl_flags)) { |
602 | list_add_tail(&gh.gh_list, &gl->gl_waiters1); | 606 | list_add_tail(&gh.gh_list, &gl->gl_waiters1); |
603 | } else { | 607 | } else { |
604 | gl->gl_owner = current; | 608 | gl->gl_owner_pid = current->pid; |
605 | gl->gl_ip = (unsigned long)__builtin_return_address(0); | 609 | gl->gl_ip = (unsigned long)__builtin_return_address(0); |
606 | clear_bit(HIF_WAIT, &gh.gh_iflags); | 610 | clear_bit(HIF_WAIT, &gh.gh_iflags); |
607 | smp_mb(); | 611 | smp_mb(); |
@@ -628,7 +632,7 @@ static int gfs2_glmutex_trylock(struct gfs2_glock *gl) | |||
628 | if (test_and_set_bit(GLF_LOCK, &gl->gl_flags)) { | 632 | if (test_and_set_bit(GLF_LOCK, &gl->gl_flags)) { |
629 | acquired = 0; | 633 | acquired = 0; |
630 | } else { | 634 | } else { |
631 | gl->gl_owner = current; | 635 | gl->gl_owner_pid = current->pid; |
632 | gl->gl_ip = (unsigned long)__builtin_return_address(0); | 636 | gl->gl_ip = (unsigned long)__builtin_return_address(0); |
633 | } | 637 | } |
634 | spin_unlock(&gl->gl_spin); | 638 | spin_unlock(&gl->gl_spin); |
@@ -646,7 +650,7 @@ static void gfs2_glmutex_unlock(struct gfs2_glock *gl) | |||
646 | { | 650 | { |
647 | spin_lock(&gl->gl_spin); | 651 | spin_lock(&gl->gl_spin); |
648 | clear_bit(GLF_LOCK, &gl->gl_flags); | 652 | clear_bit(GLF_LOCK, &gl->gl_flags); |
649 | gl->gl_owner = NULL; | 653 | gl->gl_owner_pid = 0; |
650 | gl->gl_ip = 0; | 654 | gl->gl_ip = 0; |
651 | run_queue(gl); | 655 | run_queue(gl); |
652 | BUG_ON(!spin_is_locked(&gl->gl_spin)); | 656 | BUG_ON(!spin_is_locked(&gl->gl_spin)); |
@@ -999,12 +1003,12 @@ static int glock_wait_internal(struct gfs2_holder *gh) | |||
999 | } | 1003 | } |
1000 | 1004 | ||
1001 | static inline struct gfs2_holder * | 1005 | static inline struct gfs2_holder * |
1002 | find_holder_by_owner(struct list_head *head, struct task_struct *owner) | 1006 | find_holder_by_owner(struct list_head *head, pid_t pid) |
1003 | { | 1007 | { |
1004 | struct gfs2_holder *gh; | 1008 | struct gfs2_holder *gh; |
1005 | 1009 | ||
1006 | list_for_each_entry(gh, head, gh_list) { | 1010 | list_for_each_entry(gh, head, gh_list) { |
1007 | if (gh->gh_owner == owner) | 1011 | if (gh->gh_owner_pid == pid) |
1008 | return gh; | 1012 | return gh; |
1009 | } | 1013 | } |
1010 | 1014 | ||
@@ -1036,24 +1040,24 @@ static void add_to_queue(struct gfs2_holder *gh) | |||
1036 | struct gfs2_glock *gl = gh->gh_gl; | 1040 | struct gfs2_glock *gl = gh->gh_gl; |
1037 | struct gfs2_holder *existing; | 1041 | struct gfs2_holder *existing; |
1038 | 1042 | ||
1039 | BUG_ON(!gh->gh_owner); | 1043 | BUG_ON(!gh->gh_owner_pid); |
1040 | if (test_and_set_bit(HIF_WAIT, &gh->gh_iflags)) | 1044 | if (test_and_set_bit(HIF_WAIT, &gh->gh_iflags)) |
1041 | BUG(); | 1045 | BUG(); |
1042 | 1046 | ||
1043 | existing = find_holder_by_owner(&gl->gl_holders, gh->gh_owner); | 1047 | existing = find_holder_by_owner(&gl->gl_holders, gh->gh_owner_pid); |
1044 | if (existing) { | 1048 | if (existing) { |
1045 | print_symbol(KERN_WARNING "original: %s\n", existing->gh_ip); | 1049 | print_symbol(KERN_WARNING "original: %s\n", existing->gh_ip); |
1046 | printk(KERN_INFO "pid : %d\n", existing->gh_owner->pid); | 1050 | printk(KERN_INFO "pid : %d\n", existing->gh_owner_pid); |
1047 | printk(KERN_INFO "lock type : %d lock state : %d\n", | 1051 | printk(KERN_INFO "lock type : %d lock state : %d\n", |
1048 | existing->gh_gl->gl_name.ln_type, existing->gh_gl->gl_state); | 1052 | existing->gh_gl->gl_name.ln_type, existing->gh_gl->gl_state); |
1049 | print_symbol(KERN_WARNING "new: %s\n", gh->gh_ip); | 1053 | print_symbol(KERN_WARNING "new: %s\n", gh->gh_ip); |
1050 | printk(KERN_INFO "pid : %d\n", gh->gh_owner->pid); | 1054 | printk(KERN_INFO "pid : %d\n", gh->gh_owner_pid); |
1051 | printk(KERN_INFO "lock type : %d lock state : %d\n", | 1055 | printk(KERN_INFO "lock type : %d lock state : %d\n", |
1052 | gl->gl_name.ln_type, gl->gl_state); | 1056 | gl->gl_name.ln_type, gl->gl_state); |
1053 | BUG(); | 1057 | BUG(); |
1054 | } | 1058 | } |
1055 | 1059 | ||
1056 | existing = find_holder_by_owner(&gl->gl_waiters3, gh->gh_owner); | 1060 | existing = find_holder_by_owner(&gl->gl_waiters3, gh->gh_owner_pid); |
1057 | if (existing) { | 1061 | if (existing) { |
1058 | print_symbol(KERN_WARNING "original: %s\n", existing->gh_ip); | 1062 | print_symbol(KERN_WARNING "original: %s\n", existing->gh_ip); |
1059 | print_symbol(KERN_WARNING "new: %s\n", gh->gh_ip); | 1063 | print_symbol(KERN_WARNING "new: %s\n", gh->gh_ip); |
@@ -1756,6 +1760,22 @@ void gfs2_gl_hash_clear(struct gfs2_sbd *sdp, int wait) | |||
1756 | * Diagnostic routines to help debug distributed deadlock | 1760 | * Diagnostic routines to help debug distributed deadlock |
1757 | */ | 1761 | */ |
1758 | 1762 | ||
1763 | static void gfs2_print_symbol(struct glock_iter *gi, const char *fmt, | ||
1764 | unsigned long address) | ||
1765 | { | ||
1766 | /* when sprint_symbol becomes available in the new kernel, replace this */ | ||
1767 | /* function with: | ||
1768 | char buffer[KSYM_SYMBOL_LEN]; | ||
1769 | |||
1770 | sprint_symbol(buffer, address); | ||
1771 | print_dbg(gi, fmt, buffer); | ||
1772 | */ | ||
1773 | if (gi) | ||
1774 | print_dbg(gi, fmt, address); | ||
1775 | else | ||
1776 | print_symbol(fmt, address); | ||
1777 | } | ||
1778 | |||
1759 | /** | 1779 | /** |
1760 | * dump_holder - print information about a glock holder | 1780 | * dump_holder - print information about a glock holder |
1761 | * @str: a string naming the type of holder | 1781 | * @str: a string naming the type of holder |
@@ -1768,10 +1788,18 @@ static int dump_holder(struct glock_iter *gi, char *str, | |||
1768 | struct gfs2_holder *gh) | 1788 | struct gfs2_holder *gh) |
1769 | { | 1789 | { |
1770 | unsigned int x; | 1790 | unsigned int x; |
1791 | struct task_struct *gh_owner; | ||
1771 | 1792 | ||
1772 | print_dbg(gi, " %s\n", str); | 1793 | print_dbg(gi, " %s\n", str); |
1773 | print_dbg(gi, " owner = %ld\n", | 1794 | if (gh->gh_owner_pid) { |
1774 | (gh->gh_owner) ? (long)gh->gh_owner->pid : -1); | 1795 | print_dbg(gi, " owner = %ld ", (long)gh->gh_owner_pid); |
1796 | gh_owner = find_task_by_pid(gh->gh_owner_pid); | ||
1797 | if (gh_owner) | ||
1798 | print_dbg(gi, "(%s)\n", gh_owner->comm); | ||
1799 | else | ||
1800 | print_dbg(gi, "(ended)\n"); | ||
1801 | } else | ||
1802 | print_dbg(gi, " owner = -1\n"); | ||
1775 | print_dbg(gi, " gh_state = %u\n", gh->gh_state); | 1803 | print_dbg(gi, " gh_state = %u\n", gh->gh_state); |
1776 | print_dbg(gi, " gh_flags ="); | 1804 | print_dbg(gi, " gh_flags ="); |
1777 | for (x = 0; x < 32; x++) | 1805 | for (x = 0; x < 32; x++) |
@@ -1784,10 +1812,7 @@ static int dump_holder(struct glock_iter *gi, char *str, | |||
1784 | if (test_bit(x, &gh->gh_iflags)) | 1812 | if (test_bit(x, &gh->gh_iflags)) |
1785 | print_dbg(gi, " %u", x); | 1813 | print_dbg(gi, " %u", x); |
1786 | print_dbg(gi, " \n"); | 1814 | print_dbg(gi, " \n"); |
1787 | if (gi) | 1815 | gfs2_print_symbol(gi, " initialized at: %s\n", gh->gh_ip); |
1788 | print_dbg(gi, " initialized at: 0x%x\n", gh->gh_ip); | ||
1789 | else | ||
1790 | print_symbol(KERN_INFO " initialized at: %s\n", gh->gh_ip); | ||
1791 | 1816 | ||
1792 | return 0; | 1817 | return 0; |
1793 | } | 1818 | } |
@@ -1828,6 +1853,7 @@ static int dump_glock(struct glock_iter *gi, struct gfs2_glock *gl) | |||
1828 | struct gfs2_holder *gh; | 1853 | struct gfs2_holder *gh; |
1829 | unsigned int x; | 1854 | unsigned int x; |
1830 | int error = -ENOBUFS; | 1855 | int error = -ENOBUFS; |
1856 | struct task_struct *gl_owner; | ||
1831 | 1857 | ||
1832 | spin_lock(&gl->gl_spin); | 1858 | spin_lock(&gl->gl_spin); |
1833 | 1859 | ||
@@ -1838,10 +1864,21 @@ static int dump_glock(struct glock_iter *gi, struct gfs2_glock *gl) | |||
1838 | if (test_bit(x, &gl->gl_flags)) | 1864 | if (test_bit(x, &gl->gl_flags)) |
1839 | print_dbg(gi, " %u", x); | 1865 | print_dbg(gi, " %u", x); |
1840 | } | 1866 | } |
1867 | if (!test_bit(GLF_LOCK, &gl->gl_flags)) | ||
1868 | print_dbg(gi, " (unlocked)"); | ||
1841 | print_dbg(gi, " \n"); | 1869 | print_dbg(gi, " \n"); |
1842 | print_dbg(gi, " gl_ref = %d\n", atomic_read(&gl->gl_ref)); | 1870 | print_dbg(gi, " gl_ref = %d\n", atomic_read(&gl->gl_ref)); |
1843 | print_dbg(gi, " gl_state = %u\n", gl->gl_state); | 1871 | print_dbg(gi, " gl_state = %u\n", gl->gl_state); |
1844 | print_dbg(gi, " gl_owner = %s\n", gl->gl_owner->comm); | 1872 | if (gl->gl_owner_pid) { |
1873 | gl_owner = find_task_by_pid(gl->gl_owner_pid); | ||
1874 | if (gl_owner) | ||
1875 | print_dbg(gi, " gl_owner = pid %d (%s)\n", | ||
1876 | gl->gl_owner_pid, gl_owner->comm); | ||
1877 | else | ||
1878 | print_dbg(gi, " gl_owner = %d (ended)\n", | ||
1879 | gl->gl_owner_pid); | ||
1880 | } else | ||
1881 | print_dbg(gi, " gl_owner = -1\n"); | ||
1845 | print_dbg(gi, " gl_ip = %lu\n", gl->gl_ip); | 1882 | print_dbg(gi, " gl_ip = %lu\n", gl->gl_ip); |
1846 | print_dbg(gi, " req_gh = %s\n", (gl->gl_req_gh) ? "yes" : "no"); | 1883 | print_dbg(gi, " req_gh = %s\n", (gl->gl_req_gh) ? "yes" : "no"); |
1847 | print_dbg(gi, " req_bh = %s\n", (gl->gl_req_bh) ? "yes" : "no"); | 1884 | print_dbg(gi, " req_bh = %s\n", (gl->gl_req_bh) ? "yes" : "no"); |
diff --git a/fs/gfs2/glock.h b/fs/gfs2/glock.h index 5e662eadc6f2..11477ca3a3c0 100644 --- a/fs/gfs2/glock.h +++ b/fs/gfs2/glock.h | |||
@@ -38,7 +38,7 @@ static inline int gfs2_glock_is_locked_by_me(struct gfs2_glock *gl) | |||
38 | /* Look in glock's list of holders for one with current task as owner */ | 38 | /* Look in glock's list of holders for one with current task as owner */ |
39 | spin_lock(&gl->gl_spin); | 39 | spin_lock(&gl->gl_spin); |
40 | list_for_each_entry(gh, &gl->gl_holders, gh_list) { | 40 | list_for_each_entry(gh, &gl->gl_holders, gh_list) { |
41 | if (gh->gh_owner == current) { | 41 | if (gh->gh_owner_pid == current->pid) { |
42 | locked = 1; | 42 | locked = 1; |
43 | break; | 43 | break; |
44 | } | 44 | } |
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 9c125823d760..fdf04705906f 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h | |||
@@ -127,7 +127,7 @@ struct gfs2_holder { | |||
127 | struct list_head gh_list; | 127 | struct list_head gh_list; |
128 | 128 | ||
129 | struct gfs2_glock *gh_gl; | 129 | struct gfs2_glock *gh_gl; |
130 | struct task_struct *gh_owner; | 130 | pid_t gh_owner_pid; |
131 | unsigned int gh_state; | 131 | unsigned int gh_state; |
132 | unsigned gh_flags; | 132 | unsigned gh_flags; |
133 | 133 | ||
@@ -155,7 +155,7 @@ struct gfs2_glock { | |||
155 | unsigned int gl_hash; | 155 | unsigned int gl_hash; |
156 | unsigned int gl_demote_state; /* state requested by remote node */ | 156 | unsigned int gl_demote_state; /* state requested by remote node */ |
157 | unsigned long gl_demote_time; /* time of first demote request */ | 157 | unsigned long gl_demote_time; /* time of first demote request */ |
158 | struct task_struct *gl_owner; | 158 | pid_t gl_owner_pid; |
159 | unsigned long gl_ip; | 159 | unsigned long gl_ip; |
160 | struct list_head gl_holders; | 160 | struct list_head gl_holders; |
161 | struct list_head gl_waiters1; /* HIF_MUTEX */ | 161 | struct list_head gl_waiters1; /* HIF_MUTEX */ |