[patch 06/10] propagate error values from clone_mnt
From: Miklos Szeredi [EMAIL PROTECTED] 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 [EMAIL PROTECTED] --- Index: linux/fs/namespace.c === --- linux.orig/fs/namespace.c 2007-04-13 13:22:17.0 +0200 +++ linux/fs/namespace.c2007-04-13 13:25:35.0 +0200 @@ -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; } @@ -782,11 +782,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; @@ -807,8 +807,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); @@ -816,7 +816,7 @@ struct vfsmount *copy_tree(struct vfsmou } } return res; -Enomem: + error: if (res) { LIST_HEAD(umount_list); spin_lock(vfsmount_lock); @@ -824,7 +824,7 @@ Enomem: spin_unlock(vfsmount_lock); release_mounts(umount_list); } - return
[patch 06/10] propagate error values from clone_mnt
From: Miklos Szeredi [EMAIL PROTECTED] 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 [EMAIL PROTECTED] --- Index: linux/fs/namespace.c === --- linux.orig/fs/namespace.c 2007-04-12 13:54:36.0 +0200 +++ linux/fs/namespace.c2007-04-12 14:04:25.0 +0200 @@ -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