diff options
Diffstat (limited to 'fs/nfs/namespace.c')
-rw-r--r-- | fs/nfs/namespace.c | 25 |
1 files changed, 18 insertions, 7 deletions
diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c index d8b8d56266cb..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 | */ |
41 | char *nfs_path(const char *base, const struct dentry *dentry, | 43 | char *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,12 +100,13 @@ 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->nfs_client->rpc_ops->lookup(parent->d_inode, | 112 | err = server->nfs_client->rpc_ops->lookup(parent->d_inode, |
@@ -134,6 +139,8 @@ static void * nfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd) | |||
134 | schedule_delayed_work(&nfs_automount_task, nfs_mountpoint_expiry_timeout); | 139 | schedule_delayed_work(&nfs_automount_task, nfs_mountpoint_expiry_timeout); |
135 | out: | 140 | out: |
136 | 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); | ||
137 | return ERR_PTR(err); | 144 | return ERR_PTR(err); |
138 | out_err: | 145 | out_err: |
139 | path_release(nd); | 146 | path_release(nd); |
@@ -183,14 +190,14 @@ static struct vfsmount *nfs_do_clone_mount(struct nfs_server *server, | |||
183 | switch (server->nfs_client->cl_nfsversion) { | 190 | switch (server->nfs_client->cl_nfsversion) { |
184 | case 2: | 191 | case 2: |
185 | case 3: | 192 | case 3: |
186 | mnt = vfs_kern_mount(&clone_nfs_fs_type, 0, devname, mountdata); | 193 | mnt = vfs_kern_mount(&nfs_xdev_fs_type, 0, devname, mountdata); |
187 | break; | 194 | break; |
188 | case 4: | 195 | case 4: |
189 | mnt = vfs_kern_mount(&clone_nfs4_fs_type, 0, devname, mountdata); | 196 | mnt = vfs_kern_mount(&nfs4_xdev_fs_type, 0, devname, mountdata); |
190 | } | 197 | } |
191 | return mnt; | 198 | return mnt; |
192 | #else | 199 | #else |
193 | return vfs_kern_mount(&clone_nfs_fs_type, 0, devname, mountdata); | 200 | return vfs_kern_mount(&nfs_xdev_fs_type, 0, devname, mountdata); |
194 | #endif | 201 | #endif |
195 | } | 202 | } |
196 | 203 | ||
@@ -216,6 +223,8 @@ struct vfsmount *nfs_do_submount(const struct vfsmount *mnt_parent, | |||
216 | char *page = (char *) __get_free_page(GFP_USER); | 223 | char *page = (char *) __get_free_page(GFP_USER); |
217 | char *devname; | 224 | char *devname; |
218 | 225 | ||
226 | dprintk("--> nfs_do_submount()\n"); | ||
227 | |||
219 | dprintk("%s: submounting on %s/%s\n", __FUNCTION__, | 228 | dprintk("%s: submounting on %s/%s\n", __FUNCTION__, |
220 | dentry->d_parent->d_name.name, | 229 | dentry->d_parent->d_name.name, |
221 | dentry->d_name.name); | 230 | dentry->d_name.name); |
@@ -230,5 +239,7 @@ free_page: | |||
230 | free_page((unsigned long)page); | 239 | free_page((unsigned long)page); |
231 | out: | 240 | out: |
232 | dprintk("%s: done\n", __FUNCTION__); | 241 | dprintk("%s: done\n", __FUNCTION__); |
242 | |||
243 | dprintk("<-- nfs_do_submount() = %p\n", mnt); | ||
233 | return mnt; | 244 | return mnt; |
234 | } | 245 | } |