diff options
| author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2012-05-08 13:39:59 +0200 | 
|---|---|---|
| committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2012-05-08 13:39:59 +0200 | 
| commit | 5e13a0c5ec05d382b488a691dfb8af015b1dea1e (patch) | |
| tree | 7a06dfa1f7661f8908193f2437b32452520221d3 /fs/nfs/nfs4namespace.c | |
| parent | b615b57a124a4af7b68196bc2fb8acc236041fa2 (diff) | |
| parent | 4f256e8aa3eda15c11c3cec3ec5336e1fc579cbd (diff) | |
| download | olio-linux-3.10-5e13a0c5ec05d382b488a691dfb8af015b1dea1e.tar.xz olio-linux-3.10-5e13a0c5ec05d382b488a691dfb8af015b1dea1e.zip  | |
Merge remote-tracking branch 'airlied/drm-core-next' into drm-intel-next-queued
Backmerge of drm-next to resolve a few ugly conflicts and to get a few
fixes from 3.4-rc6 (which drm-next has already merged). Note that this
merge also restricts the stencil cache lra evict policy workaround to
snb (as it should) - I had to frob the code anyway because the
CM0_MASK_SHIFT define died in the masked bit cleanups.
We need the backmerge to get Paulo Zanoni's infoframe regression fix
for gm45 - further bugfixes from him touch the same area and would
needlessly conflict.
Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
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 ||  |