diff options
author | Bryan Schumaker <bjschuma@netapp.com> | 2012-04-27 13:27:40 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-04-27 14:10:02 -0400 |
commit | 72de53ec4bca39c26709122a8f78bfefe7b6bca4 (patch) | |
tree | dac32c44281b153df7104037c1e97c11deffae69 /fs/nfs/nfs4namespace.c | |
parent | db0a9593d52f935c80085d8993bdcead1ad30b0c (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.c | 52 |
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 | ||
135 | static 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 | |||
155 | out: | ||
156 | put_page(page); | ||
157 | return flavor; | ||
158 | } | ||
159 | |||
160 | /* | ||
161 | * Please call rpc_shutdown_client() when you are done with this client. | ||
162 | */ | ||
163 | struct 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 | |||
135 | static struct vfsmount *try_location(struct nfs_clone_mount *mountdata, | 187 | static 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) |