--- /dev/null
+From c5066945b7ea346a11424dbeb7830b7d7d00c206 Mon Sep 17 00:00:00 2001
+From: Bryan Schumaker <bjschuma@netapp.com>
+Date: Thu, 9 Aug 2012 14:05:49 -0400
+Subject: NFS: Clear key construction data if the idmap upcall fails
+
+From: Bryan Schumaker <bjschuma@netapp.com>
+
+commit c5066945b7ea346a11424dbeb7830b7d7d00c206 upstream.
+
+idmap_pipe_downcall already clears this field if the upcall succeeds,
+but if it fails (rpc.idmapd isn't running) the field will still be set
+on the next call triggering a BUG_ON(). This patch tries to handle all
+possible ways that the upcall could fail and clear the idmap key data
+for each one.
+
+Signed-off-by: Bryan Schumaker <bjschuma@netapp.com>
+Tested-by: William Dauchy <wdauchy@gmail.com>
+Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfs/idmap.c | 56 ++++++++++++++++++++++++++++++++++++++++++--------------
+ 1 file changed, 42 insertions(+), 14 deletions(-)
+
+--- a/fs/nfs/idmap.c
++++ b/fs/nfs/idmap.c
+@@ -63,6 +63,12 @@ struct idmap {
+ struct mutex idmap_mutex;
+ };
+
++struct idmap_legacy_upcalldata {
++ struct rpc_pipe_msg pipe_msg;
++ struct idmap_msg idmap_msg;
++ struct idmap *idmap;
++};
++
+ /**
+ * nfs_fattr_init_names - initialise the nfs_fattr owner_name/group_name fields
+ * @fattr: fully initialised struct nfs_fattr
+@@ -326,6 +332,7 @@ static ssize_t nfs_idmap_get_key(const c
+ ret = nfs_idmap_request_key(&key_type_id_resolver_legacy,
+ name, namelen, type, data,
+ data_size, idmap);
++ idmap->idmap_key_cons = NULL;
+ mutex_unlock(&idmap->idmap_mutex);
+ }
+ return ret;
+@@ -383,11 +390,13 @@ static const match_table_t nfs_idmap_tok
+ static int nfs_idmap_legacy_upcall(struct key_construction *, const char *, void *);
+ static ssize_t idmap_pipe_downcall(struct file *, const char __user *,
+ size_t);
++static void idmap_release_pipe(struct inode *);
+ static void idmap_pipe_destroy_msg(struct rpc_pipe_msg *);
+
+ static const struct rpc_pipe_ops idmap_upcall_ops = {
+ .upcall = rpc_pipe_generic_upcall,
+ .downcall = idmap_pipe_downcall,
++ .release_pipe = idmap_release_pipe,
+ .destroy_msg = idmap_pipe_destroy_msg,
+ };
+
+@@ -619,7 +628,8 @@ void nfs_idmap_quit(void)
+ nfs_idmap_quit_keyring();
+ }
+
+-static int nfs_idmap_prepare_message(char *desc, struct idmap_msg *im,
++static int nfs_idmap_prepare_message(char *desc, struct idmap *idmap,
++ struct idmap_msg *im,
+ struct rpc_pipe_msg *msg)
+ {
+ substring_t substr;
+@@ -662,6 +672,7 @@ static int nfs_idmap_legacy_upcall(struc
+ const char *op,
+ void *aux)
+ {
++ struct idmap_legacy_upcalldata *data;
+ struct rpc_pipe_msg *msg;
+ struct idmap_msg *im;
+ struct idmap *idmap = (struct idmap *)aux;
+@@ -669,15 +680,15 @@ static int nfs_idmap_legacy_upcall(struc
+ int ret = -ENOMEM;
+
+ /* msg and im are freed in idmap_pipe_destroy_msg */
+- msg = kmalloc(sizeof(*msg), GFP_KERNEL);
+- if (!msg)
+- goto out0;
+-
+- im = kmalloc(sizeof(*im), GFP_KERNEL);
+- if (!im)
++ data = kmalloc(sizeof(*data), GFP_KERNEL);
++ if (!data)
+ goto out1;
+
+- ret = nfs_idmap_prepare_message(key->description, im, msg);
++ msg = &data->pipe_msg;
++ im = &data->idmap_msg;
++ data->idmap = idmap;
++
++ ret = nfs_idmap_prepare_message(key->description, idmap, im, msg);
+ if (ret < 0)
+ goto out2;
+
+@@ -686,15 +697,15 @@ static int nfs_idmap_legacy_upcall(struc
+
+ ret = rpc_queue_upcall(idmap->idmap_pipe, msg);
+ if (ret < 0)
+- goto out2;
++ goto out3;
+
+ return ret;
+
++out3:
++ idmap->idmap_key_cons = NULL;
+ out2:
+- kfree(im);
++ kfree(data);
+ out1:
+- kfree(msg);
+-out0:
+ complete_request_key(cons, ret);
+ return ret;
+ }
+@@ -778,9 +789,26 @@ out_incomplete:
+ static void
+ idmap_pipe_destroy_msg(struct rpc_pipe_msg *msg)
+ {
++ struct idmap_legacy_upcalldata *data = container_of(msg,
++ struct idmap_legacy_upcalldata,
++ pipe_msg);
++ struct idmap *idmap = data->idmap;
++ struct key_construction *cons;
++ if (msg->errno) {
++ cons = ACCESS_ONCE(idmap->idmap_key_cons);
++ idmap->idmap_key_cons = NULL;
++ complete_request_key(cons, msg->errno);
++ }
+ /* Free memory allocated in nfs_idmap_legacy_upcall() */
+- kfree(msg->data);
+- kfree(msg);
++ kfree(data);
++}
++
++static void
++idmap_release_pipe(struct inode *inode)
++{
++ struct rpc_inode *rpci = RPC_I(inode);
++ struct idmap *idmap = (struct idmap *)rpci->private;
++ idmap->idmap_key_cons = NULL;
+ }
+
+ int nfs_map_name_to_uid(const struct nfs_server *server, const char *name, size_t namelen, __u32 *uid)
--- /dev/null
+From 12dfd080556124088ed61a292184947711b46cbe Mon Sep 17 00:00:00 2001
+From: Bryan Schumaker <bjschuma@netapp.com>
+Date: Thu, 9 Aug 2012 14:05:50 -0400
+Subject: NFS: return -ENOKEY when the upcall fails to map the name
+
+From: Bryan Schumaker <bjschuma@netapp.com>
+
+commit 12dfd080556124088ed61a292184947711b46cbe upstream.
+
+This allows the normal error-paths to handle the error, rather than
+making a special call to complete_request_key() just for this instance.
+
+Signed-off-by: Bryan Schumaker <bjschuma@netapp.com>
+Tested-by: William Dauchy <wdauchy@gmail.com>
+Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfs/idmap.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+--- a/fs/nfs/idmap.c
++++ b/fs/nfs/idmap.c
+@@ -763,9 +763,8 @@ idmap_pipe_downcall(struct file *filp, c
+ }
+
+ if (!(im.im_status & IDMAP_STATUS_SUCCESS)) {
+- ret = mlen;
+- complete_request_key(cons, -ENOKEY);
+- goto out_incomplete;
++ ret = -ENOKEY;
++ goto out;
+ }
+
+ namelen_in = strnlen(im.im_name, IDMAP_NAMESZ);
+@@ -782,7 +781,6 @@ idmap_pipe_downcall(struct file *filp, c
+
+ out:
+ complete_request_key(cons, ret);
+-out_incomplete:
+ return ret;
+ }
+
--- /dev/null
+From 3dd4765fce04c0b4af1e0bc4c0b10f906f95fabc Mon Sep 17 00:00:00 2001
+From: Jeff Layton <jlayton@redhat.com>
+Date: Thu, 2 Aug 2012 14:30:56 -0400
+Subject: nfs: tear down caches in nfs_init_writepagecache when allocation fails
+
+From: Jeff Layton <jlayton@redhat.com>
+
+commit 3dd4765fce04c0b4af1e0bc4c0b10f906f95fabc upstream.
+
+...and ensure that we tear down the nfs_commit_data cache too when
+unloading the module.
+
+Cc: Bryan Schumaker <bjschuma@netapp.com>
+Signed-off-by: Jeff Layton <jlayton@redhat.com>
+Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfs/write.c | 15 ++++++++++++---
+ 1 file changed, 12 insertions(+), 3 deletions(-)
+
+--- a/fs/nfs/write.c
++++ b/fs/nfs/write.c
+@@ -1806,19 +1806,19 @@ int __init nfs_init_writepagecache(void)
+ nfs_wdata_mempool = mempool_create_slab_pool(MIN_POOL_WRITE,
+ nfs_wdata_cachep);
+ if (nfs_wdata_mempool == NULL)
+- return -ENOMEM;
++ goto out_destroy_write_cache;
+
+ nfs_cdata_cachep = kmem_cache_create("nfs_commit_data",
+ sizeof(struct nfs_commit_data),
+ 0, SLAB_HWCACHE_ALIGN,
+ NULL);
+ if (nfs_cdata_cachep == NULL)
+- return -ENOMEM;
++ goto out_destroy_write_mempool;
+
+ nfs_commit_mempool = mempool_create_slab_pool(MIN_POOL_COMMIT,
+ nfs_wdata_cachep);
+ if (nfs_commit_mempool == NULL)
+- return -ENOMEM;
++ goto out_destroy_commit_cache;
+
+ /*
+ * NFS congestion size, scale with available memory.
+@@ -1841,11 +1841,20 @@ int __init nfs_init_writepagecache(void)
+ nfs_congestion_kb = 256*1024;
+
+ return 0;
++
++out_destroy_commit_cache:
++ kmem_cache_destroy(nfs_cdata_cachep);
++out_destroy_write_mempool:
++ mempool_destroy(nfs_wdata_mempool);
++out_destroy_write_cache:
++ kmem_cache_destroy(nfs_wdata_cachep);
++ return -ENOMEM;
+ }
+
+ void nfs_destroy_writepagecache(void)
+ {
+ mempool_destroy(nfs_commit_mempool);
++ kmem_cache_destroy(nfs_cdata_cachep);
+ mempool_destroy(nfs_wdata_mempool);
+ kmem_cache_destroy(nfs_wdata_cachep);
+ }
--- /dev/null
+From 39307655a1effa8d913bba054c0e985bfaca808c Mon Sep 17 00:00:00 2001
+From: "J. Bruce Fields" <bfields@redhat.com>
+Date: Thu, 16 Aug 2012 17:01:21 -0400
+Subject: nfsd4: fix security flavor of NFSv4.0 callback
+
+From: "J. Bruce Fields" <bfields@redhat.com>
+
+commit 39307655a1effa8d913bba054c0e985bfaca808c upstream.
+
+Commit d5497fc693a446ce9100fcf4117c3f795ddfd0d2 "nfsd4: move rq_flavor
+into svc_cred" forgot to remove cl_flavor from the client, leaving two
+places (cl_flavor and cl_cred.cr_flavor) for the flavor to be stored.
+After that patch, the latter was the one that was updated, but the
+former was the one that the callback used.
+
+Symptoms were a long delay on utime(). This is because the utime()
+generated a setattr which recalled a delegation, but the cb_recall was
+ignored by the client because it had the wrong security flavor.
+
+Tested-by: Jamie Heilman <jamie@audible.transient.net>
+Reported-by: Jamie Heilman <jamie@audible.transient.net>
+Signed-off-by: J. Bruce Fields <bfields@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfsd/nfs4callback.c | 4 ++--
+ fs/nfsd/state.h | 1 -
+ 2 files changed, 2 insertions(+), 3 deletions(-)
+
+--- a/fs/nfsd/nfs4callback.c
++++ b/fs/nfsd/nfs4callback.c
+@@ -651,12 +651,12 @@ static int setup_callback_client(struct
+
+ if (clp->cl_minorversion == 0) {
+ if (!clp->cl_cred.cr_principal &&
+- (clp->cl_flavor >= RPC_AUTH_GSS_KRB5))
++ (clp->cl_cred.cr_flavor >= RPC_AUTH_GSS_KRB5))
+ return -EINVAL;
+ args.client_name = clp->cl_cred.cr_principal;
+ args.prognumber = conn->cb_prog,
+ args.protocol = XPRT_TRANSPORT_TCP;
+- args.authflavor = clp->cl_flavor;
++ args.authflavor = clp->cl_cred.cr_flavor;
+ clp->cl_cb_ident = conn->cb_ident;
+ } else {
+ if (!conn->cb_xprt)
+--- a/fs/nfsd/state.h
++++ b/fs/nfsd/state.h
+@@ -231,7 +231,6 @@ struct nfs4_client {
+ nfs4_verifier cl_verifier; /* generated by client */
+ time_t cl_time; /* time of last lease renewal */
+ struct sockaddr_storage cl_addr; /* client ipaddress */
+- u32 cl_flavor; /* setclientid pseudoflavor */
+ struct svc_cred cl_cred; /* setclientid principal */
+ clientid_t cl_clientid; /* generated by server */
+ nfs4_verifier cl_confirm; /* generated by server */
--- /dev/null
+From 086600430493e04b802bee6e5b3ce0458e4eb77f Mon Sep 17 00:00:00 2001
+From: Trond Myklebust <Trond.Myklebust@netapp.com>
+Date: Mon, 20 Aug 2012 12:42:15 -0400
+Subject: NFSv3: Ensure that do_proc_get_root() reports errors correctly
+
+From: Trond Myklebust <Trond.Myklebust@netapp.com>
+
+commit 086600430493e04b802bee6e5b3ce0458e4eb77f upstream.
+
+If the rpc call to NFS3PROC_FSINFO fails, then we need to report that
+error so that the mount fails. Otherwise we can end up with a
+superblock with completely unusable values for block sizes, maxfilesize,
+etc.
+
+Reported-by: Yuanming Chen <hikvision_linux@163.com>
+Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfs/nfs3proc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/nfs/nfs3proc.c
++++ b/fs/nfs/nfs3proc.c
+@@ -69,7 +69,7 @@ do_proc_get_root(struct rpc_clnt *client
+ nfs_fattr_init(info->fattr);
+ status = rpc_call_sync(client, &msg, 0);
+ dprintk("%s: reply fsinfo: %d\n", __func__, status);
+- if (!(info->fattr->valid & NFS_ATTR_FATTR)) {
++ if (status == 0 && !(info->fattr->valid & NFS_ATTR_FATTR)) {
+ msg.rpc_proc = &nfs3_procedures[NFS3PROC_GETATTR];
+ msg.rpc_resp = info->fattr;
+ status = rpc_call_sync(client, &msg, 0);
--- /dev/null
+From 47fbf7976e0b7d9dcdd799e2a1baba19064d9631 Mon Sep 17 00:00:00 2001
+From: Trond Myklebust <Trond.Myklebust@netapp.com>
+Date: Wed, 8 Aug 2012 16:03:13 -0400
+Subject: NFSv4.1: Remove a bogus BUG_ON() in nfs4_layoutreturn_done
+
+From: Trond Myklebust <Trond.Myklebust@netapp.com>
+
+commit 47fbf7976e0b7d9dcdd799e2a1baba19064d9631 upstream.
+
+Ever since commit 0a57cdac3f (NFSv4.1 send layoutreturn to fence
+disconnected data server) we've been sending layoutreturn calls
+while there is potentially still outstanding I/O to the data
+servers. The reason we do this is to avoid races between replayed
+writes to the MDS and the original writes to the DS.
+
+When this happens, the BUG_ON() in nfs4_layoutreturn_done can
+be triggered because it assumes that we would never call
+layoutreturn without knowing that all I/O to the DS is
+finished. The fix is to remove the BUG_ON() now that the
+assumptions behind the test are obsolete.
+
+Reported-by: Boaz Harrosh <bharrosh@panasas.com>
+Reported-by: Tigran Mkrtchyan <tigran.mkrtchyan@desy.de>
+Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfs/nfs4proc.c | 8 ++------
+ 1 file changed, 2 insertions(+), 6 deletions(-)
+
+--- a/fs/nfs/nfs4proc.c
++++ b/fs/nfs/nfs4proc.c
+@@ -6300,12 +6300,8 @@ static void nfs4_layoutreturn_done(struc
+ return;
+ }
+ spin_lock(&lo->plh_inode->i_lock);
+- if (task->tk_status == 0) {
+- if (lrp->res.lrs_present) {
+- pnfs_set_layout_stateid(lo, &lrp->res.stateid, true);
+- } else
+- BUG_ON(!list_empty(&lo->plh_segs));
+- }
++ if (task->tk_status == 0 && lrp->res.lrs_present)
++ pnfs_set_layout_stateid(lo, &lrp->res.stateid, true);
+ lo->plh_block_lgets--;
+ spin_unlock(&lo->plh_inode->i_lock);
+ dprintk("<-- %s\n", __func__);
--- /dev/null
+From 8554116e17eef055d9dd58a94b3427cb2ad1c317 Mon Sep 17 00:00:00 2001
+From: Idan Kedar <idank@tonian.com>
+Date: Thu, 2 Aug 2012 11:47:10 +0300
+Subject: pnfs: defer release of pages in layoutget
+
+From: Idan Kedar <idank@tonian.com>
+
+commit 8554116e17eef055d9dd58a94b3427cb2ad1c317 upstream.
+
+we have encountered a bug whereby reading a lot of files (copying
+fedora's /bin) from a pNFS mount and hitting Ctrl+C in the middle caused
+a general protection fault in xdr_shrink_bufhead. this function is
+called when decoding the response from LAYOUTGET. the decoding is done
+by a worker thread, and the caller of LAYOUTGET waits for the worker
+thread to complete.
+
+hitting Ctrl+C caused the synchronous wait to end and the next thing the
+caller does is to free the pages, so when the worker thread calls
+xdr_shrink_bufhead, the pages are gone. therefore, the cleanup of these
+pages has been moved to nfs4_layoutget_release.
+
+Signed-off-by: Idan Kedar <idank@tonian.com>
+Signed-off-by: Benny Halevy <bhalevy@tonian.com>
+Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfs/nfs4proc.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
+ fs/nfs/pnfs.c | 39 ------------------------------------
+ fs/nfs/pnfs.h | 2 -
+ 3 files changed, 58 insertions(+), 40 deletions(-)
+
+--- a/fs/nfs/nfs4proc.c
++++ b/fs/nfs/nfs4proc.c
+@@ -6164,11 +6164,58 @@ static void nfs4_layoutget_done(struct r
+ dprintk("<-- %s\n", __func__);
+ }
+
++static size_t max_response_pages(struct nfs_server *server)
++{
++ u32 max_resp_sz = server->nfs_client->cl_session->fc_attrs.max_resp_sz;
++ return nfs_page_array_len(0, max_resp_sz);
++}
++
++static void nfs4_free_pages(struct page **pages, size_t size)
++{
++ int i;
++
++ if (!pages)
++ return;
++
++ for (i = 0; i < size; i++) {
++ if (!pages[i])
++ break;
++ __free_page(pages[i]);
++ }
++ kfree(pages);
++}
++
++static struct page **nfs4_alloc_pages(size_t size, gfp_t gfp_flags)
++{
++ struct page **pages;
++ int i;
++
++ pages = kcalloc(size, sizeof(struct page *), gfp_flags);
++ if (!pages) {
++ dprintk("%s: can't alloc array of %zu pages\n", __func__, size);
++ return NULL;
++ }
++
++ for (i = 0; i < size; i++) {
++ pages[i] = alloc_page(gfp_flags);
++ if (!pages[i]) {
++ dprintk("%s: failed to allocate page\n", __func__);
++ nfs4_free_pages(pages, size);
++ return NULL;
++ }
++ }
++
++ return pages;
++}
++
+ static void nfs4_layoutget_release(void *calldata)
+ {
+ struct nfs4_layoutget *lgp = calldata;
++ struct nfs_server *server = NFS_SERVER(lgp->args.inode);
++ size_t max_pages = max_response_pages(server);
+
+ dprintk("--> %s\n", __func__);
++ nfs4_free_pages(lgp->args.layout.pages, max_pages);
+ put_nfs_open_context(lgp->args.ctx);
+ kfree(calldata);
+ dprintk("<-- %s\n", __func__);
+@@ -6180,9 +6227,10 @@ static const struct rpc_call_ops nfs4_la
+ .rpc_release = nfs4_layoutget_release,
+ };
+
+-int nfs4_proc_layoutget(struct nfs4_layoutget *lgp)
++int nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags)
+ {
+ struct nfs_server *server = NFS_SERVER(lgp->args.inode);
++ size_t max_pages = max_response_pages(server);
+ struct rpc_task *task;
+ struct rpc_message msg = {
+ .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LAYOUTGET],
+@@ -6200,6 +6248,13 @@ int nfs4_proc_layoutget(struct nfs4_layo
+
+ dprintk("--> %s\n", __func__);
+
++ lgp->args.layout.pages = nfs4_alloc_pages(max_pages, gfp_flags);
++ if (!lgp->args.layout.pages) {
++ nfs4_layoutget_release(lgp);
++ return -ENOMEM;
++ }
++ lgp->args.layout.pglen = max_pages * PAGE_SIZE;
++
+ lgp->res.layoutp = &lgp->args.layout;
+ lgp->res.seq_res.sr_slot = NULL;
+ nfs41_init_sequence(&lgp->args.seq_args, &lgp->res.seq_res, 0);
+--- a/fs/nfs/pnfs.c
++++ b/fs/nfs/pnfs.c
+@@ -583,9 +583,6 @@ send_layoutget(struct pnfs_layout_hdr *l
+ struct nfs_server *server = NFS_SERVER(ino);
+ struct nfs4_layoutget *lgp;
+ struct pnfs_layout_segment *lseg = NULL;
+- struct page **pages = NULL;
+- int i;
+- u32 max_resp_sz, max_pages;
+
+ dprintk("--> %s\n", __func__);
+
+@@ -594,20 +591,6 @@ send_layoutget(struct pnfs_layout_hdr *l
+ if (lgp == NULL)
+ return NULL;
+
+- /* allocate pages for xdr post processing */
+- max_resp_sz = server->nfs_client->cl_session->fc_attrs.max_resp_sz;
+- max_pages = nfs_page_array_len(0, max_resp_sz);
+-
+- pages = kcalloc(max_pages, sizeof(struct page *), gfp_flags);
+- if (!pages)
+- goto out_err_free;
+-
+- for (i = 0; i < max_pages; i++) {
+- pages[i] = alloc_page(gfp_flags);
+- if (!pages[i])
+- goto out_err_free;
+- }
+-
+ lgp->args.minlength = PAGE_CACHE_SIZE;
+ if (lgp->args.minlength > range->length)
+ lgp->args.minlength = range->length;
+@@ -616,39 +599,19 @@ send_layoutget(struct pnfs_layout_hdr *l
+ lgp->args.type = server->pnfs_curr_ld->id;
+ lgp->args.inode = ino;
+ lgp->args.ctx = get_nfs_open_context(ctx);
+- lgp->args.layout.pages = pages;
+- lgp->args.layout.pglen = max_pages * PAGE_SIZE;
+ lgp->lsegpp = &lseg;
+ lgp->gfp_flags = gfp_flags;
+
+ /* Synchronously retrieve layout information from server and
+ * store in lseg.
+ */
+- nfs4_proc_layoutget(lgp);
++ nfs4_proc_layoutget(lgp, gfp_flags);
+ if (!lseg) {
+ /* remember that LAYOUTGET failed and suspend trying */
+ set_bit(lo_fail_bit(range->iomode), &lo->plh_flags);
+ }
+
+- /* free xdr pages */
+- for (i = 0; i < max_pages; i++)
+- __free_page(pages[i]);
+- kfree(pages);
+-
+ return lseg;
+-
+-out_err_free:
+- /* free any allocated xdr pages, lgp as it's not used */
+- if (pages) {
+- for (i = 0; i < max_pages; i++) {
+- if (!pages[i])
+- break;
+- __free_page(pages[i]);
+- }
+- kfree(pages);
+- }
+- kfree(lgp);
+- return NULL;
+ }
+
+ /* Initiates a LAYOUTRETURN(FILE) */
+--- a/fs/nfs/pnfs.h
++++ b/fs/nfs/pnfs.h
+@@ -171,7 +171,7 @@ extern int nfs4_proc_getdevicelist(struc
+ struct pnfs_devicelist *devlist);
+ extern int nfs4_proc_getdeviceinfo(struct nfs_server *server,
+ struct pnfs_device *dev);
+-extern int nfs4_proc_layoutget(struct nfs4_layoutget *lgp);
++extern int nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags);
+ extern int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp);
+
+ /* pnfs.c */
alsa-hda-don-t-create-dysfunctional-mixer-controls-for-ca0132.patch
alsa-hda-fix-leftover-codec-power_transition.patch
target-fix-null-pointer-dereference-bug-alloc_page-fails-to-get-memory.patch
+nfsv3-ensure-that-do_proc_get_root-reports-errors-correctly.patch
+pnfs-defer-release-of-pages-in-layoutget.patch
+nfs-tear-down-caches-in-nfs_init_writepagecache-when-allocation-fails.patch
+nfsv4.1-remove-a-bogus-bug_on-in-nfs4_layoutreturn_done.patch
+nfs-clear-key-construction-data-if-the-idmap-upcall-fails.patch
+nfs-return-enokey-when-the-upcall-fails-to-map-the-name.patch
+nfsd4-fix-security-flavor-of-nfsv4.0-callback.patch