The patch titled unprivileged mounts: propagate error values from clone_mnt has been removed from the -mm tree. Its filename was unprivileged-mounts-propagate-error-values-from-clone_mnt.patch This patch was dropped because an updated version will be merged ------------------------------------------------------ Subject: unprivileged mounts: propagate error values from clone_mnt From: Miklos Szeredi <mszeredi@xxxxxxx> Allow clone_mnt() to return errors other than ENOMEM. This will be used for returning a different error value when the number of user mounts goes over the limit. Fix copy_tree() to return EPERM for unbindable mounts. Don't propagate further from dup_mnt_ns() as that copy_tree() can only fail with -ENOMEM. Signed-off-by: Miklos Szeredi <mszeredi@xxxxxxx> Cc: Serge Hallyn <serue@xxxxxxxxxx> Cc: "Eric W. Biederman" <ebiederm@xxxxxxxxxxxx> Cc: Christoph Hellwig <hch@xxxxxx> Cc: Al Viro <viro@xxxxxxxxxxxxxxxxxx> Cc: Ram Pai <linuxram@xxxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- fs/namespace.c | 88 +++++++++++++++++++++++------------------------ fs/pnode.c | 5 +- 2 files changed, 47 insertions(+), 46 deletions(-) diff -puN fs/namespace.c~unprivileged-mounts-propagate-error-values-from-clone_mnt fs/namespace.c --- a/fs/namespace.c~unprivileged-mounts-propagate-error-values-from-clone_mnt +++ a/fs/namespace.c @@ -261,42 +261,42 @@ static struct vfsmount *clone_mnt(struct { struct super_block *sb = old->mnt_sb; struct vfsmount *mnt = alloc_vfsmnt(old->mnt_devname); + if (!mnt) + return ERR_PTR(-ENOMEM); - if (mnt) { - mnt->mnt_flags = old->mnt_flags; - atomic_inc(&sb->s_active); - mnt->mnt_sb = sb; - mnt->mnt_root = dget(root); - mnt->mnt_mountpoint = mnt->mnt_root; - mnt->mnt_parent = mnt; - - /* don't copy the MNT_USER flag */ - mnt->mnt_flags &= ~MNT_USER; - if (flag & CL_SETUSER) - set_mnt_user(mnt); - - if (flag & CL_SLAVE) { - list_add(&mnt->mnt_slave, &old->mnt_slave_list); - mnt->mnt_master = old; - CLEAR_MNT_SHARED(mnt); - } else { - if ((flag & CL_PROPAGATION) || IS_MNT_SHARED(old)) - list_add(&mnt->mnt_share, &old->mnt_share); - if (IS_MNT_SLAVE(old)) - list_add(&mnt->mnt_slave, &old->mnt_slave); - mnt->mnt_master = old->mnt_master; - } - if (flag & CL_MAKE_SHARED) - set_mnt_shared(mnt); + mnt->mnt_flags = old->mnt_flags; + atomic_inc(&sb->s_active); + mnt->mnt_sb = sb; + mnt->mnt_root = dget(root); + mnt->mnt_mountpoint = mnt->mnt_root; + mnt->mnt_parent = mnt; + + /* don't copy the MNT_USER flag */ + mnt->mnt_flags &= ~MNT_USER; + if (flag & CL_SETUSER) + set_mnt_user(mnt); - /* stick the duplicate mount on the same expiry list - * as the original if that was on one */ - if (flag & CL_EXPIRE) { - spin_lock(&vfsmount_lock); - if (!list_empty(&old->mnt_expire)) - list_add(&mnt->mnt_expire, &old->mnt_expire); - spin_unlock(&vfsmount_lock); - } + if (flag & CL_SLAVE) { + list_add(&mnt->mnt_slave, &old->mnt_slave_list); + mnt->mnt_master = old; + CLEAR_MNT_SHARED(mnt); + } else { + if ((flag & CL_PROPAGATION) || IS_MNT_SHARED(old)) + list_add(&mnt->mnt_share, &old->mnt_share); + if (IS_MNT_SLAVE(old)) + list_add(&mnt->mnt_slave, &old->mnt_slave); + mnt->mnt_master = old->mnt_master; + } + if (flag & CL_MAKE_SHARED) + set_mnt_shared(mnt); + + /* stick the duplicate mount on the same expiry list + * as the original if that was on one */ + if (flag & CL_EXPIRE) { + spin_lock(&vfsmount_lock); + if (!list_empty(&old->mnt_expire)) + list_add(&mnt->mnt_expire, &old->mnt_expire); + spin_unlock(&vfsmount_lock); } return mnt; } @@ -781,11 +781,11 @@ struct vfsmount *copy_tree(struct vfsmou struct nameidata nd; if (!(flag & CL_COPY_ALL) && IS_MNT_UNBINDABLE(mnt)) - return NULL; + return ERR_PTR(-EPERM); res = q = clone_mnt(mnt, dentry, flag); - if (!q) - goto Enomem; + if (IS_ERR(q)) + goto error; q->mnt_mountpoint = mnt->mnt_mountpoint; p = mnt; @@ -806,8 +806,8 @@ struct vfsmount *copy_tree(struct vfsmou nd.mnt = q; nd.dentry = p->mnt_mountpoint; q = clone_mnt(p, p->mnt_root, flag); - if (!q) - goto Enomem; + if (IS_ERR(q)) + goto error; spin_lock(&vfsmount_lock); list_add_tail(&q->mnt_list, &res->mnt_list); attach_mnt(q, &nd); @@ -815,7 +815,7 @@ struct vfsmount *copy_tree(struct vfsmou } } return res; -Enomem: + error: if (res) { LIST_HEAD(umount_list); spin_lock(&vfsmount_lock); @@ -823,7 +823,7 @@ Enomem: spin_unlock(&vfsmount_lock); release_mounts(&umount_list); } - return NULL; + return q; } /* @@ -1002,13 +1002,13 @@ static int do_loopback(struct nameidata goto out; clone_flags = (flags & MS_SETUSER) ? CL_SETUSER : 0; - err = -ENOMEM; if (flags & MS_REC) mnt = copy_tree(old_nd.mnt, old_nd.dentry, clone_flags); else mnt = clone_mnt(old_nd.mnt, old_nd.dentry, clone_flags); - if (!mnt) + err = PTR_ERR(mnt); + if (IS_ERR(mnt)) goto out; err = graft_tree(mnt, nd); @@ -1553,7 +1553,7 @@ static struct mnt_namespace *dup_mnt_ns( /* First pass: copy the tree topology */ new_ns->root = copy_tree(mnt_ns->root, mnt_ns->root->mnt_root, CL_COPY_ALL | CL_EXPIRE); - if (!new_ns->root) { + if (IS_ERR(new_ns->root)) { up_write(&namespace_sem); kfree(new_ns); return NULL; diff -puN fs/pnode.c~unprivileged-mounts-propagate-error-values-from-clone_mnt fs/pnode.c --- a/fs/pnode.c~unprivileged-mounts-propagate-error-values-from-clone_mnt +++ a/fs/pnode.c @@ -187,8 +187,9 @@ int propagate_mnt(struct vfsmount *dest_ source = get_source(m, prev_dest_mnt, prev_src_mnt, &type); - if (!(child = copy_tree(source, source->mnt_root, type))) { - ret = -ENOMEM; + child = copy_tree(source, source->mnt_root, type); + if (IS_ERR(child)) { + ret = PTR_ERR(child); list_splice(tree_list, tmp_list.prev); goto out; } _ Patches currently in -mm which might be from mszeredi@xxxxxxx are split-mmap.patch only-allow-nonlinear-vmas-for-ram-backed-filesystems.patch fix-quadratic-behavior-of-shrink_dcache_parent.patch mm-shrink-parent-dentries-when-shrinking-slab.patch add-filesystem-subtype-support.patch add-file-position-info-to-proc.patch add-file-position-info-to-proc-fix.patch check-privileges-before-setting-mount-propagation.patch consolidate-generic_writepages-and-mpage_writepages.patch unprivileged-mounts-propagate-error-values-from-clone_mnt.patch unprivileged-mounts-propagate-error-values-from-clone_mnt-fix.patch unprivileged-mounts-allow-unprivileged-bind-mounts.patch unprivileged-mounts-allow-unprivileged-bind-mounts-fix.patch unprivileged-mounts-put-declaration-of-put_filesystem-in-fsh.patch unprivileged-mounts-allow-unprivileged-mounts.patch unprivileged-mounts-allow-unprivileged-fuse-mounts.patch - To unsubscribe from this list: send the line "unsubscribe mm-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html