diff options
| author | Takashi Iwai <tiwai@suse.de> | 2012-05-21 12:45:18 +0200 | 
|---|---|---|
| committer | Takashi Iwai <tiwai@suse.de> | 2012-05-21 12:45:18 +0200 | 
| commit | 775b2449bdba7c97dda9f274c92bf7a83dac4142 (patch) | |
| tree | b4bee45c13762ea93642b1e38c62de454e51cf5d /fs/nfs/nfs4namespace.c | |
| parent | 21363cf0ca5c9c62e34e37422fb1d13d70d3de3c (diff) | |
| parent | 5fb86e5d4a951ddb0474cdfd809380c8e2a8d101 (diff) | |
| download | olio-linux-3.10-775b2449bdba7c97dda9f274c92bf7a83dac4142.tar.xz olio-linux-3.10-775b2449bdba7c97dda9f274c92bf7a83dac4142.zip  | |
Merge branch 'topic/asoc' into for-linus
Diffstat (limited to 'fs/nfs/nfs4namespace.c')
| -rw-r--r-- | fs/nfs/nfs4namespace.c | 86 | 
1 files changed, 81 insertions, 5 deletions
diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c index 9c8eca315f4..a7f3dedc4ec 100644 --- a/fs/nfs/nfs4namespace.c +++ b/fs/nfs/nfs4namespace.c @@ -52,6 +52,30 @@ Elong:  }  /* + * return the path component of "<server>:<path>" + *  nfspath - the "<server>:<path>" string + *  end - one past the last char that could contain "<server>:" + * returns NULL on failure + */ +static char *nfs_path_component(const char *nfspath, const char *end) +{ +	char *p; + +	if (*nfspath == '[') { +		/* parse [] escaped IPv6 addrs */ +		p = strchr(nfspath, ']'); +		if (p != NULL && ++p < end && *p == ':') +			return p + 1; +	} else { +		/* otherwise split on first colon */ +		p = strchr(nfspath, ':'); +		if (p != NULL && p < end) +			return p + 1; +	} +	return NULL; +} + +/*   * Determine the mount path as a string   */  static char *nfs4_path(struct dentry *dentry, char *buffer, ssize_t buflen) @@ -59,9 +83,9 @@ static char *nfs4_path(struct dentry *dentry, char *buffer, ssize_t buflen)  	char *limit;  	char *path = nfs_path(&limit, dentry, buffer, buflen);  	if (!IS_ERR(path)) { -		char *colon = strchr(path, ':'); -		if (colon && colon < limit) -			path = colon + 1; +		char *path_component = nfs_path_component(path, limit); +		if (path_component) +			return path_component;  	}  	return path;  } @@ -108,6 +132,58 @@ static size_t nfs_parse_server_name(char *string, size_t len,  	return ret;  } +static rpc_authflavor_t nfs4_negotiate_security(struct inode *inode, struct qstr *name) +{ +	struct page *page; +	struct nfs4_secinfo_flavors *flavors; +	rpc_authflavor_t flavor; +	int err; + +	page = alloc_page(GFP_KERNEL); +	if (!page) +		return -ENOMEM; +	flavors = page_address(page); + +	err = nfs4_proc_secinfo(inode, name, flavors); +	if (err < 0) { +		flavor = err; +		goto out; +	} + +	flavor = nfs_find_best_sec(flavors); + +out: +	put_page(page); +	return flavor; +} + +/* + * Please call rpc_shutdown_client() when you are done with this client. + */ +struct rpc_clnt *nfs4_create_sec_client(struct rpc_clnt *clnt, struct inode *inode, +					struct qstr *name) +{ +	struct rpc_clnt *clone; +	struct rpc_auth *auth; +	rpc_authflavor_t flavor; + +	flavor = nfs4_negotiate_security(inode, name); +	if (flavor < 0) +		return ERR_PTR(flavor); + +	clone = rpc_clone_client(clnt); +	if (IS_ERR(clone)) +		return clone; + +	auth = rpcauth_create(flavor, clone); +	if (!auth) { +		rpc_shutdown_client(clone); +		clone = ERR_PTR(-EIO); +	} + +	return clone; +} +  static struct vfsmount *try_location(struct nfs_clone_mount *mountdata,  				     char *page, char *page2,  				     const struct nfs4_fs_location *location) @@ -224,7 +300,7 @@ out:   * @dentry - dentry of referral   *   */ -struct vfsmount *nfs_do_refmount(struct dentry *dentry) +struct vfsmount *nfs_do_refmount(struct rpc_clnt *client, struct dentry *dentry)  {  	struct vfsmount *mnt = ERR_PTR(-ENOMEM);  	struct dentry *parent; @@ -250,7 +326,7 @@ struct vfsmount *nfs_do_refmount(struct dentry *dentry)  	dprintk("%s: getting locations for %s/%s\n",  		__func__, parent->d_name.name, dentry->d_name.name); -	err = nfs4_proc_fs_locations(parent->d_inode, &dentry->d_name, fs_locations, page); +	err = nfs4_proc_fs_locations(client, parent->d_inode, &dentry->d_name, fs_locations, page);  	dput(parent);  	if (err != 0 ||  	    fs_locations->nlocations <= 0 ||  |