1) reports deleted inode in dentry_path() consistent with that in __d_path() 2) modified __d_path() to use prepend(), reducing the size of __d_path() 3) moved all the functionality that reports mount information in /proc under CONFIG_PROC_FS. Code compile tested only with and without CONFIG_PROC_FS. Signed-off-by: Ram Pai <linuxram@xxxxxxxxxx> --- fs/dcache.c | 66 +++++++++++++++++++---------------------------- fs/namespace.c | 15 +++++++++- fs/pnode.c | 24 +++++++++++------ fs/pnode.h | 6 +++- fs/seq_file.c | 2 + include/linux/dcache.h | 3 ++ include/linux/mount.h | 2 + include/linux/seq_file.h | 3 ++ 8 files changed, 73 insertions(+), 48 deletions(-) Index: linux-2.6.24/fs/dcache.c =================================================================== --- linux-2.6.24.orig/fs/dcache.c +++ linux-2.6.24/fs/dcache.c @@ -1747,6 +1747,17 @@ shouldnt_be_hashed: goto shouldnt_be_hashed; } +static int prepend(char **buffer, int *buflen, const char *str, + int namelen) +{ + *buflen -= namelen; + if (*buflen < 0) + return -ENAMETOOLONG; + *buffer -= namelen; + memcpy(*buffer, str, namelen); + return 0; +} + /** * d_path - return the path of a dentry * @dentry: dentry to report @@ -1768,17 +1779,11 @@ static char *__d_path(struct dentry *den { char * end = buffer+buflen; char * retval; - int namelen; - *--end = '\0'; - buflen--; - if (!IS_ROOT(dentry) && d_unhashed(dentry)) { - buflen -= 10; - end -= 10; - if (buflen < 0) + prepend(&end, &buflen, "\0", 1); + if (!IS_ROOT(dentry) && d_unhashed(dentry) && + (prepend(&end, &buflen, " (deleted)", 10) != 0)) goto Elong; - memcpy(end, " (deleted)", 10); - } if (buflen < 1) goto Elong; @@ -1805,13 +1810,10 @@ static char *__d_path(struct dentry *den } parent = dentry->d_parent; prefetch(parent); - namelen = dentry->d_name.len; - buflen -= namelen + 1; - if (buflen < 0) + if ((prepend(&end, &buflen, dentry->d_name.name, + dentry->d_name.len) != 0) || + (prepend(&end, &buflen, "/", 1) != 0)) goto Elong; - end -= namelen; - memcpy(end, dentry->d_name.name, namelen); - *--end = '/'; retval = end; dentry = parent; } @@ -1819,12 +1821,10 @@ static char *__d_path(struct dentry *den return retval; global_root: - namelen = dentry->d_name.len; - buflen -= namelen; - if (buflen < 0) - goto Elong; - retval -= namelen-1; /* hit the slash */ - memcpy(retval, dentry->d_name.name, namelen); + retval += 1; /* hit the slash */ + if (prepend(&retval, &buflen, dentry->d_name.name, + dentry->d_name.len) !=0 ) + goto Elong; return retval; Elong: return ERR_PTR(-ENAMETOOLONG); @@ -1890,17 +1890,8 @@ char *dynamic_dname(struct dentry *dentr return memcpy(buffer, temp, sz); } -static int prepend(char **buffer, int *buflen, const char *str, - int namelen) -{ - *buflen -= namelen; - if (*buflen < 0) - return 1; - *buffer -= namelen; - memcpy(*buffer, str, namelen); - return 0; -} +#ifdef CONFIG_PROC_FS /* * Write full pathname from the root of the filesystem into the buffer. */ @@ -1910,11 +1901,9 @@ char *dentry_path(struct dentry *dentry, char *retval; spin_lock(&dcache_lock); - prepend(&end, &buflen, "\0", 1); - if (!IS_ROOT(dentry) && d_unhashed(dentry)) { - if (prepend(&end, &buflen, "//deleted", 9)) + if (!IS_ROOT(dentry) && d_unhashed(dentry) && + (prepend(&end, &buflen, " (deleted)", 10) != 0)) goto Elong; - } if (buflen < 1) goto Elong; /* Get '/' right */ @@ -1929,9 +1918,9 @@ char *dentry_path(struct dentry *dentry, parent = dentry->d_parent; prefetch(parent); - if (prepend(&end, &buflen, dentry->d_name.name, - dentry->d_name.len) || - prepend(&end, &buflen, "/", 1)) + if ((prepend(&end, &buflen, dentry->d_name.name, + dentry->d_name.len) != 0) || + (prepend(&end, &buflen, "/", 1) != 0)) goto Elong; retval = end; @@ -1943,6 +1932,7 @@ Elong: spin_unlock(&dcache_lock); return ERR_PTR(-ENAMETOOLONG); } +#endif /* CONFIG_PROC_FS */ /* * NOTE! The user-level library version returns a Index: linux-2.6.24/fs/namespace.c =================================================================== --- linux-2.6.24.orig/fs/namespace.c +++ linux-2.6.24/fs/namespace.c @@ -40,7 +40,10 @@ __cacheline_aligned_in_smp DEFINE_SPINLOCK(vfsmount_lock); static int event; + +#ifdef CONFIG_PROC_FS static DEFINE_IDA(mnt_id_ida); +#endif /* CONFIG_PROC_FS */ static struct list_head *mount_hashtable __read_mostly; static struct kmem_cache *mnt_cache __read_mostly; @@ -60,6 +63,7 @@ static inline unsigned long hash(struct #define MNT_WRITER_UNDERFLOW_LIMIT -(1<<16) +#ifdef CONFIG_PROC_FS static int mnt_alloc_id(struct vfsmount *mnt) { int res; @@ -82,11 +86,14 @@ static void mnt_free_id(struct vfsmount ida_remove(&mnt_id_ida, mnt->mnt_id); spin_unlock(&vfsmount_lock); } +#endif /* CONFIG_PROC_FS */ struct vfsmount *alloc_vfsmnt(const char *name) { struct vfsmount *mnt = kmem_cache_zalloc(mnt_cache, GFP_KERNEL); if (mnt) { + +#ifdef CONFIG_PROC_FS int err; err = mnt_alloc_id(mnt); @@ -96,6 +103,8 @@ struct vfsmount *alloc_vfsmnt(const char } mnt->mnt_pgid = -1; +#endif /* CONFIG_PROC_FS */ + atomic_set(&mnt->mnt_count, 1); INIT_LIST_HEAD(&mnt->mnt_hash); INIT_LIST_HEAD(&mnt->mnt_child); @@ -381,7 +390,9 @@ EXPORT_SYMBOL(simple_set_mnt); void free_vfsmnt(struct vfsmount *mnt) { kfree(mnt->mnt_devname); +#ifdef CONFIG_PROC_FS mnt_free_id(mnt); +#endif /* CONFIG_PROC_FS */ kmem_cache_free(mnt_cache, mnt); } @@ -679,6 +690,7 @@ void save_mount_options(struct super_blo } EXPORT_SYMBOL(save_mount_options); +#ifdef CONFIG_PROC_FS /* iterator */ static void *m_start(struct seq_file *m, loff_t *pos) { @@ -808,7 +820,7 @@ static int show_mountinfo(struct seq_fil if (IS_MNT_SHARED(mnt)) seq_putc(m, ','); - seq_printf(m, "slave:%i", get_master_id(mnt)); + seq_printf(m, "slave:%i", get_master_group_id(mnt)); if (dominator_id != -1) seq_printf(m, ":%i", dominator_id); } @@ -866,6 +878,7 @@ const struct seq_operations mountstats_o .stop = m_stop, .show = show_vfsstat, }; +#endif /* CONFIG_PROC_FS */ /** * may_umount_tree - check if a mount tree is busy Index: linux-2.6.24/fs/seq_file.c =================================================================== --- linux-2.6.24.orig/fs/seq_file.c +++ linux-2.6.24/fs/seq_file.c @@ -391,6 +391,7 @@ int seq_path(struct seq_file *m, struct } EXPORT_SYMBOL(seq_path); +#ifdef CONFIG_PROC_FS /* * returns the path of the 'dentry' from the root of its filesystem. */ @@ -412,6 +413,7 @@ int seq_dentry(struct seq_file *m, struc return -1; } EXPORT_SYMBOL(seq_dentry); +#endif /* CONFIG_PROC_FS */ static void *single_start(struct seq_file *p, loff_t *pos) { Index: linux-2.6.24/include/linux/dcache.h =================================================================== --- linux-2.6.24.orig/include/linux/dcache.h +++ linux-2.6.24/include/linux/dcache.h @@ -303,7 +303,10 @@ extern int d_validate(struct dentry *, s extern char *dynamic_dname(struct dentry *, char *, int, const char *, ...); extern char *d_path(struct path *, char *, int); + +#ifdef CONFIG_PROC_FS extern char *dentry_path(struct dentry *, char *, int); +#endif /* CONFIG_PROC_FS */ /* Allocation counts.. */ Index: linux-2.6.24/include/linux/seq_file.h =================================================================== --- linux-2.6.24.orig/include/linux/seq_file.h +++ linux-2.6.24/include/linux/seq_file.h @@ -44,7 +44,10 @@ int seq_printf(struct seq_file *, const __attribute__ ((format (printf,2,3))); int seq_path(struct seq_file *, struct path *, char *); + +#ifdef CONFIG_PROC_FS int seq_dentry(struct seq_file *, struct dentry *, char *); +#endif /* CONFIG_PROC_FS */ int single_open(struct file *, int (*)(struct seq_file *, void *), void *); int single_release(struct inode *, struct file *); Index: linux-2.6.24/fs/pnode.c =================================================================== --- linux-2.6.24.orig/fs/pnode.c +++ linux-2.6.24/fs/pnode.c @@ -12,8 +12,10 @@ #include <linux/idr.h> #include "pnode.h" +#ifdef CONFIG_PROC_FS static DEFINE_SPINLOCK(mnt_pgid_lock); static DEFINE_IDA(mnt_pgid_ida); +#endif /* CONFIG_PROC_FS */ /* return the next shared peer mount of @p */ static inline struct vfsmount *next_peer(struct vfsmount *p) @@ -42,18 +44,18 @@ void set_mnt_shared(struct vfsmount *mnt int res; retry: - spin_lock(&mnt_pgid_lock); - if (IS_MNT_SHARED(mnt)) { - spin_unlock(&mnt_pgid_lock); + if (IS_MNT_SHARED(mnt)) return; - } +#ifdef CONFIG_PROC_FS + spin_lock(&mnt_pgid_lock); res = ida_get_new(&mnt_pgid_ida, &mnt->mnt_pgid); spin_unlock(&mnt_pgid_lock); if (res == -EAGAIN) { if (ida_pre_get(&mnt_pgid_ida, GFP_KERNEL)) goto retry; } +#endif /* CONFIG_PROC_FS */ __set_mnt_shared(mnt); } @@ -61,10 +63,13 @@ void clear_mnt_shared(struct vfsmount *m { if (IS_MNT_SHARED(mnt)) { mnt->mnt_flags &= ~MNT_SHARED; +#ifdef CONFIG_PROC_FS mnt->mnt_pgid = -1; +#endif /* CONFIG_PROC_FS */ } } +#ifdef CONFIG_PROC_FS void make_mnt_peer(struct vfsmount *old, struct vfsmount *mnt) { mnt->mnt_pgid = old->mnt_pgid; @@ -77,7 +82,7 @@ int get_peer_group_id(struct vfsmount *m return mnt->mnt_pgid; } -int get_master_id(struct vfsmount *mnt) +int get_master_group_id(struct vfsmount *mnt) { int id; @@ -119,6 +124,7 @@ int get_dominator_id_same_ns(struct vfsm return id; } +#endif /* CONFIG_PROC_FS */ static int do_make_slave(struct vfsmount *mnt) { @@ -138,13 +144,15 @@ static int do_make_slave(struct vfsmount if (peer_mnt == mnt) peer_mnt = NULL; } - if (!list_empty(&mnt->mnt_share)) - list_del_init(&mnt->mnt_share); - else if (IS_MNT_SHARED(mnt)) { + +#ifdef CONFIG_PROC_FS + if (IS_MNT_SHARED(mnt) && list_empty(&mnt->mnt_share)) { spin_lock(&mnt_pgid_lock); ida_remove(&mnt_pgid_ida, mnt->mnt_pgid); spin_unlock(&mnt_pgid_lock); } +#endif /* CONFIG_PROC_FS */ + list_del_init(&mnt->mnt_share); if (peer_mnt) master = peer_mnt; Index: linux-2.6.24/fs/pnode.h =================================================================== --- linux-2.6.24.orig/fs/pnode.h +++ linux-2.6.24/fs/pnode.h @@ -31,7 +31,11 @@ int propagate_mnt(struct vfsmount *, str struct list_head *); int propagate_umount(struct list_head *); int propagate_mount_busy(struct vfsmount *, int); + +#ifdef CONFIG_PROC_FS int get_peer_group_id(struct vfsmount *); -int get_master_id(struct vfsmount *); +int get_master_group_id(struct vfsmount *); int get_dominator_id_same_ns(struct vfsmount *); +#endif /* CONFIG_PROC_FS */ + #endif /* _LINUX_PNODE_H */ Index: linux-2.6.24/include/linux/mount.h =================================================================== --- linux-2.6.24.orig/include/linux/mount.h +++ linux-2.6.24/include/linux/mount.h @@ -56,8 +56,10 @@ struct vfsmount { struct list_head mnt_slave; /* slave list entry */ struct vfsmount *mnt_master; /* slave is on master->mnt_slave_list */ struct mnt_namespace *mnt_ns; /* containing namespace */ +#ifdef CONFIG_PROC_FS int mnt_id; /* mount identifier */ int mnt_pgid; /* peer group identifier */ +#endif /* CONFIG_PROC_FS */ /* * We put mnt_count & mnt_expiry_mark at the end of struct vfsmount * to let these frequently modified fields in a separate cache line -- 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