aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/glock.c
diff options
context:
space:
mode:
authorRobert Peterson <rpeterso@redhat.com>2007-03-16 06:26:37 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2007-05-01 04:10:29 -0400
commit7c52b166c588c98cf3d2b2e7e6a0468a98e84d0d (patch)
tree3a38426f1479263cd75fa76204cdc1a620e7ca9f /fs/gfs2/glock.c
parentdc87c3985e9b442c60994308a96f887579addc39 (diff)
[GFS2] Add gfs2_tool lockdump support to gfs2 (bz 228540)
The attached patch resolves bz 228540. This adds the capability for gfs2 to dump gfs2 locks through the debugfs file system. This used to exist in gfs1 as "gfs_tool lockdump" but it's missing from gfs2 because all the ioctls were stripped out. Please see the bugzilla for more history about the fix. This patch is also attached to the bugzilla record. The patch is against Steve Whitehouse's latest nmw git tree kernel (2.6.21-rc1) and has been tested on system trin-10. Signed-off-by: Robert Peterson <rpeterso@redhat.com> Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/glock.c')
-rw-r--r--fs/gfs2/glock.c314
1 files changed, 251 insertions, 63 deletions
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 12accb08fe02..9f203ef4da61 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -23,6 +23,8 @@
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/rwsem.h> 24#include <linux/rwsem.h>
25#include <asm/uaccess.h> 25#include <asm/uaccess.h>
26#include <linux/seq_file.h>
27#include <linux/debugfs.h>
26 28
27#include "gfs2.h" 29#include "gfs2.h"
28#include "incore.h" 30#include "incore.h"
@@ -40,14 +42,22 @@ struct gfs2_gl_hash_bucket {
40 struct hlist_head hb_list; 42 struct hlist_head hb_list;
41}; 43};
42 44
45struct glock_iter {
46 int hash; /* hash bucket index */
47 struct gfs2_sbd *sdp; /* incore superblock */
48 struct gfs2_glock *gl; /* current glock struct */
49 struct hlist_head *hb_list; /* current hash bucket ptr */
50 struct seq_file *seq; /* sequence file for debugfs */
51 char string[512]; /* scratch space */
52};
53
43typedef void (*glock_examiner) (struct gfs2_glock * gl); 54typedef void (*glock_examiner) (struct gfs2_glock * gl);
44 55
45static int gfs2_dump_lockstate(struct gfs2_sbd *sdp); 56static int gfs2_dump_lockstate(struct gfs2_sbd *sdp);
46static int dump_glock(struct gfs2_glock *gl);
47static int dump_inode(struct gfs2_inode *ip);
48static void gfs2_glock_xmote_th(struct gfs2_holder *gh); 57static void gfs2_glock_xmote_th(struct gfs2_holder *gh);
49static void gfs2_glock_drop_th(struct gfs2_glock *gl); 58static void gfs2_glock_drop_th(struct gfs2_glock *gl);
50static DECLARE_RWSEM(gfs2_umount_flush_sem); 59static DECLARE_RWSEM(gfs2_umount_flush_sem);
60static struct dentry *gfs2_root;
51 61
52#define GFS2_GL_HASH_SHIFT 15 62#define GFS2_GL_HASH_SHIFT 15
53#define GFS2_GL_HASH_SIZE (1 << GFS2_GL_HASH_SHIFT) 63#define GFS2_GL_HASH_SIZE (1 << GFS2_GL_HASH_SHIFT)
@@ -1109,6 +1119,20 @@ find_holder_by_owner(struct list_head *head, struct task_struct *owner)
1109 return NULL; 1119 return NULL;
1110} 1120}
1111 1121
1122static void print_dbg(struct glock_iter *gi, const char *fmt, ...)
1123{
1124 va_list args;
1125
1126 va_start(args, fmt);
1127 if (gi) {
1128 vsprintf(gi->string, fmt, args);
1129 seq_printf(gi->seq, gi->string);
1130 }
1131 else
1132 vprintk(fmt, args);
1133 va_end(args);
1134}
1135
1112/** 1136/**
1113 * add_to_queue - Add a holder to the wait queue (but look for recursion) 1137 * add_to_queue - Add a holder to the wait queue (but look for recursion)
1114 * @gh: the holder structure to add 1138 * @gh: the holder structure to add
@@ -1849,31 +1873,32 @@ void gfs2_gl_hash_clear(struct gfs2_sbd *sdp, int wait)
1849 * Returns: 0 on success, -ENOBUFS when we run out of space 1873 * Returns: 0 on success, -ENOBUFS when we run out of space
1850 */ 1874 */
1851 1875
1852static int dump_holder(char *str, struct gfs2_holder *gh) 1876static int dump_holder(struct glock_iter *gi, char *str,
1877 struct gfs2_holder *gh)
1853{ 1878{
1854 unsigned int x; 1879 unsigned int x;
1855 int error = -ENOBUFS;
1856 1880
1857 printk(KERN_INFO " %s\n", str); 1881 print_dbg(gi, " %s\n", str);
1858 printk(KERN_INFO " owner = %ld\n", 1882 print_dbg(gi, " owner = %ld\n",
1859 (gh->gh_owner) ? (long)gh->gh_owner->pid : -1); 1883 (gh->gh_owner) ? (long)gh->gh_owner->pid : -1);
1860 printk(KERN_INFO " gh_state = %u\n", gh->gh_state); 1884 print_dbg(gi, " gh_state = %u\n", gh->gh_state);
1861 printk(KERN_INFO " gh_flags ="); 1885 print_dbg(gi, " gh_flags =");
1862 for (x = 0; x < 32; x++) 1886 for (x = 0; x < 32; x++)
1863 if (gh->gh_flags & (1 << x)) 1887 if (gh->gh_flags & (1 << x))
1864 printk(" %u", x); 1888 print_dbg(gi, " %u", x);
1865 printk(" \n"); 1889 print_dbg(gi, " \n");
1866 printk(KERN_INFO " error = %d\n", gh->gh_error); 1890 print_dbg(gi, " error = %d\n", gh->gh_error);
1867 printk(KERN_INFO " gh_iflags ="); 1891 print_dbg(gi, " gh_iflags =");
1868 for (x = 0; x < 32; x++) 1892 for (x = 0; x < 32; x++)
1869 if (test_bit(x, &gh->gh_iflags)) 1893 if (test_bit(x, &gh->gh_iflags))
1870 printk(" %u", x); 1894 print_dbg(gi, " %u", x);
1871 printk(" \n"); 1895 print_dbg(gi, " \n");
1872 print_symbol(KERN_INFO " initialized at: %s\n", gh->gh_ip); 1896 if (gi)
1873 1897 print_dbg(gi, " initialized at: 0x%x\n", gh->gh_ip);
1874 error = 0; 1898 else
1899 print_symbol(KERN_INFO " initialized at: %s\n", gh->gh_ip);
1875 1900
1876 return error; 1901 return 0;
1877} 1902}
1878 1903
1879/** 1904/**
@@ -1883,25 +1908,20 @@ static int dump_holder(char *str, struct gfs2_holder *gh)
1883 * Returns: 0 on success, -ENOBUFS when we run out of space 1908 * Returns: 0 on success, -ENOBUFS when we run out of space
1884 */ 1909 */
1885 1910
1886static int dump_inode(struct gfs2_inode *ip) 1911static int dump_inode(struct glock_iter *gi, struct gfs2_inode *ip)
1887{ 1912{
1888 unsigned int x; 1913 unsigned int x;
1889 int error = -ENOBUFS;
1890 1914
1891 printk(KERN_INFO " Inode:\n"); 1915 print_dbg(gi, " Inode:\n");
1892 printk(KERN_INFO " num = %llu %llu\n", 1916 print_dbg(gi, " num = %llu/%llu\n",
1893 (unsigned long long)ip->i_num.no_formal_ino, 1917 ip->i_num.no_formal_ino, ip->i_num.no_addr);
1894 (unsigned long long)ip->i_num.no_addr); 1918 print_dbg(gi, " type = %u\n", IF2DT(ip->i_inode.i_mode));
1895 printk(KERN_INFO " type = %u\n", IF2DT(ip->i_inode.i_mode)); 1919 print_dbg(gi, " i_flags =");
1896 printk(KERN_INFO " i_flags =");
1897 for (x = 0; x < 32; x++) 1920 for (x = 0; x < 32; x++)
1898 if (test_bit(x, &ip->i_flags)) 1921 if (test_bit(x, &ip->i_flags))
1899 printk(" %u", x); 1922 print_dbg(gi, " %u", x);
1900 printk(" \n"); 1923 print_dbg(gi, " \n");
1901 1924 return 0;
1902 error = 0;
1903
1904 return error;
1905} 1925}
1906 1926
1907/** 1927/**
@@ -1912,7 +1932,7 @@ static int dump_inode(struct gfs2_inode *ip)
1912 * Returns: 0 on success, -ENOBUFS when we run out of space 1932 * Returns: 0 on success, -ENOBUFS when we run out of space
1913 */ 1933 */
1914 1934
1915static int dump_glock(struct gfs2_glock *gl) 1935static int dump_glock(struct glock_iter *gi, struct gfs2_glock *gl)
1916{ 1936{
1917 struct gfs2_holder *gh; 1937 struct gfs2_holder *gh;
1918 unsigned int x; 1938 unsigned int x;
@@ -1920,66 +1940,66 @@ static int dump_glock(struct gfs2_glock *gl)
1920 1940
1921 spin_lock(&gl->gl_spin); 1941 spin_lock(&gl->gl_spin);
1922 1942
1923 printk(KERN_INFO "Glock 0x%p (%u, %llu)\n", gl, gl->gl_name.ln_type, 1943 print_dbg(gi, "Glock 0x%p (%u, %llu)\n", gl, gl->gl_name.ln_type,
1924 (unsigned long long)gl->gl_name.ln_number); 1944 (unsigned long long)gl->gl_name.ln_number);
1925 printk(KERN_INFO " gl_flags ="); 1945 print_dbg(gi, " gl_flags =");
1926 for (x = 0; x < 32; x++) { 1946 for (x = 0; x < 32; x++) {
1927 if (test_bit(x, &gl->gl_flags)) 1947 if (test_bit(x, &gl->gl_flags))
1928 printk(" %u", x); 1948 print_dbg(gi, " %u", x);
1929 } 1949 }
1930 printk(" \n"); 1950 print_dbg(gi, " \n");
1931 printk(KERN_INFO " gl_ref = %d\n", atomic_read(&gl->gl_ref)); 1951 print_dbg(gi, " gl_ref = %d\n", atomic_read(&gl->gl_ref));
1932 printk(KERN_INFO " gl_state = %u\n", gl->gl_state); 1952 print_dbg(gi, " gl_state = %u\n", gl->gl_state);
1933 printk(KERN_INFO " gl_owner = %s\n", gl->gl_owner->comm); 1953 print_dbg(gi, " gl_owner = %s\n", gl->gl_owner->comm);
1934 print_symbol(KERN_INFO " gl_ip = %s\n", gl->gl_ip); 1954 print_dbg(gi, " gl_ip = %lu\n", gl->gl_ip);
1935 printk(KERN_INFO " req_gh = %s\n", (gl->gl_req_gh) ? "yes" : "no"); 1955 print_dbg(gi, " req_gh = %s\n", (gl->gl_req_gh) ? "yes" : "no");
1936 printk(KERN_INFO " req_bh = %s\n", (gl->gl_req_bh) ? "yes" : "no"); 1956 print_dbg(gi, " req_bh = %s\n", (gl->gl_req_bh) ? "yes" : "no");
1937 printk(KERN_INFO " lvb_count = %d\n", atomic_read(&gl->gl_lvb_count)); 1957 print_dbg(gi, " lvb_count = %d\n", atomic_read(&gl->gl_lvb_count));
1938 printk(KERN_INFO " object = %s\n", (gl->gl_object) ? "yes" : "no"); 1958 print_dbg(gi, " object = %s\n", (gl->gl_object) ? "yes" : "no");
1939 printk(KERN_INFO " le = %s\n", 1959 print_dbg(gi, " le = %s\n",
1940 (list_empty(&gl->gl_le.le_list)) ? "no" : "yes"); 1960 (list_empty(&gl->gl_le.le_list)) ? "no" : "yes");
1941 printk(KERN_INFO " reclaim = %s\n", 1961 print_dbg(gi, " reclaim = %s\n",
1942 (list_empty(&gl->gl_reclaim)) ? "no" : "yes"); 1962 (list_empty(&gl->gl_reclaim)) ? "no" : "yes");
1943 if (gl->gl_aspace) 1963 if (gl->gl_aspace)
1944 printk(KERN_INFO " aspace = 0x%p nrpages = %lu\n", gl->gl_aspace, 1964 print_dbg(gi, " aspace = 0x%p nrpages = %lu\n", gl->gl_aspace,
1945 gl->gl_aspace->i_mapping->nrpages); 1965 gl->gl_aspace->i_mapping->nrpages);
1946 else 1966 else
1947 printk(KERN_INFO " aspace = no\n"); 1967 print_dbg(gi, " aspace = no\n");
1948 printk(KERN_INFO " ail = %d\n", atomic_read(&gl->gl_ail_count)); 1968 print_dbg(gi, " ail = %d\n", atomic_read(&gl->gl_ail_count));
1949 if (gl->gl_req_gh) { 1969 if (gl->gl_req_gh) {
1950 error = dump_holder("Request", gl->gl_req_gh); 1970 error = dump_holder(gi, "Request", gl->gl_req_gh);
1951 if (error) 1971 if (error)
1952 goto out; 1972 goto out;
1953 } 1973 }
1954 list_for_each_entry(gh, &gl->gl_holders, gh_list) { 1974 list_for_each_entry(gh, &gl->gl_holders, gh_list) {
1955 error = dump_holder("Holder", gh); 1975 error = dump_holder(gi, "Holder", gh);
1956 if (error) 1976 if (error)
1957 goto out; 1977 goto out;
1958 } 1978 }
1959 list_for_each_entry(gh, &gl->gl_waiters1, gh_list) { 1979 list_for_each_entry(gh, &gl->gl_waiters1, gh_list) {
1960 error = dump_holder("Waiter1", gh); 1980 error = dump_holder(gi, "Waiter1", gh);
1961 if (error) 1981 if (error)
1962 goto out; 1982 goto out;
1963 } 1983 }
1964 list_for_each_entry(gh, &gl->gl_waiters2, gh_list) { 1984 list_for_each_entry(gh, &gl->gl_waiters2, gh_list) {
1965 error = dump_holder("Waiter2", gh); 1985 error = dump_holder(gi, "Waiter2", gh);
1966 if (error) 1986 if (error)
1967 goto out; 1987 goto out;
1968 } 1988 }
1969 list_for_each_entry(gh, &gl->gl_waiters3, gh_list) { 1989 list_for_each_entry(gh, &gl->gl_waiters3, gh_list) {
1970 error = dump_holder("Waiter3", gh); 1990 error = dump_holder(gi, "Waiter3", gh);
1971 if (error) 1991 if (error)
1972 goto out; 1992 goto out;
1973 } 1993 }
1974 if (gl->gl_ops == &gfs2_inode_glops && gl->gl_object) { 1994 if (gl->gl_ops == &gfs2_inode_glops && gl->gl_object) {
1975 if (!test_bit(GLF_LOCK, &gl->gl_flags) && 1995 if (!test_bit(GLF_LOCK, &gl->gl_flags) &&
1976 list_empty(&gl->gl_holders)) { 1996 list_empty(&gl->gl_holders)) {
1977 error = dump_inode(gl->gl_object); 1997 error = dump_inode(gi, gl->gl_object);
1978 if (error) 1998 if (error)
1979 goto out; 1999 goto out;
1980 } else { 2000 } else {
1981 error = -ENOBUFS; 2001 error = -ENOBUFS;
1982 printk(KERN_INFO " Inode: busy\n"); 2002 print_dbg(gi, " Inode: busy\n");
1983 } 2003 }
1984 } 2004 }
1985 2005
@@ -2014,7 +2034,7 @@ static int gfs2_dump_lockstate(struct gfs2_sbd *sdp)
2014 if (gl->gl_sbd != sdp) 2034 if (gl->gl_sbd != sdp)
2015 continue; 2035 continue;
2016 2036
2017 error = dump_glock(gl); 2037 error = dump_glock(NULL, gl);
2018 if (error) 2038 if (error)
2019 break; 2039 break;
2020 } 2040 }
@@ -2043,3 +2063,171 @@ int __init gfs2_glock_init(void)
2043 return 0; 2063 return 0;
2044} 2064}
2045 2065
2066static int gfs2_glock_iter_next(struct glock_iter *gi)
2067{
2068 while (1) {
2069 if (!gi->hb_list) { /* If we don't have a hash bucket yet */
2070 gi->hb_list = &gl_hash_table[gi->hash].hb_list;
2071 if (hlist_empty(gi->hb_list)) {
2072 gi->hash++;
2073 gi->hb_list = NULL;
2074 if (gi->hash >= GFS2_GL_HASH_SIZE)
2075 return 1;
2076 else
2077 continue;
2078 }
2079 if (!hlist_empty(gi->hb_list)) {
2080 gi->gl = list_entry(gi->hb_list->first,
2081 struct gfs2_glock,
2082 gl_list);
2083 }
2084 } else {
2085 if (gi->gl->gl_list.next == NULL) {
2086 gi->hash++;
2087 gi->hb_list = NULL;
2088 continue;
2089 }
2090 gi->gl = list_entry(gi->gl->gl_list.next,
2091 struct gfs2_glock, gl_list);
2092 }
2093 if (gi->gl)
2094 break;
2095 }
2096 return 0;
2097}
2098
2099static void gfs2_glock_iter_free(struct glock_iter *gi)
2100{
2101 kfree(gi);
2102}
2103
2104static struct glock_iter *gfs2_glock_iter_init(struct gfs2_sbd *sdp)
2105{
2106 struct glock_iter *gi;
2107
2108 gi = kmalloc(sizeof (*gi), GFP_KERNEL);
2109 if (!gi)
2110 return NULL;
2111
2112 gi->sdp = sdp;
2113 gi->hash = 0;
2114 gi->gl = NULL;
2115 gi->hb_list = NULL;
2116 gi->seq = NULL;
2117 memset(gi->string, 0, sizeof(gi->string));
2118
2119 if (gfs2_glock_iter_next(gi)) {
2120 gfs2_glock_iter_free(gi);
2121 return NULL;
2122 }
2123
2124 return gi;
2125}
2126
2127static void *gfs2_glock_seq_start(struct seq_file *file, loff_t *pos)
2128{
2129 struct glock_iter *gi;
2130 loff_t n = *pos;
2131
2132 gi = gfs2_glock_iter_init(file->private);
2133 if (!gi)
2134 return NULL;
2135
2136 while (n--) {
2137 if (gfs2_glock_iter_next(gi)) {
2138 gfs2_glock_iter_free(gi);
2139 return NULL;
2140 }
2141 }
2142
2143 return gi;
2144}
2145
2146static void *gfs2_glock_seq_next(struct seq_file *file, void *iter_ptr,
2147 loff_t *pos)
2148{
2149 struct glock_iter *gi = iter_ptr;
2150
2151 (*pos)++;
2152
2153 if (gfs2_glock_iter_next(gi)) {
2154 gfs2_glock_iter_free(gi);
2155 return NULL;
2156 }
2157
2158 return gi;
2159}
2160
2161static void gfs2_glock_seq_stop(struct seq_file *file, void *iter_ptr)
2162{
2163 /* nothing for now */
2164}
2165
2166static int gfs2_glock_seq_show(struct seq_file *file, void *iter_ptr)
2167{
2168 struct glock_iter *gi = iter_ptr;
2169
2170 gi->seq = file;
2171 dump_glock(gi, gi->gl);
2172
2173 return 0;
2174}
2175
2176static struct seq_operations gfs2_glock_seq_ops = {
2177 .start = gfs2_glock_seq_start,
2178 .next = gfs2_glock_seq_next,
2179 .stop = gfs2_glock_seq_stop,
2180 .show = gfs2_glock_seq_show,
2181};
2182
2183static int gfs2_debugfs_open(struct inode *inode, struct file *file)
2184{
2185 struct seq_file *seq;
2186 int ret;
2187
2188 ret = seq_open(file, &gfs2_glock_seq_ops);
2189 if (ret)
2190 return ret;
2191
2192 seq = file->private_data;
2193 seq->private = inode->i_private;
2194
2195 return 0;
2196}
2197
2198static const struct file_operations gfs2_debug_fops = {
2199 .owner = THIS_MODULE,
2200 .open = gfs2_debugfs_open,
2201 .read = seq_read,
2202 .llseek = seq_lseek,
2203 .release = seq_release
2204};
2205
2206int gfs2_create_debugfs_file(struct gfs2_sbd *sdp)
2207{
2208 sdp->debugfs_dentry = debugfs_create_file(sdp->sd_table_name,
2209 S_IFREG | S_IRUGO,
2210 gfs2_root, sdp,
2211 &gfs2_debug_fops);
2212 if (!sdp->debugfs_dentry)
2213 return -ENOMEM;
2214
2215 return 0;
2216}
2217
2218void gfs2_delete_debugfs_file(struct gfs2_sbd *sdp)
2219{
2220 if (sdp->debugfs_dentry)
2221 debugfs_remove(sdp->debugfs_dentry);
2222}
2223
2224int gfs2_register_debugfs(void)
2225{
2226 gfs2_root = debugfs_create_dir("gfs2", NULL);
2227 return gfs2_root ? 0 : -ENOMEM;
2228}
2229
2230void gfs2_unregister_debugfs(void)
2231{
2232 debugfs_remove(gfs2_root);
2233}