diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2010-04-16 16:22:46 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2010-05-14 15:09:21 -0400 |
commit | 815409d22df870ea0b0d86f2a3bf33c35bcef55c (patch) | |
tree | 99fa8d5ac56d3f14fa1313739d3f9b65176f4e8f /fs/nfs/getroot.c | |
parent | 2d36bfde8565b315e624302d12da5a7c9d195522 (diff) |
NFSv4: Eliminate nfs4_path_walk()
All we really want is the ability to retrieve the root file handle. We no
longer need the ability to walk down the path, since that is now done in
nfs_follow_remote_path().
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/getroot.c')
-rw-r--r-- | fs/nfs/getroot.c | 115 |
1 files changed, 22 insertions, 93 deletions
diff --git a/fs/nfs/getroot.c b/fs/nfs/getroot.c index b35d2a616066..ada369a5647b 100644 --- a/fs/nfs/getroot.c +++ b/fs/nfs/getroot.c | |||
@@ -122,115 +122,44 @@ struct dentry *nfs_get_root(struct super_block *sb, struct nfs_fh *mntfh) | |||
122 | 122 | ||
123 | #ifdef CONFIG_NFS_V4 | 123 | #ifdef CONFIG_NFS_V4 |
124 | 124 | ||
125 | /* | 125 | int nfs4_get_rootfh(struct nfs_server *server, struct nfs_fh *mntfh) |
126 | * Do a simple pathwalk from the root FH of the server to the nominated target | ||
127 | * of the mountpoint | ||
128 | * - give error on symlinks | ||
129 | * - give error on ".." occurring in the path | ||
130 | * - follow traversals | ||
131 | */ | ||
132 | int nfs4_path_walk(struct nfs_server *server, | ||
133 | struct nfs_fh *mntfh, | ||
134 | const char *path) | ||
135 | { | 126 | { |
136 | struct nfs_fsinfo fsinfo; | 127 | struct nfs_fsinfo fsinfo; |
137 | struct nfs_fattr fattr; | 128 | int ret = -ENOMEM; |
138 | struct nfs_fh lastfh; | ||
139 | struct qstr name; | ||
140 | int ret; | ||
141 | 129 | ||
142 | dprintk("--> nfs4_path_walk(,,%s)\n", path); | 130 | dprintk("--> nfs4_get_rootfh()\n"); |
143 | 131 | ||
144 | fsinfo.fattr = &fattr; | 132 | fsinfo.fattr = nfs_alloc_fattr(); |
145 | nfs_fattr_init(&fattr); | 133 | if (fsinfo.fattr == NULL) |
146 | 134 | goto out; | |
147 | /* Eat leading slashes */ | ||
148 | while (*path == '/') | ||
149 | path++; | ||
150 | 135 | ||
151 | /* Start by getting the root filehandle from the server */ | 136 | /* Start by getting the root filehandle from the server */ |
152 | ret = server->nfs_client->rpc_ops->getroot(server, mntfh, &fsinfo); | 137 | ret = server->nfs_client->rpc_ops->getroot(server, mntfh, &fsinfo); |
153 | if (ret < 0) { | 138 | if (ret < 0) { |
154 | dprintk("nfs4_get_root: getroot error = %d\n", -ret); | 139 | dprintk("nfs4_get_rootfh: getroot error = %d\n", -ret); |
155 | return ret; | 140 | goto out; |
156 | } | 141 | } |
157 | 142 | ||
158 | if (!S_ISDIR(fattr.mode)) { | 143 | if (!(fsinfo.fattr->valid & NFS_ATTR_FATTR_MODE) |
159 | printk(KERN_ERR "nfs4_get_root:" | 144 | || !S_ISDIR(fsinfo.fattr->mode)) { |
145 | printk(KERN_ERR "nfs4_get_rootfh:" | ||
160 | " getroot encountered non-directory\n"); | 146 | " getroot encountered non-directory\n"); |
161 | return -ENOTDIR; | 147 | ret = -ENOTDIR; |
148 | goto out; | ||
162 | } | 149 | } |
163 | 150 | ||
164 | /* FIXME: It is quite valid for the server to return a referral here */ | 151 | if (fsinfo.fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL) { |
165 | if (fattr.valid & NFS_ATTR_FATTR_V4_REFERRAL) { | 152 | printk(KERN_ERR "nfs4_get_rootfh:" |
166 | printk(KERN_ERR "nfs4_get_root:" | ||
167 | " getroot obtained referral\n"); | 153 | " getroot obtained referral\n"); |
168 | return -EREMOTE; | 154 | ret = -EREMOTE; |
155 | goto out; | ||
169 | } | 156 | } |
170 | 157 | ||
171 | next_component: | 158 | memcpy(&server->fsid, &fsinfo.fattr->fsid, sizeof(server->fsid)); |
172 | dprintk("Next: %s\n", path); | 159 | out: |
173 | 160 | nfs_free_fattr(fsinfo.fattr); | |
174 | /* extract the next bit of the path */ | 161 | dprintk("<-- nfs4_get_rootfh() = %d\n", ret); |
175 | if (!*path) | 162 | return ret; |
176 | goto path_walk_complete; | ||
177 | |||
178 | name.name = path; | ||
179 | while (*path && *path != '/') | ||
180 | path++; | ||
181 | name.len = path - (const char *) name.name; | ||
182 | |||
183 | if (name.len > NFS4_MAXNAMLEN) | ||
184 | return -ENAMETOOLONG; | ||
185 | |||
186 | eat_dot_dir: | ||
187 | while (*path == '/') | ||
188 | path++; | ||
189 | |||
190 | if (path[0] == '.' && (path[1] == '/' || !path[1])) { | ||
191 | path += 2; | ||
192 | goto eat_dot_dir; | ||
193 | } | ||
194 | |||
195 | /* FIXME: Why shouldn't the user be able to use ".." in the path? */ | ||
196 | if (path[0] == '.' && path[1] == '.' && (path[2] == '/' || !path[2]) | ||
197 | ) { | ||
198 | printk(KERN_ERR "nfs4_get_root:" | ||
199 | " Mount path contains reference to \"..\"\n"); | ||
200 | return -EINVAL; | ||
201 | } | ||
202 | |||
203 | /* lookup the next FH in the sequence */ | ||
204 | memcpy(&lastfh, mntfh, sizeof(lastfh)); | ||
205 | |||
206 | dprintk("LookupFH: %*.*s [%s]\n", name.len, name.len, name.name, path); | ||
207 | |||
208 | ret = server->nfs_client->rpc_ops->lookupfh(server, &lastfh, &name, | ||
209 | mntfh, &fattr); | ||
210 | if (ret < 0) { | ||
211 | dprintk("nfs4_get_root: getroot error = %d\n", -ret); | ||
212 | return ret; | ||
213 | } | ||
214 | |||
215 | if (!S_ISDIR(fattr.mode)) { | ||
216 | printk(KERN_ERR "nfs4_get_root:" | ||
217 | " lookupfh encountered non-directory\n"); | ||
218 | return -ENOTDIR; | ||
219 | } | ||
220 | |||
221 | /* FIXME: Referrals are quite valid here too */ | ||
222 | if (fattr.valid & NFS_ATTR_FATTR_V4_REFERRAL) { | ||
223 | printk(KERN_ERR "nfs4_get_root:" | ||
224 | " lookupfh obtained referral\n"); | ||
225 | return -EREMOTE; | ||
226 | } | ||
227 | |||
228 | goto next_component; | ||
229 | |||
230 | path_walk_complete: | ||
231 | memcpy(&server->fsid, &fattr.fsid, sizeof(server->fsid)); | ||
232 | dprintk("<-- nfs4_path_walk() = 0\n"); | ||
233 | return 0; | ||
234 | } | 163 | } |
235 | 164 | ||
236 | /* | 165 | /* |