aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/Makefile18
-rw-r--r--fs/nfs/client.c2
-rw-r--r--fs/nfs/file.c4
-rw-r--r--fs/nfs/idmap.c62
-rw-r--r--fs/nfs/inode.c2
-rw-r--r--fs/nfs/nfs3proc.c4
-rw-r--r--fs/nfs/nfs4_fs.h3
-rw-r--r--fs/nfs/nfs4client.c2
-rw-r--r--fs/nfs/nfs4file.c4
-rw-r--r--fs/nfs/nfs4proc.c127
-rw-r--r--fs/nfs/nfs4super.c15
-rw-r--r--fs/nfs/nfs4xdr.c41
-rw-r--r--fs/nfs/objlayout/objio_osd.c55
-rw-r--r--fs/nfs/pagelist.c2
-rw-r--r--fs/nfs/pnfs.c39
-rw-r--r--fs/nfs/pnfs.h2
-rw-r--r--fs/nfs/super.c41
-rw-r--r--fs/nfs/write.c15
18 files changed, 278 insertions, 160 deletions
diff --git a/fs/nfs/Makefile b/fs/nfs/Makefile
index 8bf3a3f6925a..b7db60897f91 100644
--- a/fs/nfs/Makefile
+++ b/fs/nfs/Makefile
@@ -12,19 +12,19 @@ nfs-$(CONFIG_ROOT_NFS) += nfsroot.o
12nfs-$(CONFIG_SYSCTL) += sysctl.o 12nfs-$(CONFIG_SYSCTL) += sysctl.o
13nfs-$(CONFIG_NFS_FSCACHE) += fscache.o fscache-index.o 13nfs-$(CONFIG_NFS_FSCACHE) += fscache.o fscache-index.o
14 14
15obj-$(CONFIG_NFS_V2) += nfs2.o 15obj-$(CONFIG_NFS_V2) += nfsv2.o
16nfs2-y := nfs2super.o proc.o nfs2xdr.o 16nfsv2-y := nfs2super.o proc.o nfs2xdr.o
17 17
18obj-$(CONFIG_NFS_V3) += nfs3.o 18obj-$(CONFIG_NFS_V3) += nfsv3.o
19nfs3-y := nfs3super.o nfs3client.o nfs3proc.o nfs3xdr.o 19nfsv3-y := nfs3super.o nfs3client.o nfs3proc.o nfs3xdr.o
20nfs3-$(CONFIG_NFS_V3_ACL) += nfs3acl.o 20nfsv3-$(CONFIG_NFS_V3_ACL) += nfs3acl.o
21 21
22obj-$(CONFIG_NFS_V4) += nfs4.o 22obj-$(CONFIG_NFS_V4) += nfsv4.o
23nfs4-y := nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o nfs4super.o nfs4file.o \ 23nfsv4-y := nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o nfs4super.o nfs4file.o \
24 delegation.o idmap.o callback.o callback_xdr.o callback_proc.o \ 24 delegation.o idmap.o callback.o callback_xdr.o callback_proc.o \
25 nfs4namespace.o nfs4getroot.o nfs4client.o 25 nfs4namespace.o nfs4getroot.o nfs4client.o
26nfs4-$(CONFIG_SYSCTL) += nfs4sysctl.o 26nfsv4-$(CONFIG_SYSCTL) += nfs4sysctl.o
27nfs4-$(CONFIG_NFS_V4_1) += pnfs.o pnfs_dev.o 27nfsv4-$(CONFIG_NFS_V4_1) += pnfs.o pnfs_dev.o
28 28
29obj-$(CONFIG_PNFS_FILE_LAYOUT) += nfs_layout_nfsv41_files.o 29obj-$(CONFIG_PNFS_FILE_LAYOUT) += nfs_layout_nfsv41_files.o
30nfs_layout_nfsv41_files-y := nfs4filelayout.o nfs4filelayoutdev.o 30nfs_layout_nfsv41_files-y := nfs4filelayout.o nfs4filelayoutdev.o
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 9fc0d9dfc91b..99694442b93f 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -105,7 +105,7 @@ struct nfs_subversion *get_nfs_version(unsigned int version)
105 105
106 if (IS_ERR(nfs)) { 106 if (IS_ERR(nfs)) {
107 mutex_lock(&nfs_version_mutex); 107 mutex_lock(&nfs_version_mutex);
108 request_module("nfs%d", version); 108 request_module("nfsv%d", version);
109 nfs = find_nfs_version(version); 109 nfs = find_nfs_version(version);
110 mutex_unlock(&nfs_version_mutex); 110 mutex_unlock(&nfs_version_mutex);
111 } 111 }
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 75d6d0a3d32e..6a7fcab7ecb3 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -287,10 +287,12 @@ nfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync)
287 struct inode *inode = file->f_path.dentry->d_inode; 287 struct inode *inode = file->f_path.dentry->d_inode;
288 288
289 ret = filemap_write_and_wait_range(inode->i_mapping, start, end); 289 ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
290 if (ret != 0)
291 goto out;
290 mutex_lock(&inode->i_mutex); 292 mutex_lock(&inode->i_mutex);
291 ret = nfs_file_fsync_commit(file, start, end, datasync); 293 ret = nfs_file_fsync_commit(file, start, end, datasync);
292 mutex_unlock(&inode->i_mutex); 294 mutex_unlock(&inode->i_mutex);
293 295out:
294 return ret; 296 return ret;
295} 297}
296 298
diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c
index b701358c39c3..a850079467d8 100644
--- a/fs/nfs/idmap.c
+++ b/fs/nfs/idmap.c
@@ -61,6 +61,12 @@ struct idmap {
61 struct mutex idmap_mutex; 61 struct mutex idmap_mutex;
62}; 62};
63 63
64struct idmap_legacy_upcalldata {
65 struct rpc_pipe_msg pipe_msg;
66 struct idmap_msg idmap_msg;
67 struct idmap *idmap;
68};
69
64/** 70/**
65 * nfs_fattr_init_names - initialise the nfs_fattr owner_name/group_name fields 71 * nfs_fattr_init_names - initialise the nfs_fattr owner_name/group_name fields
66 * @fattr: fully initialised struct nfs_fattr 72 * @fattr: fully initialised struct nfs_fattr
@@ -324,6 +330,7 @@ static ssize_t nfs_idmap_get_key(const char *name, size_t namelen,
324 ret = nfs_idmap_request_key(&key_type_id_resolver_legacy, 330 ret = nfs_idmap_request_key(&key_type_id_resolver_legacy,
325 name, namelen, type, data, 331 name, namelen, type, data,
326 data_size, idmap); 332 data_size, idmap);
333 idmap->idmap_key_cons = NULL;
327 mutex_unlock(&idmap->idmap_mutex); 334 mutex_unlock(&idmap->idmap_mutex);
328 } 335 }
329 return ret; 336 return ret;
@@ -380,11 +387,13 @@ static const match_table_t nfs_idmap_tokens = {
380static int nfs_idmap_legacy_upcall(struct key_construction *, const char *, void *); 387static int nfs_idmap_legacy_upcall(struct key_construction *, const char *, void *);
381static ssize_t idmap_pipe_downcall(struct file *, const char __user *, 388static ssize_t idmap_pipe_downcall(struct file *, const char __user *,
382 size_t); 389 size_t);
390static void idmap_release_pipe(struct inode *);
383static void idmap_pipe_destroy_msg(struct rpc_pipe_msg *); 391static void idmap_pipe_destroy_msg(struct rpc_pipe_msg *);
384 392
385static const struct rpc_pipe_ops idmap_upcall_ops = { 393static const struct rpc_pipe_ops idmap_upcall_ops = {
386 .upcall = rpc_pipe_generic_upcall, 394 .upcall = rpc_pipe_generic_upcall,
387 .downcall = idmap_pipe_downcall, 395 .downcall = idmap_pipe_downcall,
396 .release_pipe = idmap_release_pipe,
388 .destroy_msg = idmap_pipe_destroy_msg, 397 .destroy_msg = idmap_pipe_destroy_msg,
389}; 398};
390 399
@@ -616,7 +625,8 @@ void nfs_idmap_quit(void)
616 nfs_idmap_quit_keyring(); 625 nfs_idmap_quit_keyring();
617} 626}
618 627
619static int nfs_idmap_prepare_message(char *desc, struct idmap_msg *im, 628static int nfs_idmap_prepare_message(char *desc, struct idmap *idmap,
629 struct idmap_msg *im,
620 struct rpc_pipe_msg *msg) 630 struct rpc_pipe_msg *msg)
621{ 631{
622 substring_t substr; 632 substring_t substr;
@@ -659,6 +669,7 @@ static int nfs_idmap_legacy_upcall(struct key_construction *cons,
659 const char *op, 669 const char *op,
660 void *aux) 670 void *aux)
661{ 671{
672 struct idmap_legacy_upcalldata *data;
662 struct rpc_pipe_msg *msg; 673 struct rpc_pipe_msg *msg;
663 struct idmap_msg *im; 674 struct idmap_msg *im;
664 struct idmap *idmap = (struct idmap *)aux; 675 struct idmap *idmap = (struct idmap *)aux;
@@ -666,15 +677,15 @@ static int nfs_idmap_legacy_upcall(struct key_construction *cons,
666 int ret = -ENOMEM; 677 int ret = -ENOMEM;
667 678
668 /* msg and im are freed in idmap_pipe_destroy_msg */ 679 /* msg and im are freed in idmap_pipe_destroy_msg */
669 msg = kmalloc(sizeof(*msg), GFP_KERNEL); 680 data = kmalloc(sizeof(*data), GFP_KERNEL);
670 if (!msg) 681 if (!data)
671 goto out0;
672
673 im = kmalloc(sizeof(*im), GFP_KERNEL);
674 if (!im)
675 goto out1; 682 goto out1;
676 683
677 ret = nfs_idmap_prepare_message(key->description, im, msg); 684 msg = &data->pipe_msg;
685 im = &data->idmap_msg;
686 data->idmap = idmap;
687
688 ret = nfs_idmap_prepare_message(key->description, idmap, im, msg);
678 if (ret < 0) 689 if (ret < 0)
679 goto out2; 690 goto out2;
680 691
@@ -683,15 +694,15 @@ static int nfs_idmap_legacy_upcall(struct key_construction *cons,
683 694
684 ret = rpc_queue_upcall(idmap->idmap_pipe, msg); 695 ret = rpc_queue_upcall(idmap->idmap_pipe, msg);
685 if (ret < 0) 696 if (ret < 0)
686 goto out2; 697 goto out3;
687 698
688 return ret; 699 return ret;
689 700
701out3:
702 idmap->idmap_key_cons = NULL;
690out2: 703out2:
691 kfree(im); 704 kfree(data);
692out1: 705out1:
693 kfree(msg);
694out0:
695 complete_request_key(cons, ret); 706 complete_request_key(cons, ret);
696 return ret; 707 return ret;
697} 708}
@@ -749,9 +760,8 @@ idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
749 } 760 }
750 761
751 if (!(im.im_status & IDMAP_STATUS_SUCCESS)) { 762 if (!(im.im_status & IDMAP_STATUS_SUCCESS)) {
752 ret = mlen; 763 ret = -ENOKEY;
753 complete_request_key(cons, -ENOKEY); 764 goto out;
754 goto out_incomplete;
755 } 765 }
756 766
757 namelen_in = strnlen(im.im_name, IDMAP_NAMESZ); 767 namelen_in = strnlen(im.im_name, IDMAP_NAMESZ);
@@ -768,16 +778,32 @@ idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
768 778
769out: 779out:
770 complete_request_key(cons, ret); 780 complete_request_key(cons, ret);
771out_incomplete:
772 return ret; 781 return ret;
773} 782}
774 783
775static void 784static void
776idmap_pipe_destroy_msg(struct rpc_pipe_msg *msg) 785idmap_pipe_destroy_msg(struct rpc_pipe_msg *msg)
777{ 786{
787 struct idmap_legacy_upcalldata *data = container_of(msg,
788 struct idmap_legacy_upcalldata,
789 pipe_msg);
790 struct idmap *idmap = data->idmap;
791 struct key_construction *cons;
792 if (msg->errno) {
793 cons = ACCESS_ONCE(idmap->idmap_key_cons);
794 idmap->idmap_key_cons = NULL;
795 complete_request_key(cons, msg->errno);
796 }
778 /* Free memory allocated in nfs_idmap_legacy_upcall() */ 797 /* Free memory allocated in nfs_idmap_legacy_upcall() */
779 kfree(msg->data); 798 kfree(data);
780 kfree(msg); 799}
800
801static void
802idmap_release_pipe(struct inode *inode)
803{
804 struct rpc_inode *rpci = RPC_I(inode);
805 struct idmap *idmap = (struct idmap *)rpci->private;
806 idmap->idmap_key_cons = NULL;
781} 807}
782 808
783int nfs_map_name_to_uid(const struct nfs_server *server, const char *name, size_t namelen, __u32 *uid) 809int nfs_map_name_to_uid(const struct nfs_server *server, const char *name, size_t namelen, __u32 *uid)
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index c6e895f0fbf3..9b47610338f5 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -154,7 +154,7 @@ static void nfs_zap_caches_locked(struct inode *inode)
154 nfsi->attrtimeo = NFS_MINATTRTIMEO(inode); 154 nfsi->attrtimeo = NFS_MINATTRTIMEO(inode);
155 nfsi->attrtimeo_timestamp = jiffies; 155 nfsi->attrtimeo_timestamp = jiffies;
156 156
157 memset(NFS_COOKIEVERF(inode), 0, sizeof(NFS_COOKIEVERF(inode))); 157 memset(NFS_I(inode)->cookieverf, 0, sizeof(NFS_I(inode)->cookieverf));
158 if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) 158 if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode))
159 nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE; 159 nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE;
160 else 160 else
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
index 0952c791df36..69322096c325 100644
--- a/fs/nfs/nfs3proc.c
+++ b/fs/nfs/nfs3proc.c
@@ -69,7 +69,7 @@ do_proc_get_root(struct rpc_clnt *client, struct nfs_fh *fhandle,
69 nfs_fattr_init(info->fattr); 69 nfs_fattr_init(info->fattr);
70 status = rpc_call_sync(client, &msg, 0); 70 status = rpc_call_sync(client, &msg, 0);
71 dprintk("%s: reply fsinfo: %d\n", __func__, status); 71 dprintk("%s: reply fsinfo: %d\n", __func__, status);
72 if (!(info->fattr->valid & NFS_ATTR_FATTR)) { 72 if (status == 0 && !(info->fattr->valid & NFS_ATTR_FATTR)) {
73 msg.rpc_proc = &nfs3_procedures[NFS3PROC_GETATTR]; 73 msg.rpc_proc = &nfs3_procedures[NFS3PROC_GETATTR];
74 msg.rpc_resp = info->fattr; 74 msg.rpc_resp = info->fattr;
75 status = rpc_call_sync(client, &msg, 0); 75 status = rpc_call_sync(client, &msg, 0);
@@ -643,7 +643,7 @@ nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
643 u64 cookie, struct page **pages, unsigned int count, int plus) 643 u64 cookie, struct page **pages, unsigned int count, int plus)
644{ 644{
645 struct inode *dir = dentry->d_inode; 645 struct inode *dir = dentry->d_inode;
646 __be32 *verf = NFS_COOKIEVERF(dir); 646 __be32 *verf = NFS_I(dir)->cookieverf;
647 struct nfs3_readdirargs arg = { 647 struct nfs3_readdirargs arg = {
648 .fh = NFS_FH(dir), 648 .fh = NFS_FH(dir),
649 .cookie = cookie, 649 .cookie = cookie,
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index 3b950dd81e81..da0618aeeadb 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -205,6 +205,9 @@ extern const struct dentry_operations nfs4_dentry_operations;
205int nfs_atomic_open(struct inode *, struct dentry *, struct file *, 205int nfs_atomic_open(struct inode *, struct dentry *, struct file *,
206 unsigned, umode_t, int *); 206 unsigned, umode_t, int *);
207 207
208/* super.c */
209extern struct file_system_type nfs4_fs_type;
210
208/* nfs4namespace.c */ 211/* nfs4namespace.c */
209rpc_authflavor_t nfs_find_best_sec(struct nfs4_secinfo_flavors *); 212rpc_authflavor_t nfs_find_best_sec(struct nfs4_secinfo_flavors *);
210struct rpc_clnt *nfs4_create_sec_client(struct rpc_clnt *, struct inode *, struct qstr *); 213struct rpc_clnt *nfs4_create_sec_client(struct rpc_clnt *, struct inode *, struct qstr *);
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c
index cbcdfaf32505..24eb663f8ed5 100644
--- a/fs/nfs/nfs4client.c
+++ b/fs/nfs/nfs4client.c
@@ -74,7 +74,7 @@ struct nfs_client *nfs4_alloc_client(const struct nfs_client_initdata *cl_init)
74 return clp; 74 return clp;
75 75
76error: 76error:
77 kfree(clp); 77 nfs_free_client(clp);
78 return ERR_PTR(err); 78 return ERR_PTR(err);
79} 79}
80 80
diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c
index acb65e7887f8..eb5eb8eef4d3 100644
--- a/fs/nfs/nfs4file.c
+++ b/fs/nfs/nfs4file.c
@@ -96,13 +96,15 @@ nfs4_file_fsync(struct file *file, loff_t start, loff_t end, int datasync)
96 struct inode *inode = file->f_path.dentry->d_inode; 96 struct inode *inode = file->f_path.dentry->d_inode;
97 97
98 ret = filemap_write_and_wait_range(inode->i_mapping, start, end); 98 ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
99 if (ret != 0)
100 goto out;
99 mutex_lock(&inode->i_mutex); 101 mutex_lock(&inode->i_mutex);
100 ret = nfs_file_fsync_commit(file, start, end, datasync); 102 ret = nfs_file_fsync_commit(file, start, end, datasync);
101 if (!ret && !datasync) 103 if (!ret && !datasync)
102 /* application has asked for meta-data sync */ 104 /* application has asked for meta-data sync */
103 ret = pnfs_layoutcommit_inode(inode, true); 105 ret = pnfs_layoutcommit_inode(inode, true);
104 mutex_unlock(&inode->i_mutex); 106 mutex_unlock(&inode->i_mutex);
105 107out:
106 return ret; 108 return ret;
107} 109}
108 110
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index a99a8d948721..1e50326d00dd 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -3215,11 +3215,11 @@ static int _nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
3215 dentry->d_parent->d_name.name, 3215 dentry->d_parent->d_name.name,
3216 dentry->d_name.name, 3216 dentry->d_name.name,
3217 (unsigned long long)cookie); 3217 (unsigned long long)cookie);
3218 nfs4_setup_readdir(cookie, NFS_COOKIEVERF(dir), dentry, &args); 3218 nfs4_setup_readdir(cookie, NFS_I(dir)->cookieverf, dentry, &args);
3219 res.pgbase = args.pgbase; 3219 res.pgbase = args.pgbase;
3220 status = nfs4_call_sync(NFS_SERVER(dir)->client, NFS_SERVER(dir), &msg, &args.seq_args, &res.seq_res, 0); 3220 status = nfs4_call_sync(NFS_SERVER(dir)->client, NFS_SERVER(dir), &msg, &args.seq_args, &res.seq_res, 0);
3221 if (status >= 0) { 3221 if (status >= 0) {
3222 memcpy(NFS_COOKIEVERF(dir), res.verifier.data, NFS4_VERIFIER_SIZE); 3222 memcpy(NFS_I(dir)->cookieverf, res.verifier.data, NFS4_VERIFIER_SIZE);
3223 status += args.pgbase; 3223 status += args.pgbase;
3224 } 3224 }
3225 3225
@@ -3653,11 +3653,11 @@ static inline int nfs4_server_supports_acls(struct nfs_server *server)
3653 && (server->acl_bitmask & ACL4_SUPPORT_DENY_ACL); 3653 && (server->acl_bitmask & ACL4_SUPPORT_DENY_ACL);
3654} 3654}
3655 3655
3656/* Assuming that XATTR_SIZE_MAX is a multiple of PAGE_CACHE_SIZE, and that 3656/* Assuming that XATTR_SIZE_MAX is a multiple of PAGE_SIZE, and that
3657 * it's OK to put sizeof(void) * (XATTR_SIZE_MAX/PAGE_CACHE_SIZE) bytes on 3657 * it's OK to put sizeof(void) * (XATTR_SIZE_MAX/PAGE_SIZE) bytes on
3658 * the stack. 3658 * the stack.
3659 */ 3659 */
3660#define NFS4ACL_MAXPAGES (XATTR_SIZE_MAX >> PAGE_CACHE_SHIFT) 3660#define NFS4ACL_MAXPAGES DIV_ROUND_UP(XATTR_SIZE_MAX, PAGE_SIZE)
3661 3661
3662static int buf_to_pages_noslab(const void *buf, size_t buflen, 3662static int buf_to_pages_noslab(const void *buf, size_t buflen,
3663 struct page **pages, unsigned int *pgbase) 3663 struct page **pages, unsigned int *pgbase)
@@ -3668,7 +3668,7 @@ static int buf_to_pages_noslab(const void *buf, size_t buflen,
3668 spages = pages; 3668 spages = pages;
3669 3669
3670 do { 3670 do {
3671 len = min_t(size_t, PAGE_CACHE_SIZE, buflen); 3671 len = min_t(size_t, PAGE_SIZE, buflen);
3672 newpage = alloc_page(GFP_KERNEL); 3672 newpage = alloc_page(GFP_KERNEL);
3673 3673
3674 if (newpage == NULL) 3674 if (newpage == NULL)
@@ -3737,9 +3737,10 @@ out:
3737static void nfs4_write_cached_acl(struct inode *inode, struct page **pages, size_t pgbase, size_t acl_len) 3737static void nfs4_write_cached_acl(struct inode *inode, struct page **pages, size_t pgbase, size_t acl_len)
3738{ 3738{
3739 struct nfs4_cached_acl *acl; 3739 struct nfs4_cached_acl *acl;
3740 size_t buflen = sizeof(*acl) + acl_len;
3740 3741
3741 if (pages && acl_len <= PAGE_SIZE) { 3742 if (buflen <= PAGE_SIZE) {
3742 acl = kmalloc(sizeof(*acl) + acl_len, GFP_KERNEL); 3743 acl = kmalloc(buflen, GFP_KERNEL);
3743 if (acl == NULL) 3744 if (acl == NULL)
3744 goto out; 3745 goto out;
3745 acl->cached = 1; 3746 acl->cached = 1;
@@ -3781,17 +3782,15 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu
3781 .rpc_argp = &args, 3782 .rpc_argp = &args,
3782 .rpc_resp = &res, 3783 .rpc_resp = &res,
3783 }; 3784 };
3784 int ret = -ENOMEM, npages, i; 3785 unsigned int npages = DIV_ROUND_UP(buflen, PAGE_SIZE);
3785 size_t acl_len = 0; 3786 int ret = -ENOMEM, i;
3786 3787
3787 npages = (buflen + PAGE_SIZE - 1) >> PAGE_SHIFT;
3788 /* As long as we're doing a round trip to the server anyway, 3788 /* As long as we're doing a round trip to the server anyway,
3789 * let's be prepared for a page of acl data. */ 3789 * let's be prepared for a page of acl data. */
3790 if (npages == 0) 3790 if (npages == 0)
3791 npages = 1; 3791 npages = 1;
3792 3792 if (npages > ARRAY_SIZE(pages))
3793 /* Add an extra page to handle the bitmap returned */ 3793 return -ERANGE;
3794 npages++;
3795 3794
3796 for (i = 0; i < npages; i++) { 3795 for (i = 0; i < npages; i++) {
3797 pages[i] = alloc_page(GFP_KERNEL); 3796 pages[i] = alloc_page(GFP_KERNEL);
@@ -3807,11 +3806,6 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu
3807 args.acl_len = npages * PAGE_SIZE; 3806 args.acl_len = npages * PAGE_SIZE;
3808 args.acl_pgbase = 0; 3807 args.acl_pgbase = 0;
3809 3808
3810 /* Let decode_getfacl know not to fail if the ACL data is larger than
3811 * the page we send as a guess */
3812 if (buf == NULL)
3813 res.acl_flags |= NFS4_ACL_LEN_REQUEST;
3814
3815 dprintk("%s buf %p buflen %zu npages %d args.acl_len %zu\n", 3809 dprintk("%s buf %p buflen %zu npages %d args.acl_len %zu\n",
3816 __func__, buf, buflen, npages, args.acl_len); 3810 __func__, buf, buflen, npages, args.acl_len);
3817 ret = nfs4_call_sync(NFS_SERVER(inode)->client, NFS_SERVER(inode), 3811 ret = nfs4_call_sync(NFS_SERVER(inode)->client, NFS_SERVER(inode),
@@ -3819,20 +3813,19 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu
3819 if (ret) 3813 if (ret)
3820 goto out_free; 3814 goto out_free;
3821 3815
3822 acl_len = res.acl_len - res.acl_data_offset; 3816 /* Handle the case where the passed-in buffer is too short */
3823 if (acl_len > args.acl_len) 3817 if (res.acl_flags & NFS4_ACL_TRUNC) {
3824 nfs4_write_cached_acl(inode, NULL, 0, acl_len); 3818 /* Did the user only issue a request for the acl length? */
3825 else 3819 if (buf == NULL)
3826 nfs4_write_cached_acl(inode, pages, res.acl_data_offset, 3820 goto out_ok;
3827 acl_len);
3828 if (buf) {
3829 ret = -ERANGE; 3821 ret = -ERANGE;
3830 if (acl_len > buflen) 3822 goto out_free;
3831 goto out_free;
3832 _copy_from_pages(buf, pages, res.acl_data_offset,
3833 acl_len);
3834 } 3823 }
3835 ret = acl_len; 3824 nfs4_write_cached_acl(inode, pages, res.acl_data_offset, res.acl_len);
3825 if (buf)
3826 _copy_from_pages(buf, pages, res.acl_data_offset, res.acl_len);
3827out_ok:
3828 ret = res.acl_len;
3836out_free: 3829out_free:
3837 for (i = 0; i < npages; i++) 3830 for (i = 0; i < npages; i++)
3838 if (pages[i]) 3831 if (pages[i])
@@ -3890,10 +3883,13 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl
3890 .rpc_argp = &arg, 3883 .rpc_argp = &arg,
3891 .rpc_resp = &res, 3884 .rpc_resp = &res,
3892 }; 3885 };
3886 unsigned int npages = DIV_ROUND_UP(buflen, PAGE_SIZE);
3893 int ret, i; 3887 int ret, i;
3894 3888
3895 if (!nfs4_server_supports_acls(server)) 3889 if (!nfs4_server_supports_acls(server))
3896 return -EOPNOTSUPP; 3890 return -EOPNOTSUPP;
3891 if (npages > ARRAY_SIZE(pages))
3892 return -ERANGE;
3897 i = buf_to_pages_noslab(buf, buflen, arg.acl_pages, &arg.acl_pgbase); 3893 i = buf_to_pages_noslab(buf, buflen, arg.acl_pages, &arg.acl_pgbase);
3898 if (i < 0) 3894 if (i < 0)
3899 return i; 3895 return i;
@@ -6223,11 +6219,58 @@ static void nfs4_layoutget_done(struct rpc_task *task, void *calldata)
6223 dprintk("<-- %s\n", __func__); 6219 dprintk("<-- %s\n", __func__);
6224} 6220}
6225 6221
6222static size_t max_response_pages(struct nfs_server *server)
6223{
6224 u32 max_resp_sz = server->nfs_client->cl_session->fc_attrs.max_resp_sz;
6225 return nfs_page_array_len(0, max_resp_sz);
6226}
6227
6228static void nfs4_free_pages(struct page **pages, size_t size)
6229{
6230 int i;
6231
6232 if (!pages)
6233 return;
6234
6235 for (i = 0; i < size; i++) {
6236 if (!pages[i])
6237 break;
6238 __free_page(pages[i]);
6239 }
6240 kfree(pages);
6241}
6242
6243static struct page **nfs4_alloc_pages(size_t size, gfp_t gfp_flags)
6244{
6245 struct page **pages;
6246 int i;
6247
6248 pages = kcalloc(size, sizeof(struct page *), gfp_flags);
6249 if (!pages) {
6250 dprintk("%s: can't alloc array of %zu pages\n", __func__, size);
6251 return NULL;
6252 }
6253
6254 for (i = 0; i < size; i++) {
6255 pages[i] = alloc_page(gfp_flags);
6256 if (!pages[i]) {
6257 dprintk("%s: failed to allocate page\n", __func__);
6258 nfs4_free_pages(pages, size);
6259 return NULL;
6260 }
6261 }
6262
6263 return pages;
6264}
6265
6226static void nfs4_layoutget_release(void *calldata) 6266static void nfs4_layoutget_release(void *calldata)
6227{ 6267{
6228 struct nfs4_layoutget *lgp = calldata; 6268 struct nfs4_layoutget *lgp = calldata;
6269 struct nfs_server *server = NFS_SERVER(lgp->args.inode);
6270 size_t max_pages = max_response_pages(server);
6229 6271
6230 dprintk("--> %s\n", __func__); 6272 dprintk("--> %s\n", __func__);
6273 nfs4_free_pages(lgp->args.layout.pages, max_pages);
6231 put_nfs_open_context(lgp->args.ctx); 6274 put_nfs_open_context(lgp->args.ctx);
6232 kfree(calldata); 6275 kfree(calldata);
6233 dprintk("<-- %s\n", __func__); 6276 dprintk("<-- %s\n", __func__);
@@ -6239,9 +6282,10 @@ static const struct rpc_call_ops nfs4_layoutget_call_ops = {
6239 .rpc_release = nfs4_layoutget_release, 6282 .rpc_release = nfs4_layoutget_release,
6240}; 6283};
6241 6284
6242int nfs4_proc_layoutget(struct nfs4_layoutget *lgp) 6285void nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags)
6243{ 6286{
6244 struct nfs_server *server = NFS_SERVER(lgp->args.inode); 6287 struct nfs_server *server = NFS_SERVER(lgp->args.inode);
6288 size_t max_pages = max_response_pages(server);
6245 struct rpc_task *task; 6289 struct rpc_task *task;
6246 struct rpc_message msg = { 6290 struct rpc_message msg = {
6247 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LAYOUTGET], 6291 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LAYOUTGET],
@@ -6259,12 +6303,19 @@ int nfs4_proc_layoutget(struct nfs4_layoutget *lgp)
6259 6303
6260 dprintk("--> %s\n", __func__); 6304 dprintk("--> %s\n", __func__);
6261 6305
6306 lgp->args.layout.pages = nfs4_alloc_pages(max_pages, gfp_flags);
6307 if (!lgp->args.layout.pages) {
6308 nfs4_layoutget_release(lgp);
6309 return;
6310 }
6311 lgp->args.layout.pglen = max_pages * PAGE_SIZE;
6312
6262 lgp->res.layoutp = &lgp->args.layout; 6313 lgp->res.layoutp = &lgp->args.layout;
6263 lgp->res.seq_res.sr_slot = NULL; 6314 lgp->res.seq_res.sr_slot = NULL;
6264 nfs41_init_sequence(&lgp->args.seq_args, &lgp->res.seq_res, 0); 6315 nfs41_init_sequence(&lgp->args.seq_args, &lgp->res.seq_res, 0);
6265 task = rpc_run_task(&task_setup_data); 6316 task = rpc_run_task(&task_setup_data);
6266 if (IS_ERR(task)) 6317 if (IS_ERR(task))
6267 return PTR_ERR(task); 6318 return;
6268 status = nfs4_wait_for_completion_rpc_task(task); 6319 status = nfs4_wait_for_completion_rpc_task(task);
6269 if (status == 0) 6320 if (status == 0)
6270 status = task->tk_status; 6321 status = task->tk_status;
@@ -6272,7 +6323,7 @@ int nfs4_proc_layoutget(struct nfs4_layoutget *lgp)
6272 status = pnfs_layout_process(lgp); 6323 status = pnfs_layout_process(lgp);
6273 rpc_put_task(task); 6324 rpc_put_task(task);
6274 dprintk("<-- %s status=%d\n", __func__, status); 6325 dprintk("<-- %s status=%d\n", __func__, status);
6275 return status; 6326 return;
6276} 6327}
6277 6328
6278static void 6329static void
@@ -6304,12 +6355,8 @@ static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata)
6304 return; 6355 return;
6305 } 6356 }
6306 spin_lock(&lo->plh_inode->i_lock); 6357 spin_lock(&lo->plh_inode->i_lock);
6307 if (task->tk_status == 0) { 6358 if (task->tk_status == 0 && lrp->res.lrs_present)
6308 if (lrp->res.lrs_present) { 6359 pnfs_set_layout_stateid(lo, &lrp->res.stateid, true);
6309 pnfs_set_layout_stateid(lo, &lrp->res.stateid, true);
6310 } else
6311 BUG_ON(!list_empty(&lo->plh_segs));
6312 }
6313 lo->plh_block_lgets--; 6360 lo->plh_block_lgets--;
6314 spin_unlock(&lo->plh_inode->i_lock); 6361 spin_unlock(&lo->plh_inode->i_lock);
6315 dprintk("<-- %s\n", __func__); 6362 dprintk("<-- %s\n", __func__);
diff --git a/fs/nfs/nfs4super.c b/fs/nfs/nfs4super.c
index 12a31a9dbcdd..bd61221ad2c5 100644
--- a/fs/nfs/nfs4super.c
+++ b/fs/nfs/nfs4super.c
@@ -23,14 +23,6 @@ static struct dentry *nfs4_referral_mount(struct file_system_type *fs_type,
23static struct dentry *nfs4_remote_referral_mount(struct file_system_type *fs_type, 23static struct dentry *nfs4_remote_referral_mount(struct file_system_type *fs_type,
24 int flags, const char *dev_name, void *raw_data); 24 int flags, const char *dev_name, void *raw_data);
25 25
26static struct file_system_type nfs4_fs_type = {
27 .owner = THIS_MODULE,
28 .name = "nfs4",
29 .mount = nfs_fs_mount,
30 .kill_sb = nfs_kill_super,
31 .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
32};
33
34static struct file_system_type nfs4_remote_fs_type = { 26static struct file_system_type nfs4_remote_fs_type = {
35 .owner = THIS_MODULE, 27 .owner = THIS_MODULE,
36 .name = "nfs4", 28 .name = "nfs4",
@@ -344,14 +336,8 @@ static int __init init_nfs_v4(void)
344 if (err) 336 if (err)
345 goto out1; 337 goto out1;
346 338
347 err = register_filesystem(&nfs4_fs_type);
348 if (err < 0)
349 goto out2;
350
351 register_nfs_version(&nfs_v4); 339 register_nfs_version(&nfs_v4);
352 return 0; 340 return 0;
353out2:
354 nfs4_unregister_sysctl();
355out1: 341out1:
356 nfs_idmap_quit(); 342 nfs_idmap_quit();
357out: 343out:
@@ -361,7 +347,6 @@ out:
361static void __exit exit_nfs_v4(void) 347static void __exit exit_nfs_v4(void)
362{ 348{
363 unregister_nfs_version(&nfs_v4); 349 unregister_nfs_version(&nfs_v4);
364 unregister_filesystem(&nfs4_fs_type);
365 nfs4_unregister_sysctl(); 350 nfs4_unregister_sysctl();
366 nfs_idmap_quit(); 351 nfs_idmap_quit();
367} 352}
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index ca13483edd60..8dba6bd48557 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -5045,22 +5045,19 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req,
5045 struct nfs_getaclres *res) 5045 struct nfs_getaclres *res)
5046{ 5046{
5047 unsigned int savep; 5047 unsigned int savep;
5048 __be32 *bm_p;
5049 uint32_t attrlen, 5048 uint32_t attrlen,
5050 bitmap[3] = {0}; 5049 bitmap[3] = {0};
5051 int status; 5050 int status;
5052 size_t page_len = xdr->buf->page_len; 5051 unsigned int pg_offset;
5053 5052
5054 res->acl_len = 0; 5053 res->acl_len = 0;
5055 if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0) 5054 if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0)
5056 goto out; 5055 goto out;
5057 5056
5058 bm_p = xdr->p; 5057 xdr_enter_page(xdr, xdr->buf->page_len);
5059 res->acl_data_offset = be32_to_cpup(bm_p) + 2; 5058
5060 res->acl_data_offset <<= 2; 5059 /* Calculate the offset of the page data */
5061 /* Check if the acl data starts beyond the allocated buffer */ 5060 pg_offset = xdr->buf->head[0].iov_len;
5062 if (res->acl_data_offset > page_len)
5063 return -ERANGE;
5064 5061
5065 if ((status = decode_attr_bitmap(xdr, bitmap)) != 0) 5062 if ((status = decode_attr_bitmap(xdr, bitmap)) != 0)
5066 goto out; 5063 goto out;
@@ -5074,23 +5071,16 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req,
5074 /* The bitmap (xdr len + bitmaps) and the attr xdr len words 5071 /* The bitmap (xdr len + bitmaps) and the attr xdr len words
5075 * are stored with the acl data to handle the problem of 5072 * are stored with the acl data to handle the problem of
5076 * variable length bitmaps.*/ 5073 * variable length bitmaps.*/
5077 xdr->p = bm_p; 5074 res->acl_data_offset = xdr_stream_pos(xdr) - pg_offset;
5078
5079 /* We ignore &savep and don't do consistency checks on
5080 * the attr length. Let userspace figure it out.... */
5081 attrlen += res->acl_data_offset;
5082 if (attrlen > page_len) {
5083 if (res->acl_flags & NFS4_ACL_LEN_REQUEST) {
5084 /* getxattr interface called with a NULL buf */
5085 res->acl_len = attrlen;
5086 goto out;
5087 }
5088 dprintk("NFS: acl reply: attrlen %u > page_len %zu\n",
5089 attrlen, page_len);
5090 return -EINVAL;
5091 }
5092 xdr_read_pages(xdr, attrlen);
5093 res->acl_len = attrlen; 5075 res->acl_len = attrlen;
5076
5077 /* Check for receive buffer overflow */
5078 if (res->acl_len > (xdr->nwords << 2) ||
5079 res->acl_len + res->acl_data_offset > xdr->buf->page_len) {
5080 res->acl_flags |= NFS4_ACL_TRUNC;
5081 dprintk("NFS: acl reply: attrlen %u > page_len %u\n",
5082 attrlen, xdr->nwords << 2);
5083 }
5094 } else 5084 } else
5095 status = -EOPNOTSUPP; 5085 status = -EOPNOTSUPP;
5096 5086
@@ -6235,7 +6225,8 @@ static int nfs4_xdr_dec_open(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
6235 status = decode_open(xdr, res); 6225 status = decode_open(xdr, res);
6236 if (status) 6226 if (status)
6237 goto out; 6227 goto out;
6238 if (decode_getfh(xdr, &res->fh) != 0) 6228 status = decode_getfh(xdr, &res->fh);
6229 if (status)
6239 goto out; 6230 goto out;
6240 decode_getfattr(xdr, res->f_attr, res->server); 6231 decode_getfattr(xdr, res->f_attr, res->server);
6241out: 6232out:
diff --git a/fs/nfs/objlayout/objio_osd.c b/fs/nfs/objlayout/objio_osd.c
index f50d3e8d6f22..ea6d111b03e9 100644
--- a/fs/nfs/objlayout/objio_osd.c
+++ b/fs/nfs/objlayout/objio_osd.c
@@ -570,17 +570,66 @@ static bool objio_pg_test(struct nfs_pageio_descriptor *pgio,
570 return false; 570 return false;
571 571
572 return pgio->pg_count + req->wb_bytes <= 572 return pgio->pg_count + req->wb_bytes <=
573 OBJIO_LSEG(pgio->pg_lseg)->layout.max_io_length; 573 (unsigned long)pgio->pg_layout_private;
574}
575
576void objio_init_read(struct nfs_pageio_descriptor *pgio, struct nfs_page *req)
577{
578 pnfs_generic_pg_init_read(pgio, req);
579 if (unlikely(pgio->pg_lseg == NULL))
580 return; /* Not pNFS */
581
582 pgio->pg_layout_private = (void *)
583 OBJIO_LSEG(pgio->pg_lseg)->layout.max_io_length;
584}
585
586static bool aligned_on_raid_stripe(u64 offset, struct ore_layout *layout,
587 unsigned long *stripe_end)
588{
589 u32 stripe_off;
590 unsigned stripe_size;
591
592 if (layout->raid_algorithm == PNFS_OSD_RAID_0)
593 return true;
594
595 stripe_size = layout->stripe_unit *
596 (layout->group_width - layout->parity);
597
598 div_u64_rem(offset, stripe_size, &stripe_off);
599 if (!stripe_off)
600 return true;
601
602 *stripe_end = stripe_size - stripe_off;
603 return false;
604}
605
606void objio_init_write(struct nfs_pageio_descriptor *pgio, struct nfs_page *req)
607{
608 unsigned long stripe_end = 0;
609
610 pnfs_generic_pg_init_write(pgio, req);
611 if (unlikely(pgio->pg_lseg == NULL))
612 return; /* Not pNFS */
613
614 if (req->wb_offset ||
615 !aligned_on_raid_stripe(req->wb_index * PAGE_SIZE,
616 &OBJIO_LSEG(pgio->pg_lseg)->layout,
617 &stripe_end)) {
618 pgio->pg_layout_private = (void *)stripe_end;
619 } else {
620 pgio->pg_layout_private = (void *)
621 OBJIO_LSEG(pgio->pg_lseg)->layout.max_io_length;
622 }
574} 623}
575 624
576static const struct nfs_pageio_ops objio_pg_read_ops = { 625static const struct nfs_pageio_ops objio_pg_read_ops = {
577 .pg_init = pnfs_generic_pg_init_read, 626 .pg_init = objio_init_read,
578 .pg_test = objio_pg_test, 627 .pg_test = objio_pg_test,
579 .pg_doio = pnfs_generic_pg_readpages, 628 .pg_doio = pnfs_generic_pg_readpages,
580}; 629};
581 630
582static const struct nfs_pageio_ops objio_pg_write_ops = { 631static const struct nfs_pageio_ops objio_pg_write_ops = {
583 .pg_init = pnfs_generic_pg_init_write, 632 .pg_init = objio_init_write,
584 .pg_test = objio_pg_test, 633 .pg_test = objio_pg_test,
585 .pg_doio = pnfs_generic_pg_writepages, 634 .pg_doio = pnfs_generic_pg_writepages,
586}; 635};
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
index 1a6732ed04a4..311a79681e2b 100644
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -49,6 +49,7 @@ void nfs_pgheader_init(struct nfs_pageio_descriptor *desc,
49 hdr->io_start = req_offset(hdr->req); 49 hdr->io_start = req_offset(hdr->req);
50 hdr->good_bytes = desc->pg_count; 50 hdr->good_bytes = desc->pg_count;
51 hdr->dreq = desc->pg_dreq; 51 hdr->dreq = desc->pg_dreq;
52 hdr->layout_private = desc->pg_layout_private;
52 hdr->release = release; 53 hdr->release = release;
53 hdr->completion_ops = desc->pg_completion_ops; 54 hdr->completion_ops = desc->pg_completion_ops;
54 if (hdr->completion_ops->init_hdr) 55 if (hdr->completion_ops->init_hdr)
@@ -268,6 +269,7 @@ void nfs_pageio_init(struct nfs_pageio_descriptor *desc,
268 desc->pg_error = 0; 269 desc->pg_error = 0;
269 desc->pg_lseg = NULL; 270 desc->pg_lseg = NULL;
270 desc->pg_dreq = NULL; 271 desc->pg_dreq = NULL;
272 desc->pg_layout_private = NULL;
271} 273}
272EXPORT_SYMBOL_GPL(nfs_pageio_init); 274EXPORT_SYMBOL_GPL(nfs_pageio_init);
273 275
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 76875bfcf19c..2e00feacd4be 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -583,9 +583,6 @@ send_layoutget(struct pnfs_layout_hdr *lo,
583 struct nfs_server *server = NFS_SERVER(ino); 583 struct nfs_server *server = NFS_SERVER(ino);
584 struct nfs4_layoutget *lgp; 584 struct nfs4_layoutget *lgp;
585 struct pnfs_layout_segment *lseg = NULL; 585 struct pnfs_layout_segment *lseg = NULL;
586 struct page **pages = NULL;
587 int i;
588 u32 max_resp_sz, max_pages;
589 586
590 dprintk("--> %s\n", __func__); 587 dprintk("--> %s\n", __func__);
591 588
@@ -594,20 +591,6 @@ send_layoutget(struct pnfs_layout_hdr *lo,
594 if (lgp == NULL) 591 if (lgp == NULL)
595 return NULL; 592 return NULL;
596 593
597 /* allocate pages for xdr post processing */
598 max_resp_sz = server->nfs_client->cl_session->fc_attrs.max_resp_sz;
599 max_pages = nfs_page_array_len(0, max_resp_sz);
600
601 pages = kcalloc(max_pages, sizeof(struct page *), gfp_flags);
602 if (!pages)
603 goto out_err_free;
604
605 for (i = 0; i < max_pages; i++) {
606 pages[i] = alloc_page(gfp_flags);
607 if (!pages[i])
608 goto out_err_free;
609 }
610
611 lgp->args.minlength = PAGE_CACHE_SIZE; 594 lgp->args.minlength = PAGE_CACHE_SIZE;
612 if (lgp->args.minlength > range->length) 595 if (lgp->args.minlength > range->length)
613 lgp->args.minlength = range->length; 596 lgp->args.minlength = range->length;
@@ -616,39 +599,19 @@ send_layoutget(struct pnfs_layout_hdr *lo,
616 lgp->args.type = server->pnfs_curr_ld->id; 599 lgp->args.type = server->pnfs_curr_ld->id;
617 lgp->args.inode = ino; 600 lgp->args.inode = ino;
618 lgp->args.ctx = get_nfs_open_context(ctx); 601 lgp->args.ctx = get_nfs_open_context(ctx);
619 lgp->args.layout.pages = pages;
620 lgp->args.layout.pglen = max_pages * PAGE_SIZE;
621 lgp->lsegpp = &lseg; 602 lgp->lsegpp = &lseg;
622 lgp->gfp_flags = gfp_flags; 603 lgp->gfp_flags = gfp_flags;
623 604
624 /* Synchronously retrieve layout information from server and 605 /* Synchronously retrieve layout information from server and
625 * store in lseg. 606 * store in lseg.
626 */ 607 */
627 nfs4_proc_layoutget(lgp); 608 nfs4_proc_layoutget(lgp, gfp_flags);
628 if (!lseg) { 609 if (!lseg) {
629 /* remember that LAYOUTGET failed and suspend trying */ 610 /* remember that LAYOUTGET failed and suspend trying */
630 set_bit(lo_fail_bit(range->iomode), &lo->plh_flags); 611 set_bit(lo_fail_bit(range->iomode), &lo->plh_flags);
631 } 612 }
632 613
633 /* free xdr pages */
634 for (i = 0; i < max_pages; i++)
635 __free_page(pages[i]);
636 kfree(pages);
637
638 return lseg; 614 return lseg;
639
640out_err_free:
641 /* free any allocated xdr pages, lgp as it's not used */
642 if (pages) {
643 for (i = 0; i < max_pages; i++) {
644 if (!pages[i])
645 break;
646 __free_page(pages[i]);
647 }
648 kfree(pages);
649 }
650 kfree(lgp);
651 return NULL;
652} 615}
653 616
654/* 617/*
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
index 2c6c80503ba4..745aa1b39e7c 100644
--- a/fs/nfs/pnfs.h
+++ b/fs/nfs/pnfs.h
@@ -172,7 +172,7 @@ extern int nfs4_proc_getdevicelist(struct nfs_server *server,
172 struct pnfs_devicelist *devlist); 172 struct pnfs_devicelist *devlist);
173extern int nfs4_proc_getdeviceinfo(struct nfs_server *server, 173extern int nfs4_proc_getdeviceinfo(struct nfs_server *server,
174 struct pnfs_device *dev); 174 struct pnfs_device *dev);
175extern int nfs4_proc_layoutget(struct nfs4_layoutget *lgp); 175extern void nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags);
176extern int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp); 176extern int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp);
177 177
178/* pnfs.c */ 178/* pnfs.c */
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index ac6a3c55dce4..b8eda700584b 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -319,6 +319,34 @@ EXPORT_SYMBOL_GPL(nfs_sops);
319static void nfs4_validate_mount_flags(struct nfs_parsed_mount_data *); 319static void nfs4_validate_mount_flags(struct nfs_parsed_mount_data *);
320static int nfs4_validate_mount_data(void *options, 320static int nfs4_validate_mount_data(void *options,
321 struct nfs_parsed_mount_data *args, const char *dev_name); 321 struct nfs_parsed_mount_data *args, const char *dev_name);
322
323struct file_system_type nfs4_fs_type = {
324 .owner = THIS_MODULE,
325 .name = "nfs4",
326 .mount = nfs_fs_mount,
327 .kill_sb = nfs_kill_super,
328 .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
329};
330EXPORT_SYMBOL_GPL(nfs4_fs_type);
331
332static int __init register_nfs4_fs(void)
333{
334 return register_filesystem(&nfs4_fs_type);
335}
336
337static void unregister_nfs4_fs(void)
338{
339 unregister_filesystem(&nfs4_fs_type);
340}
341#else
342static int __init register_nfs4_fs(void)
343{
344 return 0;
345}
346
347static void unregister_nfs4_fs(void)
348{
349}
322#endif 350#endif
323 351
324static struct shrinker acl_shrinker = { 352static struct shrinker acl_shrinker = {
@@ -337,12 +365,18 @@ int __init register_nfs_fs(void)
337 if (ret < 0) 365 if (ret < 0)
338 goto error_0; 366 goto error_0;
339 367
340 ret = nfs_register_sysctl(); 368 ret = register_nfs4_fs();
341 if (ret < 0) 369 if (ret < 0)
342 goto error_1; 370 goto error_1;
371
372 ret = nfs_register_sysctl();
373 if (ret < 0)
374 goto error_2;
343 register_shrinker(&acl_shrinker); 375 register_shrinker(&acl_shrinker);
344 return 0; 376 return 0;
345 377
378error_2:
379 unregister_nfs4_fs();
346error_1: 380error_1:
347 unregister_filesystem(&nfs_fs_type); 381 unregister_filesystem(&nfs_fs_type);
348error_0: 382error_0:
@@ -356,6 +390,7 @@ void __exit unregister_nfs_fs(void)
356{ 390{
357 unregister_shrinker(&acl_shrinker); 391 unregister_shrinker(&acl_shrinker);
358 nfs_unregister_sysctl(); 392 nfs_unregister_sysctl();
393 unregister_nfs4_fs();
359 unregister_filesystem(&nfs_fs_type); 394 unregister_filesystem(&nfs_fs_type);
360} 395}
361 396
@@ -1832,6 +1867,7 @@ static int nfs23_validate_mount_data(void *options,
1832 1867
1833 memcpy(sap, &data->addr, sizeof(data->addr)); 1868 memcpy(sap, &data->addr, sizeof(data->addr));
1834 args->nfs_server.addrlen = sizeof(data->addr); 1869 args->nfs_server.addrlen = sizeof(data->addr);
1870 args->nfs_server.port = ntohs(data->addr.sin_port);
1835 if (!nfs_verify_server_address(sap)) 1871 if (!nfs_verify_server_address(sap))
1836 goto out_no_address; 1872 goto out_no_address;
1837 1873
@@ -2529,6 +2565,7 @@ static int nfs4_validate_mount_data(void *options,
2529 return -EFAULT; 2565 return -EFAULT;
2530 if (!nfs_verify_server_address(sap)) 2566 if (!nfs_verify_server_address(sap))
2531 goto out_no_address; 2567 goto out_no_address;
2568 args->nfs_server.port = ntohs(((struct sockaddr_in *)sap)->sin_port);
2532 2569
2533 if (data->auth_flavourlen) { 2570 if (data->auth_flavourlen) {
2534 if (data->auth_flavourlen > 1) 2571 if (data->auth_flavourlen > 1)
@@ -2645,4 +2682,6 @@ MODULE_PARM_DESC(max_session_slots, "Maximum number of outstanding NFSv4.1 "
2645module_param(send_implementation_id, ushort, 0644); 2682module_param(send_implementation_id, ushort, 0644);
2646MODULE_PARM_DESC(send_implementation_id, 2683MODULE_PARM_DESC(send_implementation_id,
2647 "Send implementation ID with NFSv4.1 exchange_id"); 2684 "Send implementation ID with NFSv4.1 exchange_id");
2685MODULE_ALIAS("nfs4");
2686
2648#endif /* CONFIG_NFS_V4 */ 2687#endif /* CONFIG_NFS_V4 */
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 5829d0ce7cfb..e3b55372726c 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -1814,19 +1814,19 @@ int __init nfs_init_writepagecache(void)
1814 nfs_wdata_mempool = mempool_create_slab_pool(MIN_POOL_WRITE, 1814 nfs_wdata_mempool = mempool_create_slab_pool(MIN_POOL_WRITE,
1815 nfs_wdata_cachep); 1815 nfs_wdata_cachep);
1816 if (nfs_wdata_mempool == NULL) 1816 if (nfs_wdata_mempool == NULL)
1817 return -ENOMEM; 1817 goto out_destroy_write_cache;
1818 1818
1819 nfs_cdata_cachep = kmem_cache_create("nfs_commit_data", 1819 nfs_cdata_cachep = kmem_cache_create("nfs_commit_data",
1820 sizeof(struct nfs_commit_data), 1820 sizeof(struct nfs_commit_data),
1821 0, SLAB_HWCACHE_ALIGN, 1821 0, SLAB_HWCACHE_ALIGN,
1822 NULL); 1822 NULL);
1823 if (nfs_cdata_cachep == NULL) 1823 if (nfs_cdata_cachep == NULL)
1824 return -ENOMEM; 1824 goto out_destroy_write_mempool;
1825 1825
1826 nfs_commit_mempool = mempool_create_slab_pool(MIN_POOL_COMMIT, 1826 nfs_commit_mempool = mempool_create_slab_pool(MIN_POOL_COMMIT,
1827 nfs_wdata_cachep); 1827 nfs_wdata_cachep);
1828 if (nfs_commit_mempool == NULL) 1828 if (nfs_commit_mempool == NULL)
1829 return -ENOMEM; 1829 goto out_destroy_commit_cache;
1830 1830
1831 /* 1831 /*
1832 * NFS congestion size, scale with available memory. 1832 * NFS congestion size, scale with available memory.
@@ -1849,11 +1849,20 @@ int __init nfs_init_writepagecache(void)
1849 nfs_congestion_kb = 256*1024; 1849 nfs_congestion_kb = 256*1024;
1850 1850
1851 return 0; 1851 return 0;
1852
1853out_destroy_commit_cache:
1854 kmem_cache_destroy(nfs_cdata_cachep);
1855out_destroy_write_mempool:
1856 mempool_destroy(nfs_wdata_mempool);
1857out_destroy_write_cache:
1858 kmem_cache_destroy(nfs_wdata_cachep);
1859 return -ENOMEM;
1852} 1860}
1853 1861
1854void nfs_destroy_writepagecache(void) 1862void nfs_destroy_writepagecache(void)
1855{ 1863{
1856 mempool_destroy(nfs_commit_mempool); 1864 mempool_destroy(nfs_commit_mempool);
1865 kmem_cache_destroy(nfs_cdata_cachep);
1857 mempool_destroy(nfs_wdata_mempool); 1866 mempool_destroy(nfs_wdata_mempool);
1858 kmem_cache_destroy(nfs_wdata_cachep); 1867 kmem_cache_destroy(nfs_wdata_cachep);
1859} 1868}