]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.2-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 19 Sep 2015 16:07:40 +0000 (09:07 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 19 Sep 2015 16:07:40 +0000 (09:07 -0700)
added patches:
acpi-pci-penalize-legacy-irq-used-by-acpi-sci.patch
dm-cache-fix-leaking-of-deferred-bio-prison-cells.patch
dm-stats-report-precise_timestamps-and-histogram-in.patch
drivercore-fix-unregistration-path-of-platform-devices.patch
fs-create-and-use-seq_show_option-for-escaping.patch
fs-set-the-size-of-empty-dirs-to-0.patch
hpfs-update-ctime-and-mtime-on-directory-modification.patch
memory-hotplug-add-hot-added-memory-ranges-to-memblock-before-allocate-node_data-for-a-node.patch
ocfs2-direct-write-will-call-ocfs2_rw_unlock-twice-when-doing-aio-dio.patch

queue-4.2/acpi-pci-penalize-legacy-irq-used-by-acpi-sci.patch [new file with mode: 0644]
queue-4.2/dm-cache-fix-leaking-of-deferred-bio-prison-cells.patch [new file with mode: 0644]
queue-4.2/dm-stats-report-precise_timestamps-and-histogram-in.patch [new file with mode: 0644]
queue-4.2/drivercore-fix-unregistration-path-of-platform-devices.patch [new file with mode: 0644]
queue-4.2/fs-create-and-use-seq_show_option-for-escaping.patch [new file with mode: 0644]
queue-4.2/fs-set-the-size-of-empty-dirs-to-0.patch [new file with mode: 0644]
queue-4.2/hpfs-update-ctime-and-mtime-on-directory-modification.patch [new file with mode: 0644]
queue-4.2/memory-hotplug-add-hot-added-memory-ranges-to-memblock-before-allocate-node_data-for-a-node.patch [new file with mode: 0644]
queue-4.2/ocfs2-direct-write-will-call-ocfs2_rw_unlock-twice-when-doing-aio-dio.patch [new file with mode: 0644]
queue-4.2/series

diff --git a/queue-4.2/acpi-pci-penalize-legacy-irq-used-by-acpi-sci.patch b/queue-4.2/acpi-pci-penalize-legacy-irq-used-by-acpi-sci.patch
new file mode 100644 (file)
index 0000000..e3db627
--- /dev/null
@@ -0,0 +1,139 @@
+From 5d0ddfebb93069061880fc57ee4ba7246bd1e1ee Mon Sep 17 00:00:00 2001
+From: Jiang Liu <jiang.liu@linux.intel.com>
+Date: Fri, 21 Aug 2015 15:36:23 +0800
+Subject: ACPI, PCI: Penalize legacy IRQ used by ACPI SCI
+
+From: Jiang Liu <jiang.liu@linux.intel.com>
+
+commit 5d0ddfebb93069061880fc57ee4ba7246bd1e1ee upstream.
+
+Nick Meier reported a regression with HyperV that "
+  After rebooting the VM, the following messages are logged in syslog
+  when trying to load the tulip driver:
+    tulip: Linux Tulip drivers version 1.1.15 (Feb 27, 2007)
+    tulip: 0000:00:0a.0: PCI INT A: failed to register GSI
+    tulip: Cannot enable tulip board #0, aborting
+    tulip: probe of 0000:00:0a.0 failed with error -16
+  Errors occur in 3.19.0 kernel
+  Works in 3.17 kernel.
+"
+
+According to the ACPI dump file posted by Nick at
+https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1440072
+
+The ACPI MADT table includes an interrupt source overridden entry for
+ACPI SCI:
+[236h 0566  1]                Subtable Type : 02 <Interrupt Source Override>
+[237h 0567  1]                       Length : 0A
+[238h 0568  1]                          Bus : 00
+[239h 0569  1]                       Source : 09
+[23Ah 0570  4]                    Interrupt : 00000009
+[23Eh 0574  2]        Flags (decoded below) : 000D
+                                   Polarity : 1
+                               Trigger Mode : 3
+
+And in DSDT table, we have _PRT method to define PCI interrupts, which
+eventually goes to:
+        Name (PRSA, ResourceTemplate ()
+        {
+            IRQ (Level, ActiveLow, Shared, )
+                {3,4,5,7,9,10,11,12,14,15}
+        })
+        Name (PRSB, ResourceTemplate ()
+        {
+            IRQ (Level, ActiveLow, Shared, )
+                {3,4,5,7,9,10,11,12,14,15}
+        })
+        Name (PRSC, ResourceTemplate ()
+        {
+            IRQ (Level, ActiveLow, Shared, )
+                {3,4,5,7,9,10,11,12,14,15}
+        })
+        Name (PRSD, ResourceTemplate ()
+        {
+            IRQ (Level, ActiveLow, Shared, )
+                {3,4,5,7,9,10,11,12,14,15}
+        })
+
+According to the MADT and DSDT tables, IRQ 9 may be used for:
+ 1) ACPI SCI in level, high mode
+ 2) PCI legacy IRQ in level, low mode
+So there's a conflict in polarity setting for IRQ 9.
+
+Prior to commit cd68f6bd53cf ("x86, irq, acpi: Get rid of special
+handling of GSI for ACPI SCI"), ACPI SCI is handled specially and
+there's no check for conflicts between ACPI SCI and PCI legagy IRQ.
+And it seems that the HyperV hypervisor doesn't make use of the
+polarity configuration in IOAPIC entry, so it just works.
+
+Commit cd68f6bd53cf gets rid of the specially handling of ACPI SCI,
+and then the pin attribute checking code discloses the conflicts
+between ACPI SCI and PCI legacy IRQ on HyperV virtual machine,
+and rejects the request to assign IRQ9 to PCI devices.
+
+So penalize legacy IRQ used by ACPI SCI and mark it unusable if ACPI
+SCI attributes conflict with PCI IRQ attributes.
+
+Please refer to following links for more information:
+https://bugzilla.kernel.org/show_bug.cgi?id=101301
+https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1440072
+
+Fixes: cd68f6bd53cf ("x86, irq, acpi: Get rid of special handling of GSI for ACPI SCI")
+Reported-and-tested-by: Nick Meier <nmeier@microsoft.com>
+Acked-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/kernel/acpi/boot.c |    1 +
+ drivers/acpi/pci_link.c     |   16 ++++++++++++++++
+ include/linux/acpi.h        |    2 +-
+ 3 files changed, 18 insertions(+), 1 deletion(-)
+
+--- a/arch/x86/kernel/acpi/boot.c
++++ b/arch/x86/kernel/acpi/boot.c
+@@ -445,6 +445,7 @@ static void __init acpi_sci_ioapic_setup
+               polarity = acpi_sci_flags & ACPI_MADT_POLARITY_MASK;
+       mp_override_legacy_irq(bus_irq, polarity, trigger, gsi);
++      acpi_penalize_sci_irq(bus_irq, trigger, polarity);
+       /*
+        * stash over-ride to indicate we've been here
+--- a/drivers/acpi/pci_link.c
++++ b/drivers/acpi/pci_link.c
+@@ -826,6 +826,22 @@ void acpi_penalize_isa_irq(int irq, int
+ }
+ /*
++ * Penalize IRQ used by ACPI SCI. If ACPI SCI pin attributes conflict with
++ * PCI IRQ attributes, mark ACPI SCI as ISA_ALWAYS so it won't be use for
++ * PCI IRQs.
++ */
++void acpi_penalize_sci_irq(int irq, int trigger, int polarity)
++{
++      if (irq >= 0 && irq < ARRAY_SIZE(acpi_irq_penalty)) {
++              if (trigger != ACPI_MADT_TRIGGER_LEVEL ||
++                  polarity != ACPI_MADT_POLARITY_ACTIVE_LOW)
++                      acpi_irq_penalty[irq] += PIRQ_PENALTY_ISA_ALWAYS;
++              else
++                      acpi_irq_penalty[irq] += PIRQ_PENALTY_PCI_USING;
++      }
++}
++
++/*
+  * Over-ride default table to reserve additional IRQs for use by ISA
+  * e.g. acpi_irq_isa=5
+  * Useful for telling ACPI how not to interfere with your ISA sound card.
+--- a/include/linux/acpi.h
++++ b/include/linux/acpi.h
+@@ -221,7 +221,7 @@ struct pci_dev;
+ int acpi_pci_irq_enable (struct pci_dev *dev);
+ void acpi_penalize_isa_irq(int irq, int active);
+-
++void acpi_penalize_sci_irq(int irq, int trigger, int polarity);
+ void acpi_pci_irq_disable (struct pci_dev *dev);
+ extern int ec_read(u8 addr, u8 *val);
diff --git a/queue-4.2/dm-cache-fix-leaking-of-deferred-bio-prison-cells.patch b/queue-4.2/dm-cache-fix-leaking-of-deferred-bio-prison-cells.patch
new file mode 100644 (file)
index 0000000..b082445
--- /dev/null
@@ -0,0 +1,45 @@
+From 9153df7405ae04c1b0466de720e0a685cfea1a3a Mon Sep 17 00:00:00 2001
+From: Joe Thornber <ejt@redhat.com>
+Date: Mon, 31 Aug 2015 18:20:08 +0100
+Subject: dm cache: fix leaking of deferred bio prison cells
+
+From: Joe Thornber <ejt@redhat.com>
+
+commit 9153df7405ae04c1b0466de720e0a685cfea1a3a upstream.
+
+There were two cases where dm_cell_visit_release() was being called,
+which removes the cell from the prison's rbtree, but the callers didn't
+also return the cell to the mempool.  Fix this by having them call
+free_prison_cell().
+
+This leak manifested as the 'kmalloc-96' slab growing until OOM.
+
+Fixes: 651f5fa2a3 ("dm cache: defer whole cells")
+Signed-off-by: Joe Thornber <ejt@redhat.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/dm-cache-target.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/md/dm-cache-target.c
++++ b/drivers/md/dm-cache-target.c
+@@ -1729,6 +1729,8 @@ static void remap_cell_to_origin_clear_d
+               remap_to_origin(cache, bio);
+               issue(cache, bio);
+       }
++
++      free_prison_cell(cache, cell);
+ }
+ static void remap_cell_to_cache_dirty(struct cache *cache, struct dm_bio_prison_cell *cell,
+@@ -1763,6 +1765,8 @@ static void remap_cell_to_cache_dirty(st
+               remap_to_cache(cache, bio, cblock);
+               issue(cache, bio);
+       }
++
++      free_prison_cell(cache, cell);
+ }
+ /*----------------------------------------------------------------*/
diff --git a/queue-4.2/dm-stats-report-precise_timestamps-and-histogram-in.patch b/queue-4.2/dm-stats-report-precise_timestamps-and-histogram-in.patch
new file mode 100644 (file)
index 0000000..1d7f065
--- /dev/null
@@ -0,0 +1,83 @@
+From bd49784fd1e8f42c7600fbfa206361324857f373 Mon Sep 17 00:00:00 2001
+From: Mikulas Patocka <mpatocka@redhat.com>
+Date: Tue, 18 Aug 2015 16:26:16 -0400
+Subject: dm stats: report precise_timestamps and histogram in
+ @stats_list output
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+commit bd49784fd1e8f42c7600fbfa206361324857f373 upstream.
+
+If the user selected the precise_timestamps or histogram options, report
+it in the @stats_list message output.
+
+If the user didn't select these options, no extra tokens are reported,
+thus it is backward compatible with old software that doesn't know about
+precise timestamps and histogram.
+
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Cc: stable@vger.kernel.org # 4.2
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ Documentation/device-mapper/statistics.txt |    4 ++++
+ drivers/md/dm-stats.c                      |   14 +++++++++++++-
+ include/uapi/linux/dm-ioctl.h              |    4 ++--
+ 3 files changed, 19 insertions(+), 3 deletions(-)
+
+--- a/Documentation/device-mapper/statistics.txt
++++ b/Documentation/device-mapper/statistics.txt
+@@ -121,6 +121,10 @@ Messages
+       Output format:
+         <region_id>: <start_sector>+<length> <step> <program_id> <aux_data>
++              precise_timestamps histogram:n1,n2,n3,...
++
++      The strings "precise_timestamps" and "histogram" are printed only
++      if they were specified when creating the region.
+     @stats_print <region_id> [<starting_line> <number_of_lines>]
+--- a/drivers/md/dm-stats.c
++++ b/drivers/md/dm-stats.c
+@@ -457,12 +457,24 @@ static int dm_stats_list(struct dm_stats
+       list_for_each_entry(s, &stats->list, list_entry) {
+               if (!program || !strcmp(program, s->program_id)) {
+                       len = s->end - s->start;
+-                      DMEMIT("%d: %llu+%llu %llu %s %s\n", s->id,
++                      DMEMIT("%d: %llu+%llu %llu %s %s", s->id,
+                               (unsigned long long)s->start,
+                               (unsigned long long)len,
+                               (unsigned long long)s->step,
+                               s->program_id,
+                               s->aux_data);
++                      if (s->stat_flags & STAT_PRECISE_TIMESTAMPS)
++                              DMEMIT(" precise_timestamps");
++                      if (s->n_histogram_entries) {
++                              unsigned i;
++                              DMEMIT(" histogram:");
++                              for (i = 0; i < s->n_histogram_entries; i++) {
++                                      if (i)
++                                              DMEMIT(",");
++                                      DMEMIT("%llu", s->histogram_boundaries[i]);
++                              }
++                      }
++                      DMEMIT("\n");
+               }
+       }
+       mutex_unlock(&stats->mutex);
+--- a/include/uapi/linux/dm-ioctl.h
++++ b/include/uapi/linux/dm-ioctl.h
+@@ -267,9 +267,9 @@ enum {
+ #define DM_DEV_SET_GEOMETRY   _IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl)
+ #define DM_VERSION_MAJOR      4
+-#define DM_VERSION_MINOR      32
++#define DM_VERSION_MINOR      33
+ #define DM_VERSION_PATCHLEVEL 0
+-#define DM_VERSION_EXTRA      "-ioctl (2015-6-26)"
++#define DM_VERSION_EXTRA      "-ioctl (2015-8-18)"
+ /* Status bits */
+ #define DM_READONLY_FLAG      (1 << 0) /* In/Out */
diff --git a/queue-4.2/drivercore-fix-unregistration-path-of-platform-devices.patch b/queue-4.2/drivercore-fix-unregistration-path-of-platform-devices.patch
new file mode 100644 (file)
index 0000000..97d5960
--- /dev/null
@@ -0,0 +1,67 @@
+From 7f5dcaf1fdf289767a126a0a5cc3ef39b5254b06 Mon Sep 17 00:00:00 2001
+From: Grant Likely <grant.likely@linaro.org>
+Date: Sun, 7 Jun 2015 15:20:11 +0100
+Subject: drivercore: Fix unregistration path of platform devices
+
+From: Grant Likely <grant.likely@linaro.org>
+
+commit 7f5dcaf1fdf289767a126a0a5cc3ef39b5254b06 upstream.
+
+The unregister path of platform_device is broken. On registration, it
+will register all resources with either a parent already set, or
+type==IORESOURCE_{IO,MEM}. However, on unregister it will release
+everything with type==IORESOURCE_{IO,MEM}, but ignore the others. There
+are also cases where resources don't get registered in the first place,
+like with devices created by of_platform_populate()*.
+
+Fix the unregister path to be symmetrical with the register path by
+checking the parent pointer instead of the type field to decide which
+resources to unregister. This is safe because the upshot of the
+registration path algorithm is that registered resources have a parent
+pointer, and non-registered resources do not.
+
+* It can be argued that of_platform_populate() should be registering
+  it's resources, and they argument has some merit. However, there are
+  quite a few platforms that end up broken if we try to do that due to
+  overlapping resources in the device tree. Until that is fixed, we need
+  to solve the immediate problem.
+
+Cc: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
+Cc: Wolfram Sang <wsa@the-dreams.de>
+Cc: Rob Herring <robh@kernel.org>
+Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com>
+Signed-off-by: Grant Likely <grant.likely@linaro.org>
+Tested-by: Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com>
+Tested-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Signed-off-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/base/platform.c |    8 ++------
+ 1 file changed, 2 insertions(+), 6 deletions(-)
+
+--- a/drivers/base/platform.c
++++ b/drivers/base/platform.c
+@@ -375,9 +375,7 @@ int platform_device_add(struct platform_
+       while (--i >= 0) {
+               struct resource *r = &pdev->resource[i];
+-              unsigned long type = resource_type(r);
+-
+-              if (type == IORESOURCE_MEM || type == IORESOURCE_IO)
++              if (r->parent)
+                       release_resource(r);
+       }
+@@ -408,9 +406,7 @@ void platform_device_del(struct platform
+               for (i = 0; i < pdev->num_resources; i++) {
+                       struct resource *r = &pdev->resource[i];
+-                      unsigned long type = resource_type(r);
+-
+-                      if (type == IORESOURCE_MEM || type == IORESOURCE_IO)
++                      if (r->parent)
+                               release_resource(r);
+               }
+       }
diff --git a/queue-4.2/fs-create-and-use-seq_show_option-for-escaping.patch b/queue-4.2/fs-create-and-use-seq_show_option-for-escaping.patch
new file mode 100644 (file)
index 0000000..2980cee
--- /dev/null
@@ -0,0 +1,345 @@
+From a068acf2ee77693e0bf39d6e07139ba704f461c3 Mon Sep 17 00:00:00 2001
+From: Kees Cook <keescook@chromium.org>
+Date: Fri, 4 Sep 2015 15:44:57 -0700
+Subject: fs: create and use seq_show_option for escaping
+
+From: Kees Cook <keescook@chromium.org>
+
+commit a068acf2ee77693e0bf39d6e07139ba704f461c3 upstream.
+
+Many file systems that implement the show_options hook fail to correctly
+escape their output which could lead to unescaped characters (e.g.  new
+lines) leaking into /proc/mounts and /proc/[pid]/mountinfo files.  This
+could lead to confusion, spoofed entries (resulting in things like
+systemd issuing false d-bus "mount" notifications), and who knows what
+else.  This looks like it would only be the root user stepping on
+themselves, but it's possible weird things could happen in containers or
+in other situations with delegated mount privileges.
+
+Here's an example using overlay with setuid fusermount trusting the
+contents of /proc/mounts (via the /etc/mtab symlink).  Imagine the use
+of "sudo" is something more sneaky:
+
+  $ BASE="ovl"
+  $ MNT="$BASE/mnt"
+  $ LOW="$BASE/lower"
+  $ UP="$BASE/upper"
+  $ WORK="$BASE/work/ 0 0
+  none /proc fuse.pwn user_id=1000"
+  $ mkdir -p "$LOW" "$UP" "$WORK"
+  $ sudo mount -t overlay -o "lowerdir=$LOW,upperdir=$UP,workdir=$WORK" none /mnt
+  $ cat /proc/mounts
+  none /root/ovl/mnt overlay rw,relatime,lowerdir=ovl/lower,upperdir=ovl/upper,workdir=ovl/work/ 0 0
+  none /proc fuse.pwn user_id=1000 0 0
+  $ fusermount -u /proc
+  $ cat /proc/mounts
+  cat: /proc/mounts: No such file or directory
+
+This fixes the problem by adding new seq_show_option and
+seq_show_option_n helpers, and updating the vulnerable show_option
+handlers to use them as needed.  Some, like SELinux, need to be open
+coded due to unusual existing escape mechanisms.
+
+[akpm@linux-foundation.org: add lost chunk, per Kees]
+[keescook@chromium.org: seq_show_option should be using const parameters]
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Acked-by: Serge Hallyn <serge.hallyn@canonical.com>
+Acked-by: Jan Kara <jack@suse.com>
+Acked-by: Paul Moore <paul@paul-moore.com>
+Cc: J. R. Okajima <hooanon05g@gmail.com>
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ceph/super.c          |    2 +-
+ fs/cifs/cifsfs.c         |    6 +++---
+ fs/ext4/super.c          |    4 ++--
+ fs/gfs2/super.c          |    6 +++---
+ fs/hfs/super.c           |    4 ++--
+ fs/hfsplus/options.c     |    4 ++--
+ fs/hostfs/hostfs_kern.c  |    2 +-
+ fs/ocfs2/super.c         |    4 ++--
+ fs/overlayfs/super.c     |    6 +++---
+ fs/reiserfs/super.c      |    8 +++++---
+ fs/xfs/xfs_super.c       |    4 ++--
+ include/linux/seq_file.h |   35 +++++++++++++++++++++++++++++++++++
+ kernel/cgroup.c          |    7 ++++---
+ net/ceph/ceph_common.c   |    7 +++++--
+ security/selinux/hooks.c |    2 +-
+ 15 files changed, 71 insertions(+), 30 deletions(-)
+
+--- a/fs/ceph/super.c
++++ b/fs/ceph/super.c
+@@ -479,7 +479,7 @@ static int ceph_show_options(struct seq_
+       if (fsopt->max_readdir_bytes != CEPH_MAX_READDIR_BYTES_DEFAULT)
+               seq_printf(m, ",readdir_max_bytes=%d", fsopt->max_readdir_bytes);
+       if (strcmp(fsopt->snapdir_name, CEPH_SNAPDIRNAME_DEFAULT))
+-              seq_printf(m, ",snapdirname=%s", fsopt->snapdir_name);
++              seq_show_option(m, "snapdirname", fsopt->snapdir_name);
+       return 0;
+ }
+--- a/fs/cifs/cifsfs.c
++++ b/fs/cifs/cifsfs.c
+@@ -394,17 +394,17 @@ cifs_show_options(struct seq_file *s, st
+       struct sockaddr *srcaddr;
+       srcaddr = (struct sockaddr *)&tcon->ses->server->srcaddr;
+-      seq_printf(s, ",vers=%s", tcon->ses->server->vals->version_string);
++      seq_show_option(s, "vers", tcon->ses->server->vals->version_string);
+       cifs_show_security(s, tcon->ses);
+       cifs_show_cache_flavor(s, cifs_sb);
+       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)
+               seq_puts(s, ",multiuser");
+       else if (tcon->ses->user_name)
+-              seq_printf(s, ",username=%s", tcon->ses->user_name);
++              seq_show_option(s, "username", tcon->ses->user_name);
+       if (tcon->ses->domainName)
+-              seq_printf(s, ",domain=%s", tcon->ses->domainName);
++              seq_show_option(s, "domain", tcon->ses->domainName);
+       if (srcaddr->sa_family != AF_UNSPEC) {
+               struct sockaddr_in *saddr4;
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -1763,10 +1763,10 @@ static inline void ext4_show_quota_optio
+       }
+       if (sbi->s_qf_names[USRQUOTA])
+-              seq_printf(seq, ",usrjquota=%s", sbi->s_qf_names[USRQUOTA]);
++              seq_show_option(seq, "usrjquota", sbi->s_qf_names[USRQUOTA]);
+       if (sbi->s_qf_names[GRPQUOTA])
+-              seq_printf(seq, ",grpjquota=%s", sbi->s_qf_names[GRPQUOTA]);
++              seq_show_option(seq, "grpjquota", sbi->s_qf_names[GRPQUOTA]);
+ #endif
+ }
+--- a/fs/gfs2/super.c
++++ b/fs/gfs2/super.c
+@@ -1334,11 +1334,11 @@ static int gfs2_show_options(struct seq_
+       if (is_ancestor(root, sdp->sd_master_dir))
+               seq_puts(s, ",meta");
+       if (args->ar_lockproto[0])
+-              seq_printf(s, ",lockproto=%s", args->ar_lockproto);
++              seq_show_option(s, "lockproto", args->ar_lockproto);
+       if (args->ar_locktable[0])
+-              seq_printf(s, ",locktable=%s", args->ar_locktable);
++              seq_show_option(s, "locktable", args->ar_locktable);
+       if (args->ar_hostdata[0])
+-              seq_printf(s, ",hostdata=%s", args->ar_hostdata);
++              seq_show_option(s, "hostdata", args->ar_hostdata);
+       if (args->ar_spectator)
+               seq_puts(s, ",spectator");
+       if (args->ar_localflocks)
+--- a/fs/hfs/super.c
++++ b/fs/hfs/super.c
+@@ -136,9 +136,9 @@ static int hfs_show_options(struct seq_f
+       struct hfs_sb_info *sbi = HFS_SB(root->d_sb);
+       if (sbi->s_creator != cpu_to_be32(0x3f3f3f3f))
+-              seq_printf(seq, ",creator=%.4s", (char *)&sbi->s_creator);
++              seq_show_option_n(seq, "creator", (char *)&sbi->s_creator, 4);
+       if (sbi->s_type != cpu_to_be32(0x3f3f3f3f))
+-              seq_printf(seq, ",type=%.4s", (char *)&sbi->s_type);
++              seq_show_option_n(seq, "type", (char *)&sbi->s_type, 4);
+       seq_printf(seq, ",uid=%u,gid=%u",
+                       from_kuid_munged(&init_user_ns, sbi->s_uid),
+                       from_kgid_munged(&init_user_ns, sbi->s_gid));
+--- a/fs/hfsplus/options.c
++++ b/fs/hfsplus/options.c
+@@ -218,9 +218,9 @@ int hfsplus_show_options(struct seq_file
+       struct hfsplus_sb_info *sbi = HFSPLUS_SB(root->d_sb);
+       if (sbi->creator != HFSPLUS_DEF_CR_TYPE)
+-              seq_printf(seq, ",creator=%.4s", (char *)&sbi->creator);
++              seq_show_option_n(seq, "creator", (char *)&sbi->creator, 4);
+       if (sbi->type != HFSPLUS_DEF_CR_TYPE)
+-              seq_printf(seq, ",type=%.4s", (char *)&sbi->type);
++              seq_show_option_n(seq, "type", (char *)&sbi->type, 4);
+       seq_printf(seq, ",umask=%o,uid=%u,gid=%u", sbi->umask,
+                       from_kuid_munged(&init_user_ns, sbi->uid),
+                       from_kgid_munged(&init_user_ns, sbi->gid));
+--- a/fs/hostfs/hostfs_kern.c
++++ b/fs/hostfs/hostfs_kern.c
+@@ -260,7 +260,7 @@ static int hostfs_show_options(struct se
+       size_t offset = strlen(root_ino) + 1;
+       if (strlen(root_path) > offset)
+-              seq_printf(seq, ",%s", root_path + offset);
++              seq_show_option(seq, root_path + offset, NULL);
+       if (append)
+               seq_puts(seq, ",append");
+--- a/fs/ocfs2/super.c
++++ b/fs/ocfs2/super.c
+@@ -1550,8 +1550,8 @@ static int ocfs2_show_options(struct seq
+               seq_printf(s, ",localflocks,");
+       if (osb->osb_cluster_stack[0])
+-              seq_printf(s, ",cluster_stack=%.*s", OCFS2_STACK_LABEL_LEN,
+-                         osb->osb_cluster_stack);
++              seq_show_option_n(s, "cluster_stack", osb->osb_cluster_stack,
++                                OCFS2_STACK_LABEL_LEN);
+       if (opts & OCFS2_MOUNT_USRQUOTA)
+               seq_printf(s, ",usrquota");
+       if (opts & OCFS2_MOUNT_GRPQUOTA)
+--- a/fs/overlayfs/super.c
++++ b/fs/overlayfs/super.c
+@@ -588,10 +588,10 @@ static int ovl_show_options(struct seq_f
+       struct super_block *sb = dentry->d_sb;
+       struct ovl_fs *ufs = sb->s_fs_info;
+-      seq_printf(m, ",lowerdir=%s", ufs->config.lowerdir);
++      seq_show_option(m, "lowerdir", ufs->config.lowerdir);
+       if (ufs->config.upperdir) {
+-              seq_printf(m, ",upperdir=%s", ufs->config.upperdir);
+-              seq_printf(m, ",workdir=%s", ufs->config.workdir);
++              seq_show_option(m, "upperdir", ufs->config.upperdir);
++              seq_show_option(m, "workdir", ufs->config.workdir);
+       }
+       return 0;
+ }
+--- a/fs/reiserfs/super.c
++++ b/fs/reiserfs/super.c
+@@ -714,18 +714,20 @@ static int reiserfs_show_options(struct
+               seq_puts(seq, ",acl");
+       if (REISERFS_SB(s)->s_jdev)
+-              seq_printf(seq, ",jdev=%s", REISERFS_SB(s)->s_jdev);
++              seq_show_option(seq, "jdev", REISERFS_SB(s)->s_jdev);
+       if (journal->j_max_commit_age != journal->j_default_max_commit_age)
+               seq_printf(seq, ",commit=%d", journal->j_max_commit_age);
+ #ifdef CONFIG_QUOTA
+       if (REISERFS_SB(s)->s_qf_names[USRQUOTA])
+-              seq_printf(seq, ",usrjquota=%s", REISERFS_SB(s)->s_qf_names[USRQUOTA]);
++              seq_show_option(seq, "usrjquota",
++                              REISERFS_SB(s)->s_qf_names[USRQUOTA]);
+       else if (opts & (1 << REISERFS_USRQUOTA))
+               seq_puts(seq, ",usrquota");
+       if (REISERFS_SB(s)->s_qf_names[GRPQUOTA])
+-              seq_printf(seq, ",grpjquota=%s", REISERFS_SB(s)->s_qf_names[GRPQUOTA]);
++              seq_show_option(seq, "grpjquota",
++                              REISERFS_SB(s)->s_qf_names[GRPQUOTA]);
+       else if (opts & (1 << REISERFS_GRPQUOTA))
+               seq_puts(seq, ",grpquota");
+       if (REISERFS_SB(s)->s_jquota_fmt) {
+--- a/fs/xfs/xfs_super.c
++++ b/fs/xfs/xfs_super.c
+@@ -511,9 +511,9 @@ xfs_showargs(
+               seq_printf(m, "," MNTOPT_LOGBSIZE "=%dk", mp->m_logbsize >> 10);
+       if (mp->m_logname)
+-              seq_printf(m, "," MNTOPT_LOGDEV "=%s", mp->m_logname);
++              seq_show_option(m, MNTOPT_LOGDEV, mp->m_logname);
+       if (mp->m_rtname)
+-              seq_printf(m, "," MNTOPT_RTDEV "=%s", mp->m_rtname);
++              seq_show_option(m, MNTOPT_RTDEV, mp->m_rtname);
+       if (mp->m_dalign > 0)
+               seq_printf(m, "," MNTOPT_SUNIT "=%d",
+--- a/include/linux/seq_file.h
++++ b/include/linux/seq_file.h
+@@ -149,6 +149,41 @@ static inline struct user_namespace *seq
+ #endif
+ }
++/**
++ * seq_show_options - display mount options with appropriate escapes.
++ * @m: the seq_file handle
++ * @name: the mount option name
++ * @value: the mount option name's value, can be NULL
++ */
++static inline void seq_show_option(struct seq_file *m, const char *name,
++                                 const char *value)
++{
++      seq_putc(m, ',');
++      seq_escape(m, name, ",= \t\n\\");
++      if (value) {
++              seq_putc(m, '=');
++              seq_escape(m, value, ", \t\n\\");
++      }
++}
++
++/**
++ * seq_show_option_n - display mount options with appropriate escapes
++ *                   where @value must be a specific length.
++ * @m: the seq_file handle
++ * @name: the mount option name
++ * @value: the mount option name's value, cannot be NULL
++ * @length: the length of @value to display
++ *
++ * This is a macro since this uses "length" to define the size of the
++ * stack buffer.
++ */
++#define seq_show_option_n(m, name, value, length) {   \
++      char val_buf[length + 1];                       \
++      strncpy(val_buf, value, length);                \
++      val_buf[length] = '\0';                         \
++      seq_show_option(m, name, val_buf);              \
++}
++
+ #define SEQ_START_TOKEN ((void *)1)
+ /*
+  * Helpers for iteration over list_head-s in seq_files
+--- a/kernel/cgroup.c
++++ b/kernel/cgroup.c
+@@ -1334,7 +1334,7 @@ static int cgroup_show_options(struct se
+       for_each_subsys(ss, ssid)
+               if (root->subsys_mask & (1 << ssid))
+-                      seq_printf(seq, ",%s", ss->name);
++                      seq_show_option(seq, ss->name, NULL);
+       if (root->flags & CGRP_ROOT_NOPREFIX)
+               seq_puts(seq, ",noprefix");
+       if (root->flags & CGRP_ROOT_XATTR)
+@@ -1342,13 +1342,14 @@ static int cgroup_show_options(struct se
+       spin_lock(&release_agent_path_lock);
+       if (strlen(root->release_agent_path))
+-              seq_printf(seq, ",release_agent=%s", root->release_agent_path);
++              seq_show_option(seq, "release_agent",
++                              root->release_agent_path);
+       spin_unlock(&release_agent_path_lock);
+       if (test_bit(CGRP_CPUSET_CLONE_CHILDREN, &root->cgrp.flags))
+               seq_puts(seq, ",clone_children");
+       if (strlen(root->name))
+-              seq_printf(seq, ",name=%s", root->name);
++              seq_show_option(seq, "name", root->name);
+       return 0;
+ }
+--- a/net/ceph/ceph_common.c
++++ b/net/ceph/ceph_common.c
+@@ -517,8 +517,11 @@ int ceph_print_client_options(struct seq
+       struct ceph_options *opt = client->options;
+       size_t pos = m->count;
+-      if (opt->name)
+-              seq_printf(m, "name=%s,", opt->name);
++      if (opt->name) {
++              seq_puts(m, "name=");
++              seq_escape(m, opt->name, ", \t\n\\");
++              seq_putc(m, ',');
++      }
+       if (opt->key)
+               seq_puts(m, "secret=<hidden>,");
+--- a/security/selinux/hooks.c
++++ b/security/selinux/hooks.c
+@@ -1100,7 +1100,7 @@ static void selinux_write_opts(struct se
+               seq_puts(m, prefix);
+               if (has_comma)
+                       seq_putc(m, '\"');
+-              seq_puts(m, opts->mnt_opts[i]);
++              seq_escape(m, opts->mnt_opts[i], "\"\n\\");
+               if (has_comma)
+                       seq_putc(m, '\"');
+       }
diff --git a/queue-4.2/fs-set-the-size-of-empty-dirs-to-0.patch b/queue-4.2/fs-set-the-size-of-empty-dirs-to-0.patch
new file mode 100644 (file)
index 0000000..8eefb4a
--- /dev/null
@@ -0,0 +1,36 @@
+From 4b75de8615050c1b0dd8d7794838c42f74ed36ba Mon Sep 17 00:00:00 2001
+From: "Eric W. Biederman" <ebiederm@xmission.com>
+Date: Wed, 12 Aug 2015 15:00:12 -0500
+Subject: fs: Set the size of empty dirs to 0.
+
+From: "Eric W. Biederman" <ebiederm@xmission.com>
+
+commit 4b75de8615050c1b0dd8d7794838c42f74ed36ba upstream.
+
+Before the make_empty_dir_inode calls were introduce into proc, sysfs,
+and sysctl those directories when stated reported an i_size of 0.
+make_empty_dir_inode started reporting an i_size of 2.  At least one
+userspace application depended on stat returning i_size of 0.  So
+modify make_empty_dir_inode to cause an i_size of 0 to be reported for
+these directories.
+
+Reported-by: Tejun Heo <tj@kernel.org>
+Acked-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/libfs.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/libfs.c
++++ b/fs/libfs.c
+@@ -1185,7 +1185,7 @@ void make_empty_dir_inode(struct inode *
+       inode->i_uid = GLOBAL_ROOT_UID;
+       inode->i_gid = GLOBAL_ROOT_GID;
+       inode->i_rdev = 0;
+-      inode->i_size = 2;
++      inode->i_size = 0;
+       inode->i_blkbits = PAGE_SHIFT;
+       inode->i_blocks = 0;
diff --git a/queue-4.2/hpfs-update-ctime-and-mtime-on-directory-modification.patch b/queue-4.2/hpfs-update-ctime-and-mtime-on-directory-modification.patch
new file mode 100644 (file)
index 0000000..3c4c677
--- /dev/null
@@ -0,0 +1,110 @@
+From f49a26e7718dd30b49e3541e3e25aecf5e7294e2 Mon Sep 17 00:00:00 2001
+From: Mikulas Patocka <mikulas@twibright.com>
+Date: Wed, 2 Sep 2015 22:51:53 +0200
+Subject: hpfs: update ctime and mtime on directory modification
+
+From: Mikulas Patocka <mikulas@twibright.com>
+
+commit f49a26e7718dd30b49e3541e3e25aecf5e7294e2 upstream.
+
+Update ctime and mtime when a directory is modified. (though OS/2 doesn't
+update them anyway)
+
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/hpfs/namei.c |   25 ++++++++++++++++++++++++-
+ 1 file changed, 24 insertions(+), 1 deletion(-)
+
+--- a/fs/hpfs/namei.c
++++ b/fs/hpfs/namei.c
+@@ -8,6 +8,17 @@
+ #include <linux/sched.h>
+ #include "hpfs_fn.h"
++static void hpfs_update_directory_times(struct inode *dir)
++{
++      time_t t = get_seconds();
++      if (t == dir->i_mtime.tv_sec &&
++          t == dir->i_ctime.tv_sec)
++              return;
++      dir->i_mtime.tv_sec = dir->i_ctime.tv_sec = t;
++      dir->i_mtime.tv_nsec = dir->i_ctime.tv_nsec = 0;
++      hpfs_write_inode_nolock(dir);
++}
++
+ static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
+ {
+       const unsigned char *name = dentry->d_name.name;
+@@ -99,6 +110,7 @@ static int hpfs_mkdir(struct inode *dir,
+               result->i_mode = mode | S_IFDIR;
+               hpfs_write_inode_nolock(result);
+       }
++      hpfs_update_directory_times(dir);
+       d_instantiate(dentry, result);
+       hpfs_unlock(dir->i_sb);
+       return 0;
+@@ -187,6 +199,7 @@ static int hpfs_create(struct inode *dir
+               result->i_mode = mode | S_IFREG;
+               hpfs_write_inode_nolock(result);
+       }
++      hpfs_update_directory_times(dir);
+       d_instantiate(dentry, result);
+       hpfs_unlock(dir->i_sb);
+       return 0;
+@@ -262,6 +275,7 @@ static int hpfs_mknod(struct inode *dir,
+       insert_inode_hash(result);
+       hpfs_write_inode_nolock(result);
++      hpfs_update_directory_times(dir);
+       d_instantiate(dentry, result);
+       brelse(bh);
+       hpfs_unlock(dir->i_sb);
+@@ -340,6 +354,7 @@ static int hpfs_symlink(struct inode *di
+       insert_inode_hash(result);
+       hpfs_write_inode_nolock(result);
++      hpfs_update_directory_times(dir);
+       d_instantiate(dentry, result);
+       hpfs_unlock(dir->i_sb);
+       return 0;
+@@ -423,6 +438,8 @@ again:
+ out1:
+       hpfs_brelse4(&qbh);
+ out:
++      if (!err)
++              hpfs_update_directory_times(dir);
+       hpfs_unlock(dir->i_sb);
+       return err;
+ }
+@@ -477,6 +494,8 @@ static int hpfs_rmdir(struct inode *dir,
+ out1:
+       hpfs_brelse4(&qbh);
+ out:
++      if (!err)
++              hpfs_update_directory_times(dir);
+       hpfs_unlock(dir->i_sb);
+       return err;
+ }
+@@ -595,7 +614,7 @@ static int hpfs_rename(struct inode *old
+               goto end1;
+       }
+-      end:
++end:
+       hpfs_i(i)->i_parent_dir = new_dir->i_ino;
+       if (S_ISDIR(i->i_mode)) {
+               inc_nlink(new_dir);
+@@ -610,6 +629,10 @@ static int hpfs_rename(struct inode *old
+               brelse(bh);
+       }
+ end1:
++      if (!err) {
++              hpfs_update_directory_times(old_dir);
++              hpfs_update_directory_times(new_dir);
++      }
+       hpfs_unlock(i->i_sb);
+       return err;
+ }
diff --git a/queue-4.2/memory-hotplug-add-hot-added-memory-ranges-to-memblock-before-allocate-node_data-for-a-node.patch b/queue-4.2/memory-hotplug-add-hot-added-memory-ranges-to-memblock-before-allocate-node_data-for-a-node.patch
new file mode 100644 (file)
index 0000000..d64cc4a
--- /dev/null
@@ -0,0 +1,88 @@
+From 7f36e3e56db1ae75d1e157011b3cb2e0957f0a7e Mon Sep 17 00:00:00 2001
+From: Tang Chen <tangchen@cn.fujitsu.com>
+Date: Fri, 4 Sep 2015 15:42:32 -0700
+Subject: memory-hotplug: add hot-added memory ranges to memblock before allocate node_data for a node.
+
+From: Tang Chen <tangchen@cn.fujitsu.com>
+
+commit 7f36e3e56db1ae75d1e157011b3cb2e0957f0a7e upstream.
+
+Commit f9126ab9241f ("memory-hotplug: fix wrong edge when hot add a new
+node") hot-added memory range to memblock, after creating pgdat for new
+node.
+
+But there is a problem:
+
+  add_memory()
+  |--> hotadd_new_pgdat()
+       |--> free_area_init_node()
+            |--> get_pfn_range_for_nid()
+                 |--> find start_pfn and end_pfn in memblock
+  |--> ......
+  |--> memblock_add_node(start, size, nid)    --------    Here, just too late.
+
+get_pfn_range_for_nid() will find that start_pfn and end_pfn are both 0.
+As a result, when adding memory, dmesg will give the following wrong
+message.
+
+  Initmem setup node 5 [mem 0x0000000000000000-0xffffffffffffffff]
+  On node 5 totalpages: 0
+  Built 5 zonelists in Node order, mobility grouping on.  Total pages: 32588823
+  Policy zone: Normal
+  init_memory_mapping: [mem 0x60000000000-0x607ffffffff]
+
+The solution is simple, just add the memory range to memblock a little
+earlier, before hotadd_new_pgdat().
+
+[akpm@linux-foundation.org: coding-style fixes]
+Signed-off-by: Tang Chen <tangchen@cn.fujitsu.com>
+Cc: Xishi Qiu <qiuxishi@huawei.com>
+Cc: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
+Cc: Kamezawa Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
+Cc: Taku Izumi <izumi.taku@jp.fujitsu.com>
+Cc: Gu Zheng <guz.fnst@cn.fujitsu.com>
+Cc: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
+Cc: Vlastimil Babka <vbabka@suse.cz>
+Cc: Mel Gorman <mgorman@techsingularity.net>
+Cc: David Rientjes <rientjes@google.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ mm/memory_hotplug.c |   10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+--- a/mm/memory_hotplug.c
++++ b/mm/memory_hotplug.c
+@@ -1248,6 +1248,14 @@ int __ref add_memory(int nid, u64 start,
+       mem_hotplug_begin();
++      /*
++       * Add new range to memblock so that when hotadd_new_pgdat() is called
++       * to allocate new pgdat, get_pfn_range_for_nid() will be able to find
++       * this new range and calculate total pages correctly.  The range will
++       * be removed at hot-remove time.
++       */
++      memblock_add_node(start, size, nid);
++
+       new_node = !node_online(nid);
+       if (new_node) {
+               pgdat = hotadd_new_pgdat(nid, start);
+@@ -1277,7 +1285,6 @@ int __ref add_memory(int nid, u64 start,
+       /* create new memmap entry */
+       firmware_map_add_hotplug(start, start + size, "System RAM");
+-      memblock_add_node(start, size, nid);
+       goto out;
+@@ -1286,6 +1293,7 @@ error:
+       if (new_pgdat)
+               rollback_node_hotadd(nid, pgdat);
+       release_memory_resource(res);
++      memblock_remove(start, size);
+ out:
+       mem_hotplug_done();
diff --git a/queue-4.2/ocfs2-direct-write-will-call-ocfs2_rw_unlock-twice-when-doing-aio-dio.patch b/queue-4.2/ocfs2-direct-write-will-call-ocfs2_rw_unlock-twice-when-doing-aio-dio.patch
new file mode 100644 (file)
index 0000000..4963f25
--- /dev/null
@@ -0,0 +1,75 @@
+From aa1057b3dec478b20c77bad07442318ae36d893c Mon Sep 17 00:00:00 2001
+From: Ryan Ding <ryan.ding@oracle.com>
+Date: Fri, 4 Sep 2015 15:42:36 -0700
+Subject: ocfs2: direct write will call ocfs2_rw_unlock() twice when doing aio+dio
+
+From: Ryan Ding <ryan.ding@oracle.com>
+
+commit aa1057b3dec478b20c77bad07442318ae36d893c upstream.
+
+ocfs2_file_write_iter() is usng the wrong return value ('written').  This
+will cause ocfs2_rw_unlock() be called both in write_iter & end_io,
+triggering a BUG_ON.
+
+This issue was introduced by commit 7da839c47589 ("ocfs2: use
+__generic_file_write_iter()").
+
+Orabug: 21612107
+Fixes: 7da839c47589 ("ocfs2: use __generic_file_write_iter()")
+Signed-off-by: Ryan Ding <ryan.ding@oracle.com>
+Reviewed-by: Junxiao Bi <junxiao.bi@oracle.com>
+Cc: Al Viro <viro@zeniv.linux.org.uk>
+Cc: Mark Fasheh <mfasheh@suse.com>
+Cc: Joel Becker <jlbec@evilplan.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ocfs2/file.c |   28 ++++++++++++++--------------
+ 1 file changed, 14 insertions(+), 14 deletions(-)
+
+--- a/fs/ocfs2/file.c
++++ b/fs/ocfs2/file.c
+@@ -2372,6 +2372,20 @@ relock:
+       /* buffered aio wouldn't have proper lock coverage today */
+       BUG_ON(written == -EIOCBQUEUED && !(iocb->ki_flags & IOCB_DIRECT));
++      /*
++       * deep in g_f_a_w_n()->ocfs2_direct_IO we pass in a ocfs2_dio_end_io
++       * function pointer which is called when o_direct io completes so that
++       * it can unlock our rw lock.
++       * Unfortunately there are error cases which call end_io and others
++       * that don't.  so we don't have to unlock the rw_lock if either an
++       * async dio is going to do it in the future or an end_io after an
++       * error has already done it.
++       */
++      if ((written == -EIOCBQUEUED) || (!ocfs2_iocb_is_rw_locked(iocb))) {
++              rw_level = -1;
++              unaligned_dio = 0;
++      }
++
+       if (unlikely(written <= 0))
+               goto no_sync;
+@@ -2396,20 +2410,6 @@ relock:
+       }
+ no_sync:
+-      /*
+-       * deep in g_f_a_w_n()->ocfs2_direct_IO we pass in a ocfs2_dio_end_io
+-       * function pointer which is called when o_direct io completes so that
+-       * it can unlock our rw lock.
+-       * Unfortunately there are error cases which call end_io and others
+-       * that don't.  so we don't have to unlock the rw_lock if either an
+-       * async dio is going to do it in the future or an end_io after an
+-       * error has already done it.
+-       */
+-      if ((ret == -EIOCBQUEUED) || (!ocfs2_iocb_is_rw_locked(iocb))) {
+-              rw_level = -1;
+-              unaligned_dio = 0;
+-      }
+-
+       if (unaligned_dio) {
+               ocfs2_iocb_clear_unaligned_aio(iocb);
+               mutex_unlock(&OCFS2_I(inode)->ip_unaligned_aio);
index f27298401c32c12db794f28b83e30c968ec7d6b9..9d8ea1eebd6054347edaa385463bc39f86ad13b5 100644 (file)
@@ -109,3 +109,12 @@ arm-dts-fix-clock-frequency-of-display-timing0-for-exynos3250-rinato.patch
 arm-omap2-dra7-clockdomain-change-l4per2_7xx_clkdm-to-sw_wkup.patch
 arm-rockchip-fix-the-cpu-soft-reset.patch
 arm-dts-rockchip-fix-rk3288-watchdog-irq.patch
+acpi-pci-penalize-legacy-irq-used-by-acpi-sci.patch
+drivercore-fix-unregistration-path-of-platform-devices.patch
+dm-stats-report-precise_timestamps-and-histogram-in.patch
+dm-cache-fix-leaking-of-deferred-bio-prison-cells.patch
+fs-set-the-size-of-empty-dirs-to-0.patch
+hpfs-update-ctime-and-mtime-on-directory-modification.patch
+ocfs2-direct-write-will-call-ocfs2_rw_unlock-twice-when-doing-aio-dio.patch
+memory-hotplug-add-hot-added-memory-ranges-to-memblock-before-allocate-node_data-for-a-node.patch
+fs-create-and-use-seq_show_option-for-escaping.patch