Skip to content

Commit

Permalink
VFS: Add VFS helper functions for setting up private namespaces
Browse files Browse the repository at this point in the history
The purpose of this patch is to improve the remote mount path lookup
support for distributed filesystems such as the NFSv4 client.

When given a mount command of the form "mount server:/foo/bar /mnt", the
NFSv4 client is required to look up the filehandle for "server:/", and
then look up each component of the remote mount path "foo/bar" in order
to find the directory that is actually going to be mounted on /mnt.
Following that remote mount path may involve following symlinks,
crossing server-side mount points and even following referrals to
filesystem volumes on other servers.

Since the standard VFS path lookup code already supports walking paths
that contain all these features (using in-kernel automounts for
following referrals) we would like to be able to reuse that rather than
duplicate the full path traversal functionality in the NFSv4 client code.

This patch therefore defines a VFS helper function create_mnt_ns(), that
sets up a temporary filesystem namespace and attaches a root filesystem to
it. It exports the create_mnt_ns() and put_mnt_ns() function for use by
filesystem modules.

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Trond Myklebust authored and Linus Torvalds committed Jun 23, 2009
1 parent 616511d commit cf8d2c1
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 8 deletions.
45 changes: 37 additions & 8 deletions fs/namespace.c
Original file line number Diff line number Diff line change
Expand Up @@ -1937,6 +1937,21 @@ long do_mount(char *dev_name, char *dir_name, char *type_page,
return retval;
}

static struct mnt_namespace *alloc_mnt_ns(void)
{
struct mnt_namespace *new_ns;

new_ns = kmalloc(sizeof(struct mnt_namespace), GFP_KERNEL);
if (!new_ns)
return ERR_PTR(-ENOMEM);
atomic_set(&new_ns->count, 1);
new_ns->root = NULL;
INIT_LIST_HEAD(&new_ns->list);
init_waitqueue_head(&new_ns->poll);
new_ns->event = 0;
return new_ns;
}

/*
* Allocate a new namespace structure and populate it with contents
* copied from the namespace of the passed in task structure.
Expand All @@ -1948,14 +1963,9 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns,
struct vfsmount *rootmnt = NULL, *pwdmnt = NULL;
struct vfsmount *p, *q;

new_ns = kmalloc(sizeof(struct mnt_namespace), GFP_KERNEL);
if (!new_ns)
return ERR_PTR(-ENOMEM);

atomic_set(&new_ns->count, 1);
INIT_LIST_HEAD(&new_ns->list);
init_waitqueue_head(&new_ns->poll);
new_ns->event = 0;
new_ns = alloc_mnt_ns();
if (IS_ERR(new_ns))
return new_ns;

down_write(&namespace_sem);
/* First pass: copy the tree topology */
Expand Down Expand Up @@ -2019,6 +2029,24 @@ struct mnt_namespace *copy_mnt_ns(unsigned long flags, struct mnt_namespace *ns,
return new_ns;
}

/**
* create_mnt_ns - creates a private namespace and adds a root filesystem
* @mnt: pointer to the new root filesystem mountpoint
*/
struct mnt_namespace *create_mnt_ns(struct vfsmount *mnt)
{
struct mnt_namespace *new_ns;

new_ns = alloc_mnt_ns();
if (!IS_ERR(new_ns)) {
mnt->mnt_ns = new_ns;
new_ns->root = mnt;
list_add(&new_ns->list, &new_ns->root->mnt_list);
}
return new_ns;
}
EXPORT_SYMBOL(create_mnt_ns);

SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name,
char __user *, type, unsigned long, flags, void __user *, data)
{
Expand Down Expand Up @@ -2264,3 +2292,4 @@ void put_mnt_ns(struct mnt_namespace *ns)
release_mounts(&umount_list);
kfree(ns);
}
EXPORT_SYMBOL(put_mnt_ns);
1 change: 1 addition & 0 deletions include/linux/mnt_namespace.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ struct proc_mounts {

struct fs_struct;

extern struct mnt_namespace *create_mnt_ns(struct vfsmount *mnt);
extern struct mnt_namespace *copy_mnt_ns(unsigned long, struct mnt_namespace *,
struct fs_struct *);
extern void put_mnt_ns(struct mnt_namespace *ns);
Expand Down

0 comments on commit cf8d2c1

Please sign in to comment.