Re: [RFC][PATCH] VFS: create /proc/<pid>/mountinfo

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




On Jan 19 2008 12:05, Miklos Szeredi wrote:
>+
>+/*
>+ * Write full pathname from the root of the filesystem into the buffer.
>+ */
>+char *dentry_path(struct dentry *dentry, char *buf, int buflen)

Hm, this functions looks very much like __d_path(). Is it
an unintentional copy?

>+{
>+	char *end = buf + buflen;
>+	char *retval;
>+
>+	spin_lock(&dcache_lock);
>+	prepend(&end, &buflen, "\0", 1);
>+	if (!IS_ROOT(dentry) && d_unhashed(dentry)) {
>+		if (prepend(&end, &buflen, "//deleted", 9))
>+			goto Elong;
>+	}
>+	if (buflen < 1)
>+		goto Elong;
>+	/* Get '/' right */
>+	retval = end-1;
>+	*retval = '/';
>+
>+	for (;;) {
>+		struct dentry *parent;
>+		if (IS_ROOT(dentry))
>+			break;
>+
>+		parent = dentry->d_parent;
>+		prefetch(parent);
>+
>+		if (prepend(&end, &buflen, dentry->d_name.name,
>+				dentry->d_name.len) ||
>+		    prepend(&end, &buflen, "/", 1))
>+			goto Elong;
>+
>+		retval = end;
>+		dentry = parent;
>+	}
>+	spin_unlock(&dcache_lock);
>+	return retval;
>+Elong:
>+	spin_unlock(&dcache_lock);
>+	return ERR_PTR(-ENAMETOOLONG);
>+}
>+
> /*
>  * NOTE! The user-level library version returns a
>  * character pointer. The kernel system call just
>===================================================================
>--- linux.orig/fs/namespace.c	2008-01-18 19:21:38.000000000 +0100
>+++ linux/fs/namespace.c	2008-01-18 23:39:35.000000000 +0100
>@@ -27,6 +27,7 @@
> #include <linux/mount.h>
> #include <linux/ramfs.h>
> #include <linux/log2.h>
>+#include <linux/idr.h>
> #include <asm/uaccess.h>
> #include <asm/unistd.h>
> #include "pnode.h"

(IDR numbers are IMO fine.)

>@@ -601,28 +635,29 @@ static inline void mangle(struct seq_fil
> 	seq_escape(m, s, " \t\n\\");
> }
> 
>+static struct proc_fs_info {

These do not seem to be static data. Please mark them as const.

static const struct proc_fs_info.

>+	int flag;
>+	char *str;

const char *str.

>+} fs_info[] = {
>+	{ MS_SYNCHRONOUS, ",sync" },
>+	{ MS_DIRSYNC, ",dirsync" },
>+	{ MS_MANDLOCK, ",mand" },
>+	{ 0, NULL }
>+};
>+static struct proc_fs_info mnt_info[] = {
      const
>+	{ MNT_NOSUID, ",nosuid" },
>+	{ MNT_NODEV, ",nodev" },
>+	{ MNT_NOEXEC, ",noexec" },
>+	{ MNT_NOATIME, ",noatime" },
>+	{ MNT_NODIRATIME, ",nodiratime" },
>+	{ MNT_RELATIME, ",relatime" },
>+	{ 0, NULL }
>+};
>+
> static int show_vfsmnt(struct seq_file *m, void *v)
> {
> 	struct vfsmount *mnt = list_entry(v, struct vfsmount, mnt_list);
> 	int err = 0;
>-	static struct proc_fs_info {
>-		int flag;
>-		char *str;
>-	} fs_info[] = {
>-		{ MS_SYNCHRONOUS, ",sync" },
>-		{ MS_DIRSYNC, ",dirsync" },
>-		{ MS_MANDLOCK, ",mand" },
>-		{ 0, NULL }
>-	};
>-	static struct proc_fs_info mnt_info[] = {
>-		{ MNT_NOSUID, ",nosuid" },
>-		{ MNT_NODEV, ",nodev" },
>-		{ MNT_NOEXEC, ",noexec" },
>-		{ MNT_NOATIME, ",noatime" },
>-		{ MNT_NODIRATIME, ",nodiratime" },
>-		{ MNT_RELATIME, ",relatime" },
>-		{ 0, NULL }
>-	};
> 	struct proc_fs_info *fs_infop;
>@@ -657,6 +692,63 @@ struct seq_operations mounts_op = {
> 	.show	= show_vfsmnt
> };
> 
>+static int show_mountinfo(struct seq_file *m, void *v)
>+{
>+	struct vfsmount *mnt = list_entry(v, struct vfsmount, mnt_list);
>+	struct super_block *sb = mnt->mnt_sb;
>+	struct path mnt_path = { .dentry = mnt->mnt_root, .mnt = mnt };
>+	struct proc_fs_info *fs_infop;
>+	int err = 0;
>+
>+	seq_printf(m, "%i %i %u:%u ", mnt->mnt_id, mnt->mnt_parent->mnt_id,
>+		   MAJOR(sb->s_dev), MINOR(sb->s_dev));
>+	mangle(m, sb->s_type->name);
>+	if (sb->s_subtype && sb->s_subtype[0]) {
>+		seq_putc(m, '.');
>+		mangle(m, sb->s_subtype);
>+	}
>+	seq_putc(m, ' ');
>+	mangle(m, mnt->mnt_devname ? mnt->mnt_devname : "none");
>+	seq_putc(m, ' ');
>+	seq_dentry(m, mnt->mnt_root, " \t\n\\");
>+	seq_putc(m, ' ');
>+	seq_path(m, &mnt_path, " \t\n\\");
>+	seq_putc(m, ' ');
>+	seq_puts(m, mnt->mnt_flags & MNT_READONLY ? "ro" : "rw");
>+	for (fs_infop = mnt_info; fs_infop->flag; fs_infop++) {
>+		if (mnt->mnt_flags & fs_infop->flag)
>+			seq_puts(m, fs_infop->str);
>+	}

>+	seq_putc(m, ' ');
>+	seq_puts(m, sb->s_flags & MS_RDONLY ? "ro" : "rw");
>+	for (fs_infop = fs_info; fs_infop->flag; fs_infop++) {
>+		if (sb->s_flags & fs_infop->flag)
>+			seq_puts(m, fs_infop->str);
>+	}

{} could go.

>+	if (sb->s_op->show_options)
>+		err = sb->s_op->show_options(m, mnt);
>+	if (IS_MNT_SHARED(mnt)) {
>+		seq_printf(m, " shared:%i", get_peer_group_id(mnt));
>+		if (IS_MNT_SLAVE(mnt))
>+			seq_printf(m, ",slave:%i", get_master_id(mnt));
>+	} else if (IS_MNT_SLAVE(mnt)) {
>+		seq_printf(m, " slave:%i", get_master_id(mnt));
>+	} else if (IS_MNT_UNBINDABLE(mnt)) {
>+		seq_printf(m, " unbindable");
>+	} else {
>+		seq_printf(m, " private");
>+	}
>+	seq_putc(m, '\n');
>+	return err;
>+}
>+
>+struct seq_operations mountinfo_op = {
I think this can go const.

>+	.start	= m_start,
>+	.next	= m_next,
>+	.stop	= m_stop,
>+	.show	= show_mountinfo,
>+};
>+
> static int show_vfsstat(struct seq_file *m, void *v)
> {
> 	struct vfsmount *mnt = list_entry(v, struct vfsmount, mnt_list);
>Index: linux/fs/seq_file.c
>===================================================================
>--- linux.orig/fs/seq_file.c	2008-01-18 19:21:38.000000000 +0100
>+++ linux/fs/seq_file.c	2008-01-18 19:22:27.000000000 +0100
>@@ -349,28 +349,40 @@ int seq_printf(struct seq_file *m, const
> }
> EXPORT_SYMBOL(seq_printf);
> 
>+static char *mangle_path(char *s, char *p, char *esc)
                                    const char *p, const char *esc
>+{
>+	while (s <= p) {
>+		char c = *p++;
>+		if (!c) {
>+			return s;
>+		} else if (!strchr(esc, c)) {
>+			*s++ = c;
>+		} else if (s + 4 > p) {
>+			break;
>+		} else {
>+			*s++ = '\\';
>+			*s++ = '0' + ((c & 0300) >> 6);
>+			*s++ = '0' + ((c & 070) >> 3);
>+			*s++ = '0' + (c & 07);
>+		}
>+	}
>+	return NULL;
>+}
>+
>+/*
>+ * return the absolute path of 'dentry' residing in mount 'mnt'.
>+ */
> int seq_path(struct seq_file *m, struct path *path, char *esc)
> {
> 	if (m->count < m->size) {
>@@ -379,6 +391,28 @@ int seq_path(struct seq_file *m, struct 
> }
> EXPORT_SYMBOL(seq_path);
> 
>+/*
>+ * returns the path of the 'dentry' from the root of its filesystem.
>+ */
>+int seq_dentry(struct seq_file *m, struct dentry *dentry, char *esc)
                                                           const char *esc
>+{
>+	if (m->count < m->size) {
>+		char *s = m->buf + m->count;
>+		char *p = dentry_path(dentry, s, m->size - m->count);
>+		if (!IS_ERR(p)) {
>+			s = mangle_path(s, p, esc);
>+			if (s) {
>+				p = m->buf + m->count;
>+				m->count = s - m->buf;
>+				return s - p;
>+			}
>+		}
>+	}
>+	m->count = m->size;
>+	return -1;
>+}
>+EXPORT_SYMBOL(seq_dentry);
>+
> static void *single_start(struct seq_file *p, loff_t *pos)
> {
> 	return NULL + (*pos == 0);
>===================================================================
>--- linux.orig/include/linux/mount.h	2008-01-18 19:21:38.000000000 +0100
>+++ linux/include/linux/mount.h	2008-01-18 23:39:35.000000000 +0100
>@@ -56,6 +56,7 @@ 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 */
>+	int mnt_id;			/* mount identifier */
> 	/*
> 	 * We put mnt_count & mnt_expiry_mark at the end of struct vfsmount
> 	 * to let these frequently modified fields in a separate cache line

Should/could it be unsigned int, or does it need to store -1?

-
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

[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux