aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4namespace.c
diff options
context:
space:
mode:
authorBryan Schumaker <bjschuma@netapp.com>2012-04-27 13:27:40 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-04-27 14:10:02 -0400
commit72de53ec4bca39c26709122a8f78bfefe7b6bca4 (patch)
treedac32c44281b153df7104037c1e97c11deffae69 /fs/nfs/nfs4namespace.c
parentdb0a9593d52f935c80085d8993bdcead1ad30b0c (diff)
NFS: Do secinfo as part of lookup
Whenever lookup sees wrongsec do a secinfo and retry the lookup to find attributes of the file or directory, such as "is this a referral mountpoint?". This also allows me to remove handling -NFS4ERR_WRONSEC as part of getattr xdr decoding. Signed-off-by: Bryan Schumaker <bjschuma@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4namespace.c')
-rw-r--r--fs/nfs/nfs4namespace.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c
index 7483a177dc97..9f8681bf90de 100644
--- a/fs/nfs/nfs4namespace.c
+++ b/fs/nfs/nfs4namespace.c
@@ -132,6 +132,58 @@ static size_t nfs_parse_server_name(char *string, size_t len,
132 return ret; 132 return ret;
133} 133}
134 134
135static rpc_authflavor_t nfs4_negotiate_security(struct inode *inode, struct qstr *name)
136{
137 struct page *page;
138 struct nfs4_secinfo_flavors *flavors;
139 rpc_authflavor_t flavor;
140 int err;
141
142 page = alloc_page(GFP_KERNEL);
143 if (!page)
144 return -ENOMEM;
145 flavors = page_address(page);
146
147 err = nfs4_proc_secinfo(inode, name, flavors);
148 if (err < 0) {
149 flavor = err;
150 goto out;
151 }
152
153 flavor = nfs_find_best_sec(flavors);
154
155out:
156 put_page(page);
157 return flavor;
158}
159
160/*
161 * Please call rpc_shutdown_client() when you are done with this client.
162 */
163struct rpc_clnt *nfs4_create_sec_client(struct rpc_clnt *clnt, struct inode *inode,
164 struct qstr *name)
165{
166 struct rpc_clnt *clone;
167 struct rpc_auth *auth;
168 rpc_authflavor_t flavor;
169
170 flavor = nfs4_negotiate_security(inode, name);
171 if (flavor < 0)
172 return ERR_PTR(flavor);
173
174 clone = rpc_clone_client(clnt);
175 if (IS_ERR(clone))
176 return clone;
177
178 auth = rpcauth_create(flavor, clone);
179 if (!auth) {
180 rpc_shutdown_client(clone);
181 clone = ERR_PTR(-EIO);
182 }
183
184 return clone;
185}
186
135static struct vfsmount *try_location(struct nfs_clone_mount *mountdata, 187static struct vfsmount *try_location(struct nfs_clone_mount *mountdata,
136 char *page, char *page2, 188 char *page, char *page2,
137 const struct nfs4_fs_location *location) 189 const struct nfs4_fs_location *location)