--- /dev/null
+From 8d96b10639fb402357b75b055b1e82a65ff95050 Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb@suse.de>
+Date: Wed, 31 Oct 2012 12:16:01 +1100
+Subject: NFS: fix bug in legacy DNS resolver.
+
+From: NeilBrown <neilb@suse.de>
+
+commit 8d96b10639fb402357b75b055b1e82a65ff95050 upstream.
+
+The DNS resolver's use of the sunrpc cache involves a 'ttl' number
+(relative) rather that a timeout (absolute). This confused me when
+I wrote
+ commit c5b29f885afe890f953f7f23424045cdad31d3e4
+ "sunrpc: use seconds since boot in expiry cache"
+
+and I managed to break it. The effect is that any TTL is interpreted
+as 0, and nothing useful gets into the cache.
+
+This patch removes the use of get_expiry() - which really expects an
+expiry time - and uses get_uint() instead, treating the int correctly
+as a ttl.
+
+This fixes a regression that has been present since 2.6.37, causing
+certain NFS accesses in certain environments to incorrectly fail.
+
+Reported-by: Chuck Lever <chuck.lever@oracle.com>
+Tested-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: NeilBrown <neilb@suse.de>
+Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfs/dns_resolve.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/fs/nfs/dns_resolve.c
++++ b/fs/nfs/dns_resolve.c
+@@ -217,7 +217,7 @@ static int nfs_dns_parse(struct cache_de
+ {
+ char buf1[NFS_DNS_HOSTNAME_MAXLEN+1];
+ struct nfs_dns_ent key, *item;
+- unsigned long ttl;
++ unsigned int ttl;
+ ssize_t len;
+ int ret = -EINVAL;
+
+@@ -240,7 +240,8 @@ static int nfs_dns_parse(struct cache_de
+ key.namelen = len;
+ memset(&key.h, 0, sizeof(key.h));
+
+- ttl = get_expiry(&buf);
++ if (get_uint(&buf, &ttl) < 0)
++ goto out;
+ if (ttl == 0)
+ goto out;
+ key.h.expiry_time = ttl + seconds_since_boot();
--- /dev/null
+From 97a54868262da1629a3e65121e65b8e8c4419d9f Mon Sep 17 00:00:00 2001
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Sun, 21 Oct 2012 19:23:52 +0100
+Subject: nfs: Show original device name verbatim in /proc/*/mount{s,info}
+
+From: Ben Hutchings <ben@decadent.org.uk>
+
+commit 97a54868262da1629a3e65121e65b8e8c4419d9f upstream.
+
+Since commit c7f404b ('vfs: new superblock methods to override
+/proc/*/mount{s,info}'), nfs_path() is used to generate the mounted
+device name reported back to userland.
+
+nfs_path() always generates a trailing slash when the given dentry is
+the root of an NFS mount, but userland may expect the original device
+name to be returned verbatim (as it used to be). Make this
+canonicalisation optional and change the callers accordingly.
+
+[jrnieder@gmail.com: use flag instead of bool argument]
+Reported-and-tested-by: Chris Hiestand <chiestand@salk.edu>
+Reference: http://bugs.debian.org/669314
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
+Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfs/internal.h | 5 +++--
+ fs/nfs/namespace.c | 19 ++++++++++++++-----
+ fs/nfs/nfs4namespace.c | 3 ++-
+ fs/nfs/super.c | 2 +-
+ 4 files changed, 20 insertions(+), 9 deletions(-)
+
+--- a/fs/nfs/internal.h
++++ b/fs/nfs/internal.h
+@@ -353,8 +353,9 @@ extern void nfs_sb_active(struct super_b
+ extern void nfs_sb_deactive(struct super_block *sb);
+
+ /* namespace.c */
++#define NFS_PATH_CANONICAL 1
+ extern char *nfs_path(char **p, struct dentry *dentry,
+- char *buffer, ssize_t buflen);
++ char *buffer, ssize_t buflen, unsigned flags);
+ extern struct vfsmount *nfs_d_automount(struct path *path);
+ struct vfsmount *nfs_submount(struct nfs_server *, struct dentry *,
+ struct nfs_fh *, struct nfs_fattr *);
+@@ -491,7 +492,7 @@ static inline char *nfs_devname(struct d
+ char *buffer, ssize_t buflen)
+ {
+ char *dummy;
+- return nfs_path(&dummy, dentry, buffer, buflen);
++ return nfs_path(&dummy, dentry, buffer, buflen, NFS_PATH_CANONICAL);
+ }
+
+ /*
+--- a/fs/nfs/namespace.c
++++ b/fs/nfs/namespace.c
+@@ -33,6 +33,7 @@ int nfs_mountpoint_expiry_timeout = 500
+ * @dentry - pointer to dentry
+ * @buffer - result buffer
+ * @buflen - length of buffer
++ * @flags - options (see below)
+ *
+ * Helper function for constructing the server pathname
+ * by arbitrary hashed dentry.
+@@ -40,8 +41,14 @@ int nfs_mountpoint_expiry_timeout = 500
+ * This is mainly for use in figuring out the path on the
+ * server side when automounting on top of an existing partition
+ * and in generating /proc/mounts and friends.
++ *
++ * Supported flags:
++ * NFS_PATH_CANONICAL: ensure there is exactly one slash after
++ * the original device (export) name
++ * (if unset, the original name is returned verbatim)
+ */
+-char *nfs_path(char **p, struct dentry *dentry, char *buffer, ssize_t buflen)
++char *nfs_path(char **p, struct dentry *dentry, char *buffer, ssize_t buflen,
++ unsigned flags)
+ {
+ char *end;
+ int namelen;
+@@ -74,7 +81,7 @@ rename_retry:
+ rcu_read_unlock();
+ goto rename_retry;
+ }
+- if (*end != '/') {
++ if ((flags & NFS_PATH_CANONICAL) && *end != '/') {
+ if (--buflen < 0) {
+ spin_unlock(&dentry->d_lock);
+ rcu_read_unlock();
+@@ -91,9 +98,11 @@ rename_retry:
+ return end;
+ }
+ namelen = strlen(base);
+- /* Strip off excess slashes in base string */
+- while (namelen > 0 && base[namelen - 1] == '/')
+- namelen--;
++ if (flags & NFS_PATH_CANONICAL) {
++ /* Strip off excess slashes in base string */
++ while (namelen > 0 && base[namelen - 1] == '/')
++ namelen--;
++ }
+ buflen -= namelen;
+ if (buflen < 0) {
+ spin_unlock(&dentry->d_lock);
+--- a/fs/nfs/nfs4namespace.c
++++ b/fs/nfs/nfs4namespace.c
+@@ -81,7 +81,8 @@ static char *nfs_path_component(const ch
+ static char *nfs4_path(struct dentry *dentry, char *buffer, ssize_t buflen)
+ {
+ char *limit;
+- char *path = nfs_path(&limit, dentry, buffer, buflen);
++ char *path = nfs_path(&limit, dentry, buffer, buflen,
++ NFS_PATH_CANONICAL);
+ if (!IS_ERR(path)) {
+ char *path_component = nfs_path_component(path, limit);
+ if (path_component)
+--- a/fs/nfs/super.c
++++ b/fs/nfs/super.c
+@@ -765,7 +765,7 @@ int nfs_show_devname(struct seq_file *m,
+ int err = 0;
+ if (!page)
+ return -ENOMEM;
+- devname = nfs_path(&dummy, root, page, PAGE_SIZE);
++ devname = nfs_path(&dummy, root, page, PAGE_SIZE, 0);
+ if (IS_ERR(devname))
+ err = PTR_ERR(devname);
+ else
--- /dev/null
+From 399f11c3d872bd748e1575574de265a6304c7c43 Mon Sep 17 00:00:00 2001
+From: Bryan Schumaker <bjschuma@netapp.com>
+Date: Tue, 30 Oct 2012 16:06:35 -0400
+Subject: NFS: Wait for session recovery to finish before returning
+
+From: Bryan Schumaker <bjschuma@netapp.com>
+
+commit 399f11c3d872bd748e1575574de265a6304c7c43 upstream.
+
+Currently, we will schedule session recovery and then return to the
+caller of nfs4_handle_exception. This works for most cases, but causes
+a hang on the following test case:
+
+ Client Server
+ ------ ------
+ Open file over NFS v4.1
+ Write to file
+ Expire client
+ Try to lock file
+
+The server will return NFS4ERR_BADSESSION, prompting the client to
+schedule recovery. However, the client will continue placing lock
+attempts and the open recovery never seems to be scheduled. The
+simplest solution is to wait for session recovery to run before retrying
+the lock.
+
+Signed-off-by: Bryan Schumaker <bjschuma@netapp.com>
+Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfs/nfs4proc.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/fs/nfs/nfs4proc.c
++++ b/fs/nfs/nfs4proc.c
+@@ -331,8 +331,7 @@ static int nfs4_handle_exception(struct
+ dprintk("%s ERROR: %d Reset session\n", __func__,
+ errorcode);
+ nfs4_schedule_session_recovery(clp->cl_session, errorcode);
+- exception->retry = 1;
+- break;
++ goto wait_on_recovery;
+ #endif /* defined(CONFIG_NFS_V4_1) */
+ case -NFS4ERR_FILE_OPEN:
+ if (exception->timeout > HZ) {
--- /dev/null
+From acce94e68a0f346115fd41cdc298197d2d5a59ad Mon Sep 17 00:00:00 2001
+From: Scott Mayhew <smayhew@redhat.com>
+Date: Tue, 16 Oct 2012 13:22:19 -0400
+Subject: nfsv3: Make v3 mounts fail with ETIMEDOUTs instead EIO on mountd timeouts
+
+From: Scott Mayhew <smayhew@redhat.com>
+
+commit acce94e68a0f346115fd41cdc298197d2d5a59ad upstream.
+
+In very busy v3 environment, rpc.mountd can respond to the NULL
+procedure but not the MNT procedure in a timely manner causing
+the MNT procedure to time out. The problem is the mount system
+call returns EIO which causes the mount to fail, instead of
+ETIMEDOUT, which would cause the mount to be retried.
+
+This patch sets the RPC_TASK_SOFT|RPC_TASK_TIMEOUT flags to
+the rpc_call_sync() call in nfs_mount() which causes
+ETIMEDOUT to be returned on timed out connections.
+
+Signed-off-by: Steve Dickson <steved@redhat.com>
+Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfs/mount_clnt.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/nfs/mount_clnt.c
++++ b/fs/nfs/mount_clnt.c
+@@ -181,7 +181,7 @@ int nfs_mount(struct nfs_mount_request *
+ else
+ msg.rpc_proc = &mnt_clnt->cl_procinfo[MOUNTPROC_MNT];
+
+- status = rpc_call_sync(mnt_clnt, &msg, 0);
++ status = rpc_call_sync(mnt_clnt, &msg, RPC_TASK_SOFT|RPC_TASK_TIMEOUT);
+ rpc_shutdown_client(mnt_clnt);
+
+ if (status < 0)
--- /dev/null
+From 2b1bc308f492589f7d49012ed24561534ea2be8c Mon Sep 17 00:00:00 2001
+From: Trond Myklebust <Trond.Myklebust@netapp.com>
+Date: Mon, 29 Oct 2012 18:53:23 -0400
+Subject: NFSv4: nfs4_locku_done must release the sequence id
+
+From: Trond Myklebust <Trond.Myklebust@netapp.com>
+
+commit 2b1bc308f492589f7d49012ed24561534ea2be8c upstream.
+
+If the state recovery machinery is triggered by the call to
+nfs4_async_handle_error() then we can deadlock.
+
+Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfs/nfs4proc.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/nfs/nfs4proc.c
++++ b/fs/nfs/nfs4proc.c
+@@ -4390,6 +4390,7 @@ static void nfs4_locku_done(struct rpc_t
+ if (nfs4_async_handle_error(task, calldata->server, NULL) == -EAGAIN)
+ rpc_restart_call_prepare(task);
+ }
++ nfs_release_seqid(calldata->arg.seqid);
+ }
+
+ static void nfs4_locku_prepare(struct rpc_task *task, void *data)
--- /dev/null
+From 2240a9e2d013d8269ea425b73e1d7a54c7bc141f Mon Sep 17 00:00:00 2001
+From: Trond Myklebust <Trond.Myklebust@netapp.com>
+Date: Mon, 29 Oct 2012 18:37:40 -0400
+Subject: NFSv4.1: We must release the sequence id when we fail to get a session slot
+
+From: Trond Myklebust <Trond.Myklebust@netapp.com>
+
+commit 2240a9e2d013d8269ea425b73e1d7a54c7bc141f upstream.
+
+If we do not release the sequence id in cases where we fail to get a
+session slot, then we can deadlock if we hit a recovery scenario.
+
+Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfs/nfs4proc.c | 36 +++++++++++++++++++++++-------------
+ 1 file changed, 23 insertions(+), 13 deletions(-)
+
+--- a/fs/nfs/nfs4proc.c
++++ b/fs/nfs/nfs4proc.c
+@@ -1499,9 +1499,11 @@ static void nfs4_open_prepare(struct rpc
+ data->timestamp = jiffies;
+ if (nfs4_setup_sequence(data->o_arg.server,
+ &data->o_arg.seq_args,
+- &data->o_res.seq_res, task))
+- return;
+- rpc_call_start(task);
++ &data->o_res.seq_res,
++ task) != 0)
++ nfs_release_seqid(data->o_arg.seqid);
++ else
++ rpc_call_start(task);
+ return;
+ unlock_no_action:
+ rcu_read_unlock();
+@@ -2182,9 +2184,10 @@ static void nfs4_close_prepare(struct rp
+ if (nfs4_setup_sequence(NFS_SERVER(calldata->inode),
+ &calldata->arg.seq_args,
+ &calldata->res.seq_res,
+- task))
+- goto out;
+- rpc_call_start(task);
++ task) != 0)
++ nfs_release_seqid(calldata->arg.seqid);
++ else
++ rpc_call_start(task);
+ out:
+ dprintk("%s: done!\n", __func__);
+ }
+@@ -4407,9 +4410,11 @@ static void nfs4_locku_prepare(struct rp
+ calldata->timestamp = jiffies;
+ if (nfs4_setup_sequence(calldata->server,
+ &calldata->arg.seq_args,
+- &calldata->res.seq_res, task))
+- return;
+- rpc_call_start(task);
++ &calldata->res.seq_res,
++ task) != 0)
++ nfs_release_seqid(calldata->arg.seqid);
++ else
++ rpc_call_start(task);
+ }
+
+ static const struct rpc_call_ops nfs4_locku_ops = {
+@@ -4554,7 +4559,7 @@ static void nfs4_lock_prepare(struct rpc
+ /* Do we need to do an open_to_lock_owner? */
+ if (!(data->arg.lock_seqid->sequence->flags & NFS_SEQID_CONFIRMED)) {
+ if (nfs_wait_on_sequence(data->arg.open_seqid, task) != 0)
+- return;
++ goto out_release_lock_seqid;
+ data->arg.open_stateid = &state->stateid;
+ data->arg.new_lock_owner = 1;
+ data->res.open_seqid = data->arg.open_seqid;
+@@ -4563,10 +4568,15 @@ static void nfs4_lock_prepare(struct rpc
+ data->timestamp = jiffies;
+ if (nfs4_setup_sequence(data->server,
+ &data->arg.seq_args,
+- &data->res.seq_res, task))
++ &data->res.seq_res,
++ task) == 0) {
++ rpc_call_start(task);
+ return;
+- rpc_call_start(task);
+- dprintk("%s: done!, ret = %d\n", __func__, data->rpc_status);
++ }
++ nfs_release_seqid(data->arg.open_seqid);
++out_release_lock_seqid:
++ nfs_release_seqid(data->arg.lock_seqid);
++ dprintk("%s: done!, ret = %d\n", __func__, task->tk_status);
+ }
+
+ static void nfs4_recover_lock_prepare(struct rpc_task *task, void *calldata)
mac80211-verify-that-skb-data-is-present.patch
mac80211-make-sure-data-is-accessible-in-eapol-check.patch
mac80211-fix-ssid-copy-on-ibss-join.patch
+nfsv3-make-v3-mounts-fail-with-etimedouts-instead-eio-on-mountd-timeouts.patch
+nfs-show-original-device-name-verbatim-in-proc-mount-s-info.patch
+nfsv4-nfs4_locku_done-must-release-the-sequence-id.patch
+nfsv4.1-we-must-release-the-sequence-id-when-we-fail-to-get-a-session-slot.patch
+nfs-wait-for-session-recovery-to-finish-before-returning.patch
+nfs-fix-bug-in-legacy-dns-resolver.patch