patch-2.4.18 linux/fs/namespace.c
Next file: linux/fs/nfs/file.c
Previous file: linux/fs/namei.c
Back to the patch index
Back to the overall index
- Lines: 77
- Date:
Wed Jan 23 21:21:17 2002
- Orig file:
linux.orig/fs/namespace.c
- Orig date:
Mon Feb 18 20:18:40 2002
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/namespace.c linux/fs/namespace.c
@@ -563,6 +563,67 @@
return err;
}
+static int do_move_mount(struct nameidata *nd, char *old_name)
+{
+ struct nameidata old_nd, parent_nd;
+ struct vfsmount *p;
+ int err = 0;
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ if (!old_name || !*old_name)
+ return -EINVAL;
+ if (path_init(old_name, LOOKUP_POSITIVE|LOOKUP_FOLLOW, &old_nd))
+ err = path_walk(old_name, &old_nd);
+ if (err)
+ return err;
+
+ down(&mount_sem);
+ while(d_mountpoint(nd->dentry) && follow_down(&nd->mnt, &nd->dentry))
+ ;
+ err = -EINVAL;
+ if (!check_mnt(nd->mnt) || !check_mnt(old_nd.mnt))
+ goto out;
+
+ err = -ENOENT;
+ down(&nd->dentry->d_inode->i_zombie);
+ if (IS_DEADDIR(nd->dentry->d_inode))
+ goto out1;
+
+ spin_lock(&dcache_lock);
+ if (!IS_ROOT(nd->dentry) && d_unhashed(nd->dentry))
+ goto out2;
+
+ err = -EINVAL;
+ if (old_nd.dentry != old_nd.mnt->mnt_root)
+ goto out2;
+
+ if (old_nd.mnt == old_nd.mnt->mnt_parent)
+ goto out2;
+
+ if (S_ISDIR(nd->dentry->d_inode->i_mode) !=
+ S_ISDIR(old_nd.dentry->d_inode->i_mode))
+ goto out2;
+
+ err = -ELOOP;
+ for (p = nd->mnt; p->mnt_parent!=p; p = p->mnt_parent)
+ if (p == old_nd.mnt)
+ goto out2;
+ err = 0;
+
+ detach_mnt(old_nd.mnt, &parent_nd);
+ attach_mnt(old_nd.mnt, nd);
+out2:
+ spin_unlock(&dcache_lock);
+out1:
+ up(&nd->dentry->d_inode->i_zombie);
+out:
+ up(&mount_sem);
+ if (!err)
+ path_release(&parent_nd);
+ path_release(&old_nd);
+ return err;
+}
+
static int do_add_mount(struct nameidata *nd, char *type, int flags,
int mnt_flags, char *name, void *data)
{
@@ -679,6 +740,8 @@
data_page);
else if (flags & MS_BIND)
retval = do_loopback(&nd, dev_name, flags & MS_REC);
+ else if (flags & MS_MOVE)
+ retval = do_move_mount(&nd, dev_name);
else
retval = do_add_mount(&nd, type_page, flags, mnt_flags,
dev_name, data_page);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)