]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 6 Nov 2015 05:53:51 +0000 (21:53 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 6 Nov 2015 05:53:51 +0000 (21:53 -0800)
added patches:
rbd-don-t-leak-parent_spec-in-rbd_dev_probe_parent.patch
rbd-prevent-kernel-stack-blow-up-on-rbd-map.patch
rbd-require-stable-pages-if-message-data-crcs-are-enabled.patch

queue-3.10/rbd-don-t-leak-parent_spec-in-rbd_dev_probe_parent.patch [new file with mode: 0644]
queue-3.10/rbd-prevent-kernel-stack-blow-up-on-rbd-map.patch [new file with mode: 0644]
queue-3.10/rbd-require-stable-pages-if-message-data-crcs-are-enabled.patch [new file with mode: 0644]
queue-3.10/series

diff --git a/queue-3.10/rbd-don-t-leak-parent_spec-in-rbd_dev_probe_parent.patch b/queue-3.10/rbd-don-t-leak-parent_spec-in-rbd_dev_probe_parent.patch
new file mode 100644 (file)
index 0000000..c100e08
--- /dev/null
@@ -0,0 +1,87 @@
+From 1f2c6651f69c14d0d3a9cfbda44ea101b02160ba Mon Sep 17 00:00:00 2001
+From: Ilya Dryomov <idryomov@gmail.com>
+Date: Sun, 11 Oct 2015 19:38:00 +0200
+Subject: rbd: don't leak parent_spec in rbd_dev_probe_parent()
+
+From: Ilya Dryomov <idryomov@gmail.com>
+
+commit 1f2c6651f69c14d0d3a9cfbda44ea101b02160ba upstream.
+
+Currently we leak parent_spec and trigger a "parent reference
+underflow" warning if rbd_dev_create() in rbd_dev_probe_parent() fails.
+The problem is we take the !parent out_err branch and that only drops
+refcounts; parent_spec that would've been freed had we called
+rbd_dev_unparent() remains and triggers rbd_warn() in
+rbd_dev_parent_put() - at that point we have parent_spec != NULL and
+parent_ref == 0, so counter ends up being -1 after the decrement.
+
+Redo rbd_dev_probe_parent() to fix this.
+
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+[idryomov@gmail.com: backport to < 4.2: rbd_dev->opts]
+Reviewed-by: Alex Elder <elder@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/block/rbd.c |   35 +++++++++++++++--------------------
+ 1 file changed, 15 insertions(+), 20 deletions(-)
+
+--- a/drivers/block/rbd.c
++++ b/drivers/block/rbd.c
+@@ -4834,41 +4834,36 @@ out_err:
+ static int rbd_dev_probe_parent(struct rbd_device *rbd_dev)
+ {
+       struct rbd_device *parent = NULL;
+-      struct rbd_spec *parent_spec;
+-      struct rbd_client *rbdc;
+       int ret;
+       if (!rbd_dev->parent_spec)
+               return 0;
+-      /*
+-       * We need to pass a reference to the client and the parent
+-       * spec when creating the parent rbd_dev.  Images related by
+-       * parent/child relationships always share both.
+-       */
+-      parent_spec = rbd_spec_get(rbd_dev->parent_spec);
+-      rbdc = __rbd_get_client(rbd_dev->rbd_client);
+-      ret = -ENOMEM;
+-      parent = rbd_dev_create(rbdc, parent_spec);
+-      if (!parent)
++      parent = rbd_dev_create(rbd_dev->rbd_client, rbd_dev->parent_spec);
++      if (!parent) {
++              ret = -ENOMEM;
+               goto out_err;
++      }
++
++      /*
++       * Images related by parent/child relationships always share
++       * rbd_client and spec/parent_spec, so bump their refcounts.
++       */
++      __rbd_get_client(rbd_dev->rbd_client);
++      rbd_spec_get(rbd_dev->parent_spec);
+       ret = rbd_dev_image_probe(parent, false);
+       if (ret < 0)
+               goto out_err;
++
+       rbd_dev->parent = parent;
+       atomic_set(&rbd_dev->parent_ref, 1);
+-
+       return 0;
++
+ out_err:
+-      if (parent) {
+-              rbd_dev_unparent(rbd_dev);
++      rbd_dev_unparent(rbd_dev);
++      if (parent)
+               rbd_dev_destroy(parent);
+-      } else {
+-              rbd_put_client(rbdc);
+-              rbd_spec_put(parent_spec);
+-      }
+-
+       return ret;
+ }
diff --git a/queue-3.10/rbd-prevent-kernel-stack-blow-up-on-rbd-map.patch b/queue-3.10/rbd-prevent-kernel-stack-blow-up-on-rbd-map.patch
new file mode 100644 (file)
index 0000000..d148e1c
--- /dev/null
@@ -0,0 +1,136 @@
+From 6d69bb536bac0d403d83db1ca841444981b280cd Mon Sep 17 00:00:00 2001
+From: Ilya Dryomov <idryomov@gmail.com>
+Date: Sun, 11 Oct 2015 19:38:00 +0200
+Subject: rbd: prevent kernel stack blow up on rbd map
+
+From: Ilya Dryomov <idryomov@gmail.com>
+
+commit 6d69bb536bac0d403d83db1ca841444981b280cd upstream.
+
+Mapping an image with a long parent chain (e.g. image foo, whose parent
+is bar, whose parent is baz, etc) currently leads to a kernel stack
+overflow, due to the following recursion in the reply path:
+
+  rbd_osd_req_callback()
+    rbd_obj_request_complete()
+      rbd_img_obj_callback()
+        rbd_img_parent_read_callback()
+          rbd_obj_request_complete()
+            ...
+
+Limit the parent chain to 16 images, which is ~5K worth of stack.  When
+the above recursion is eliminated, this limit can be lifted.
+
+Fixes: http://tracker.ceph.com/issues/12538
+
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Reviewed-by: Josh Durgin <jdurgin@redhat.com>
+[idryomov@gmail.com: backport to 3.10: rbd_dev->opts, context]
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+
+---
+ drivers/block/rbd.c |   29 +++++++++++++++++++++--------
+ 1 file changed, 21 insertions(+), 8 deletions(-)
+
+--- a/drivers/block/rbd.c
++++ b/drivers/block/rbd.c
+@@ -93,6 +93,8 @@ static int atomic_dec_return_safe(atomic
+ #define RBD_MINORS_PER_MAJOR  256             /* max minors per blkdev */
++#define RBD_MAX_PARENT_CHAIN_LEN      16
++
+ #define RBD_SNAP_DEV_NAME_PREFIX      "snap_"
+ #define RBD_MAX_SNAP_NAME_LEN \
+                       (NAME_MAX - (sizeof (RBD_SNAP_DEV_NAME_PREFIX) - 1))
+@@ -394,7 +396,7 @@ static ssize_t rbd_add(struct bus_type *
+                      size_t count);
+ static ssize_t rbd_remove(struct bus_type *bus, const char *buf,
+                         size_t count);
+-static int rbd_dev_image_probe(struct rbd_device *rbd_dev, bool mapping);
++static int rbd_dev_image_probe(struct rbd_device *rbd_dev, int depth);
+ static void rbd_spec_put(struct rbd_spec *spec);
+ static struct bus_attribute rbd_bus_attrs[] = {
+@@ -4831,7 +4833,12 @@ out_err:
+       return ret;
+ }
+-static int rbd_dev_probe_parent(struct rbd_device *rbd_dev)
++/*
++ * @depth is rbd_dev_image_probe() -> rbd_dev_probe_parent() ->
++ * rbd_dev_image_probe() recursion depth, which means it's also the
++ * length of the already discovered part of the parent chain.
++ */
++static int rbd_dev_probe_parent(struct rbd_device *rbd_dev, int depth)
+ {
+       struct rbd_device *parent = NULL;
+       int ret;
+@@ -4839,6 +4846,12 @@ static int rbd_dev_probe_parent(struct r
+       if (!rbd_dev->parent_spec)
+               return 0;
++      if (++depth > RBD_MAX_PARENT_CHAIN_LEN) {
++              pr_info("parent chain is too long (%d)\n", depth);
++              ret = -EINVAL;
++              goto out_err;
++      }
++
+       parent = rbd_dev_create(rbd_dev->rbd_client, rbd_dev->parent_spec);
+       if (!parent) {
+               ret = -ENOMEM;
+@@ -4852,7 +4865,7 @@ static int rbd_dev_probe_parent(struct r
+       __rbd_get_client(rbd_dev->rbd_client);
+       rbd_spec_get(rbd_dev->parent_spec);
+-      ret = rbd_dev_image_probe(parent, false);
++      ret = rbd_dev_image_probe(parent, depth);
+       if (ret < 0)
+               goto out_err;
+@@ -4969,7 +4982,7 @@ static void rbd_dev_image_release(struct
+  * parent), initiate a watch on its header object before using that
+  * object to get detailed information about the rbd image.
+  */
+-static int rbd_dev_image_probe(struct rbd_device *rbd_dev, bool mapping)
++static int rbd_dev_image_probe(struct rbd_device *rbd_dev, int depth)
+ {
+       int ret;
+       int tmp;
+@@ -4990,7 +5003,7 @@ static int rbd_dev_image_probe(struct rb
+       if (ret)
+               goto err_out_format;
+-      if (mapping) {
++      if (!depth) {
+               ret = rbd_dev_header_watch_sync(rbd_dev, true);
+               if (ret)
+                       goto out_header_name;
+@@ -5007,7 +5020,7 @@ static int rbd_dev_image_probe(struct rb
+       if (ret)
+               goto err_out_probe;
+-      ret = rbd_dev_probe_parent(rbd_dev);
++      ret = rbd_dev_probe_parent(rbd_dev, depth);
+       if (ret)
+               goto err_out_probe;
+@@ -5018,7 +5031,7 @@ static int rbd_dev_image_probe(struct rb
+ err_out_probe:
+       rbd_dev_unprobe(rbd_dev);
+ err_out_watch:
+-      if (mapping) {
++      if (!depth) {
+               tmp = rbd_dev_header_watch_sync(rbd_dev, false);
+               if (tmp)
+                       rbd_warn(rbd_dev, "unable to tear down "
+@@ -5089,7 +5102,7 @@ static ssize_t rbd_add(struct bus_type *
+       rbdc = NULL;            /* rbd_dev now owns this */
+       spec = NULL;            /* rbd_dev now owns this */
+-      rc = rbd_dev_image_probe(rbd_dev, true);
++      rc = rbd_dev_image_probe(rbd_dev, 0);
+       if (rc < 0)
+               goto err_out_rbd_dev;
diff --git a/queue-3.10/rbd-require-stable-pages-if-message-data-crcs-are-enabled.patch b/queue-3.10/rbd-require-stable-pages-if-message-data-crcs-are-enabled.patch
new file mode 100644 (file)
index 0000000..9d2cf94
--- /dev/null
@@ -0,0 +1,46 @@
+From bae818ee1577c27356093901a0ea48f672eda514 Mon Sep 17 00:00:00 2001
+From: Ronny Hegewald <ronny.hegewald@online.de>
+Date: Thu, 15 Oct 2015 18:50:46 +0000
+Subject: rbd: require stable pages if message data CRCs are enabled
+
+From: Ronny Hegewald <ronny.hegewald@online.de>
+
+commit bae818ee1577c27356093901a0ea48f672eda514 upstream.
+
+rbd requires stable pages, as it performs a crc of the page data before
+they are send to the OSDs.
+
+But since kernel 3.9 (patch 1d1d1a767206fbe5d4c69493b7e6d2a8d08cc0a0
+"mm: only enforce stable page writes if the backing device requires
+it") it is not assumed anymore that block devices require stable pages.
+
+This patch sets the necessary flag to get stable pages back for rbd.
+
+In a ceph installation that provides multiple ext4 formatted rbd
+devices "bad crc" messages appeared regularly (ca 1 message every 1-2
+minutes on every OSD that provided the data for the rbd) in the
+OSD-logs before this patch. After this patch this messages are pretty
+much gone (only ca 1-2 / month / OSD).
+
+Signed-off-by: Ronny Hegewald <Ronny.Hegewald@online.de>
+[idryomov@gmail.com: require stable pages only in crc case, changelog]
+[idryomov@gmail.com: backport to 3.9-3.17: context]
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/block/rbd.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/block/rbd.c
++++ b/drivers/block/rbd.c
+@@ -3453,6 +3453,9 @@ static int rbd_init_disk(struct rbd_devi
+       blk_queue_io_opt(q, segment_size);
+       blk_queue_merge_bvec(q, rbd_merge_bvec);
++      if (!ceph_test_opt(rbd_dev->rbd_client->client, NOCRC))
++              q->backing_dev_info.capabilities |= BDI_CAP_STABLE_WRITES;
++
+       disk->queue = q;
+       q->queuedata = rbd_dev;
index 5a4fc68362b6f41114f9e9b80fffbee94e9fc532..b9105f0af4becb1c14560c1771a4c1fa16bca2e0 100644 (file)
@@ -7,3 +7,6 @@ asoc-wm8904-correct-number-of-eq-registers.patch
 x86-setup-extend-low-identity-map-to-cover-whole-kernel-range.patch
 mm-make-sendfile-2-killable.patch
 drm-nouveau-gem-return-only-valid-domain-when-there-s-only-one.patch
+rbd-require-stable-pages-if-message-data-crcs-are-enabled.patch
+rbd-don-t-leak-parent_spec-in-rbd_dev_probe_parent.patch
+rbd-prevent-kernel-stack-blow-up-on-rbd-map.patch