]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 9 Feb 2014 00:10:52 +0000 (16:10 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 9 Feb 2014 00:10:52 +0000 (16:10 -0800)
added patches:
dm-space-map-common-make-sure-new-space-is-used-during-extend.patch
dm-wait-until-embedded-kobject-is-released-before-destroying-a-device.patch

queue-3.4/dm-space-map-common-make-sure-new-space-is-used-during-extend.patch [new file with mode: 0644]
queue-3.4/dm-wait-until-embedded-kobject-is-released-before-destroying-a-device.patch [new file with mode: 0644]
queue-3.4/series

diff --git a/queue-3.4/dm-space-map-common-make-sure-new-space-is-used-during-extend.patch b/queue-3.4/dm-space-map-common-make-sure-new-space-is-used-during-extend.patch
new file mode 100644 (file)
index 0000000..01aa47d
--- /dev/null
@@ -0,0 +1,55 @@
+From 12c91a5c2d2a8e8cc40a9552313e1e7b0a2d9ee3 Mon Sep 17 00:00:00 2001
+From: Joe Thornber <ejt@redhat.com>
+Date: Tue, 7 Jan 2014 15:47:59 +0000
+Subject: dm space map common: make sure new space is used during extend
+
+From: Joe Thornber <ejt@redhat.com>
+
+commit 12c91a5c2d2a8e8cc40a9552313e1e7b0a2d9ee3 upstream.
+
+When extending a low level space map we should update nr_blocks at
+the start so the new space is used for the index entries.
+
+Otherwise extend can fail, e.g.: sm_metadata_extend call sequence
+that fails:
+ -> sm_ll_extend
+    -> dm_tm_new_block -> dm_sm_new_block -> sm_bootstrap_new_block
+    => returns -ENOSPC because smm->begin == smm->ll.nr_blocks
+
+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/persistent-data/dm-space-map-common.c |    6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/drivers/md/persistent-data/dm-space-map-common.c
++++ b/drivers/md/persistent-data/dm-space-map-common.c
+@@ -244,6 +244,10 @@ int sm_ll_extend(struct ll_disk *ll, dm_
+               return -EINVAL;
+       }
++      /*
++       * We need to set this before the dm_tm_new_block() call below.
++       */
++      ll->nr_blocks = nr_blocks;
+       for (i = old_blocks; i < blocks; i++) {
+               struct dm_block *b;
+               struct disk_index_entry idx;
+@@ -251,6 +255,7 @@ int sm_ll_extend(struct ll_disk *ll, dm_
+               r = dm_tm_new_block(ll->tm, &dm_sm_bitmap_validator, &b);
+               if (r < 0)
+                       return r;
++
+               idx.blocknr = cpu_to_le64(dm_block_location(b));
+               r = dm_tm_unlock(ll->tm, b);
+@@ -265,7 +270,6 @@ int sm_ll_extend(struct ll_disk *ll, dm_
+                       return r;
+       }
+-      ll->nr_blocks = nr_blocks;
+       return 0;
+ }
diff --git a/queue-3.4/dm-wait-until-embedded-kobject-is-released-before-destroying-a-device.patch b/queue-3.4/dm-wait-until-embedded-kobject-is-released-before-destroying-a-device.patch
new file mode 100644 (file)
index 0000000..4f1ece3
--- /dev/null
@@ -0,0 +1,125 @@
+From be35f486108227e10fe5d96fd42fb2b344c59983 Mon Sep 17 00:00:00 2001
+From: Mikulas Patocka <mpatocka@redhat.com>
+Date: Mon, 6 Jan 2014 23:01:22 -0500
+Subject: dm: wait until embedded kobject is released before destroying a device
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+commit be35f486108227e10fe5d96fd42fb2b344c59983 upstream.
+
+There may be other parts of the kernel holding a reference on the dm
+kobject.  We must wait until all references are dropped before
+deallocating the mapped_device structure.
+
+The dm_kobject_release method signals that all references are dropped
+via completion.  But dm_kobject_release doesn't free the kobject (which
+is embedded in the mapped_device structure).
+
+This is the sequence of operations:
+* when destroying a DM device, call kobject_put from dm_sysfs_exit
+* wait until all users stop using the kobject, when it happens the
+  release method is called
+* the release method signals the completion and should return without
+  delay
+* the dm device removal code that waits on the completion continues
+* the dm device removal code drops the dm_mod reference the device had
+* the dm device removal code frees the mapped_device structure that
+  contains the kobject
+
+Using kobject this way should avoid the module unload race that was
+mentioned at the beginning of this thread:
+https://lkml.org/lkml/2014/1/4/83
+
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/dm-sysfs.c |   10 +++++++++-
+ drivers/md/dm.c       |   11 +++++++++++
+ drivers/md/dm.h       |    2 ++
+ 3 files changed, 22 insertions(+), 1 deletion(-)
+
+--- a/drivers/md/dm-sysfs.c
++++ b/drivers/md/dm-sysfs.c
+@@ -79,6 +79,11 @@ static const struct sysfs_ops dm_sysfs_o
+       .show   = dm_attr_show,
+ };
++static void dm_kobject_release(struct kobject *kobj)
++{
++      complete(dm_get_completion_from_kobject(kobj));
++}
++
+ /*
+  * dm kobject is embedded in mapped_device structure
+  * no need to define release function here
+@@ -86,6 +91,7 @@ static const struct sysfs_ops dm_sysfs_o
+ static struct kobj_type dm_ktype = {
+       .sysfs_ops      = &dm_sysfs_ops,
+       .default_attrs  = dm_attrs,
++      .release        = dm_kobject_release,
+ };
+ /*
+@@ -104,5 +110,7 @@ int dm_sysfs_init(struct mapped_device *
+  */
+ void dm_sysfs_exit(struct mapped_device *md)
+ {
+-      kobject_put(dm_kobject(md));
++      struct kobject *kobj = dm_kobject(md);
++      kobject_put(kobj);
++      wait_for_completion(dm_get_completion_from_kobject(kobj));
+ }
+--- a/drivers/md/dm.c
++++ b/drivers/md/dm.c
+@@ -194,6 +194,9 @@ struct mapped_device {
+       /* sysfs handle */
+       struct kobject kobj;
++      /* wait until the kobject is released */
++      struct completion kobj_completion;
++
+       /* zero-length flush that will be cloned and submitted to targets */
+       struct bio flush_bio;
+ };
+@@ -1891,6 +1894,7 @@ static struct mapped_device *alloc_dev(i
+       init_waitqueue_head(&md->wait);
+       INIT_WORK(&md->work, dm_wq_work);
+       init_waitqueue_head(&md->eventq);
++      init_completion(&md->kobj_completion);
+       md->disk->major = _major;
+       md->disk->first_minor = minor;
+@@ -2705,6 +2709,13 @@ struct mapped_device *dm_get_from_kobjec
+       return md;
+ }
++struct completion *dm_get_completion_from_kobject(struct kobject *kobj)
++{
++      struct mapped_device *md = container_of(kobj, struct mapped_device, kobj);
++
++      return &md->kobj_completion;
++}
++
+ int dm_suspended_md(struct mapped_device *md)
+ {
+       return test_bit(DMF_SUSPENDED, &md->flags);
+--- a/drivers/md/dm.h
++++ b/drivers/md/dm.h
+@@ -15,6 +15,7 @@
+ #include <linux/list.h>
+ #include <linux/blkdev.h>
+ #include <linux/hdreg.h>
++#include <linux/completion.h>
+ /*
+  * Suspend feature flags
+@@ -123,6 +124,7 @@ int dm_sysfs_init(struct mapped_device *
+ void dm_sysfs_exit(struct mapped_device *md);
+ struct kobject *dm_kobject(struct mapped_device *md);
+ struct mapped_device *dm_get_from_kobject(struct kobject *kobj);
++struct completion *dm_get_completion_from_kobject(struct kobject *kobj);
+ /*
+  * Targets for linear and striped mappings
index 5e70e849904f2e9f20afdac0b2a1a803d8afb08f..afbcb0549bf77d46ff99428d0989c7fe2b031114 100644 (file)
@@ -12,3 +12,5 @@ spidev-fix-hang-when-transfer_one_message-fails.patch
 nfsv4-open-must-handle-the-nfs4err_io-return-code-correctly.patch
 nfs4.1-properly-handle-enotsup-in-secinfo_no_name.patch
 sunrpc-fix-infinite-loop-in-rpc-state-machine.patch
+dm-wait-until-embedded-kobject-is-released-before-destroying-a-device.patch
+dm-space-map-common-make-sure-new-space-is-used-during-extend.patch