The /proc/dentry_mobs file lists the device the mob is located on, the path to the dentry (starting from the device root) its usage and size. I tried to make it very simple, as this API is not perfect from my POV and will most likely be rewritten. For the same reason (simplicity) the dentry_path is used, not the full path to the root. Signed-off-by: Pavel Emelyanov <xemul@xxxxxxxxxx> --- fs/dcache.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++ fs/proc/root.c | 3 ++ include/linux/dcache.h | 2 + 3 files changed, 63 insertions(+), 0 deletions(-) diff --git a/fs/dcache.c b/fs/dcache.c index 01e3464..c1120b3 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -3028,6 +3028,7 @@ int dcache_new_mob(struct dentry *root) spin_unlock(&root->d_lock); spin_lock(&dcache_mobs_lock); + dmob->mob_root = root; list_add(&dmob->mobs, &dentry_mobs); dentry_mobs_nr++; spin_unlock(&dcache_mobs_lock); @@ -3068,6 +3069,63 @@ int dcache_get_mob_stat(struct dentry *de, struct dentry_mob_stat __user *stat) return 0; } +static int dentry_mobs_show(struct seq_file *f, void *v) +{ + struct dentry_mob *dmob; + + dmob = list_entry(v, struct dentry_mob, mobs); + if (dmob == &init_dentry_mob) + seq_putc(f, '/'); + else { + struct dentry *root = dmob->mob_root; + + seq_printf(f, "%u:%u ", MAJOR(root->d_sb->s_dev), + MINOR(root->d_sb->s_dev)); + seq_dentry(f, root, " \t\n\\"); + } + + seq_printf(f, " %lu %lu\n", + (unsigned long)percpu_counter_sum_positive(&dmob->nr_dentry), + dmob->nr_dentry_max); + + return 0; +} + +static void *dentry_mobs_start(struct seq_file *f, loff_t *pos) +{ + spin_lock(&dcache_mobs_lock); + return seq_list_start(&dentry_mobs, *pos); +} + +static void *dentry_mobs_next(struct seq_file *f, void *v, loff_t *pos) +{ + return seq_list_next(v, &dentry_mobs, pos); +} + +static void dentry_mobs_stop(struct seq_file *f, void *v) +{ + spin_unlock(&dcache_mobs_lock); +} + +static const struct seq_operations dentry_mobs_ops = { + .start = dentry_mobs_start, + .next = dentry_mobs_next, + .stop = dentry_mobs_stop, + .show = dentry_mobs_show +}; + +static int dentry_mobs_open(struct inode *inode, struct file *filp) +{ + return seq_open(filp, &dentry_mobs_ops); +} + +const struct file_operations proc_dentry_mobs_fops = { + .open = dentry_mobs_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + static __initdata unsigned long dhash_entries; static int __init set_dhash_entries(char *str) { diff --git a/fs/proc/root.c b/fs/proc/root.c index ef9fa8e..e4d4983 100644 --- a/fs/proc/root.c +++ b/fs/proc/root.c @@ -18,6 +18,7 @@ #include <linux/bitops.h> #include <linux/mount.h> #include <linux/pid_namespace.h> +#include <linux/dcache.h> #include "internal.h" @@ -133,6 +134,8 @@ void __init proc_root_init(void) proc_device_tree_init(); #endif proc_mkdir("bus", NULL); + + proc_create("dentry_mobs", S_IRUGO, NULL, &proc_dentry_mobs_fops); proc_sys_init(); } diff --git a/include/linux/dcache.h b/include/linux/dcache.h index 7b1fdc1..8a9a5a5 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -53,6 +53,7 @@ struct dentry_mob { unsigned long nr_dentry_max; struct list_head dentry_lru; struct list_head mobs; + struct dentry *mob_root; }; struct dentry; @@ -64,6 +65,7 @@ struct dentry_mob_stat { int dcache_new_mob(struct dentry *root); int dcache_set_mob_size(struct dentry *de, unsigned long size); int dcache_get_mob_stat(struct dentry *de, struct dentry_mob_stat __user *stat); +extern const struct file_operations proc_dentry_mobs_fops; /* * Compare 2 name strings, return 0 if they match, otherwise non-zero. -- 1.5.5.6 -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html