From: Ram Pai <linuxram@us.ibm.com>
To: Miklos Szeredi <miklos@szeredi.hu>
Cc: viro@ZenIV.linux.org.uk, linux-fsdevel@vger.kernel.org
Subject: [RFC PATCH v2] vfs: optimization to /proc/<pid>/mountinfo patch
Date: Sun, 09 Mar 2008 23:53:34 -0700 [thread overview]
Message-ID: <1205132015.15345.87.camel@ram.us.ibm.com> (raw)
In-Reply-To: <E1JSZAc-0001Kk-MK@pomaz-ex.szeredi.hu>
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@us.ibm.com>
---
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
next prev parent reply other threads:[~2008-03-10 6:52 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-02-20 15:39 how to show propagation state for mounts Miklos Szeredi
2008-02-20 16:04 ` Al Viro
2008-02-20 16:27 ` Miklos Szeredi
2008-02-20 19:29 ` Ram Pai
2008-02-20 21:14 ` Al Viro
2008-02-20 21:35 ` Miklos Szeredi
2008-02-22 14:46 ` [rfc patch] " Miklos Szeredi
2008-03-05 19:25 ` Serge E. Hallyn
2008-03-05 19:34 ` Miklos Szeredi
2008-03-05 20:23 ` Ram Pai
2008-03-10 6:53 ` Ram Pai [this message]
2008-03-10 7:10 ` [RFC PATCH v2] vfs: optimization to /proc/<pid>/mountinfo patch Christoph Hellwig
2008-03-10 11:39 ` Miklos Szeredi
2008-02-20 16:31 ` how to show propagation state for mounts Matthew Wilcox
2008-02-20 19:42 ` Ram Pai
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1205132015.15345.87.camel@ram.us.ibm.com \
--to=linuxram@us.ibm.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=miklos@szeredi.hu \
--cc=viro@ZenIV.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.