lkml.org 
[lkml]   [2009]   [Oct]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 37/41] union-mount: Check read-only/read-write status of layers
    Date
    The top layer of a union mount must be writable (in order to support
    readdir-triggered copyups) and the bottom layer must be read-only (to
    avoid nasty races).

    Thanks to Felix Fietkau <nbd@openwrt.org> for a bug fix.

    XXX - Add requirement that top layer is mounted only once

    Signed-off-by: Valerie Aurora <vaurora@redhat.com>
    ---
    fs/namespace.c | 73 +++++++++++++++++++++++++++++++++++++++++++++----------
    1 files changed, 59 insertions(+), 14 deletions(-)

    diff --git a/fs/namespace.c b/fs/namespace.c
    index 505974a..9b71743 100644
    --- a/fs/namespace.c
    +++ b/fs/namespace.c
    @@ -1462,6 +1462,61 @@ static int do_change_type(struct path *path, int flag)
    }

    /*
    + * Mount-time check of upper and lower layer file systems to see if we
    + * can union mount one on the other.
    + *
    + * Union mounts must follow these rules:
    + *
    + * - The lower layer must be read-only. This avoids lots of nasty
    + * unsolvable races where file system structures disappear suddenly.
    + * XXX - Checking the vfsmnt for read-only is a temporary hack; the
    + * file system could be mounted read-write elsewhere. We need to
    + * enforce read-only at the superblock level (patches coming).
    + *
    + * - The upper layer must be writable. This isn't an absolute
    + * requirement; right now we need it to make readdir() work since we
    + * copy up directory entries to the top level. A possible
    + * workaround is to mount a tmpfs file system transparently over the
    + * top.
    + *
    + * - The upper layer must support whiteouts and fallthrus (if it is
    + * writeable).
    + *
    + * - The lower layer must not also be a union mount. This is just to
    + * make life simpler for now, there is no inherent limitation on the
    + * number of layers.
    + *
    + * XXX - Check other mount flags for incompatibilities - I'm sure
    + * there are some.
    + */
    +
    +static int
    +check_union_mnt(struct path *mntpnt, struct vfsmount *top_mnt, int mnt_flags)
    +{
    + struct vfsmount *lower_mnt = mntpnt->mnt;
    +
    + /* Is this even a union mount? */
    + if (!(mnt_flags & MNT_UNION))
    + return 0;
    +
    + /* Lower layer must be read-only and not a union mount */
    + if (!(lower_mnt->mnt_sb->s_flags & MS_RDONLY) ||
    + (lower_mnt->mnt_flags & MNT_UNION))
    + return -EBUSY;
    +
    + /* Upper layer must be writable */
    + if (mnt_flags & MNT_READONLY)
    + return -EROFS;
    +
    + /* Upper layer must support whiteouts and fallthrus */
    + if (!(top_mnt->mnt_sb->s_flags & MS_WHITEOUT))
    + return -EINVAL;
    +
    + /* All good! */
    + return 0;
    +}
    +
    +/*
    * do loopback mount.
    */
    static int do_loopback(struct path *path, char *old_name, int recurse,
    @@ -1495,13 +1550,8 @@ static int do_loopback(struct path *path, char *old_name, int recurse,
    if (!mnt)
    goto out;

    - /*
    - * Unions couldn't be writable if the filesystem doesn't know about
    - * whiteouts
    - */
    - err = -ENOTSUPP;
    - if ((mnt_flags & MNT_UNION) &&
    - !(mnt->mnt_sb->s_flags & (MS_WHITEOUT|MS_RDONLY)))
    + err = check_union_mnt(path, mnt, mnt_flags);
    + if (err)
    goto out;

    if (mnt_flags & MNT_UNION)
    @@ -1726,13 +1776,8 @@ int do_add_mount(struct vfsmount *newmnt, struct path *path,
    if (S_ISLNK(newmnt->mnt_root->d_inode->i_mode))
    goto unlock;

    - /*
    - * Unions couldn't be writable if the filesystem doesn't know about
    - * whiteouts
    - */
    - err = -ENOTSUPP;
    - if ((mnt_flags & MNT_UNION) &&
    - !(newmnt->mnt_sb->s_flags & (MS_WHITEOUT|MS_RDONLY)))
    + err = check_union_mnt(path, newmnt, mnt_flags);
    + if (err)
    goto unlock;

    newmnt->mnt_flags = mnt_flags;
    --
    1.6.3.3


    \
     
     \ /
      Last update: 2009-10-21 21:45    [W:0.026 / U:33.280 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site