From: Oleg Drokin Date: Sun, 1 Jan 2017 15:59:10 +0000 (-0500) Subject: LU-8066 obd: Add debugfs root X-Git-Tag: 2.9.52~37 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=8c613142f138f809df6b525d134751b3d846ff8e LU-8066 obd: Add debugfs root This is just plumbing for migrating remaining procfs to debugfs support Linux-commit: 5c8c82f63a11c07a0687d2c71411166017012689 ldebugfs_remove is usually called on directories with files passed in as attributes, so simple debugfs_remove failes on them as not empty Switch to debugfs_remove_recursive. This fixes a number of problems where a new filesystem is mounted after being unmounted first. Linux-commit: 6a491f2b80f2806221ba3a5a3e26fbe945f82d83 Turns out we mistakenly export some pretty-wide-reaching debugfs functions as EXPORT_SYMBOL instead of EXPORT_SYMBOL_GPL as we should, so this patch rectifies the situation. Linux-commit: da33f1dd9f69c5a5d23e1254906b027af3362e36 Move /proc/fs/lustre/devices to debugfs. The devices file prints out status information about all obd devices in the system in human readable form. Linux-commit: 4361a048743f900bb0710bd7cb36a650d7bef93a Signed-off-by: Dmitry Eremin Change-Id: Iefe6ee69b607f627c5682513128706bf0c1c3e09 Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman Signed-off-by: James Simmons Reviewed-on: https://review.whamcloud.com/23427 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Jian Yu Reviewed-by: Emoly Liu --- diff --git a/lustre/include/lprocfs_status.h b/lustre/include/lprocfs_status.h index b3eb9d6..fb6bbfa 100644 --- a/lustre/include/lprocfs_status.h +++ b/lustre/include/lprocfs_status.h @@ -40,6 +40,7 @@ #include #include +#include #include #include #include @@ -355,7 +356,7 @@ enum lprocfs_extra_opc { #define EXTRA_FIRST_OPC LDLM_GLIMPSE_ENQUEUE /* class_obd.c */ extern struct proc_dir_entry *proc_lustre_root; - +extern struct dentry *debugfs_lustre_root; extern struct kobject *lustre_kobj; struct obd_device; @@ -503,15 +504,26 @@ lprocfs_nid_stats_clear_seq_write(struct file *file, const char __user *buffer, size_t count, loff_t *off); extern int lprocfs_nid_stats_clear_seq_show(struct seq_file *file, void *data); #endif +extern int ldebugfs_register_stats(struct dentry *parent, const char *name, + struct lprocfs_stats *stats); extern int lprocfs_register_stats(struct proc_dir_entry *root, const char *name, struct lprocfs_stats *stats); /* lprocfs_status.c */ +extern int ldebugfs_add_vars(struct dentry *parent, struct lprocfs_vars *var, + void *data); extern int lprocfs_add_vars(struct proc_dir_entry *root, struct lprocfs_vars *var, void *data); + +extern struct dentry *ldebugfs_register(const char *name, + struct dentry *parent, + struct lprocfs_vars *list, + void *data); extern struct proc_dir_entry * lprocfs_register(const char *name, struct proc_dir_entry *parent, struct lprocfs_vars *list, void *data); + +extern void ldebugfs_remove(struct dentry **entryp); extern void lprocfs_remove(struct proc_dir_entry **root); extern void lprocfs_remove_proc_entry(const char *name, struct proc_dir_entry *parent); @@ -542,6 +554,11 @@ extern int lprocfs_obd_cleanup(struct obd_device *obd); #ifdef HAVE_SERVER_SUPPORT extern const struct file_operations lprocfs_evict_client_fops; #endif + +extern int ldebugfs_seq_create(struct dentry *parent, const char *name, + umode_t mode, + const struct file_operations *seq_fops, + void *data); extern int lprocfs_seq_create(struct proc_dir_entry *parent, const char *name, mode_t mode, const struct file_operations *seq_fops, @@ -664,7 +681,8 @@ static int name##_single_open(struct inode *inode, struct file *file) \ if (rc < 0) \ return rc; \ \ - return single_open(file, name##_seq_show, PDE_DATA(inode)); \ + return single_open(file, name##_seq_show, \ + inode->i_private ? : PDE_DATA(inode)); \ } \ static const struct file_operations name##_fops = { \ .owner = THIS_MODULE, \ @@ -709,7 +727,8 @@ static const struct file_operations name##_fops = { \ } \ static int name##_##type##_open(struct inode *inode, struct file *file)\ { \ - return single_open(file, NULL, PDE_DATA(inode)); \ + return single_open(file, NULL, \ + inode->i_private ? : PDE_DATA(inode));\ } \ static const struct file_operations name##_##type##_fops = { \ .open = name##_##type##_open, \ diff --git a/lustre/obdclass/linux/linux-module.c b/lustre/obdclass/linux/linux-module.c index 7a7255c..a2d69d7 100644 --- a/lustre/obdclass/linux/linux-module.c +++ b/lustre/obdclass/linux/linux-module.c @@ -334,6 +334,10 @@ static ssize_t jobid_name_store(struct kobject *kobj, struct attribute *attr, return count; } +/* Root for /sys/kernel/debug/lustre */ +struct dentry *debugfs_lustre_root; +EXPORT_SYMBOL_GPL(debugfs_lustre_root); + #ifdef CONFIG_PROC_FS /* Root for /proc/fs/lustre */ struct proc_dir_entry *proc_lustre_root = NULL; @@ -422,7 +426,7 @@ static int obd_device_list_open(struct inode *inode, struct file *file) return rc; seq = file->private_data; - seq->private = PDE_DATA(inode); + seq->private = inode->i_private; return 0; } @@ -444,6 +448,7 @@ static struct attribute_group lustre_attr_group = { int class_procfs_init(void) { struct proc_dir_entry *entry; + struct dentry *file; int rc = 0; ENTRY; @@ -460,6 +465,23 @@ int class_procfs_init(void) obd_sysctl_init(); + debugfs_lustre_root = debugfs_create_dir("lustre", NULL); + if (IS_ERR_OR_NULL(debugfs_lustre_root)) { + rc = debugfs_lustre_root ? PTR_ERR(debugfs_lustre_root) + : -ENOMEM; + debugfs_lustre_root = NULL; + kobject_put(lustre_kobj); + goto out; + } + + file = debugfs_create_file("devices", 0444, debugfs_lustre_root, NULL, + &obd_device_list_fops); + if (IS_ERR_OR_NULL(file)) { + rc = file ? PTR_ERR(file) : -ENOMEM; + kobject_put(lustre_kobj); + goto out; + } + entry = lprocfs_register("fs/lustre", NULL, NULL, NULL); if (IS_ERR(entry)) { rc = PTR_ERR(entry); @@ -469,19 +491,6 @@ int class_procfs_init(void) } proc_lustre_root = entry; - - rc = lprocfs_seq_create(proc_lustre_root, "devices", 0444, - &obd_device_list_fops, NULL); - if (rc < 0) { - CERROR("cannot create '/proc/fs/lustre/devices': rc = %d\n", - rc); - GOTO(out_proc, rc); - } - - RETURN(rc); - -out_proc: - lprocfs_remove(&proc_lustre_root); out: RETURN(rc); } @@ -490,6 +499,10 @@ int class_procfs_clean(void) { ENTRY; + debugfs_remove_recursive(debugfs_lustre_root); + + debugfs_lustre_root = NULL; + if (proc_lustre_root) lprocfs_remove(&proc_lustre_root); diff --git a/lustre/obdclass/lprocfs_status.c b/lustre/obdclass/lprocfs_status.c index c9b4711..7bb366b 100644 --- a/lustre/obdclass/lprocfs_status.c +++ b/lustre/obdclass/lprocfs_status.c @@ -114,6 +114,35 @@ EXPORT_SYMBOL(lprocfs_add_symlink); static const struct file_operations lprocfs_generic_fops = { }; +int ldebugfs_add_vars(struct dentry *parent, struct lprocfs_vars *list, + void *data) +{ + if (IS_ERR_OR_NULL(parent) || IS_ERR_OR_NULL(list)) + return -EINVAL; + + while (list->name) { + struct dentry *entry; + umode_t mode = 0; + + if (list->proc_mode != 0000) { + mode = list->proc_mode; + } else if (list->fops) { + if (list->fops->read) + mode = 0444; + if (list->fops->write) + mode |= 0200; + } + entry = debugfs_create_file(list->name, mode, parent, + list->data ? : data, + list->fops ? : &lprocfs_generic_fops); + if (IS_ERR_OR_NULL(entry)) + return entry ? PTR_ERR(entry) : -ENOMEM; + list++; + } + return 0; +} +EXPORT_SYMBOL_GPL(ldebugfs_add_vars); + /** * Add /proc entries. * @@ -155,6 +184,13 @@ lprocfs_add_vars(struct proc_dir_entry *root, struct lprocfs_vars *list, } EXPORT_SYMBOL(lprocfs_add_vars); +void ldebugfs_remove(struct dentry **entryp) +{ + debugfs_remove(*entryp); + *entryp = NULL; +} +EXPORT_SYMBOL_GPL(ldebugfs_remove); + #ifndef HAVE_REMOVE_PROC_SUBTREE /* for b=10866, global variable */ DECLARE_RWSEM(_lprocfs_lock); @@ -264,6 +300,31 @@ void lprocfs_remove_proc_entry(const char *name, struct proc_dir_entry *parent) } EXPORT_SYMBOL(lprocfs_remove_proc_entry); +struct dentry *ldebugfs_register(const char *name, struct dentry *parent, + struct lprocfs_vars *list, void *data) +{ + struct dentry *entry; + + entry = debugfs_create_dir(name, parent); + if (IS_ERR_OR_NULL(entry)) { + entry = entry ?: ERR_PTR(-ENOMEM); + goto out; + } + + if (!IS_ERR_OR_NULL(list)) { + int rc; + + rc = ldebugfs_add_vars(entry, list, data); + if (rc) { + debugfs_remove(entry); + entry = ERR_PTR(rc); + } + } +out: + return entry; +} +EXPORT_SYMBOL_GPL(ldebugfs_register); + struct proc_dir_entry * lprocfs_register(const char *name, struct proc_dir_entry *parent, struct lprocfs_vars *list, void *data) @@ -1436,7 +1497,7 @@ static int lprocfs_stats_seq_open(struct inode *inode, struct file *file) if (rc) return rc; seq = file->private_data; - seq->private = PDE_DATA(inode); + seq->private = inode->i_private ? : PDE_DATA(inode); return 0; } @@ -1449,6 +1510,22 @@ static const struct file_operations lprocfs_stats_seq_fops = { .release = lprocfs_seq_release, }; +int ldebugfs_register_stats(struct dentry *parent, const char *name, + struct lprocfs_stats *stats) +{ + struct dentry *entry; + + LASSERT(!IS_ERR_OR_NULL(parent)); + + entry = debugfs_create_file(name, 0644, parent, stats, + &lprocfs_stats_seq_fops); + if (IS_ERR_OR_NULL(entry)) + return entry ? PTR_ERR(entry) : -ENOMEM; + + return 0; +} +EXPORT_SYMBOL_GPL(ldebugfs_register_stats); + int lprocfs_register_stats(struct proc_dir_entry *root, const char *name, struct lprocfs_stats *stats) { @@ -2101,6 +2178,22 @@ char *lprocfs_find_named_value(const char *buffer, const char *name, } EXPORT_SYMBOL(lprocfs_find_named_value); +int ldebugfs_seq_create(struct dentry *parent, const char *name, umode_t mode, + const struct file_operations *seq_fops, void *data) +{ + struct dentry *entry; + + /* Disallow secretly (un)writable entries. */ + LASSERT((!seq_fops->write) == (!(mode & 0222))); + + entry = debugfs_create_file(name, mode, parent, data, seq_fops); + if (IS_ERR_OR_NULL(entry)) + return entry ? PTR_ERR(entry) : -ENOMEM; + + return 0; +} +EXPORT_SYMBOL_GPL(ldebugfs_seq_create); + int lprocfs_seq_create(struct proc_dir_entry *parent, const char *name, mode_t mode,