From: Greg Kroah-Hartman Date: Mon, 5 Nov 2012 15:36:45 +0000 (+0100) Subject: 3.4-stable patches X-Git-Tag: v3.0.52~34 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1b00c7d92fca623bf4d71ce851c36aa7b94d9fe9;p=thirdparty%2Fkernel%2Fstable-queue.git 3.4-stable patches added patches: nfs-fix-bug-in-legacy-dns-resolver.patch nfs-fix-oopses-in-nfs_lookup_revalidate-and-nfs4_lookup_revalidate.patch nfs-show-original-device-name-verbatim-in-proc-mount-s-info.patch nfsv3-make-v3-mounts-fail-with-etimedouts-instead-eio-on-mountd-timeouts.patch nfsv4.1-we-must-release-the-sequence-id-when-we-fail-to-get-a-session-slot.patch nfsv4-nfs4_locku_done-must-release-the-sequence-id.patch --- diff --git a/queue-3.4/nfs-fix-bug-in-legacy-dns-resolver.patch b/queue-3.4/nfs-fix-bug-in-legacy-dns-resolver.patch new file mode 100644 index 00000000000..a5f9a220330 --- /dev/null +++ b/queue-3.4/nfs-fix-bug-in-legacy-dns-resolver.patch @@ -0,0 +1,56 @@ +From 8d96b10639fb402357b75b055b1e82a65ff95050 Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Wed, 31 Oct 2012 12:16:01 +1100 +Subject: NFS: fix bug in legacy DNS resolver. + +From: NeilBrown + +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 +Tested-by: Chuck Lever +Signed-off-by: NeilBrown +Signed-off-by: Trond Myklebust +Signed-off-by: Greg Kroah-Hartman + +--- + 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 +@@ -214,7 +214,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; + +@@ -237,7 +237,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(); diff --git a/queue-3.4/nfs-fix-oopses-in-nfs_lookup_revalidate-and-nfs4_lookup_revalidate.patch b/queue-3.4/nfs-fix-oopses-in-nfs_lookup_revalidate-and-nfs4_lookup_revalidate.patch new file mode 100644 index 00000000000..4abc5cbdf60 --- /dev/null +++ b/queue-3.4/nfs-fix-oopses-in-nfs_lookup_revalidate-and-nfs4_lookup_revalidate.patch @@ -0,0 +1,87 @@ +From 19fa18a644a6303d49295d921e651b7e19a3a75f Mon Sep 17 00:00:00 2001 +From: Trond Myklebust +Date: Wed, 22 Aug 2012 16:08:17 -0400 +Subject: NFS: Fix Oopses in nfs_lookup_revalidate and nfs4_lookup_revalidate + +From: Trond Myklebust + +[Fixed upstream as part of 0b728e1911c, but that's a much larger patch, +this is only the nfs portion backported as needed.] + +Fix the following Oops in 3.5.1: + + BUG: unable to handle kernel NULL pointer dereference at 0000000000000038 + IP: [] nfs_lookup_revalidate+0x2d/0x480 [nfs] + PGD 337c63067 PUD 0 + Oops: 0000 [#1] SMP + CPU 5 + Modules linked in: nfs fscache nfsd lockd nfs_acl auth_rpcgss sunrpc af_packet binfmt_misc cpufreq_conservative cpufreq_userspace cpufreq_powersave dm_mod acpi_cpufreq mperf coretemp gpio_ich kvm_intel joydev kvm ioatdma hid_generic igb lpc_ich i7core_edac edac_core ptp serio_raw dca pcspkr i2c_i801 mfd_core sg pps_core usbhid crc32c_intel microcode button autofs4 uhci_hcd ttm drm_kms_helper drm i2c_algo_bit sysimgblt sysfillrect syscopyarea ehci_hcd usbcore usb_common scsi_dh_rdac scsi_dh_emc scsi_dh_hp_sw scsi_dh_alua scsi_dh edd fan ata_piix thermal processor thermal_sys + + Pid: 30431, comm: java Not tainted 3.5.1-2-default #1 Supermicro X8DTT/X8DTT + RIP: 0010:[] [] nfs_lookup_revalidate+0x2d/0x480 [nfs] + RSP: 0018:ffff8801b418bd38 EFLAGS: 00010292 + RAX: 00000000fffffff6 RBX: ffff88032016d800 RCX: 0000000000000020 + RDX: ffffffff00000000 RSI: 0000000000000000 RDI: ffff8801824a7b00 + RBP: ffff8801b418bdf8 R08: 7fffff0034323030 R09: fffffffff04c03ed + R10: ffff8801824a7b00 R11: 0000000000000002 R12: ffff8801824a7b00 + R13: ffff8801824a7b00 R14: 0000000000000000 R15: ffff8803201725d0 + FS: 00002b53a46cb700(0000) GS:ffff88033fc20000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: 0000000000000038 CR3: 000000020a426000 CR4: 00000000000007e0 + DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 + DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 + Process java (pid: 30431, threadinfo ffff8801b418a000, task ffff8801b5d20600) + Stack: + ffff8801b418be44 ffff88032016d800 ffff8801b418bdf8 0000000000000000 + ffff8801824a7b00 ffff8801b418bdd7 ffff8803201725d0 ffffffff8116a9c0 + ffff8801b5c38dc0 0000000000000007 ffff88032016d800 0000000000000000 + Call Trace: + [] lookup_dcache+0x80/0xe0 + [] __lookup_hash+0x23/0x90 + [] lookup_one_len+0xc5/0x100 + [] nfs_sillyrename+0xe3/0x210 [nfs] + [] vfs_unlink.part.25+0x7f/0xe0 + [] do_unlinkat+0x1ac/0x1d0 + [] system_call_fastpath+0x16/0x1b + [<00002b5348b5f527>] 0x2b5348b5f526 + Code: ec 38 b8 f6 ff ff ff 4c 89 64 24 18 4c 89 74 24 28 49 89 fc 48 89 5c 24 08 48 89 6c 24 10 49 89 f6 4c 89 6c 24 20 4c 89 7c 24 30 46 38 40 0f 85 d1 00 00 00 e8 c4 c4 df e0 48 8b 58 30 49 89 + RIP [] nfs_lookup_revalidate+0x2d/0x480 [nfs] + RSP + CR2: 0000000000000038 + ---[ end trace 845113ed191985dd ]--- + +This Oops affects 3.5 kernels and older, and is due to lookup_one_len() +calling down to the dentry revalidation code with a NULL pointer +to struct nameidata. + +It is fixed upstream by commit 0b728e1911c (stop passing nameidata * +to ->d_revalidate()) + +Reported-by: Richard Ems +Signed-off-by: Trond Myklebust +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfs/dir.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/fs/nfs/dir.c ++++ b/fs/nfs/dir.c +@@ -1103,7 +1103,7 @@ static int nfs_lookup_revalidate(struct + struct nfs_fattr *fattr = NULL; + int error; + +- if (nd->flags & LOOKUP_RCU) ++ if (nd && (nd->flags & LOOKUP_RCU)) + return -ECHILD; + + parent = dget_parent(dentry); +@@ -1502,7 +1502,7 @@ static int nfs_open_revalidate(struct de + struct iattr attr; + int openflags, ret = 0; + +- if (nd->flags & LOOKUP_RCU) ++ if (nd && (nd->flags & LOOKUP_RCU)) + return -ECHILD; + + inode = dentry->d_inode; diff --git a/queue-3.4/nfs-show-original-device-name-verbatim-in-proc-mount-s-info.patch b/queue-3.4/nfs-show-original-device-name-verbatim-in-proc-mount-s-info.patch new file mode 100644 index 00000000000..59468c356a1 --- /dev/null +++ b/queue-3.4/nfs-show-original-device-name-verbatim-in-proc-mount-s-info.patch @@ -0,0 +1,128 @@ +From 97a54868262da1629a3e65121e65b8e8c4419d9f Mon Sep 17 00:00:00 2001 +From: Ben Hutchings +Date: Sun, 21 Oct 2012 19:23:52 +0100 +Subject: nfs: Show original device name verbatim in /proc/*/mount{s,info} + +From: Ben Hutchings + +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 +Reference: http://bugs.debian.org/669314 +Signed-off-by: Ben Hutchings +Signed-off-by: Jonathan Nieder +Signed-off-by: Trond Myklebust +Signed-off-by: Greg Kroah-Hartman + +--- + 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 +@@ -277,8 +277,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); + #ifdef CONFIG_NFS_V4 + rpc_authflavor_t nfs_find_best_sec(struct nfs4_secinfo_flavors *); +@@ -371,7 +372,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 +@@ -37,6 +37,7 @@ static struct vfsmount *nfs_do_submount( + * @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. +@@ -44,8 +45,14 @@ static struct vfsmount *nfs_do_submount( + * 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; +@@ -78,7 +85,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(); +@@ -95,9 +102,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 +@@ -812,7 +812,7 @@ static int nfs_show_devname(struct seq_f + 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 diff --git a/queue-3.4/nfsv3-make-v3-mounts-fail-with-etimedouts-instead-eio-on-mountd-timeouts.patch b/queue-3.4/nfsv3-make-v3-mounts-fail-with-etimedouts-instead-eio-on-mountd-timeouts.patch new file mode 100644 index 00000000000..601d2a36bcb --- /dev/null +++ b/queue-3.4/nfsv3-make-v3-mounts-fail-with-etimedouts-instead-eio-on-mountd-timeouts.patch @@ -0,0 +1,38 @@ +From acce94e68a0f346115fd41cdc298197d2d5a59ad Mon Sep 17 00:00:00 2001 +From: Scott Mayhew +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 + +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 +Signed-off-by: Trond Myklebust +Signed-off-by: Greg Kroah-Hartman + +--- + 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) diff --git a/queue-3.4/nfsv4-nfs4_locku_done-must-release-the-sequence-id.patch b/queue-3.4/nfsv4-nfs4_locku_done-must-release-the-sequence-id.patch new file mode 100644 index 00000000000..a725bf4cc6c --- /dev/null +++ b/queue-3.4/nfsv4-nfs4_locku_done-must-release-the-sequence-id.patch @@ -0,0 +1,29 @@ +From 2b1bc308f492589f7d49012ed24561534ea2be8c Mon Sep 17 00:00:00 2001 +From: Trond Myklebust +Date: Mon, 29 Oct 2012 18:53:23 -0400 +Subject: NFSv4: nfs4_locku_done must release the sequence id + +From: Trond Myklebust + +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 +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfs/nfs4proc.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -4306,6 +4306,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) diff --git a/queue-3.4/nfsv4.1-we-must-release-the-sequence-id-when-we-fail-to-get-a-session-slot.patch b/queue-3.4/nfsv4.1-we-must-release-the-sequence-id-when-we-fail-to-get-a-session-slot.patch new file mode 100644 index 00000000000..72204ff54c3 --- /dev/null +++ b/queue-3.4/nfsv4.1-we-must-release-the-sequence-id-when-we-fail-to-get-a-session-slot.patch @@ -0,0 +1,93 @@ +From 2240a9e2d013d8269ea425b73e1d7a54c7bc141f Mon Sep 17 00:00:00 2001 +From: Trond Myklebust +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 + +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 +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfs/nfs4proc.c | 36 +++++++++++++++++++++++------------- + 1 file changed, 23 insertions(+), 13 deletions(-) + +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -1478,9 +1478,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(); +@@ -2097,9 +2099,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__); + } +@@ -4323,9 +4326,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 = { +@@ -4470,7 +4475,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; +@@ -4479,10 +4484,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) diff --git a/queue-3.4/series b/queue-3.4/series index 47ac4825a9c..1412fe32337 100644 --- a/queue-3.4/series +++ b/queue-3.4/series @@ -19,3 +19,9 @@ mac80211-check-management-frame-header-length.patch 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-fix-bug-in-legacy-dns-resolver.patch +nfs-fix-oopses-in-nfs_lookup_revalidate-and-nfs4_lookup_revalidate.patch