From: Greg Kroah-Hartman Date: Fri, 6 Nov 2015 05:53:51 +0000 (-0800) Subject: 3.10-stable patches X-Git-Tag: v3.10.93~30 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=af69e668632c9ade57a880513158500025e45638;p=thirdparty%2Fkernel%2Fstable-queue.git 3.10-stable patches 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 --- 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 index 00000000000..c100e08c27d --- /dev/null +++ b/queue-3.10/rbd-don-t-leak-parent_spec-in-rbd_dev_probe_parent.patch @@ -0,0 +1,87 @@ +From 1f2c6651f69c14d0d3a9cfbda44ea101b02160ba Mon Sep 17 00:00:00 2001 +From: Ilya Dryomov +Date: Sun, 11 Oct 2015 19:38:00 +0200 +Subject: rbd: don't leak parent_spec in rbd_dev_probe_parent() + +From: Ilya Dryomov + +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: backport to < 4.2: rbd_dev->opts] +Reviewed-by: Alex Elder +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..d148e1c6ca2 --- /dev/null +++ b/queue-3.10/rbd-prevent-kernel-stack-blow-up-on-rbd-map.patch @@ -0,0 +1,136 @@ +From 6d69bb536bac0d403d83db1ca841444981b280cd Mon Sep 17 00:00:00 2001 +From: Ilya Dryomov +Date: Sun, 11 Oct 2015 19:38:00 +0200 +Subject: rbd: prevent kernel stack blow up on rbd map + +From: Ilya Dryomov + +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 +Reviewed-by: Josh Durgin +[idryomov@gmail.com: backport to 3.10: rbd_dev->opts, context] +Signed-off-by: Greg Kroah-Hartman + + +--- + 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 index 00000000000..9d2cf94c75c --- /dev/null +++ b/queue-3.10/rbd-require-stable-pages-if-message-data-crcs-are-enabled.patch @@ -0,0 +1,46 @@ +From bae818ee1577c27356093901a0ea48f672eda514 Mon Sep 17 00:00:00 2001 +From: Ronny Hegewald +Date: Thu, 15 Oct 2015 18:50:46 +0000 +Subject: rbd: require stable pages if message data CRCs are enabled + +From: Ronny Hegewald + +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 +[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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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; diff --git a/queue-3.10/series b/queue-3.10/series index 5a4fc68362b..b9105f0af4b 100644 --- a/queue-3.10/series +++ b/queue-3.10/series @@ -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