Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 152978 Details for
Bug 228540
Need to add gfs2_tool lockdump support to gfs2
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
Master patch against 2.6.18-15.el5
lockdump.2.6.18-15.el5.patch (text/plain), 22.87 KB, created by
Robert Peterson
on 2007-04-19 02:48:33 UTC
(
hide
)
Description:
Master patch against 2.6.18-15.el5
Filename:
MIME Type:
Creator:
Robert Peterson
Created:
2007-04-19 02:48:33 UTC
Size:
22.87 KB
patch
obsolete
>diff -pur a/fs/gfs2/glock.c b/fs/gfs2/glock.c >--- a/fs/gfs2/glock.c 2007-04-18 13:46:52.000000000 -0500 >+++ b/fs/gfs2/glock.c 2007-04-18 14:32:25.000000000 -0500 >@@ -23,6 +23,10 @@ > #include <linux/module.h> > #include <linux/rwsem.h> > #include <asm/uaccess.h> >+#include <linux/seq_file.h> >+#include <linux/debugfs.h> >+#include <linux/module.h> >+#include <linux/kallsyms.h> > > #include "gfs2.h" > #include "incore.h" >@@ -40,11 +44,19 @@ struct gfs2_gl_hash_bucket { > struct hlist_head hb_list; > }; > >+struct glock_iter { >+ int hash; /* hash bucket index */ >+ struct gfs2_sbd *sdp; /* incore superblock */ >+ struct gfs2_glock *gl; /* current glock struct */ >+ struct hlist_head *hb_list; /* current hash bucket ptr */ >+ struct seq_file *seq; /* sequence file for debugfs */ >+ char string[512]; /* scratch space */ >+}; >+ > typedef void (*glock_examiner) (struct gfs2_glock * gl); > > static int gfs2_dump_lockstate(struct gfs2_sbd *sdp); >-static int dump_glock(struct gfs2_glock *gl); >-static int dump_inode(struct gfs2_inode *ip); >+static int dump_glock(struct glock_iter *gi, struct gfs2_glock *gl); > static void gfs2_glock_xmote_th(struct gfs2_holder *gh); > static void gfs2_glock_drop_th(struct gfs2_glock *gl); > static DECLARE_RWSEM(gfs2_umount_flush_sem); >@@ -54,6 +66,7 @@ static DECLARE_RWSEM(gfs2_umount_flush_s > #define GFS2_GL_HASH_MASK (GFS2_GL_HASH_SIZE - 1) > > static struct gfs2_gl_hash_bucket gl_hash_table[GFS2_GL_HASH_SIZE]; >+static struct dentry *gfs2_root; > > /* > * Despite what you might think, the numbers below are not arbitrary :-) >@@ -303,7 +316,7 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, > atomic_set(&gl->gl_ref, 1); > gl->gl_state = LM_ST_UNLOCKED; > gl->gl_hash = hash; >- gl->gl_owner = NULL; >+ gl->gl_owner_pid = 0; > gl->gl_ip = 0; > gl->gl_ops = glops; > gl->gl_req_gh = NULL; >@@ -367,7 +380,7 @@ void gfs2_holder_init(struct gfs2_glock > INIT_LIST_HEAD(&gh->gh_list); > gh->gh_gl = gl; > gh->gh_ip = (unsigned long)__builtin_return_address(0); >- gh->gh_owner = current; >+ gh->gh_owner_pid = current->pid; > gh->gh_state = state; > gh->gh_flags = flags; > gh->gh_error = 0; >@@ -654,7 +667,7 @@ static void gfs2_glmutex_lock(struct gfs > if (test_and_set_bit(GLF_LOCK, &gl->gl_flags)) { > list_add_tail(&gh.gh_list, &gl->gl_waiters1); > } else { >- gl->gl_owner = current; >+ gl->gl_owner_pid = current->pid; > gl->gl_ip = (unsigned long)__builtin_return_address(0); > clear_bit(HIF_WAIT, &gh.gh_iflags); > smp_mb(); >@@ -681,7 +694,7 @@ static int gfs2_glmutex_trylock(struct g > if (test_and_set_bit(GLF_LOCK, &gl->gl_flags)) { > acquired = 0; > } else { >- gl->gl_owner = current; >+ gl->gl_owner_pid = current->pid; > gl->gl_ip = (unsigned long)__builtin_return_address(0); > } > spin_unlock(&gl->gl_spin); >@@ -699,7 +712,7 @@ static void gfs2_glmutex_unlock(struct g > { > spin_lock(&gl->gl_spin); > clear_bit(GLF_LOCK, &gl->gl_flags); >- gl->gl_owner = NULL; >+ gl->gl_owner_pid = 0; > gl->gl_ip = 0; > run_queue(gl); > BUG_ON(!spin_is_locked(&gl->gl_spin)); >@@ -1097,18 +1110,32 @@ static int glock_wait_internal(struct gf > } > > static inline struct gfs2_holder * >-find_holder_by_owner(struct list_head *head, struct task_struct *owner) >+find_holder_by_owner(struct list_head *head, pid_t pid) > { > struct gfs2_holder *gh; > > list_for_each_entry(gh, head, gh_list) { >- if (gh->gh_owner == owner) >+ if (gh->gh_owner_pid == pid) > return gh; > } > > return NULL; > } > >+static void print_dbg(struct glock_iter *gi, const char *fmt, ...) >+{ >+ va_list args; >+ >+ va_start(args, fmt); >+ if (gi) { >+ vsprintf(gi->string, fmt, args); >+ seq_printf(gi->seq, gi->string); >+ } >+ else >+ vprintk(fmt, args); >+ va_end(args); >+} >+ > /** > * add_to_queue - Add a holder to the wait queue (but look for recursion) > * @gh: the holder structure to add >@@ -1120,24 +1147,24 @@ static void add_to_queue(struct gfs2_hol > struct gfs2_glock *gl = gh->gh_gl; > struct gfs2_holder *existing; > >- BUG_ON(!gh->gh_owner); >+ BUG_ON(!gh->gh_owner_pid); > if (test_and_set_bit(HIF_WAIT, &gh->gh_iflags)) > BUG(); > >- existing = find_holder_by_owner(&gl->gl_holders, gh->gh_owner); >+ existing = find_holder_by_owner(&gl->gl_holders, gh->gh_owner_pid); > if (existing) { > print_symbol(KERN_WARNING "original: %s\n", existing->gh_ip); >- printk(KERN_INFO "pid : %d\n", existing->gh_owner->pid); >+ printk(KERN_INFO "pid : %d\n", existing->gh_owner_pid); > printk(KERN_INFO "lock type : %d lock state : %d\n", > existing->gh_gl->gl_name.ln_type, existing->gh_gl->gl_state); > print_symbol(KERN_WARNING "new: %s\n", gh->gh_ip); >- printk(KERN_INFO "pid : %d\n", gh->gh_owner->pid); >+ printk(KERN_INFO "pid : %d\n", gh->gh_owner_pid); > printk(KERN_INFO "lock type : %d lock state : %d\n", > gl->gl_name.ln_type, gl->gl_state); > BUG(); > } > >- existing = find_holder_by_owner(&gl->gl_waiters3, gh->gh_owner); >+ existing = find_holder_by_owner(&gl->gl_waiters3, gh->gh_owner_pid); > if (existing) { > print_symbol(KERN_WARNING "original: %s\n", existing->gh_ip); > print_symbol(KERN_WARNING "new: %s\n", gh->gh_ip); >@@ -1841,6 +1868,15 @@ void gfs2_gl_hash_clear(struct gfs2_sbd > * Diagnostic routines to help debug distributed deadlock > */ > >+static void gfs2_print_symbol(struct glock_iter *gi, const char *fmt, >+ unsigned long address) >+{ >+ char buffer[KSYM_SYMBOL_LEN]; >+ >+ sprint_symbol(buffer, address); >+ print_dbg(gi, fmt, buffer); >+} >+ > /** > * dump_holder - print information about a glock holder > * @str: a string naming the type of holder >@@ -1849,31 +1885,37 @@ void gfs2_gl_hash_clear(struct gfs2_sbd > * Returns: 0 on success, -ENOBUFS when we run out of space > */ > >-static int dump_holder(char *str, struct gfs2_holder *gh) >+static int dump_holder(struct glock_iter *gi, char *str, >+ struct gfs2_holder *gh) > { > unsigned int x; >- int error = -ENOBUFS; >+ struct task_struct *gh_owner; > >- printk(KERN_INFO " %s\n", str); >- printk(KERN_INFO " owner = %ld\n", >- (gh->gh_owner) ? (long)gh->gh_owner->pid : -1); >- printk(KERN_INFO " gh_state = %u\n", gh->gh_state); >- printk(KERN_INFO " gh_flags ="); >+ print_dbg(gi, " %s\n", str); >+ if (gh->gh_owner_pid) { >+ print_dbg(gi, " owner = %ld ", (long)gh->gh_owner_pid); >+ gh_owner = find_task_by_pid(gh->gh_owner_pid); >+ if (gh_owner) >+ print_dbg(gi, "(%s)\n", gh_owner->comm); >+ else >+ print_dbg(gi, "(ended)\n"); >+ } else >+ print_dbg(gi, " owner = -1\n"); >+ print_dbg(gi, " gh_state = %u\n", gh->gh_state); >+ print_dbg(gi, " gh_flags ="); > for (x = 0; x < 32; x++) > if (gh->gh_flags & (1 << x)) >- printk(" %u", x); >- printk(" \n"); >- printk(KERN_INFO " error = %d\n", gh->gh_error); >- printk(KERN_INFO " gh_iflags ="); >+ print_dbg(gi, " %u", x); >+ print_dbg(gi, " \n"); >+ print_dbg(gi, " error = %d\n", gh->gh_error); >+ print_dbg(gi, " gh_iflags ="); > for (x = 0; x < 32; x++) > if (test_bit(x, &gh->gh_iflags)) >- printk(" %u", x); >- printk(" \n"); >- print_symbol(KERN_INFO " initialized at: %s\n", gh->gh_ip); >- >- error = 0; >+ print_dbg(gi, " %u", x); >+ print_dbg(gi, " \n"); >+ gfs2_print_symbol(gi, " initialized at: %s\n", gh->gh_ip); > >- return error; >+ return 0; > } > > /** >@@ -1883,25 +1925,20 @@ static int dump_holder(char *str, struct > * Returns: 0 on success, -ENOBUFS when we run out of space > */ > >-static int dump_inode(struct gfs2_inode *ip) >+static int dump_inode(struct glock_iter *gi, struct gfs2_inode *ip) > { > unsigned int x; >- int error = -ENOBUFS; > >- printk(KERN_INFO " Inode:\n"); >- printk(KERN_INFO " num = %llu %llu\n", >- (unsigned long long)ip->i_num.no_formal_ino, >- (unsigned long long)ip->i_num.no_addr); >- printk(KERN_INFO " type = %u\n", IF2DT(ip->i_inode.i_mode)); >- printk(KERN_INFO " i_flags ="); >+ print_dbg(gi, " Inode:\n"); >+ print_dbg(gi, " num = %llu/%llu\n", >+ ip->i_num.no_formal_ino, ip->i_num.no_addr); >+ print_dbg(gi, " type = %u\n", IF2DT(ip->i_inode.i_mode)); >+ print_dbg(gi, " i_flags ="); > for (x = 0; x < 32; x++) > if (test_bit(x, &ip->i_flags)) >- printk(" %u", x); >- printk(" \n"); >- >- error = 0; >- >- return error; >+ print_dbg(gi, " %u", x); >+ print_dbg(gi, " \n"); >+ return 0; > } > > /** >@@ -1912,74 +1949,86 @@ static int dump_inode(struct gfs2_inode > * Returns: 0 on success, -ENOBUFS when we run out of space > */ > >-static int dump_glock(struct gfs2_glock *gl) >+static int dump_glock(struct glock_iter *gi, struct gfs2_glock *gl) > { > struct gfs2_holder *gh; > unsigned int x; > int error = -ENOBUFS; >+ struct task_struct *gl_owner; > > spin_lock(&gl->gl_spin); > >- printk(KERN_INFO "Glock 0x%p (%u, %llu)\n", gl, gl->gl_name.ln_type, >- (unsigned long long)gl->gl_name.ln_number); >- printk(KERN_INFO " gl_flags ="); >+ print_dbg(gi, "Glock 0x%p (%u, %llu)\n", gl, gl->gl_name.ln_type, >+ (unsigned long long)gl->gl_name.ln_number); >+ print_dbg(gi, " gl_flags ="); > for (x = 0; x < 32; x++) { > if (test_bit(x, &gl->gl_flags)) >- printk(" %u", x); >+ print_dbg(gi, " %u", x); > } >- printk(" \n"); >- printk(KERN_INFO " gl_ref = %d\n", atomic_read(&gl->gl_ref)); >- printk(KERN_INFO " gl_state = %u\n", gl->gl_state); >- printk(KERN_INFO " gl_owner = %s\n", gl->gl_owner->comm); >- print_symbol(KERN_INFO " gl_ip = %s\n", gl->gl_ip); >- printk(KERN_INFO " req_gh = %s\n", (gl->gl_req_gh) ? "yes" : "no"); >- printk(KERN_INFO " req_bh = %s\n", (gl->gl_req_bh) ? "yes" : "no"); >- printk(KERN_INFO " lvb_count = %d\n", atomic_read(&gl->gl_lvb_count)); >- printk(KERN_INFO " object = %s\n", (gl->gl_object) ? "yes" : "no"); >- printk(KERN_INFO " le = %s\n", >+ if (!test_bit(GLF_LOCK, &gl->gl_flags)) >+ print_dbg(gi, " (unlocked)"); >+ print_dbg(gi, " \n"); >+ print_dbg(gi, " gl_ref = %d\n", atomic_read(&gl->gl_ref)); >+ print_dbg(gi, " gl_state = %u\n", gl->gl_state); >+ if (gl->gl_owner_pid) { >+ gl_owner = find_task_by_pid(gl->gl_owner_pid); >+ if (gl_owner) >+ print_dbg(gi, " gl_owner = pid %d (%s)\n", >+ gl->gl_owner_pid, gl_owner->comm); >+ else >+ print_dbg(gi, " gl_owner = %d (ended)\n", >+ gl->gl_owner_pid); >+ } else >+ print_dbg(gi, " gl_owner = -1\n"); >+ print_dbg(gi, " gl_ip = %lu\n", gl->gl_ip); >+ print_dbg(gi, " req_gh = %s\n", (gl->gl_req_gh) ? "yes" : "no"); >+ print_dbg(gi, " req_bh = %s\n", (gl->gl_req_bh) ? "yes" : "no"); >+ print_dbg(gi, " lvb_count = %d\n", atomic_read(&gl->gl_lvb_count)); >+ print_dbg(gi, " object = %s\n", (gl->gl_object) ? "yes" : "no"); >+ print_dbg(gi, " le = %s\n", > (list_empty(&gl->gl_le.le_list)) ? "no" : "yes"); >- printk(KERN_INFO " reclaim = %s\n", >- (list_empty(&gl->gl_reclaim)) ? "no" : "yes"); >+ print_dbg(gi, " reclaim = %s\n", >+ (list_empty(&gl->gl_reclaim)) ? "no" : "yes"); > if (gl->gl_aspace) >- printk(KERN_INFO " aspace = 0x%p nrpages = %lu\n", gl->gl_aspace, >- gl->gl_aspace->i_mapping->nrpages); >+ print_dbg(gi, " aspace = 0x%p nrpages = %lu\n", gl->gl_aspace, >+ gl->gl_aspace->i_mapping->nrpages); > else >- printk(KERN_INFO " aspace = no\n"); >- printk(KERN_INFO " ail = %d\n", atomic_read(&gl->gl_ail_count)); >+ print_dbg(gi, " aspace = no\n"); >+ print_dbg(gi, " ail = %d\n", atomic_read(&gl->gl_ail_count)); > if (gl->gl_req_gh) { >- error = dump_holder("Request", gl->gl_req_gh); >+ error = dump_holder(gi, "Request", gl->gl_req_gh); > if (error) > goto out; > } > list_for_each_entry(gh, &gl->gl_holders, gh_list) { >- error = dump_holder("Holder", gh); >+ error = dump_holder(gi, "Holder", gh); > if (error) > goto out; > } > list_for_each_entry(gh, &gl->gl_waiters1, gh_list) { >- error = dump_holder("Waiter1", gh); >- if (error) >- goto out; >- } >- list_for_each_entry(gh, &gl->gl_waiters2, gh_list) { >- error = dump_holder("Waiter2", gh); >+ error = dump_holder(gi, "Waiter1", gh); > if (error) > goto out; > } > list_for_each_entry(gh, &gl->gl_waiters3, gh_list) { >- error = dump_holder("Waiter3", gh); >+ error = dump_holder(gi, "Waiter3", gh); > if (error) > goto out; > } >+ if (test_bit(GLF_DEMOTE, &gl->gl_flags)) { >+ print_dbg(gi, " Demotion req to state %u (%llu uS ago)\n", >+ gl->gl_demote_state, >+ (u64)(jiffies - gl->gl_demote_time)*(1000000/HZ)); >+ } > if (gl->gl_ops == &gfs2_inode_glops && gl->gl_object) { > if (!test_bit(GLF_LOCK, &gl->gl_flags) && >- list_empty(&gl->gl_holders)) { >- error = dump_inode(gl->gl_object); >+ list_empty(&gl->gl_holders)) { >+ error = dump_inode(gi, gl->gl_object); > if (error) > goto out; > } else { > error = -ENOBUFS; >- printk(KERN_INFO " Inode: busy\n"); >+ print_dbg(gi, " Inode: busy\n"); > } > } > >@@ -2014,7 +2063,7 @@ static int gfs2_dump_lockstate(struct gf > if (gl->gl_sbd != sdp) > continue; > >- error = dump_glock(gl); >+ error = dump_glock(NULL, gl); > if (error) > break; > } >@@ -2043,3 +2092,189 @@ int __init gfs2_glock_init(void) > return 0; > } > >+static int gfs2_glock_iter_next(struct glock_iter *gi) >+{ >+ read_lock(gl_lock_addr(gi->hash)); >+ while (1) { >+ if (!gi->hb_list) { /* If we don't have a hash bucket yet */ >+ gi->hb_list = &gl_hash_table[gi->hash].hb_list; >+ if (hlist_empty(gi->hb_list)) { >+ read_unlock(gl_lock_addr(gi->hash)); >+ gi->hash++; >+ read_lock(gl_lock_addr(gi->hash)); >+ gi->hb_list = NULL; >+ if (gi->hash >= GFS2_GL_HASH_SIZE) { >+ read_unlock(gl_lock_addr(gi->hash)); >+ return 1; >+ } >+ else >+ continue; >+ } >+ if (!hlist_empty(gi->hb_list)) { >+ gi->gl = list_entry(gi->hb_list->first, >+ struct gfs2_glock, >+ gl_list); >+ } >+ } else { >+ if (gi->gl->gl_list.next == NULL) { >+ read_unlock(gl_lock_addr(gi->hash)); >+ gi->hash++; >+ read_lock(gl_lock_addr(gi->hash)); >+ gi->hb_list = NULL; >+ continue; >+ } >+ gi->gl = list_entry(gi->gl->gl_list.next, >+ struct gfs2_glock, gl_list); >+ } >+ if (gi->gl) >+ break; >+ } >+ read_unlock(gl_lock_addr(gi->hash)); >+ return 0; >+} >+ >+static void gfs2_glock_iter_free(struct glock_iter *gi) >+{ >+ kfree(gi); >+} >+ >+static struct glock_iter *gfs2_glock_iter_init(struct gfs2_sbd *sdp) >+{ >+ struct glock_iter *gi; >+ >+ gi = kmalloc(sizeof (*gi), GFP_KERNEL); >+ if (!gi) >+ return NULL; >+ >+ gi->sdp = sdp; >+ gi->hash = 0; >+ gi->gl = NULL; >+ gi->hb_list = NULL; >+ gi->seq = NULL; >+ memset(gi->string, 0, sizeof(gi->string)); >+ >+ if (gfs2_glock_iter_next(gi)) { >+ gfs2_glock_iter_free(gi); >+ return NULL; >+ } >+ >+ return gi; >+} >+ >+static void *gfs2_glock_seq_start(struct seq_file *file, loff_t *pos) >+{ >+ struct glock_iter *gi; >+ loff_t n = *pos; >+ >+ gi = gfs2_glock_iter_init(file->private); >+ if (!gi) >+ return NULL; >+ >+ while (n--) { >+ if (gfs2_glock_iter_next(gi)) { >+ gfs2_glock_iter_free(gi); >+ return NULL; >+ } >+ } >+ >+ return gi; >+} >+ >+static void *gfs2_glock_seq_next(struct seq_file *file, void *iter_ptr, >+ loff_t *pos) >+{ >+ struct glock_iter *gi = iter_ptr; >+ >+ (*pos)++; >+ >+ if (gfs2_glock_iter_next(gi)) { >+ gfs2_glock_iter_free(gi); >+ return NULL; >+ } >+ >+ return gi; >+} >+ >+static void gfs2_glock_seq_stop(struct seq_file *file, void *iter_ptr) >+{ >+ /* nothing for now */ >+} >+ >+static int gfs2_glock_seq_show(struct seq_file *file, void *iter_ptr) >+{ >+ struct glock_iter *gi = iter_ptr; >+ >+ gi->seq = file; >+ dump_glock(gi, gi->gl); >+ >+ return 0; >+} >+ >+static struct seq_operations gfs2_glock_seq_ops = { >+ .start = gfs2_glock_seq_start, >+ .next = gfs2_glock_seq_next, >+ .stop = gfs2_glock_seq_stop, >+ .show = gfs2_glock_seq_show, >+}; >+ >+static int gfs2_debugfs_open(struct inode *inode, struct file *file) >+{ >+ struct seq_file *seq; >+ int ret; >+ >+ ret = seq_open(file, &gfs2_glock_seq_ops); >+ if (ret) >+ return ret; >+ >+ seq = file->private_data; >+ seq->private = inode->i_private; >+ >+ return 0; >+} >+ >+static const struct file_operations gfs2_debug_fops = { >+ .owner = THIS_MODULE, >+ .open = gfs2_debugfs_open, >+ .read = seq_read, >+ .llseek = seq_lseek, >+ .release = seq_release >+}; >+ >+int gfs2_create_debugfs_file(struct gfs2_sbd *sdp) >+{ >+ sdp->debugfs_dir = debugfs_create_dir(sdp->sd_table_name, gfs2_root); >+ if (!sdp->debugfs_dir) >+ return -ENOMEM; >+ sdp->debugfs_dentry_glocks = debugfs_create_file("glocks", >+ S_IFREG | S_IRUGO, >+ sdp->debugfs_dir, sdp, >+ &gfs2_debug_fops); >+ if (!sdp->debugfs_dentry_glocks) >+ return -ENOMEM; >+ >+ return 0; >+} >+ >+void gfs2_delete_debugfs_file(struct gfs2_sbd *sdp) >+{ >+ if (sdp && sdp->debugfs_dir) { >+ if (sdp->debugfs_dentry_glocks) { >+ debugfs_remove(sdp->debugfs_dentry_glocks); >+ sdp->debugfs_dentry_glocks = NULL; >+ } >+ debugfs_remove(sdp->debugfs_dir); >+ sdp->debugfs_dir = NULL; >+ } >+} >+ >+int gfs2_register_debugfs(void) >+{ >+ gfs2_root = debugfs_create_dir("gfs2", NULL); >+ return gfs2_root ? 0 : -ENOMEM; >+} >+ >+void gfs2_unregister_debugfs(void) >+{ >+ debugfs_remove(gfs2_root); >+ gfs2_root = NULL; >+} >diff -pur a/fs/gfs2/glock.h b/fs/gfs2/glock.h >--- a/fs/gfs2/glock.h 2007-04-18 13:46:52.000000000 -0500 >+++ b/fs/gfs2/glock.h 2007-04-18 15:06:50.000000000 -0500 >@@ -38,7 +38,7 @@ static inline int gfs2_glock_is_locked_b > /* Look in glock's list of holders for one with current task as owner */ > spin_lock(&gl->gl_spin); > list_for_each_entry(gh, &gl->gl_holders, gh_list) { >- if (gh->gh_owner == current) { >+ if (gh->gh_owner_pid == current->pid) { > locked = 1; > break; > } >@@ -135,5 +135,9 @@ void gfs2_scand_internal(struct gfs2_sbd > void gfs2_gl_hash_clear(struct gfs2_sbd *sdp, int wait); > > int __init gfs2_glock_init(void); >+int gfs2_create_debugfs_file(struct gfs2_sbd *sdp); >+void gfs2_delete_debugfs_file(struct gfs2_sbd *sdp); >+int gfs2_register_debugfs(void); >+void gfs2_unregister_debugfs(void); > > #endif /* __GLOCK_DOT_H__ */ >diff -pur a/fs/gfs2/incore.h b/fs/gfs2/incore.h >--- a/fs/gfs2/incore.h 2007-04-18 13:46:52.000000000 -0500 >+++ b/fs/gfs2/incore.h 2007-04-18 15:38:33.000000000 -0500 >@@ -130,7 +130,7 @@ struct gfs2_holder { > struct list_head gh_list; > > struct gfs2_glock *gh_gl; >- struct task_struct *gh_owner; >+ pid_t gh_owner_pid; > unsigned int gh_state; > unsigned gh_flags; > >@@ -142,6 +142,7 @@ struct gfs2_holder { > enum { > GLF_LOCK = 1, > GLF_STICKY = 2, >+ GLF_DEMOTE = 3, > GLF_DIRTY = 5, > GLF_SKIP_WAITERS2 = 6, > }; >@@ -156,7 +157,9 @@ struct gfs2_glock { > > unsigned int gl_state; > unsigned int gl_hash; >- struct task_struct *gl_owner; >+ unsigned int gl_demote_state; /* state requested by remote node */ >+ unsigned long gl_demote_time; /* time of first demote request */ >+ pid_t gl_owner_pid; > unsigned long gl_ip; > struct list_head gl_holders; > struct list_head gl_waiters1; /* HIF_MUTEX */ >@@ -613,6 +616,8 @@ struct gfs2_sbd { > > unsigned long sd_last_warning; > struct vfsmount *sd_gfs2mnt; >+ struct dentry *debugfs_dir; /* debugfs directory */ >+ struct dentry *debugfs_dentry_glocks; /* for debugfs */ > }; > > #endif /* __INCORE_DOT_H__ */ >diff -pur a/fs/gfs2/main.c b/fs/gfs2/main.c >--- a/fs/gfs2/main.c 2007-04-18 08:55:40.000000000 -0500 >+++ b/fs/gfs2/main.c 2007-04-18 18:04:44.000000000 -0500 >@@ -104,6 +104,8 @@ static int __init init_gfs2_fs(void) > if (error) > goto fail_unregister; > >+ gfs2_register_debugfs(); >+ > printk("GFS2 (built %s %s) installed\n", __DATE__, __TIME__); > > return 0; >@@ -131,6 +133,7 @@ fail: > > static void __exit exit_gfs2_fs(void) > { >+ gfs2_unregister_debugfs(); > unregister_filesystem(&gfs2_fs_type); > unregister_filesystem(&gfs2meta_fs_type); > >diff -pur a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c >--- a/fs/gfs2/ops_fstype.c 2007-04-18 08:55:46.000000000 -0500 >+++ b/fs/gfs2/ops_fstype.c 2007-04-18 15:01:39.000000000 -0500 >@@ -705,6 +705,8 @@ static int fill_super(struct super_block > if (error) > goto fail; > >+ gfs2_create_debugfs_file(sdp); >+ > error = gfs2_sys_fs_add(sdp); > if (error) > goto fail; >@@ -769,6 +771,7 @@ fail_lm: > fail_sys: > gfs2_sys_fs_del(sdp); > fail: >+ gfs2_delete_debugfs_file(sdp); > kfree(sdp); > sb->s_fs_info = NULL; > return error; >@@ -914,6 +917,7 @@ error: > > static void gfs2_kill_sb(struct super_block *sb) > { >+ gfs2_delete_debugfs_file(sb->s_fs_info); > kill_block_super(sb); > } > >diff -pur a/include/linux/kallsyms.h b/include/linux/kallsyms.h >--- a/include/linux/kallsyms.h 2006-09-19 22:42:06.000000000 -0500 >+++ b/include/linux/kallsyms.h 2007-04-18 21:12:03.000000000 -0500 >@@ -7,6 +7,8 @@ > > > #define KSYM_NAME_LEN 127 >+#define KSYM_SYMBOL_LEN (sizeof("%s+%#lx/%#lx [%s]") + KSYM_NAME_LEN + \ >+ 2*(BITS_PER_LONG*3/10) + MODULE_NAME_LEN + 1) > > #ifdef CONFIG_KALLSYMS > /* Lookup the address for a symbol. Returns 0 if not found. */ >@@ -18,7 +20,13 @@ const char *kallsyms_lookup(unsigned lon > unsigned long *offset, > char **modname, char *namebuf); > >-/* Replace "%s" in format with address, if found */ >+/* Look up a kernel symbol and return it in a text buffer. */ >+extern int sprint_symbol(char *buffer, unsigned long address); >+ >+int lookup_symbol_name(unsigned long addr, char *symname); >+int lookup_symbol_attrs(unsigned long addr, unsigned long *size, unsigned long *offset, char *modname, char *name); >+ >+/* Look up a kernel symbol and print it to the kernel messages. */ > extern void __print_symbol(const char *fmt, unsigned long address); > > #else /* !CONFIG_KALLSYMS */ >@@ -36,6 +44,22 @@ static inline const char *kallsyms_looku > return NULL; > } > >+static inline int sprint_symbol(char *buffer, unsigned long addr) >+{ >+ *buffer = '\0'; >+ return 0; >+} >+ >+static inline int lookup_symbol_name(unsigned long addr, char *symname) >+{ >+ return -ERANGE; >+} >+ >+static inline int lookup_symbol_attrs(unsigned long addr, unsigned long *size, unsigned long *offset, char *modname, char *name) >+{ >+ return -ERANGE; >+} >++ > /* Stupid that this does nothing, but I didn't create this mess. */ > #define __print_symbol(fmt, addr) > #endif /*CONFIG_KALLSYMS*/ >diff -pur a/kernel/kallsyms.c b/kernel/kallsyms.c >--- a/kernel/kallsyms.c 2007-04-18 08:55:41.000000000 -0500 >+++ b/kernel/kallsyms.c 2007-04-18 21:02:41.000000000 -0500 >@@ -230,29 +230,35 @@ const char *kallsyms_lookup(unsigned lon > } > > /* Replace "%s" in format with address, or returns -errno. */ >-void __print_symbol(const char *fmt, unsigned long address) >+int sprint_symbol(char *buffer, unsigned long address) > { > char *modname; > const char *name; > unsigned long offset, size; > char namebuf[KSYM_NAME_LEN+1]; >- char buffer[sizeof("%s+%#lx/%#lx [%s]") + KSYM_NAME_LEN + >- 2*(BITS_PER_LONG*3/10) + MODULE_NAME_LEN + 1]; > > name = kallsyms_lookup(address, &size, &offset, &modname, namebuf); >- > if (!name) >- sprintf(buffer, "0x%lx", address); >+ return sprintf(buffer, "0x%lx", address); > else { > if (modname) >- sprintf(buffer, "%s+%#lx/%#lx [%s]", name, offset, >- size, modname); >+ return sprintf(buffer, "%s+%#lx/%#lx [%s]", name, offset, >+ size, modname); > else >- sprintf(buffer, "%s+%#lx/%#lx", name, offset, size); >+ return sprintf(buffer, "%s+%#lx/%#lx", name, offset, size); > } >- printk(fmt, buffer); > } > >+/* Look up a kernel symbol and print it to the kernel messages. */ >+void __print_symbol(const char *fmt, unsigned long address) >+{ >+ char buffer[KSYM_SYMBOL_LEN]; >+ >+ sprint_symbol(buffer, address); >+ >+ printk(fmt, buffer); >+} >+ > /* To avoid using get_symbol_offset for every symbol, we carry prefix along. */ > struct kallsym_iter > { >@@ -418,3 +424,4 @@ static int __init kallsyms_init(void) > __initcall(kallsyms_init); > > EXPORT_SYMBOL(__print_symbol); >+EXPORT_SYMBOL_GPL(sprint_symbol);
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 228540
:
148091
|
148880
|
149026
|
149854
|
150918
|
150925
|
150936
| 152978