Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 192286
b: refs/heads/master
c: 815409d
h: refs/heads/master
v: v3
  • Loading branch information
Trond Myklebust authored and Trond Myklebust committed May 14, 2010
1 parent 54db8c3 commit 0eec994
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 99 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 2d36bfde8565b315e624302d12da5a7c9d195522
refs/heads/master: 815409d22df870ea0b0d86f2a3bf33c35bcef55c
4 changes: 2 additions & 2 deletions trunk/fs/nfs/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -1364,7 +1364,7 @@ struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data,
goto error;

/* Probe the root fh to retrieve its FSID */
error = nfs4_path_walk(server, mntfh, data->nfs_server.export_path);
error = nfs4_get_rootfh(server, mntfh);
if (error < 0)
goto error;

Expand Down Expand Up @@ -1443,7 +1443,7 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops);

/* Probe the root fh to retrieve its FSID and filehandle */
error = nfs4_path_walk(server, mntfh, data->mnt_path);
error = nfs4_get_rootfh(server, mntfh);
if (error < 0)
goto error;

Expand Down
115 changes: 22 additions & 93 deletions trunk/fs/nfs/getroot.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,115 +122,44 @@ struct dentry *nfs_get_root(struct super_block *sb, struct nfs_fh *mntfh)

#ifdef CONFIG_NFS_V4

/*
* Do a simple pathwalk from the root FH of the server to the nominated target
* of the mountpoint
* - give error on symlinks
* - give error on ".." occurring in the path
* - follow traversals
*/
int nfs4_path_walk(struct nfs_server *server,
struct nfs_fh *mntfh,
const char *path)
int nfs4_get_rootfh(struct nfs_server *server, struct nfs_fh *mntfh)
{
struct nfs_fsinfo fsinfo;
struct nfs_fattr fattr;
struct nfs_fh lastfh;
struct qstr name;
int ret;
int ret = -ENOMEM;

dprintk("--> nfs4_path_walk(,,%s)\n", path);
dprintk("--> nfs4_get_rootfh()\n");

fsinfo.fattr = &fattr;
nfs_fattr_init(&fattr);

/* Eat leading slashes */
while (*path == '/')
path++;
fsinfo.fattr = nfs_alloc_fattr();
if (fsinfo.fattr == NULL)
goto out;

/* Start by getting the root filehandle from the server */
ret = server->nfs_client->rpc_ops->getroot(server, mntfh, &fsinfo);
if (ret < 0) {
dprintk("nfs4_get_root: getroot error = %d\n", -ret);
return ret;
dprintk("nfs4_get_rootfh: getroot error = %d\n", -ret);
goto out;
}

if (!S_ISDIR(fattr.mode)) {
printk(KERN_ERR "nfs4_get_root:"
if (!(fsinfo.fattr->valid & NFS_ATTR_FATTR_MODE)
|| !S_ISDIR(fsinfo.fattr->mode)) {
printk(KERN_ERR "nfs4_get_rootfh:"
" getroot encountered non-directory\n");
return -ENOTDIR;
ret = -ENOTDIR;
goto out;
}

/* FIXME: It is quite valid for the server to return a referral here */
if (fattr.valid & NFS_ATTR_FATTR_V4_REFERRAL) {
printk(KERN_ERR "nfs4_get_root:"
if (fsinfo.fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL) {
printk(KERN_ERR "nfs4_get_rootfh:"
" getroot obtained referral\n");
return -EREMOTE;
ret = -EREMOTE;
goto out;
}

next_component:
dprintk("Next: %s\n", path);

/* extract the next bit of the path */
if (!*path)
goto path_walk_complete;

name.name = path;
while (*path && *path != '/')
path++;
name.len = path - (const char *) name.name;

if (name.len > NFS4_MAXNAMLEN)
return -ENAMETOOLONG;

eat_dot_dir:
while (*path == '/')
path++;

if (path[0] == '.' && (path[1] == '/' || !path[1])) {
path += 2;
goto eat_dot_dir;
}

/* FIXME: Why shouldn't the user be able to use ".." in the path? */
if (path[0] == '.' && path[1] == '.' && (path[2] == '/' || !path[2])
) {
printk(KERN_ERR "nfs4_get_root:"
" Mount path contains reference to \"..\"\n");
return -EINVAL;
}

/* lookup the next FH in the sequence */
memcpy(&lastfh, mntfh, sizeof(lastfh));

dprintk("LookupFH: %*.*s [%s]\n", name.len, name.len, name.name, path);

ret = server->nfs_client->rpc_ops->lookupfh(server, &lastfh, &name,
mntfh, &fattr);
if (ret < 0) {
dprintk("nfs4_get_root: getroot error = %d\n", -ret);
return ret;
}

if (!S_ISDIR(fattr.mode)) {
printk(KERN_ERR "nfs4_get_root:"
" lookupfh encountered non-directory\n");
return -ENOTDIR;
}

/* FIXME: Referrals are quite valid here too */
if (fattr.valid & NFS_ATTR_FATTR_V4_REFERRAL) {
printk(KERN_ERR "nfs4_get_root:"
" lookupfh obtained referral\n");
return -EREMOTE;
}

goto next_component;

path_walk_complete:
memcpy(&server->fsid, &fattr.fsid, sizeof(server->fsid));
dprintk("<-- nfs4_path_walk() = 0\n");
return 0;
memcpy(&server->fsid, &fsinfo.fattr->fsid, sizeof(server->fsid));
out:
nfs_free_fattr(fsinfo.fattr);
dprintk("<-- nfs4_get_rootfh() = %d\n", ret);
return ret;
}

/*
Expand Down
4 changes: 1 addition & 3 deletions trunk/fs/nfs/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -244,9 +244,7 @@ extern struct dentry *nfs_get_root(struct super_block *, struct nfs_fh *);
#ifdef CONFIG_NFS_V4
extern struct dentry *nfs4_get_root(struct super_block *, struct nfs_fh *);

extern int nfs4_path_walk(struct nfs_server *server,
struct nfs_fh *mntfh,
const char *path);
extern int nfs4_get_rootfh(struct nfs_server *server, struct nfs_fh *mntfh);
#endif

/* read.c */
Expand Down

0 comments on commit 0eec994

Please sign in to comment.