aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/namespace.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/namespace.c')
-rw-r--r--fs/nfs/namespace.c34
1 files changed, 24 insertions, 10 deletions
diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c
index 86b3169c8cac..77b00684894d 100644
--- a/fs/nfs/namespace.c
+++ b/fs/nfs/namespace.c
@@ -2,6 +2,7 @@
2 * linux/fs/nfs/namespace.c 2 * linux/fs/nfs/namespace.c
3 * 3 *
4 * Copyright (C) 2005 Trond Myklebust <Trond.Myklebust@netapp.com> 4 * Copyright (C) 2005 Trond Myklebust <Trond.Myklebust@netapp.com>
5 * - Modified by David Howells <dhowells@redhat.com>
5 * 6 *
6 * NFS namespace 7 * NFS namespace
7 */ 8 */
@@ -28,6 +29,7 @@ int nfs_mountpoint_expiry_timeout = 500 * HZ;
28/* 29/*
29 * nfs_path - reconstruct the path given an arbitrary dentry 30 * nfs_path - reconstruct the path given an arbitrary dentry
30 * @base - arbitrary string to prepend to the path 31 * @base - arbitrary string to prepend to the path
32 * @droot - pointer to root dentry for mountpoint
31 * @dentry - pointer to dentry 33 * @dentry - pointer to dentry
32 * @buffer - result buffer 34 * @buffer - result buffer
33 * @buflen - length of buffer 35 * @buflen - length of buffer
@@ -38,7 +40,9 @@ int nfs_mountpoint_expiry_timeout = 500 * HZ;
38 * This is mainly for use in figuring out the path on the 40 * This is mainly for use in figuring out the path on the
39 * server side when automounting on top of an existing partition. 41 * server side when automounting on top of an existing partition.
40 */ 42 */
41char *nfs_path(const char *base, const struct dentry *dentry, 43char *nfs_path(const char *base,
44 const struct dentry *droot,
45 const struct dentry *dentry,
42 char *buffer, ssize_t buflen) 46 char *buffer, ssize_t buflen)
43{ 47{
44 char *end = buffer+buflen; 48 char *end = buffer+buflen;
@@ -47,7 +51,7 @@ char *nfs_path(const char *base, const struct dentry *dentry,
47 *--end = '\0'; 51 *--end = '\0';
48 buflen--; 52 buflen--;
49 spin_lock(&dcache_lock); 53 spin_lock(&dcache_lock);
50 while (!IS_ROOT(dentry)) { 54 while (!IS_ROOT(dentry) && dentry != droot) {
51 namelen = dentry->d_name.len; 55 namelen = dentry->d_name.len;
52 buflen -= namelen + 1; 56 buflen -= namelen + 1;
53 if (buflen < 0) 57 if (buflen < 0)
@@ -96,15 +100,18 @@ static void * nfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
96 struct nfs_fattr fattr; 100 struct nfs_fattr fattr;
97 int err; 101 int err;
98 102
103 dprintk("--> nfs_follow_mountpoint()\n");
104
99 BUG_ON(IS_ROOT(dentry)); 105 BUG_ON(IS_ROOT(dentry));
100 dprintk("%s: enter\n", __FUNCTION__); 106 dprintk("%s: enter\n", __FUNCTION__);
101 dput(nd->dentry); 107 dput(nd->dentry);
102 nd->dentry = dget(dentry); 108 nd->dentry = dget(dentry);
103 if (d_mountpoint(nd->dentry)) 109
104 goto out_follow;
105 /* Look it up again */ 110 /* Look it up again */
106 parent = dget_parent(nd->dentry); 111 parent = dget_parent(nd->dentry);
107 err = server->rpc_ops->lookup(parent->d_inode, &nd->dentry->d_name, &fh, &fattr); 112 err = server->nfs_client->rpc_ops->lookup(parent->d_inode,
113 &nd->dentry->d_name,
114 &fh, &fattr);
108 dput(parent); 115 dput(parent);
109 if (err != 0) 116 if (err != 0)
110 goto out_err; 117 goto out_err;
@@ -132,6 +139,8 @@ static void * nfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
132 schedule_delayed_work(&nfs_automount_task, nfs_mountpoint_expiry_timeout); 139 schedule_delayed_work(&nfs_automount_task, nfs_mountpoint_expiry_timeout);
133out: 140out:
134 dprintk("%s: done, returned %d\n", __FUNCTION__, err); 141 dprintk("%s: done, returned %d\n", __FUNCTION__, err);
142
143 dprintk("<-- nfs_follow_mountpoint() = %d\n", err);
135 return ERR_PTR(err); 144 return ERR_PTR(err);
136out_err: 145out_err:
137 path_release(nd); 146 path_release(nd);
@@ -172,22 +181,23 @@ void nfs_release_automount_timer(void)
172/* 181/*
173 * Clone a mountpoint of the appropriate type 182 * Clone a mountpoint of the appropriate type
174 */ 183 */
175static struct vfsmount *nfs_do_clone_mount(struct nfs_server *server, char *devname, 184static struct vfsmount *nfs_do_clone_mount(struct nfs_server *server,
185 const char *devname,
176 struct nfs_clone_mount *mountdata) 186 struct nfs_clone_mount *mountdata)
177{ 187{
178#ifdef CONFIG_NFS_V4 188#ifdef CONFIG_NFS_V4
179 struct vfsmount *mnt = NULL; 189 struct vfsmount *mnt = NULL;
180 switch (server->rpc_ops->version) { 190 switch (server->nfs_client->cl_nfsversion) {
181 case 2: 191 case 2:
182 case 3: 192 case 3:
183 mnt = vfs_kern_mount(&clone_nfs_fs_type, 0, devname, mountdata); 193 mnt = vfs_kern_mount(&nfs_xdev_fs_type, 0, devname, mountdata);
184 break; 194 break;
185 case 4: 195 case 4:
186 mnt = vfs_kern_mount(&clone_nfs4_fs_type, 0, devname, mountdata); 196 mnt = vfs_kern_mount(&nfs4_xdev_fs_type, 0, devname, mountdata);
187 } 197 }
188 return mnt; 198 return mnt;
189#else 199#else
190 return vfs_kern_mount(&clone_nfs_fs_type, 0, devname, mountdata); 200 return vfs_kern_mount(&nfs_xdev_fs_type, 0, devname, mountdata);
191#endif 201#endif
192} 202}
193 203
@@ -213,6 +223,8 @@ struct vfsmount *nfs_do_submount(const struct vfsmount *mnt_parent,
213 char *page = (char *) __get_free_page(GFP_USER); 223 char *page = (char *) __get_free_page(GFP_USER);
214 char *devname; 224 char *devname;
215 225
226 dprintk("--> nfs_do_submount()\n");
227
216 dprintk("%s: submounting on %s/%s\n", __FUNCTION__, 228 dprintk("%s: submounting on %s/%s\n", __FUNCTION__,
217 dentry->d_parent->d_name.name, 229 dentry->d_parent->d_name.name,
218 dentry->d_name.name); 230 dentry->d_name.name);
@@ -227,5 +239,7 @@ free_page:
227 free_page((unsigned long)page); 239 free_page((unsigned long)page);
228out: 240out:
229 dprintk("%s: done\n", __FUNCTION__); 241 dprintk("%s: done\n", __FUNCTION__);
242
243 dprintk("<-- nfs_do_submount() = %p\n", mnt);
230 return mnt; 244 return mnt;
231} 245}