lkml.org 
[lkml]   [2007]   [Apr]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[d_path 6/7] Filter out disconnected paths from /proc/mounts
    Use d_path() instead of seq_path when generating /proc/mounts and
    /proc/$id/mountstats, reuse the same buffer for all mounts, and filter out
    disconnected paths.

    This path has no net effect in itself because d_path() so far doesn't
    distinguish sconnected and disconnected paths yet. The next patch fixes that
    though; without this patch, the next patch would break /proc/mounts and
    /proc/$id/mountstats.

    There is some disagreement what /proc/mounts should include. Currently it
    reports all mounts from the current namespace and doesn't include lazy
    unmounts. This leads to ambiguities with the rootfs (which is an internal mount
    irrelevant to user-space except in the initrd), and in chroots.

    With this and the next patch, /proc/mounts only reports the mounts reachable
    for the current process, which makes a lot more sense IMO. If the current
    process is rooted in the namespace root (which it usually is), it will see all
    mounts except for the rootfs.

    Signed-off-by: Andreas Gruenbacher <agruen@suse.de>

    ---
    fs/namespace.c | 23 +++++++++++++++++++++--
    fs/proc/base.c | 10 +++++++++-
    2 files changed, 30 insertions(+), 3 deletions(-)

    --- a/fs/namespace.c
    +++ b/fs/namespace.c
    @@ -348,8 +348,16 @@ static inline void mangle(struct seq_fil
    seq_escape(m, s, " \t\n\\");
    }

    +/* Keep in sync with fs/proc/base.c! */
    +struct proc_mounts {
    + struct seq_file m;
    + void *page;
    + int event;
    +};
    +
    static int show_vfsmnt(struct seq_file *m, void *v)
    {
    + void *page = container_of(m, struct proc_mounts, m)->page;
    struct vfsmount *mnt = v;
    int err = 0;
    static struct proc_fs_info {
    @@ -371,10 +379,15 @@ static int show_vfsmnt(struct seq_file *
    { 0, NULL }
    };
    struct proc_fs_info *fs_infop;
    + char *path;
    +
    + path = d_path(mnt->mnt_root, mnt, page, PAGE_SIZE);
    + if (IS_ERR(path) || *path != '/')
    + return err;

    mangle(m, mnt->mnt_devname ? mnt->mnt_devname : "none");
    seq_putc(m, ' ');
    - seq_path(m, mnt, mnt->mnt_root, " \t\n\\");
    + mangle(m, path);
    seq_putc(m, ' ');
    mangle(m, mnt->mnt_sb->s_type->name);
    seq_puts(m, mnt->mnt_sb->s_flags & MS_RDONLY ? " ro" : " rw");
    @@ -401,8 +414,14 @@ struct seq_operations mounts_op = {

    static int show_vfsstat(struct seq_file *m, void *v)
    {
    + void *page = container_of(m, struct proc_mounts, m)->page;
    struct vfsmount *mnt = v;
    int err = 0;
    + char *path;
    +
    + path = d_path(mnt->mnt_root, mnt, page, PAGE_SIZE);
    + if (IS_ERR(path) || *path != '/')
    + return err; /* error or path unreachable from chroot */

    /* device */
    if (mnt->mnt_devname) {
    @@ -413,7 +432,7 @@ static int show_vfsstat(struct seq_file

    /* mount point */
    seq_puts(m, " mounted on ");
    - seq_path(m, mnt, mnt->mnt_root, " \t\n\\");
    + mangle(m, path);
    seq_putc(m, ' ');

    /* file system type */
    --- a/fs/proc/base.c
    +++ b/fs/proc/base.c
    @@ -354,8 +354,11 @@ static const struct inode_operations pro
    };

    extern struct seq_operations mounts_op;
    +
    +/* Keep in sync with fs/namespace.c! */
    struct proc_mounts {
    struct seq_file m;
    + void *page;
    int event;
    };

    @@ -383,12 +386,16 @@ static int __mounts_open(struct inode *i
    p = kmalloc(sizeof(struct proc_mounts), GFP_KERNEL);
    if (p) {
    file->private_data = &p->m;
    - ret = seq_open(file, seq_ops);
    + p->page = (void *)__get_free_page(GFP_KERNEL);
    + if (p->page)
    + ret = seq_open(file, seq_ops);
    if (!ret) {
    p->m.private = ns;
    p->event = ns->event;
    return 0;
    }
    + if (p->page)
    + free_page((unsigned long)p->page);
    kfree(p);
    }
    put_mnt_ns(ns);
    @@ -407,6 +414,7 @@ static int mounts_release(struct inode *
    container_of(file->private_data, struct proc_mounts, m);
    struct mnt_namespace *ns = p->m.private;

    + free_page((unsigned long)p->page);
    put_mnt_ns(ns);
    return seq_release(inode, file);
    }
    --
    Andreas Gruenbacher <agruen@suse.de>
    SUSE Labs, SUSE LINUX Products GmbH
    GF: Markus Rex, HRB 16746 (AG Nuernberg)

    GPG: AF77 FAD1 1819 D442 400F 4BC8 409A 6903 4FDD EE02

    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2007-04-20 01:57    [W:0.028 / U:60.068 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site