aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/nfs/blocklayout/blocklayout.c4
-rw-r--r--fs/nfs/client.c5
-rw-r--r--fs/nfs/idmap.c4
-rw-r--r--fs/nfs/internal.h8
-rw-r--r--fs/nfs/namespace.c93
-rw-r--r--fs/nfs/nfs4_fs.h10
-rw-r--r--fs/nfs/nfs4filelayoutdev.c2
-rw-r--r--fs/nfs/nfs4namespace.c86
-rw-r--r--fs/nfs/nfs4proc.c142
-rw-r--r--fs/nfs/nfs4xdr.c44
-rw-r--r--fs/nfs/objlayout/objlayout.c2
-rw-r--r--fs/nfs/pnfs.c2
-rw-r--r--fs/nfs/super.c4
13 files changed, 267 insertions, 139 deletions
diff --git a/fs/nfs/blocklayout/blocklayout.c b/fs/nfs/blocklayout/blocklayout.c
index 9c94297bb70e..7f6a23f0244e 100644
--- a/fs/nfs/blocklayout/blocklayout.c
+++ b/fs/nfs/blocklayout/blocklayout.c
@@ -38,6 +38,8 @@
38#include <linux/buffer_head.h> /* various write calls */ 38#include <linux/buffer_head.h> /* various write calls */
39#include <linux/prefetch.h> 39#include <linux/prefetch.h>
40 40
41#include "../pnfs.h"
42#include "../internal.h"
41#include "blocklayout.h" 43#include "blocklayout.h"
42 44
43#define NFSDBG_FACILITY NFSDBG_PNFS_LD 45#define NFSDBG_FACILITY NFSDBG_PNFS_LD
@@ -868,7 +870,7 @@ nfs4_blk_get_deviceinfo(struct nfs_server *server, const struct nfs_fh *fh,
868 * GETDEVICEINFO's maxcount 870 * GETDEVICEINFO's maxcount
869 */ 871 */
870 max_resp_sz = server->nfs_client->cl_session->fc_attrs.max_resp_sz; 872 max_resp_sz = server->nfs_client->cl_session->fc_attrs.max_resp_sz;
871 max_pages = max_resp_sz >> PAGE_SHIFT; 873 max_pages = nfs_page_array_len(0, max_resp_sz);
872 dprintk("%s max_resp_sz %u max_pages %d\n", 874 dprintk("%s max_resp_sz %u max_pages %d\n",
873 __func__, max_resp_sz, max_pages); 875 __func__, max_resp_sz, max_pages);
874 876
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index da7b5e4ff9ec..60f7e4ec842c 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -1729,7 +1729,8 @@ error:
1729 */ 1729 */
1730struct nfs_server *nfs_clone_server(struct nfs_server *source, 1730struct nfs_server *nfs_clone_server(struct nfs_server *source,
1731 struct nfs_fh *fh, 1731 struct nfs_fh *fh,
1732 struct nfs_fattr *fattr) 1732 struct nfs_fattr *fattr,
1733 rpc_authflavor_t flavor)
1733{ 1734{
1734 struct nfs_server *server; 1735 struct nfs_server *server;
1735 struct nfs_fattr *fattr_fsinfo; 1736 struct nfs_fattr *fattr_fsinfo;
@@ -1758,7 +1759,7 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source,
1758 1759
1759 error = nfs_init_server_rpcclient(server, 1760 error = nfs_init_server_rpcclient(server,
1760 source->client->cl_timeout, 1761 source->client->cl_timeout,
1761 source->client->cl_auth->au_flavor); 1762 flavor);
1762 if (error < 0) 1763 if (error < 0)
1763 goto out_free_server; 1764 goto out_free_server;
1764 if (!IS_ERR(source->client_acl)) 1765 if (!IS_ERR(source->client_acl))
diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c
index b7f348bb618b..ba3019f5934c 100644
--- a/fs/nfs/idmap.c
+++ b/fs/nfs/idmap.c
@@ -554,12 +554,16 @@ static int rpc_pipefs_event(struct notifier_block *nb, unsigned long event,
554 struct nfs_client *clp; 554 struct nfs_client *clp;
555 int error = 0; 555 int error = 0;
556 556
557 if (!try_module_get(THIS_MODULE))
558 return 0;
559
557 while ((clp = nfs_get_client_for_event(sb->s_fs_info, event))) { 560 while ((clp = nfs_get_client_for_event(sb->s_fs_info, event))) {
558 error = __rpc_pipefs_event(clp, event, sb); 561 error = __rpc_pipefs_event(clp, event, sb);
559 nfs_put_client(clp); 562 nfs_put_client(clp);
560 if (error) 563 if (error)
561 break; 564 break;
562 } 565 }
566 module_put(THIS_MODULE);
563 return error; 567 return error;
564} 568}
565 569
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 2476dc69365f..b777bdaba4c5 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -165,7 +165,8 @@ extern struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *,
165extern void nfs_free_server(struct nfs_server *server); 165extern void nfs_free_server(struct nfs_server *server);
166extern struct nfs_server *nfs_clone_server(struct nfs_server *, 166extern struct nfs_server *nfs_clone_server(struct nfs_server *,
167 struct nfs_fh *, 167 struct nfs_fh *,
168 struct nfs_fattr *); 168 struct nfs_fattr *,
169 rpc_authflavor_t);
169extern void nfs_mark_client_ready(struct nfs_client *clp, int state); 170extern void nfs_mark_client_ready(struct nfs_client *clp, int state);
170extern int nfs4_check_client_ready(struct nfs_client *clp); 171extern int nfs4_check_client_ready(struct nfs_client *clp);
171extern struct nfs_client *nfs4_set_ds_client(struct nfs_client* mds_clp, 172extern struct nfs_client *nfs4_set_ds_client(struct nfs_client* mds_clp,
@@ -186,10 +187,10 @@ static inline void nfs_fs_proc_exit(void)
186 187
187/* nfs4namespace.c */ 188/* nfs4namespace.c */
188#ifdef CONFIG_NFS_V4 189#ifdef CONFIG_NFS_V4
189extern struct vfsmount *nfs_do_refmount(struct dentry *dentry); 190extern struct vfsmount *nfs_do_refmount(struct rpc_clnt *client, struct dentry *dentry);
190#else 191#else
191static inline 192static inline
192struct vfsmount *nfs_do_refmount(struct dentry *dentry) 193struct vfsmount *nfs_do_refmount(struct rpc_clnt *client, struct dentry *dentry)
193{ 194{
194 return ERR_PTR(-ENOENT); 195 return ERR_PTR(-ENOENT);
195} 196}
@@ -234,7 +235,6 @@ extern const u32 nfs41_maxwrite_overhead;
234/* nfs4proc.c */ 235/* nfs4proc.c */
235#ifdef CONFIG_NFS_V4 236#ifdef CONFIG_NFS_V4
236extern struct rpc_procinfo nfs4_procedures[]; 237extern struct rpc_procinfo nfs4_procedures[];
237void nfs_fixup_secinfo_attributes(struct nfs_fattr *, struct nfs_fh *);
238#endif 238#endif
239 239
240extern int nfs4_init_ds_session(struct nfs_client *clp); 240extern int nfs4_init_ds_session(struct nfs_client *clp);
diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c
index 1807866bb3ab..d51868e5683c 100644
--- a/fs/nfs/namespace.c
+++ b/fs/nfs/namespace.c
@@ -148,66 +148,31 @@ rpc_authflavor_t nfs_find_best_sec(struct nfs4_secinfo_flavors *flavors)
148 return pseudoflavor; 148 return pseudoflavor;
149} 149}
150 150
151static int nfs_negotiate_security(const struct dentry *parent, 151static struct rpc_clnt *nfs_lookup_mountpoint(struct inode *dir,
152 const struct dentry *dentry, 152 struct qstr *name,
153 rpc_authflavor_t *flavor) 153 struct nfs_fh *fh,
154 struct nfs_fattr *fattr)
154{ 155{
155 struct page *page;
156 struct nfs4_secinfo_flavors *flavors;
157 int (*secinfo)(struct inode *, const struct qstr *, struct nfs4_secinfo_flavors *);
158 int ret = -EPERM;
159
160 secinfo = NFS_PROTO(parent->d_inode)->secinfo;
161 if (secinfo != NULL) {
162 page = alloc_page(GFP_KERNEL);
163 if (!page) {
164 ret = -ENOMEM;
165 goto out;
166 }
167 flavors = page_address(page);
168 ret = secinfo(parent->d_inode, &dentry->d_name, flavors);
169 *flavor = nfs_find_best_sec(flavors);
170 put_page(page);
171 }
172
173out:
174 return ret;
175}
176
177static int nfs_lookup_with_sec(struct nfs_server *server, struct dentry *parent,
178 struct dentry *dentry, struct path *path,
179 struct nfs_fh *fh, struct nfs_fattr *fattr,
180 rpc_authflavor_t *flavor)
181{
182 struct rpc_clnt *clone;
183 struct rpc_auth *auth;
184 int err; 156 int err;
185 157
186 err = nfs_negotiate_security(parent, path->dentry, flavor); 158 if (NFS_PROTO(dir)->version == 4)
187 if (err < 0) 159 return nfs4_proc_lookup_mountpoint(dir, name, fh, fattr);
188 goto out; 160
189 clone = rpc_clone_client(server->client); 161 err = NFS_PROTO(dir)->lookup(NFS_SERVER(dir)->client, dir, name, fh, fattr);
190 auth = rpcauth_create(*flavor, clone); 162 if (err)
191 if (!auth) { 163 return ERR_PTR(err);
192 err = -EIO; 164 return rpc_clone_client(NFS_SERVER(dir)->client);
193 goto out_shutdown;
194 }
195 err = server->nfs_client->rpc_ops->lookup(clone, parent->d_inode,
196 &path->dentry->d_name,
197 fh, fattr);
198out_shutdown:
199 rpc_shutdown_client(clone);
200out:
201 return err;
202} 165}
203#else /* CONFIG_NFS_V4 */ 166#else /* CONFIG_NFS_V4 */
204static inline int nfs_lookup_with_sec(struct nfs_server *server, 167static inline struct rpc_clnt *nfs_lookup_mountpoint(struct inode *dir,
205 struct dentry *parent, struct dentry *dentry, 168 struct qstr *name,
206 struct path *path, struct nfs_fh *fh, 169 struct nfs_fh *fh,
207 struct nfs_fattr *fattr, 170 struct nfs_fattr *fattr)
208 rpc_authflavor_t *flavor)
209{ 171{
210 return -EPERM; 172 int err = NFS_PROTO(dir)->lookup(NFS_SERVER(dir)->client, dir, name, fh, fattr);
173 if (err)
174 return ERR_PTR(err);
175 return rpc_clone_client(NFS_SERVER(dir)->client);
211} 176}
212#endif /* CONFIG_NFS_V4 */ 177#endif /* CONFIG_NFS_V4 */
213 178
@@ -226,12 +191,10 @@ static inline int nfs_lookup_with_sec(struct nfs_server *server,
226struct vfsmount *nfs_d_automount(struct path *path) 191struct vfsmount *nfs_d_automount(struct path *path)
227{ 192{
228 struct vfsmount *mnt; 193 struct vfsmount *mnt;
229 struct nfs_server *server = NFS_SERVER(path->dentry->d_inode);
230 struct dentry *parent; 194 struct dentry *parent;
231 struct nfs_fh *fh = NULL; 195 struct nfs_fh *fh = NULL;
232 struct nfs_fattr *fattr = NULL; 196 struct nfs_fattr *fattr = NULL;
233 int err; 197 struct rpc_clnt *client;
234 rpc_authflavor_t flavor = RPC_AUTH_UNIX;
235 198
236 dprintk("--> nfs_d_automount()\n"); 199 dprintk("--> nfs_d_automount()\n");
237 200
@@ -249,21 +212,19 @@ struct vfsmount *nfs_d_automount(struct path *path)
249 212
250 /* Look it up again to get its attributes */ 213 /* Look it up again to get its attributes */
251 parent = dget_parent(path->dentry); 214 parent = dget_parent(path->dentry);
252 err = server->nfs_client->rpc_ops->lookup(server->client, parent->d_inode, 215 client = nfs_lookup_mountpoint(parent->d_inode, &path->dentry->d_name, fh, fattr);
253 &path->dentry->d_name,
254 fh, fattr);
255 if (err == -EPERM && NFS_PROTO(parent->d_inode)->secinfo != NULL)
256 err = nfs_lookup_with_sec(server, parent, path->dentry, path, fh, fattr, &flavor);
257 dput(parent); 216 dput(parent);
258 if (err != 0) { 217 if (IS_ERR(client)) {
259 mnt = ERR_PTR(err); 218 mnt = ERR_CAST(client);
260 goto out; 219 goto out;
261 } 220 }
262 221
263 if (fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL) 222 if (fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL)
264 mnt = nfs_do_refmount(path->dentry); 223 mnt = nfs_do_refmount(client, path->dentry);
265 else 224 else
266 mnt = nfs_do_submount(path->dentry, fh, fattr, flavor); 225 mnt = nfs_do_submount(path->dentry, fh, fattr, client->cl_auth->au_flavor);
226 rpc_shutdown_client(client);
227
267 if (IS_ERR(mnt)) 228 if (IS_ERR(mnt))
268 goto out; 229 goto out;
269 230
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index b6db9e33fb7b..8d75021020b3 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -205,6 +205,9 @@ struct nfs4_state_maintenance_ops {
205extern const struct dentry_operations nfs4_dentry_operations; 205extern const struct dentry_operations nfs4_dentry_operations;
206extern const struct inode_operations nfs4_dir_inode_operations; 206extern const struct inode_operations nfs4_dir_inode_operations;
207 207
208/* nfs4namespace.c */
209struct rpc_clnt *nfs4_create_sec_client(struct rpc_clnt *, struct inode *, struct qstr *);
210
208/* nfs4proc.c */ 211/* nfs4proc.c */
209extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struct rpc_cred *, struct nfs4_setclientid_res *); 212extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struct rpc_cred *, struct nfs4_setclientid_res *);
210extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct nfs4_setclientid_res *arg, struct rpc_cred *); 213extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct nfs4_setclientid_res *arg, struct rpc_cred *);
@@ -213,8 +216,11 @@ extern int nfs4_init_clientid(struct nfs_client *, struct rpc_cred *);
213extern int nfs41_init_clientid(struct nfs_client *, struct rpc_cred *); 216extern int nfs41_init_clientid(struct nfs_client *, struct rpc_cred *);
214extern int nfs4_do_close(struct nfs4_state *state, gfp_t gfp_mask, int wait, bool roc); 217extern int nfs4_do_close(struct nfs4_state *state, gfp_t gfp_mask, int wait, bool roc);
215extern int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle); 218extern int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle);
216extern int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name, 219extern int nfs4_proc_fs_locations(struct rpc_clnt *, struct inode *, const struct qstr *,
217 struct nfs4_fs_locations *fs_locations, struct page *page); 220 struct nfs4_fs_locations *, struct page *);
221extern struct rpc_clnt *nfs4_proc_lookup_mountpoint(struct inode *, struct qstr *,
222 struct nfs_fh *, struct nfs_fattr *);
223extern int nfs4_proc_secinfo(struct inode *, const struct qstr *, struct nfs4_secinfo_flavors *);
218extern int nfs4_release_lockowner(struct nfs4_lock_state *); 224extern int nfs4_release_lockowner(struct nfs4_lock_state *);
219extern const struct xattr_handler *nfs4_xattr_handlers[]; 225extern const struct xattr_handler *nfs4_xattr_handlers[];
220 226
diff --git a/fs/nfs/nfs4filelayoutdev.c b/fs/nfs/nfs4filelayoutdev.c
index a866bbd2890a..c9cff9adb2d3 100644
--- a/fs/nfs/nfs4filelayoutdev.c
+++ b/fs/nfs/nfs4filelayoutdev.c
@@ -699,7 +699,7 @@ get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id, gfp_t gfp_fla
699 * GETDEVICEINFO's maxcount 699 * GETDEVICEINFO's maxcount
700 */ 700 */
701 max_resp_sz = server->nfs_client->cl_session->fc_attrs.max_resp_sz; 701 max_resp_sz = server->nfs_client->cl_session->fc_attrs.max_resp_sz;
702 max_pages = max_resp_sz >> PAGE_SHIFT; 702 max_pages = nfs_page_array_len(0, max_resp_sz);
703 dprintk("%s inode %p max_resp_sz %u max_pages %d\n", 703 dprintk("%s inode %p max_resp_sz %u max_pages %d\n",
704 __func__, inode, max_resp_sz, max_pages); 704 __func__, inode, max_resp_sz, max_pages);
705 705
diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c
index 9c8eca315f43..a7f3dedc4ec7 100644
--- a/fs/nfs/nfs4namespace.c
+++ b/fs/nfs/nfs4namespace.c
@@ -52,6 +52,30 @@ Elong:
52} 52}
53 53
54/* 54/*
55 * return the path component of "<server>:<path>"
56 * nfspath - the "<server>:<path>" string
57 * end - one past the last char that could contain "<server>:"
58 * returns NULL on failure
59 */
60static char *nfs_path_component(const char *nfspath, const char *end)
61{
62 char *p;
63
64 if (*nfspath == '[') {
65 /* parse [] escaped IPv6 addrs */
66 p = strchr(nfspath, ']');
67 if (p != NULL && ++p < end && *p == ':')
68 return p + 1;
69 } else {
70 /* otherwise split on first colon */
71 p = strchr(nfspath, ':');
72 if (p != NULL && p < end)
73 return p + 1;
74 }
75 return NULL;
76}
77
78/*
55 * Determine the mount path as a string 79 * Determine the mount path as a string
56 */ 80 */
57static char *nfs4_path(struct dentry *dentry, char *buffer, ssize_t buflen) 81static 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)
59 char *limit; 83 char *limit;
60 char *path = nfs_path(&limit, dentry, buffer, buflen); 84 char *path = nfs_path(&limit, dentry, buffer, buflen);
61 if (!IS_ERR(path)) { 85 if (!IS_ERR(path)) {
62 char *colon = strchr(path, ':'); 86 char *path_component = nfs_path_component(path, limit);
63 if (colon && colon < limit) 87 if (path_component)
64 path = colon + 1; 88 return path_component;
65 } 89 }
66 return path; 90 return path;
67} 91}
@@ -108,6 +132,58 @@ static size_t nfs_parse_server_name(char *string, size_t len,
108 return ret; 132 return ret;
109} 133}
110 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
111static struct vfsmount *try_location(struct nfs_clone_mount *mountdata, 187static struct vfsmount *try_location(struct nfs_clone_mount *mountdata,
112 char *page, char *page2, 188 char *page, char *page2,
113 const struct nfs4_fs_location *location) 189 const struct nfs4_fs_location *location)
@@ -224,7 +300,7 @@ out:
224 * @dentry - dentry of referral 300 * @dentry - dentry of referral
225 * 301 *
226 */ 302 */
227struct vfsmount *nfs_do_refmount(struct dentry *dentry) 303struct vfsmount *nfs_do_refmount(struct rpc_clnt *client, struct dentry *dentry)
228{ 304{
229 struct vfsmount *mnt = ERR_PTR(-ENOMEM); 305 struct vfsmount *mnt = ERR_PTR(-ENOMEM);
230 struct dentry *parent; 306 struct dentry *parent;
@@ -250,7 +326,7 @@ struct vfsmount *nfs_do_refmount(struct dentry *dentry)
250 dprintk("%s: getting locations for %s/%s\n", 326 dprintk("%s: getting locations for %s/%s\n",
251 __func__, parent->d_name.name, dentry->d_name.name); 327 __func__, parent->d_name.name, dentry->d_name.name);
252 328
253 err = nfs4_proc_fs_locations(parent->d_inode, &dentry->d_name, fs_locations, page); 329 err = nfs4_proc_fs_locations(client, parent->d_inode, &dentry->d_name, fs_locations, page);
254 dput(parent); 330 dput(parent);
255 if (err != 0 || 331 if (err != 0 ||
256 fs_locations->nlocations <= 0 || 332 fs_locations->nlocations <= 0 ||
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 60d5f4c26dda..99650aaf8937 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -2377,8 +2377,9 @@ static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
2377 * Note that we'll actually follow the referral later when 2377 * Note that we'll actually follow the referral later when
2378 * we detect fsid mismatch in inode revalidation 2378 * we detect fsid mismatch in inode revalidation
2379 */ 2379 */
2380static int nfs4_get_referral(struct inode *dir, const struct qstr *name, 2380static int nfs4_get_referral(struct rpc_clnt *client, struct inode *dir,
2381 struct nfs_fattr *fattr, struct nfs_fh *fhandle) 2381 const struct qstr *name, struct nfs_fattr *fattr,
2382 struct nfs_fh *fhandle)
2382{ 2383{
2383 int status = -ENOMEM; 2384 int status = -ENOMEM;
2384 struct page *page = NULL; 2385 struct page *page = NULL;
@@ -2391,7 +2392,7 @@ static int nfs4_get_referral(struct inode *dir, const struct qstr *name,
2391 if (locations == NULL) 2392 if (locations == NULL)
2392 goto out; 2393 goto out;
2393 2394
2394 status = nfs4_proc_fs_locations(dir, name, locations, page); 2395 status = nfs4_proc_fs_locations(client, dir, name, locations, page);
2395 if (status != 0) 2396 if (status != 0)
2396 goto out; 2397 goto out;
2397 /* Make sure server returned a different fsid for the referral */ 2398 /* Make sure server returned a different fsid for the referral */
@@ -2528,39 +2529,84 @@ static int _nfs4_proc_lookup(struct rpc_clnt *clnt, struct inode *dir,
2528 return status; 2529 return status;
2529} 2530}
2530 2531
2531void nfs_fixup_secinfo_attributes(struct nfs_fattr *fattr, struct nfs_fh *fh) 2532static void nfs_fixup_secinfo_attributes(struct nfs_fattr *fattr)
2532{ 2533{
2533 memset(fh, 0, sizeof(struct nfs_fh));
2534 fattr->fsid.major = 1;
2535 fattr->valid |= NFS_ATTR_FATTR_TYPE | NFS_ATTR_FATTR_MODE | 2534 fattr->valid |= NFS_ATTR_FATTR_TYPE | NFS_ATTR_FATTR_MODE |
2536 NFS_ATTR_FATTR_NLINK | NFS_ATTR_FATTR_FSID | NFS_ATTR_FATTR_MOUNTPOINT; 2535 NFS_ATTR_FATTR_NLINK | NFS_ATTR_FATTR_MOUNTPOINT;
2537 fattr->mode = S_IFDIR | S_IRUGO | S_IXUGO; 2536 fattr->mode = S_IFDIR | S_IRUGO | S_IXUGO;
2538 fattr->nlink = 2; 2537 fattr->nlink = 2;
2539} 2538}
2540 2539
2541static int nfs4_proc_lookup(struct rpc_clnt *clnt, struct inode *dir, struct qstr *name, 2540static int nfs4_proc_lookup_common(struct rpc_clnt **clnt, struct inode *dir,
2542 struct nfs_fh *fhandle, struct nfs_fattr *fattr) 2541 struct qstr *name, struct nfs_fh *fhandle,
2542 struct nfs_fattr *fattr)
2543{ 2543{
2544 struct nfs4_exception exception = { }; 2544 struct nfs4_exception exception = { };
2545 struct rpc_clnt *client = *clnt;
2545 int err; 2546 int err;
2546 do { 2547 do {
2547 int status; 2548 err = _nfs4_proc_lookup(client, dir, name, fhandle, fattr);
2548 2549 switch (err) {
2549 status = _nfs4_proc_lookup(clnt, dir, name, fhandle, fattr);
2550 switch (status) {
2551 case -NFS4ERR_BADNAME: 2550 case -NFS4ERR_BADNAME:
2552 return -ENOENT; 2551 err = -ENOENT;
2552 goto out;
2553 case -NFS4ERR_MOVED: 2553 case -NFS4ERR_MOVED:
2554 return nfs4_get_referral(dir, name, fattr, fhandle); 2554 err = nfs4_get_referral(client, dir, name, fattr, fhandle);
2555 goto out;
2555 case -NFS4ERR_WRONGSEC: 2556 case -NFS4ERR_WRONGSEC:
2556 nfs_fixup_secinfo_attributes(fattr, fhandle); 2557 err = -EPERM;
2558 if (client != *clnt)
2559 goto out;
2560
2561 client = nfs4_create_sec_client(client, dir, name);
2562 if (IS_ERR(client))
2563 return PTR_ERR(client);
2564
2565 exception.retry = 1;
2566 break;
2567 default:
2568 err = nfs4_handle_exception(NFS_SERVER(dir), err, &exception);
2557 } 2569 }
2558 err = nfs4_handle_exception(NFS_SERVER(dir),
2559 status, &exception);
2560 } while (exception.retry); 2570 } while (exception.retry);
2571
2572out:
2573 if (err == 0)
2574 *clnt = client;
2575 else if (client != *clnt)
2576 rpc_shutdown_client(client);
2577
2561 return err; 2578 return err;
2562} 2579}
2563 2580
2581static int nfs4_proc_lookup(struct rpc_clnt *clnt, struct inode *dir, struct qstr *name,
2582 struct nfs_fh *fhandle, struct nfs_fattr *fattr)
2583{
2584 int status;
2585 struct rpc_clnt *client = NFS_CLIENT(dir);
2586
2587 status = nfs4_proc_lookup_common(&client, dir, name, fhandle, fattr);
2588 if (client != NFS_CLIENT(dir)) {
2589 rpc_shutdown_client(client);
2590 nfs_fixup_secinfo_attributes(fattr);
2591 }
2592 return status;
2593}
2594
2595struct rpc_clnt *
2596nfs4_proc_lookup_mountpoint(struct inode *dir, struct qstr *name,
2597 struct nfs_fh *fhandle, struct nfs_fattr *fattr)
2598{
2599 int status;
2600 struct rpc_clnt *client = rpc_clone_client(NFS_CLIENT(dir));
2601
2602 status = nfs4_proc_lookup_common(&client, dir, name, fhandle, fattr);
2603 if (status < 0) {
2604 rpc_shutdown_client(client);
2605 return ERR_PTR(status);
2606 }
2607 return client;
2608}
2609
2564static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry) 2610static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry)
2565{ 2611{
2566 struct nfs_server *server = NFS_SERVER(inode); 2612 struct nfs_server *server = NFS_SERVER(inode);
@@ -3628,16 +3674,16 @@ out:
3628 return ret; 3674 return ret;
3629} 3675}
3630 3676
3631static void nfs4_write_cached_acl(struct inode *inode, const char *buf, size_t acl_len) 3677static void nfs4_write_cached_acl(struct inode *inode, struct page **pages, size_t pgbase, size_t acl_len)
3632{ 3678{
3633 struct nfs4_cached_acl *acl; 3679 struct nfs4_cached_acl *acl;
3634 3680
3635 if (buf && acl_len <= PAGE_SIZE) { 3681 if (pages && acl_len <= PAGE_SIZE) {
3636 acl = kmalloc(sizeof(*acl) + acl_len, GFP_KERNEL); 3682 acl = kmalloc(sizeof(*acl) + acl_len, GFP_KERNEL);
3637 if (acl == NULL) 3683 if (acl == NULL)
3638 goto out; 3684 goto out;
3639 acl->cached = 1; 3685 acl->cached = 1;
3640 memcpy(acl->data, buf, acl_len); 3686 _copy_from_pages(acl->data, pages, pgbase, acl_len);
3641 } else { 3687 } else {
3642 acl = kmalloc(sizeof(*acl), GFP_KERNEL); 3688 acl = kmalloc(sizeof(*acl), GFP_KERNEL);
3643 if (acl == NULL) 3689 if (acl == NULL)
@@ -3670,7 +3716,6 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu
3670 struct nfs_getaclres res = { 3716 struct nfs_getaclres res = {
3671 .acl_len = buflen, 3717 .acl_len = buflen,
3672 }; 3718 };
3673 void *resp_buf;
3674 struct rpc_message msg = { 3719 struct rpc_message msg = {
3675 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_GETACL], 3720 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_GETACL],
3676 .rpc_argp = &args, 3721 .rpc_argp = &args,
@@ -3684,24 +3729,27 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu
3684 if (npages == 0) 3729 if (npages == 0)
3685 npages = 1; 3730 npages = 1;
3686 3731
3732 /* Add an extra page to handle the bitmap returned */
3733 npages++;
3734
3687 for (i = 0; i < npages; i++) { 3735 for (i = 0; i < npages; i++) {
3688 pages[i] = alloc_page(GFP_KERNEL); 3736 pages[i] = alloc_page(GFP_KERNEL);
3689 if (!pages[i]) 3737 if (!pages[i])
3690 goto out_free; 3738 goto out_free;
3691 } 3739 }
3692 if (npages > 1) { 3740
3693 /* for decoding across pages */ 3741 /* for decoding across pages */
3694 res.acl_scratch = alloc_page(GFP_KERNEL); 3742 res.acl_scratch = alloc_page(GFP_KERNEL);
3695 if (!res.acl_scratch) 3743 if (!res.acl_scratch)
3696 goto out_free; 3744 goto out_free;
3697 } 3745
3698 args.acl_len = npages * PAGE_SIZE; 3746 args.acl_len = npages * PAGE_SIZE;
3699 args.acl_pgbase = 0; 3747 args.acl_pgbase = 0;
3748
3700 /* Let decode_getfacl know not to fail if the ACL data is larger than 3749 /* Let decode_getfacl know not to fail if the ACL data is larger than
3701 * the page we send as a guess */ 3750 * the page we send as a guess */
3702 if (buf == NULL) 3751 if (buf == NULL)
3703 res.acl_flags |= NFS4_ACL_LEN_REQUEST; 3752 res.acl_flags |= NFS4_ACL_LEN_REQUEST;
3704 resp_buf = page_address(pages[0]);
3705 3753
3706 dprintk("%s buf %p buflen %zu npages %d args.acl_len %zu\n", 3754 dprintk("%s buf %p buflen %zu npages %d args.acl_len %zu\n",
3707 __func__, buf, buflen, npages, args.acl_len); 3755 __func__, buf, buflen, npages, args.acl_len);
@@ -3712,9 +3760,9 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu
3712 3760
3713 acl_len = res.acl_len - res.acl_data_offset; 3761 acl_len = res.acl_len - res.acl_data_offset;
3714 if (acl_len > args.acl_len) 3762 if (acl_len > args.acl_len)
3715 nfs4_write_cached_acl(inode, NULL, acl_len); 3763 nfs4_write_cached_acl(inode, NULL, 0, acl_len);
3716 else 3764 else
3717 nfs4_write_cached_acl(inode, resp_buf + res.acl_data_offset, 3765 nfs4_write_cached_acl(inode, pages, res.acl_data_offset,
3718 acl_len); 3766 acl_len);
3719 if (buf) { 3767 if (buf) {
3720 ret = -ERANGE; 3768 ret = -ERANGE;
@@ -4919,8 +4967,10 @@ static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr)
4919 fattr->nlink = 2; 4967 fattr->nlink = 2;
4920} 4968}
4921 4969
4922int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name, 4970static int _nfs4_proc_fs_locations(struct rpc_clnt *client, struct inode *dir,
4923 struct nfs4_fs_locations *fs_locations, struct page *page) 4971 const struct qstr *name,
4972 struct nfs4_fs_locations *fs_locations,
4973 struct page *page)
4924{ 4974{
4925 struct nfs_server *server = NFS_SERVER(dir); 4975 struct nfs_server *server = NFS_SERVER(dir);
4926 u32 bitmask[2] = { 4976 u32 bitmask[2] = {
@@ -4954,11 +5004,26 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,
4954 nfs_fattr_init(&fs_locations->fattr); 5004 nfs_fattr_init(&fs_locations->fattr);
4955 fs_locations->server = server; 5005 fs_locations->server = server;
4956 fs_locations->nlocations = 0; 5006 fs_locations->nlocations = 0;
4957 status = nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0); 5007 status = nfs4_call_sync(client, server, &msg, &args.seq_args, &res.seq_res, 0);
4958 dprintk("%s: returned status = %d\n", __func__, status); 5008 dprintk("%s: returned status = %d\n", __func__, status);
4959 return status; 5009 return status;
4960} 5010}
4961 5011
5012int nfs4_proc_fs_locations(struct rpc_clnt *client, struct inode *dir,
5013 const struct qstr *name,
5014 struct nfs4_fs_locations *fs_locations,
5015 struct page *page)
5016{
5017 struct nfs4_exception exception = { };
5018 int err;
5019 do {
5020 err = nfs4_handle_exception(NFS_SERVER(dir),
5021 _nfs4_proc_fs_locations(client, dir, name, fs_locations, page),
5022 &exception);
5023 } while (exception.retry);
5024 return err;
5025}
5026
4962static int _nfs4_proc_secinfo(struct inode *dir, const struct qstr *name, struct nfs4_secinfo_flavors *flavors) 5027static int _nfs4_proc_secinfo(struct inode *dir, const struct qstr *name, struct nfs4_secinfo_flavors *flavors)
4963{ 5028{
4964 int status; 5029 int status;
@@ -4981,8 +5046,8 @@ static int _nfs4_proc_secinfo(struct inode *dir, const struct qstr *name, struct
4981 return status; 5046 return status;
4982} 5047}
4983 5048
4984static int nfs4_proc_secinfo(struct inode *dir, const struct qstr *name, 5049int nfs4_proc_secinfo(struct inode *dir, const struct qstr *name,
4985 struct nfs4_secinfo_flavors *flavors) 5050 struct nfs4_secinfo_flavors *flavors)
4986{ 5051{
4987 struct nfs4_exception exception = { }; 5052 struct nfs4_exception exception = { };
4988 int err; 5053 int err;
@@ -5057,10 +5122,9 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
5057 nfs4_construct_boot_verifier(clp, &verifier); 5122 nfs4_construct_boot_verifier(clp, &verifier);
5058 5123
5059 args.id_len = scnprintf(args.id, sizeof(args.id), 5124 args.id_len = scnprintf(args.id, sizeof(args.id),
5060 "%s/%s.%s/%u", 5125 "%s/%s/%u",
5061 clp->cl_ipaddr, 5126 clp->cl_ipaddr,
5062 init_utsname()->nodename, 5127 clp->cl_rpcclient->cl_nodename,
5063 init_utsname()->domainname,
5064 clp->cl_rpcclient->cl_auth->au_flavor); 5128 clp->cl_rpcclient->cl_auth->au_flavor);
5065 5129
5066 res.server_scope = kzalloc(sizeof(struct server_scope), GFP_KERNEL); 5130 res.server_scope = kzalloc(sizeof(struct server_scope), GFP_KERNEL);
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 77fc5f959c4e..c54aae364bee 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -4258,8 +4258,6 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap,
4258 status = decode_attr_error(xdr, bitmap, &err); 4258 status = decode_attr_error(xdr, bitmap, &err);
4259 if (status < 0) 4259 if (status < 0)
4260 goto xdr_error; 4260 goto xdr_error;
4261 if (err == -NFS4ERR_WRONGSEC)
4262 nfs_fixup_secinfo_attributes(fattr, fh);
4263 4261
4264 status = decode_attr_filehandle(xdr, bitmap, fh); 4262 status = decode_attr_filehandle(xdr, bitmap, fh);
4265 if (status < 0) 4263 if (status < 0)
@@ -4902,11 +4900,19 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req,
4902 bitmap[3] = {0}; 4900 bitmap[3] = {0};
4903 struct kvec *iov = req->rq_rcv_buf.head; 4901 struct kvec *iov = req->rq_rcv_buf.head;
4904 int status; 4902 int status;
4903 size_t page_len = xdr->buf->page_len;
4905 4904
4906 res->acl_len = 0; 4905 res->acl_len = 0;
4907 if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0) 4906 if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0)
4908 goto out; 4907 goto out;
4908
4909 bm_p = xdr->p; 4909 bm_p = xdr->p;
4910 res->acl_data_offset = be32_to_cpup(bm_p) + 2;
4911 res->acl_data_offset <<= 2;
4912 /* Check if the acl data starts beyond the allocated buffer */
4913 if (res->acl_data_offset > page_len)
4914 return -ERANGE;
4915
4910 if ((status = decode_attr_bitmap(xdr, bitmap)) != 0) 4916 if ((status = decode_attr_bitmap(xdr, bitmap)) != 0)
4911 goto out; 4917 goto out;
4912 if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0) 4918 if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0)
@@ -4916,28 +4922,24 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req,
4916 return -EIO; 4922 return -EIO;
4917 if (likely(bitmap[0] & FATTR4_WORD0_ACL)) { 4923 if (likely(bitmap[0] & FATTR4_WORD0_ACL)) {
4918 size_t hdrlen; 4924 size_t hdrlen;
4919 u32 recvd;
4920 4925
4921 /* The bitmap (xdr len + bitmaps) and the attr xdr len words 4926 /* The bitmap (xdr len + bitmaps) and the attr xdr len words
4922 * are stored with the acl data to handle the problem of 4927 * are stored with the acl data to handle the problem of
4923 * variable length bitmaps.*/ 4928 * variable length bitmaps.*/
4924 xdr->p = bm_p; 4929 xdr->p = bm_p;
4925 res->acl_data_offset = be32_to_cpup(bm_p) + 2;
4926 res->acl_data_offset <<= 2;
4927 4930
4928 /* We ignore &savep and don't do consistency checks on 4931 /* We ignore &savep and don't do consistency checks on
4929 * the attr length. Let userspace figure it out.... */ 4932 * the attr length. Let userspace figure it out.... */
4930 hdrlen = (u8 *)xdr->p - (u8 *)iov->iov_base; 4933 hdrlen = (u8 *)xdr->p - (u8 *)iov->iov_base;
4931 attrlen += res->acl_data_offset; 4934 attrlen += res->acl_data_offset;
4932 recvd = req->rq_rcv_buf.len - hdrlen; 4935 if (attrlen > page_len) {
4933 if (attrlen > recvd) {
4934 if (res->acl_flags & NFS4_ACL_LEN_REQUEST) { 4936 if (res->acl_flags & NFS4_ACL_LEN_REQUEST) {
4935 /* getxattr interface called with a NULL buf */ 4937 /* getxattr interface called with a NULL buf */
4936 res->acl_len = attrlen; 4938 res->acl_len = attrlen;
4937 goto out; 4939 goto out;
4938 } 4940 }
4939 dprintk("NFS: acl reply: attrlen %u > recvd %u\n", 4941 dprintk("NFS: acl reply: attrlen %u > page_len %zu\n",
4940 attrlen, recvd); 4942 attrlen, page_len);
4941 return -EINVAL; 4943 return -EINVAL;
4942 } 4944 }
4943 xdr_read_pages(xdr, attrlen); 4945 xdr_read_pages(xdr, attrlen);
@@ -5090,16 +5092,13 @@ out_err:
5090 return -EINVAL; 5092 return -EINVAL;
5091} 5093}
5092 5094
5093static int decode_secinfo(struct xdr_stream *xdr, struct nfs4_secinfo_res *res) 5095static int decode_secinfo_common(struct xdr_stream *xdr, struct nfs4_secinfo_res *res)
5094{ 5096{
5095 struct nfs4_secinfo_flavor *sec_flavor; 5097 struct nfs4_secinfo_flavor *sec_flavor;
5096 int status; 5098 int status;
5097 __be32 *p; 5099 __be32 *p;
5098 int i, num_flavors; 5100 int i, num_flavors;
5099 5101
5100 status = decode_op_hdr(xdr, OP_SECINFO);
5101 if (status)
5102 goto out;
5103 p = xdr_inline_decode(xdr, 4); 5102 p = xdr_inline_decode(xdr, 4);
5104 if (unlikely(!p)) 5103 if (unlikely(!p))
5105 goto out_overflow; 5104 goto out_overflow;
@@ -5125,6 +5124,7 @@ static int decode_secinfo(struct xdr_stream *xdr, struct nfs4_secinfo_res *res)
5125 res->flavors->num_flavors++; 5124 res->flavors->num_flavors++;
5126 } 5125 }
5127 5126
5127 status = 0;
5128out: 5128out:
5129 return status; 5129 return status;
5130out_overflow: 5130out_overflow:
@@ -5132,7 +5132,23 @@ out_overflow:
5132 return -EIO; 5132 return -EIO;
5133} 5133}
5134 5134
5135static int decode_secinfo(struct xdr_stream *xdr, struct nfs4_secinfo_res *res)
5136{
5137 int status = decode_op_hdr(xdr, OP_SECINFO);
5138 if (status)
5139 return status;
5140 return decode_secinfo_common(xdr, res);
5141}
5142
5135#if defined(CONFIG_NFS_V4_1) 5143#if defined(CONFIG_NFS_V4_1)
5144static int decode_secinfo_no_name(struct xdr_stream *xdr, struct nfs4_secinfo_res *res)
5145{
5146 int status = decode_op_hdr(xdr, OP_SECINFO_NO_NAME);
5147 if (status)
5148 return status;
5149 return decode_secinfo_common(xdr, res);
5150}
5151
5136static int decode_exchange_id(struct xdr_stream *xdr, 5152static int decode_exchange_id(struct xdr_stream *xdr,
5137 struct nfs41_exchange_id_res *res) 5153 struct nfs41_exchange_id_res *res)
5138{ 5154{
@@ -6817,7 +6833,7 @@ static int nfs4_xdr_dec_secinfo_no_name(struct rpc_rqst *rqstp,
6817 status = decode_putrootfh(xdr); 6833 status = decode_putrootfh(xdr);
6818 if (status) 6834 if (status)
6819 goto out; 6835 goto out;
6820 status = decode_secinfo(xdr, res); 6836 status = decode_secinfo_no_name(xdr, res);
6821out: 6837out:
6822 return status; 6838 return status;
6823} 6839}
diff --git a/fs/nfs/objlayout/objlayout.c b/fs/nfs/objlayout/objlayout.c
index 8d45f1c318ce..595c5fc21a19 100644
--- a/fs/nfs/objlayout/objlayout.c
+++ b/fs/nfs/objlayout/objlayout.c
@@ -604,7 +604,6 @@ int objlayout_get_deviceinfo(struct pnfs_layout_hdr *pnfslay,
604{ 604{
605 struct objlayout_deviceinfo *odi; 605 struct objlayout_deviceinfo *odi;
606 struct pnfs_device pd; 606 struct pnfs_device pd;
607 struct super_block *sb;
608 struct page *page, **pages; 607 struct page *page, **pages;
609 u32 *p; 608 u32 *p;
610 int err; 609 int err;
@@ -623,7 +622,6 @@ int objlayout_get_deviceinfo(struct pnfs_layout_hdr *pnfslay,
623 pd.pglen = PAGE_SIZE; 622 pd.pglen = PAGE_SIZE;
624 pd.mincount = 0; 623 pd.mincount = 0;
625 624
626 sb = pnfslay->plh_inode->i_sb;
627 err = nfs4_proc_getdeviceinfo(NFS_SERVER(pnfslay->plh_inode), &pd); 625 err = nfs4_proc_getdeviceinfo(NFS_SERVER(pnfslay->plh_inode), &pd);
628 dprintk("%s nfs_getdeviceinfo returned %d\n", __func__, err); 626 dprintk("%s nfs_getdeviceinfo returned %d\n", __func__, err);
629 if (err) 627 if (err)
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index b5d451586943..38512bcd2e98 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -587,7 +587,7 @@ send_layoutget(struct pnfs_layout_hdr *lo,
587 587
588 /* allocate pages for xdr post processing */ 588 /* allocate pages for xdr post processing */
589 max_resp_sz = server->nfs_client->cl_session->fc_attrs.max_resp_sz; 589 max_resp_sz = server->nfs_client->cl_session->fc_attrs.max_resp_sz;
590 max_pages = max_resp_sz >> PAGE_SHIFT; 590 max_pages = nfs_page_array_len(0, max_resp_sz);
591 591
592 pages = kcalloc(max_pages, sizeof(struct page *), gfp_flags); 592 pages = kcalloc(max_pages, sizeof(struct page *), gfp_flags);
593 if (!pages) 593 if (!pages)
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 1e6715f0616c..4ac7fca7e4bf 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -2428,7 +2428,7 @@ nfs_xdev_mount(struct file_system_type *fs_type, int flags,
2428 dprintk("--> nfs_xdev_mount()\n"); 2428 dprintk("--> nfs_xdev_mount()\n");
2429 2429
2430 /* create a new volume representation */ 2430 /* create a new volume representation */
2431 server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr); 2431 server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr, data->authflavor);
2432 if (IS_ERR(server)) { 2432 if (IS_ERR(server)) {
2433 error = PTR_ERR(server); 2433 error = PTR_ERR(server);
2434 goto out_err_noserver; 2434 goto out_err_noserver;
@@ -2955,7 +2955,7 @@ nfs4_xdev_mount(struct file_system_type *fs_type, int flags,
2955 dprintk("--> nfs4_xdev_mount()\n"); 2955 dprintk("--> nfs4_xdev_mount()\n");
2956 2956
2957 /* create a new volume representation */ 2957 /* create a new volume representation */
2958 server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr); 2958 server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr, data->authflavor);
2959 if (IS_ERR(server)) { 2959 if (IS_ERR(server)) {
2960 error = PTR_ERR(server); 2960 error = PTR_ERR(server);
2961 goto out_err_noserver; 2961 goto out_err_noserver;