From: Greg Kroah-Hartman Date: Wed, 18 Dec 2013 19:36:44 +0000 (-0800) Subject: 3.12-stable patches X-Git-Tag: v3.4.75~19 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4b6d47179d0b03e4e425aa86ad7a9009187da1e7;p=thirdparty%2Fkernel%2Fstable-queue.git 3.12-stable patches added patches: btrfs-call-mnt_drop_write-after-interrupted-subvol-deletion.patch btrfs-fix-access_ok-check-in-btrfs_ioctl_send.patch dm-array-fix-a-reference-counting-bug-in-shadow_ablock.patch dm-bufio-initialize-read-only-module-parameters.patch dm-delay-fix-a-possible-deadlock-due-to-shared-workqueue.patch dm-snapshot-avoid-snapshot-space-leak-on-crash.patch dm-space-map-disallow-decrementing-a-reference-count-below-zero.patch dm-space-map-metadata-return-on-failure-in-sm_metadata_new_block.patch dm-stats-initialize-read-only-module-parameter.patch dm-table-fail-dm_table_create-on-dm_round_up-overflow.patch dm-thin-allow-pool-in-read-only-mode-to-transition-to-read-write-mode.patch dm-thin-always-fallback-the-pool-mode-if-commit-fails.patch dm-thin-re-establish-read-only-state-when-switching-to-fail-mode.patch dm-thin-switch-to-read-only-mode-if-a-mapping-insert-fails.patch dm-thin-switch-to-read-only-mode-if-metadata-space-is-exhausted.patch media-af9033-fix-broken-i2c.patch media-af9035-add-leadtek-winfast-dtv-dongle-dual.patch media-af9035-unlock-on-error-in-af9035_i2c_master_xfer.patch media-bttv-don-t-setup-the-controls-if-there-are-no-video-devices.patch media-saa7164-fix-return-value-check-in-saa7164_initdev.patch media-tef6862-radio-tea5764-actually-assign-clamp-result.patch media-wm8775-fix-broken-audio-routing.patch --- diff --git a/queue-3.12/btrfs-call-mnt_drop_write-after-interrupted-subvol-deletion.patch b/queue-3.12/btrfs-call-mnt_drop_write-after-interrupted-subvol-deletion.patch new file mode 100644 index 00000000000..1d047ca5799 --- /dev/null +++ b/queue-3.12/btrfs-call-mnt_drop_write-after-interrupted-subvol-deletion.patch @@ -0,0 +1,40 @@ +From e43f998e47bae27e37e159915625e8d4b130153b Mon Sep 17 00:00:00 2001 +From: David Sterba +Date: Fri, 6 Dec 2013 17:51:32 +0100 +Subject: btrfs: call mnt_drop_write after interrupted subvol deletion + +From: David Sterba + +commit e43f998e47bae27e37e159915625e8d4b130153b upstream. + +If btrfs_ioctl_snap_destroy blocks on the mutex and the process is +killed, mnt_write count is unbalanced and leads to unmountable +filesystem. + +Signed-off-by: David Sterba +Signed-off-by: Chris Mason +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/ioctl.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/fs/btrfs/ioctl.c ++++ b/fs/btrfs/ioctl.c +@@ -2130,7 +2130,7 @@ static noinline int btrfs_ioctl_snap_des + + err = mutex_lock_killable_nested(&dir->i_mutex, I_MUTEX_PARENT); + if (err == -EINTR) +- goto out; ++ goto out_drop_write; + dentry = lookup_one_len(vol_args->name, parent, namelen); + if (IS_ERR(dentry)) { + err = PTR_ERR(dentry); +@@ -2293,6 +2293,7 @@ out_dput: + dput(dentry); + out_unlock_dir: + mutex_unlock(&dir->i_mutex); ++out_drop_write: + mnt_drop_write_file(file); + out: + kfree(vol_args); diff --git a/queue-3.12/btrfs-fix-access_ok-check-in-btrfs_ioctl_send.patch b/queue-3.12/btrfs-fix-access_ok-check-in-btrfs_ioctl_send.patch new file mode 100644 index 00000000000..f81ae2500e1 --- /dev/null +++ b/queue-3.12/btrfs-fix-access_ok-check-in-btrfs_ioctl_send.patch @@ -0,0 +1,35 @@ +From 700ff4f095d78af0998953e922e041d75254518b Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Thu, 10 Jan 2013 03:57:25 -0500 +Subject: Btrfs: fix access_ok() check in btrfs_ioctl_send() + +From: Dan Carpenter + +commit 700ff4f095d78af0998953e922e041d75254518b upstream. + +The closing parenthesis is in the wrong place. We want to check +"sizeof(*arg->clone_sources) * arg->clone_sources_count" instead of +"sizeof(*arg->clone_sources * arg->clone_sources_count)". + +Signed-off-by: Dan Carpenter +Reviewed-by: Jie Liu +Signed-off-by: Chris Mason +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/send.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/fs/btrfs/send.c ++++ b/fs/btrfs/send.c +@@ -4756,8 +4756,8 @@ long btrfs_ioctl_send(struct file *mnt_f + } + + if (!access_ok(VERIFY_READ, arg->clone_sources, +- sizeof(*arg->clone_sources * +- arg->clone_sources_count))) { ++ sizeof(*arg->clone_sources) * ++ arg->clone_sources_count)) { + ret = -EFAULT; + goto out; + } diff --git a/queue-3.12/dm-array-fix-a-reference-counting-bug-in-shadow_ablock.patch b/queue-3.12/dm-array-fix-a-reference-counting-bug-in-shadow_ablock.patch new file mode 100644 index 00000000000..0f791b33c8b --- /dev/null +++ b/queue-3.12/dm-array-fix-a-reference-counting-bug-in-shadow_ablock.patch @@ -0,0 +1,43 @@ +From ed9571f0cf1fe09d3506302610f3ccdfa1d22c4a Mon Sep 17 00:00:00 2001 +From: Joe Thornber +Date: Fri, 13 Dec 2013 14:55:55 +0000 +Subject: dm array: fix a reference counting bug in shadow_ablock + +From: Joe Thornber + +commit ed9571f0cf1fe09d3506302610f3ccdfa1d22c4a upstream. + +An old array block could have its reference count decremented below +zero when it is being replaced in the btree by a new array block. + +The fix is to increment the old ablock's reference count just before +inserting a new ablock into the btree. + +Signed-off-by: Joe Thornber +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/persistent-data/dm-array.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +--- a/drivers/md/persistent-data/dm-array.c ++++ b/drivers/md/persistent-data/dm-array.c +@@ -317,8 +317,16 @@ static int shadow_ablock(struct dm_array + * The shadow op will often be a noop. Only insert if it really + * copied data. + */ +- if (dm_block_location(*block) != b) ++ if (dm_block_location(*block) != b) { ++ /* ++ * dm_tm_shadow_block will have already decremented the old ++ * block, but it is still referenced by the btree. We ++ * increment to stop the insert decrementing it below zero ++ * when overwriting the old value. ++ */ ++ dm_tm_inc(info->btree_info.tm, b); + r = insert_ablock(info, index, *block, root); ++ } + + return r; + } diff --git a/queue-3.12/dm-bufio-initialize-read-only-module-parameters.patch b/queue-3.12/dm-bufio-initialize-read-only-module-parameters.patch new file mode 100644 index 00000000000..c097520b897 --- /dev/null +++ b/queue-3.12/dm-bufio-initialize-read-only-module-parameters.patch @@ -0,0 +1,45 @@ +From 4cb57ab4a2e61978f3a9b7d4f53988f30d61c27f Mon Sep 17 00:00:00 2001 +From: Mikulas Patocka +Date: Thu, 5 Dec 2013 17:33:29 -0500 +Subject: dm bufio: initialize read-only module parameters + +From: Mikulas Patocka + +commit 4cb57ab4a2e61978f3a9b7d4f53988f30d61c27f upstream. + +Some module parameters in dm-bufio are read-only. These parameters +inform the user about memory consumption. They are not supposed to be +changed by the user. + +However, despite being read-only, these parameters can be set on +modprobe or insmod command line, for example: +modprobe dm-bufio current_allocated_bytes=12345 + +The kernel doesn't expect that these variables can be non-zero at module +initialization and if the user sets them, it results in BUG. + +This patch initializes the variables in the module init routine, so that +user-supplied values are ignored. + +Signed-off-by: Mikulas Patocka +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/dm-bufio.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/md/dm-bufio.c ++++ b/drivers/md/dm-bufio.c +@@ -1717,6 +1717,11 @@ static int __init dm_bufio_init(void) + { + __u64 mem; + ++ dm_bufio_allocated_kmem_cache = 0; ++ dm_bufio_allocated_get_free_pages = 0; ++ dm_bufio_allocated_vmalloc = 0; ++ dm_bufio_current_allocated = 0; ++ + memset(&dm_bufio_caches, 0, sizeof dm_bufio_caches); + memset(&dm_bufio_cache_names, 0, sizeof dm_bufio_cache_names); + diff --git a/queue-3.12/dm-delay-fix-a-possible-deadlock-due-to-shared-workqueue.patch b/queue-3.12/dm-delay-fix-a-possible-deadlock-due-to-shared-workqueue.patch new file mode 100644 index 00000000000..b297e79181f --- /dev/null +++ b/queue-3.12/dm-delay-fix-a-possible-deadlock-due-to-shared-workqueue.patch @@ -0,0 +1,110 @@ +From 718822c1c112dc99e0c72c8968ee1db9d9d910f0 Mon Sep 17 00:00:00 2001 +From: Mikulas Patocka +Date: Fri, 15 Nov 2013 16:12:20 -0500 +Subject: dm delay: fix a possible deadlock due to shared workqueue + +From: Mikulas Patocka + +commit 718822c1c112dc99e0c72c8968ee1db9d9d910f0 upstream. + +The dm-delay target uses a shared workqueue for multiple instances. This +can cause deadlock if two or more dm-delay targets are stacked on the top +of each other. + +This patch changes dm-delay to use a per-instance workqueue. + +Signed-off-by: Mikulas Patocka +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/dm-delay.c | 23 +++++++++++------------ + 1 file changed, 11 insertions(+), 12 deletions(-) + +--- a/drivers/md/dm-delay.c ++++ b/drivers/md/dm-delay.c +@@ -20,6 +20,7 @@ + struct delay_c { + struct timer_list delay_timer; + struct mutex timer_lock; ++ struct workqueue_struct *kdelayd_wq; + struct work_struct flush_expired_bios; + struct list_head delayed_bios; + atomic_t may_delay; +@@ -45,14 +46,13 @@ struct dm_delay_info { + + static DEFINE_MUTEX(delayed_bios_lock); + +-static struct workqueue_struct *kdelayd_wq; + static struct kmem_cache *delayed_cache; + + static void handle_delayed_timer(unsigned long data) + { + struct delay_c *dc = (struct delay_c *)data; + +- queue_work(kdelayd_wq, &dc->flush_expired_bios); ++ queue_work(dc->kdelayd_wq, &dc->flush_expired_bios); + } + + static void queue_timeout(struct delay_c *dc, unsigned long expires) +@@ -191,6 +191,12 @@ out: + goto bad_dev_write; + } + ++ dc->kdelayd_wq = alloc_workqueue("kdelayd", WQ_MEM_RECLAIM, 0); ++ if (!dc->kdelayd_wq) { ++ DMERR("Couldn't start kdelayd"); ++ goto bad_queue; ++ } ++ + setup_timer(&dc->delay_timer, handle_delayed_timer, (unsigned long)dc); + + INIT_WORK(&dc->flush_expired_bios, flush_expired_bios); +@@ -203,6 +209,8 @@ out: + ti->private = dc; + return 0; + ++bad_queue: ++ mempool_destroy(dc->delayed_pool); + bad_dev_write: + if (dc->dev_write) + dm_put_device(ti, dc->dev_write); +@@ -217,7 +225,7 @@ static void delay_dtr(struct dm_target * + { + struct delay_c *dc = ti->private; + +- flush_workqueue(kdelayd_wq); ++ destroy_workqueue(dc->kdelayd_wq); + + dm_put_device(ti, dc->dev_read); + +@@ -350,12 +358,6 @@ static int __init dm_delay_init(void) + { + int r = -ENOMEM; + +- kdelayd_wq = alloc_workqueue("kdelayd", WQ_MEM_RECLAIM, 0); +- if (!kdelayd_wq) { +- DMERR("Couldn't start kdelayd"); +- goto bad_queue; +- } +- + delayed_cache = KMEM_CACHE(dm_delay_info, 0); + if (!delayed_cache) { + DMERR("Couldn't create delayed bio cache."); +@@ -373,8 +375,6 @@ static int __init dm_delay_init(void) + bad_register: + kmem_cache_destroy(delayed_cache); + bad_memcache: +- destroy_workqueue(kdelayd_wq); +-bad_queue: + return r; + } + +@@ -382,7 +382,6 @@ static void __exit dm_delay_exit(void) + { + dm_unregister_target(&delay_target); + kmem_cache_destroy(delayed_cache); +- destroy_workqueue(kdelayd_wq); + } + + /* Module hooks */ diff --git a/queue-3.12/dm-snapshot-avoid-snapshot-space-leak-on-crash.patch b/queue-3.12/dm-snapshot-avoid-snapshot-space-leak-on-crash.patch new file mode 100644 index 00000000000..542c8876a1f --- /dev/null +++ b/queue-3.12/dm-snapshot-avoid-snapshot-space-leak-on-crash.patch @@ -0,0 +1,194 @@ +From 230c83afdd9cd384348475bea1e14b80b3b6b1b8 Mon Sep 17 00:00:00 2001 +From: Mikulas Patocka +Date: Fri, 29 Nov 2013 18:13:37 -0500 +Subject: dm snapshot: avoid snapshot space leak on crash + +From: Mikulas Patocka + +commit 230c83afdd9cd384348475bea1e14b80b3b6b1b8 upstream. + +There is a possible leak of snapshot space in case of crash. + +The reason for space leaking is that chunks in the snapshot device are +allocated sequentially, but they are finished (and stored in the metadata) +out of order, depending on the order in which copying finished. + +For example, supposed that the metadata contains the following records +SUPERBLOCK +METADATA (blocks 0 ... 250) +DATA 0 +DATA 1 +DATA 2 +... +DATA 250 + +Now suppose that you allocate 10 new data blocks 251-260. Suppose that +copying of these blocks finish out of order (block 260 finished first +and the block 251 finished last). Now, the snapshot device looks like +this: +SUPERBLOCK +METADATA (blocks 0 ... 250, 260, 259, 258, 257, 256) +DATA 0 +DATA 1 +DATA 2 +... +DATA 250 +DATA 251 +DATA 252 +DATA 253 +DATA 254 +DATA 255 +METADATA (blocks 255, 254, 253, 252, 251) +DATA 256 +DATA 257 +DATA 258 +DATA 259 +DATA 260 + +Now, if the machine crashes after writing the first metadata block but +before writing the second metadata block, the space for areas DATA 250-255 +is leaked, it contains no valid data and it will never be used in the +future. + +This patch makes dm-snapshot complete exceptions in the same order they +were allocated, thus fixing this bug. + +Note: when backporting this patch to the stable kernel, change the version +field in the following way: +* if version in the stable kernel is {1, 11, 1}, change it to {1, 12, 0} +* if version in the stable kernel is {1, 10, 0} or {1, 10, 1}, change it + to {1, 10, 2} +Userspace reads the version to determine if the bug was fixed, so the +version change is needed. + +Signed-off-by: Mikulas Patocka +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/dm-snap.c | 71 +++++++++++++++++++++++++++++++++++++++++++++------ + 1 file changed, 64 insertions(+), 7 deletions(-) + +--- a/drivers/md/dm-snap.c ++++ b/drivers/md/dm-snap.c +@@ -66,6 +66,18 @@ struct dm_snapshot { + + atomic_t pending_exceptions_count; + ++ /* Protected by "lock" */ ++ sector_t exception_start_sequence; ++ ++ /* Protected by kcopyd single-threaded callback */ ++ sector_t exception_complete_sequence; ++ ++ /* ++ * A list of pending exceptions that completed out of order. ++ * Protected by kcopyd single-threaded callback. ++ */ ++ struct list_head out_of_order_list; ++ + mempool_t *pending_pool; + + struct dm_exception_table pending; +@@ -173,6 +185,14 @@ struct dm_snap_pending_exception { + */ + int started; + ++ /* There was copying error. */ ++ int copy_error; ++ ++ /* A sequence number, it is used for in-order completion. */ ++ sector_t exception_sequence; ++ ++ struct list_head out_of_order_entry; ++ + /* + * For writing a complete chunk, bypassing the copy. + */ +@@ -1094,6 +1114,9 @@ static int snapshot_ctr(struct dm_target + s->valid = 1; + s->active = 0; + atomic_set(&s->pending_exceptions_count, 0); ++ s->exception_start_sequence = 0; ++ s->exception_complete_sequence = 0; ++ INIT_LIST_HEAD(&s->out_of_order_list); + init_rwsem(&s->lock); + INIT_LIST_HEAD(&s->list); + spin_lock_init(&s->pe_lock); +@@ -1443,6 +1466,19 @@ static void commit_callback(void *contex + pending_complete(pe, success); + } + ++static void complete_exception(struct dm_snap_pending_exception *pe) ++{ ++ struct dm_snapshot *s = pe->snap; ++ ++ if (unlikely(pe->copy_error)) ++ pending_complete(pe, 0); ++ ++ else ++ /* Update the metadata if we are persistent */ ++ s->store->type->commit_exception(s->store, &pe->e, ++ commit_callback, pe); ++} ++ + /* + * Called when the copy I/O has finished. kcopyd actually runs + * this code so don't block. +@@ -1452,13 +1488,32 @@ static void copy_callback(int read_err, + struct dm_snap_pending_exception *pe = context; + struct dm_snapshot *s = pe->snap; + +- if (read_err || write_err) +- pending_complete(pe, 0); ++ pe->copy_error = read_err || write_err; + +- else +- /* Update the metadata if we are persistent */ +- s->store->type->commit_exception(s->store, &pe->e, +- commit_callback, pe); ++ if (pe->exception_sequence == s->exception_complete_sequence) { ++ s->exception_complete_sequence++; ++ complete_exception(pe); ++ ++ while (!list_empty(&s->out_of_order_list)) { ++ pe = list_entry(s->out_of_order_list.next, ++ struct dm_snap_pending_exception, out_of_order_entry); ++ if (pe->exception_sequence != s->exception_complete_sequence) ++ break; ++ s->exception_complete_sequence++; ++ list_del(&pe->out_of_order_entry); ++ complete_exception(pe); ++ } ++ } else { ++ struct list_head *lh; ++ struct dm_snap_pending_exception *pe2; ++ ++ list_for_each_prev(lh, &s->out_of_order_list) { ++ pe2 = list_entry(lh, struct dm_snap_pending_exception, out_of_order_entry); ++ if (pe2->exception_sequence < pe->exception_sequence) ++ break; ++ } ++ list_add(&pe->out_of_order_entry, lh); ++ } + } + + /* +@@ -1553,6 +1608,8 @@ __find_pending_exception(struct dm_snaps + return NULL; + } + ++ pe->exception_sequence = s->exception_start_sequence++; ++ + dm_insert_exception(&s->pending, &pe->e); + + return pe; +@@ -2192,7 +2249,7 @@ static struct target_type origin_target + + static struct target_type snapshot_target = { + .name = "snapshot", +- .version = {1, 11, 1}, ++ .version = {1, 12, 0}, + .module = THIS_MODULE, + .ctr = snapshot_ctr, + .dtr = snapshot_dtr, diff --git a/queue-3.12/dm-space-map-disallow-decrementing-a-reference-count-below-zero.patch b/queue-3.12/dm-space-map-disallow-decrementing-a-reference-count-below-zero.patch new file mode 100644 index 00000000000..999dc491570 --- /dev/null +++ b/queue-3.12/dm-space-map-disallow-decrementing-a-reference-count-below-zero.patch @@ -0,0 +1,108 @@ +From 5b564d80f8bc21094c0cd2b19b679d983aabcc29 Mon Sep 17 00:00:00 2001 +From: Joe Thornber +Date: Fri, 13 Dec 2013 12:31:08 +0000 +Subject: dm space map: disallow decrementing a reference count below zero + +From: Joe Thornber + +commit 5b564d80f8bc21094c0cd2b19b679d983aabcc29 upstream. + +The old behaviour, returning -EINVAL if a ref_count of 0 would be +decremented, was removed in commit f722063 ("dm space map: optimise +sm_ll_dec and sm_ll_inc"). To fix this regression we return an error +code from the mutator function pointer passed to sm_ll_mutate() and have +dec_ref_count() return -EINVAL if the old ref_count is 0. + +Add a DMERR to reflect the potential seriousness of this error. + +Also, add missing dm_tm_unlock() to sm_ll_mutate()'s error path. + +With this fix the following dmts regression test now passes: + dmtest run --suite cache -n /metadata_use_kernel/ + +The next patch fixes the higher-level dm-array code that exposed this +regression. + +Signed-off-by: Joe Thornber +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/persistent-data/dm-space-map-common.c | 32 ++++++++++++++++------- + 1 file changed, 23 insertions(+), 9 deletions(-) + +--- a/drivers/md/persistent-data/dm-space-map-common.c ++++ b/drivers/md/persistent-data/dm-space-map-common.c +@@ -381,7 +381,7 @@ int sm_ll_find_free_block(struct ll_disk + } + + static int sm_ll_mutate(struct ll_disk *ll, dm_block_t b, +- uint32_t (*mutator)(void *context, uint32_t old), ++ int (*mutator)(void *context, uint32_t old, uint32_t *new), + void *context, enum allocation_event *ev) + { + int r; +@@ -410,11 +410,17 @@ static int sm_ll_mutate(struct ll_disk * + + if (old > 2) { + r = sm_ll_lookup_big_ref_count(ll, b, &old); +- if (r < 0) ++ if (r < 0) { ++ dm_tm_unlock(ll->tm, nb); + return r; ++ } + } + +- ref_count = mutator(context, old); ++ r = mutator(context, old, &ref_count); ++ if (r) { ++ dm_tm_unlock(ll->tm, nb); ++ return r; ++ } + + if (ref_count <= 2) { + sm_set_bitmap(bm_le, bit, ref_count); +@@ -465,9 +471,10 @@ static int sm_ll_mutate(struct ll_disk * + return ll->save_ie(ll, index, &ie_disk); + } + +-static uint32_t set_ref_count(void *context, uint32_t old) ++static int set_ref_count(void *context, uint32_t old, uint32_t *new) + { +- return *((uint32_t *) context); ++ *new = *((uint32_t *) context); ++ return 0; + } + + int sm_ll_insert(struct ll_disk *ll, dm_block_t b, +@@ -476,9 +483,10 @@ int sm_ll_insert(struct ll_disk *ll, dm_ + return sm_ll_mutate(ll, b, set_ref_count, &ref_count, ev); + } + +-static uint32_t inc_ref_count(void *context, uint32_t old) ++static int inc_ref_count(void *context, uint32_t old, uint32_t *new) + { +- return old + 1; ++ *new = old + 1; ++ return 0; + } + + int sm_ll_inc(struct ll_disk *ll, dm_block_t b, enum allocation_event *ev) +@@ -486,9 +494,15 @@ int sm_ll_inc(struct ll_disk *ll, dm_blo + return sm_ll_mutate(ll, b, inc_ref_count, NULL, ev); + } + +-static uint32_t dec_ref_count(void *context, uint32_t old) ++static int dec_ref_count(void *context, uint32_t old, uint32_t *new) + { +- return old - 1; ++ if (!old) { ++ DMERR_LIMIT("unable to decrement a reference count below 0"); ++ return -EINVAL; ++ } ++ ++ *new = old - 1; ++ return 0; + } + + int sm_ll_dec(struct ll_disk *ll, dm_block_t b, enum allocation_event *ev) diff --git a/queue-3.12/dm-space-map-metadata-return-on-failure-in-sm_metadata_new_block.patch b/queue-3.12/dm-space-map-metadata-return-on-failure-in-sm_metadata_new_block.patch new file mode 100644 index 00000000000..d2c9f956c57 --- /dev/null +++ b/queue-3.12/dm-space-map-metadata-return-on-failure-in-sm_metadata_new_block.patch @@ -0,0 +1,95 @@ +From f62b6b8f498658a9d537c7d380e9966f15e1b2a1 Mon Sep 17 00:00:00 2001 +From: Mike Snitzer +Date: Mon, 2 Dec 2013 16:47:01 -0500 +Subject: dm space map metadata: return on failure in sm_metadata_new_block + +From: Mike Snitzer + +commit f62b6b8f498658a9d537c7d380e9966f15e1b2a1 upstream. + +Commit 2fc48021f4afdd109b9e52b6eef5db89ca80bac7 ("dm persistent +metadata: add space map threshold callback") introduced a regression +to the metadata block allocation path that resulted in errors being +ignored. This regression was uncovered by running the following +device-mapper-test-suite test: +dmtest run --suite thin-provisioning -n /exhausting_metadata_space_causes_fail_mode/ + +The ignored error codes in sm_metadata_new_block() could crash the +kernel through use of either the dm-thin or dm-cache targets, e.g.: + +device-mapper: thin: 253:4: reached low water mark for metadata device: sending event. +device-mapper: space map metadata: unable to allocate new metadata block +general protection fault: 0000 [#1] SMP +... +Workqueue: dm-thin do_worker [dm_thin_pool] +task: ffff880035ce2ab0 ti: ffff88021a054000 task.ti: ffff88021a054000 +RIP: 0010:[] [] metadata_ll_load_ie+0x15/0x30 [dm_persistent_data] +RSP: 0018:ffff88021a055a68 EFLAGS: 00010202 +RAX: 003fc8243d212ba0 RBX: ffff88021a780070 RCX: ffff88021a055a78 +RDX: ffff88021a055a78 RSI: 0040402222a92a80 RDI: ffff88021a780070 +RBP: ffff88021a055a68 R08: ffff88021a055ba4 R09: 0000000000000010 +R10: 0000000000000000 R11: 00000002a02e1000 R12: ffff88021a055ad4 +R13: 0000000000000598 R14: ffffffffa0338470 R15: ffff88021a055ba4 +FS: 0000000000000000(0000) GS:ffff88033fca0000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b +CR2: 00007f467c0291b8 CR3: 0000000001a0b000 CR4: 00000000000007e0 +Stack: + ffff88021a055ab8 ffffffffa0332020 ffff88021a055b30 0000000000000001 + ffff88021a055b30 0000000000000000 ffff88021a055b18 0000000000000000 + ffff88021a055ba4 ffff88021a055b98 ffff88021a055ae8 ffffffffa033304c +Call Trace: + [] sm_ll_lookup_bitmap+0x40/0xa0 [dm_persistent_data] + [] sm_metadata_count_is_more_than_one+0x8c/0xc0 [dm_persistent_data] + [] dm_tm_shadow_block+0x65/0x110 [dm_persistent_data] + [] sm_ll_mutate+0x80/0x300 [dm_persistent_data] + [] ? set_ref_count+0x10/0x10 [dm_persistent_data] + [] sm_ll_inc+0x1a/0x20 [dm_persistent_data] + [] sm_disk_new_block+0x60/0x80 [dm_persistent_data] + [] ? down_write+0x16/0x40 + [] dm_pool_alloc_data_block+0x54/0x80 [dm_thin_pool] + [] alloc_data_block+0x9c/0x130 [dm_thin_pool] + [] provision_block+0x4e/0x180 [dm_thin_pool] + [] ? dm_thin_find_block+0x6a/0x110 [dm_thin_pool] + [] process_bio+0x1ca/0x1f0 [dm_thin_pool] + [] ? mempool_free+0x8d/0xa0 + [] process_deferred_bios+0xc5/0x230 [dm_thin_pool] + [] do_worker+0x51/0x60 [dm_thin_pool] + [] process_one_work+0x182/0x3b0 + [] worker_thread+0x120/0x3a0 + [] ? manage_workers+0x160/0x160 + [] kthread+0xce/0xe0 + [] ? kthread_freezable_should_stop+0x70/0x70 + [] ret_from_fork+0x7c/0xb0 + [] ? kthread_freezable_should_stop+0x70/0x70 + [] ret_from_fork+0x7c/0xb0 + [] ? kthread_freezable_should_stop+0x70/0x70 + +Signed-off-by: Mike Snitzer +Acked-by: Joe Thornber +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/persistent-data/dm-space-map-metadata.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +--- a/drivers/md/persistent-data/dm-space-map-metadata.c ++++ b/drivers/md/persistent-data/dm-space-map-metadata.c +@@ -384,12 +384,16 @@ static int sm_metadata_new_block(struct + struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm); + + int r = sm_metadata_new_block_(sm, b); +- if (r) ++ if (r) { + DMERR("unable to allocate new metadata block"); ++ return r; ++ } + + r = sm_metadata_get_nr_free(sm, &count); +- if (r) ++ if (r) { + DMERR("couldn't get free block count"); ++ return r; ++ } + + check_threshold(&smm->threshold, count); + diff --git a/queue-3.12/dm-stats-initialize-read-only-module-parameter.patch b/queue-3.12/dm-stats-initialize-read-only-module-parameter.patch new file mode 100644 index 00000000000..b8051742954 --- /dev/null +++ b/queue-3.12/dm-stats-initialize-read-only-module-parameter.patch @@ -0,0 +1,41 @@ +From 76f5bee5c3b45c617f91243e85547fc8f67bc678 Mon Sep 17 00:00:00 2001 +From: Mikulas Patocka +Date: Thu, 5 Dec 2013 17:34:19 -0500 +Subject: dm stats: initialize read-only module parameter + +From: Mikulas Patocka + +commit 76f5bee5c3b45c617f91243e85547fc8f67bc678 upstream. + +The module parameter stats_current_allocated_bytes in dm-mod is +read-only. This parameter informs the user about memory +consumption. It is not supposed to be changed by the user. + +However, despite being read-only, this parameter can be set on +modprobe or insmod command line: +modprobe dm-mod stats_current_allocated_bytes=12345 + +The kernel doesn't expect that this variable can be non-zero at module +initialization and if the user sets it, it results in warning. + +This patch initializes the variable in the module init routine, so +that user-supplied value is ignored. + +Signed-off-by: Mikulas Patocka +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/dm-stats.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/md/dm-stats.c ++++ b/drivers/md/dm-stats.c +@@ -964,6 +964,7 @@ int dm_stats_message(struct mapped_devic + + int __init dm_statistics_init(void) + { ++ shared_memory_amount = 0; + dm_stat_need_rcu_barrier = 0; + return 0; + } diff --git a/queue-3.12/dm-table-fail-dm_table_create-on-dm_round_up-overflow.patch b/queue-3.12/dm-table-fail-dm_table_create-on-dm_round_up-overflow.patch new file mode 100644 index 00000000000..71a8712ab5c --- /dev/null +++ b/queue-3.12/dm-table-fail-dm_table_create-on-dm_round_up-overflow.patch @@ -0,0 +1,38 @@ +From 5b2d06576c5410c10d95adfd5c4d8b24de861d87 Mon Sep 17 00:00:00 2001 +From: Mikulas Patocka +Date: Fri, 22 Nov 2013 19:52:06 -0500 +Subject: dm table: fail dm_table_create on dm_round_up overflow + +From: Mikulas Patocka + +commit 5b2d06576c5410c10d95adfd5c4d8b24de861d87 upstream. + +The dm_round_up function may overflow to zero. In this case, +dm_table_create() must fail rather than go on to allocate an empty array +with alloc_targets(). + +This fixes a possible memory corruption that could be caused by passing +too large a number in "param->target_count". + +Signed-off-by: Mikulas Patocka +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/dm-table.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/md/dm-table.c ++++ b/drivers/md/dm-table.c +@@ -200,6 +200,11 @@ int dm_table_create(struct dm_table **re + + num_targets = dm_round_up(num_targets, KEYS_PER_NODE); + ++ if (!num_targets) { ++ kfree(t); ++ return -ENOMEM; ++ } ++ + if (alloc_targets(t, num_targets)) { + kfree(t); + return -ENOMEM; diff --git a/queue-3.12/dm-thin-allow-pool-in-read-only-mode-to-transition-to-read-write-mode.patch b/queue-3.12/dm-thin-allow-pool-in-read-only-mode-to-transition-to-read-write-mode.patch new file mode 100644 index 00000000000..3e39f280b0e --- /dev/null +++ b/queue-3.12/dm-thin-allow-pool-in-read-only-mode-to-transition-to-read-write-mode.patch @@ -0,0 +1,124 @@ +From 9b7aaa64f96f7ca280d75326fca42f42017b89ef Mon Sep 17 00:00:00 2001 +From: Joe Thornber +Date: Wed, 4 Dec 2013 16:58:19 -0500 +Subject: dm thin: allow pool in read-only mode to transition to read-write mode + +From: Joe Thornber + +commit 9b7aaa64f96f7ca280d75326fca42f42017b89ef upstream. + +A thin-pool may be in read-only mode because the pool's data or metadata +space was exhausted. To allow for recovery, by adding more space to the +pool, we must allow a pool to transition from PM_READ_ONLY to PM_WRITE +mode. Otherwise, running out of space will render the pool permanently +read-only. + +Signed-off-by: Joe Thornber +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/dm-thin-metadata.c | 8 ++++++++ + drivers/md/dm-thin-metadata.h | 1 + + drivers/md/dm-thin.c | 12 ++++++++++-- + drivers/md/persistent-data/dm-block-manager.c | 6 ++++++ + drivers/md/persistent-data/dm-block-manager.h | 7 ++++--- + 5 files changed, 29 insertions(+), 5 deletions(-) + +--- a/drivers/md/dm-thin-metadata.c ++++ b/drivers/md/dm-thin-metadata.c +@@ -1697,6 +1697,14 @@ void dm_pool_metadata_read_only(struct d + up_write(&pmd->root_lock); + } + ++void dm_pool_metadata_read_write(struct dm_pool_metadata *pmd) ++{ ++ down_write(&pmd->root_lock); ++ pmd->read_only = false; ++ dm_bm_set_read_write(pmd->bm); ++ up_write(&pmd->root_lock); ++} ++ + int dm_pool_register_metadata_threshold(struct dm_pool_metadata *pmd, + dm_block_t threshold, + dm_sm_threshold_fn fn, +--- a/drivers/md/dm-thin-metadata.h ++++ b/drivers/md/dm-thin-metadata.h +@@ -193,6 +193,7 @@ int dm_pool_resize_metadata_dev(struct d + * that nothing is changing. + */ + void dm_pool_metadata_read_only(struct dm_pool_metadata *pmd); ++void dm_pool_metadata_read_write(struct dm_pool_metadata *pmd); + + int dm_pool_register_metadata_threshold(struct dm_pool_metadata *pmd, + dm_block_t threshold, +--- a/drivers/md/dm-thin.c ++++ b/drivers/md/dm-thin.c +@@ -1425,6 +1425,7 @@ static void set_pool_mode(struct pool *p + break; + + case PM_WRITE: ++ dm_pool_metadata_read_write(pool->pmd); + pool->process_bio = process_bio; + pool->process_discard = process_discard; + pool->process_prepared_mapping = process_prepared_mapping; +@@ -1641,12 +1642,19 @@ static int bind_control_target(struct po + struct pool_c *pt = ti->private; + + /* +- * We want to make sure that degraded pools are never upgraded. ++ * We want to make sure that a pool in PM_FAIL mode is never upgraded. + */ + enum pool_mode old_mode = pool->pf.mode; + enum pool_mode new_mode = pt->adjusted_pf.mode; + +- if (old_mode > new_mode) ++ /* ++ * If we were in PM_FAIL mode, rollback of metadata failed. We're ++ * not going to recover without a thin_repair. So we never let the ++ * pool move out of the old mode. On the other hand a PM_READ_ONLY ++ * may have been due to a lack of metadata or data space, and may ++ * now work (ie. if the underlying devices have been resized). ++ */ ++ if (old_mode == PM_FAIL) + new_mode = old_mode; + + pool->ti = ti; +--- a/drivers/md/persistent-data/dm-block-manager.c ++++ b/drivers/md/persistent-data/dm-block-manager.c +@@ -626,6 +626,12 @@ void dm_bm_set_read_only(struct dm_block + } + EXPORT_SYMBOL_GPL(dm_bm_set_read_only); + ++void dm_bm_set_read_write(struct dm_block_manager *bm) ++{ ++ bm->read_only = false; ++} ++EXPORT_SYMBOL_GPL(dm_bm_set_read_write); ++ + u32 dm_bm_checksum(const void *data, size_t len, u32 init_xor) + { + return crc32c(~(u32) 0, data, len) ^ init_xor; +--- a/drivers/md/persistent-data/dm-block-manager.h ++++ b/drivers/md/persistent-data/dm-block-manager.h +@@ -108,9 +108,9 @@ int dm_bm_unlock(struct dm_block *b); + int dm_bm_flush_and_unlock(struct dm_block_manager *bm, + struct dm_block *superblock); + +- /* +- * Request data be prefetched into the cache. +- */ ++/* ++ * Request data is prefetched into the cache. ++ */ + void dm_bm_prefetch(struct dm_block_manager *bm, dm_block_t b); + + /* +@@ -125,6 +125,7 @@ void dm_bm_prefetch(struct dm_block_mana + * be returned if you do. + */ + void dm_bm_set_read_only(struct dm_block_manager *bm); ++void dm_bm_set_read_write(struct dm_block_manager *bm); + + u32 dm_bm_checksum(const void *data, size_t len, u32 init_xor); + diff --git a/queue-3.12/dm-thin-always-fallback-the-pool-mode-if-commit-fails.patch b/queue-3.12/dm-thin-always-fallback-the-pool-mode-if-commit-fails.patch new file mode 100644 index 00000000000..fbea195e207 --- /dev/null +++ b/queue-3.12/dm-thin-always-fallback-the-pool-mode-if-commit-fails.patch @@ -0,0 +1,128 @@ +From 020cc3b5e28c2e24f59f53a9154faf08564f308e Mon Sep 17 00:00:00 2001 +From: Joe Thornber +Date: Wed, 4 Dec 2013 15:05:36 -0500 +Subject: dm thin: always fallback the pool mode if commit fails + +From: Joe Thornber + +commit 020cc3b5e28c2e24f59f53a9154faf08564f308e upstream. + +Rename commit_or_fallback() to commit(). Now all previous calls to +commit() will trigger the pool mode to fallback if the commit fails. + +Also, check the error returned from commit() in alloc_data_block(). + +Signed-off-by: Joe Thornber +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/dm-thin.c | 37 +++++++++++++++---------------------- + 1 file changed, 15 insertions(+), 22 deletions(-) + +--- a/drivers/md/dm-thin.c ++++ b/drivers/md/dm-thin.c +@@ -883,32 +883,23 @@ static void schedule_zero(struct thin_c + } + } + +-static int commit(struct pool *pool) +-{ +- int r; +- +- r = dm_pool_commit_metadata(pool->pmd); +- if (r) +- DMERR_LIMIT("%s: commit failed: error = %d", +- dm_device_name(pool->pool_md), r); +- +- return r; +-} +- + /* + * A non-zero return indicates read_only or fail_io mode. + * Many callers don't care about the return value. + */ +-static int commit_or_fallback(struct pool *pool) ++static int commit(struct pool *pool) + { + int r; + + if (get_pool_mode(pool) != PM_WRITE) + return -EINVAL; + +- r = commit(pool); +- if (r) ++ r = dm_pool_commit_metadata(pool->pmd); ++ if (r) { ++ DMERR_LIMIT("%s: dm_pool_commit_metadata failed: error = %d", ++ dm_device_name(pool->pool_md), r); + set_pool_mode(pool, PM_READ_ONLY); ++ } + + return r; + } +@@ -945,7 +936,9 @@ static int alloc_data_block(struct thin_ + * Try to commit to see if that will free up some + * more space. + */ +- (void) commit_or_fallback(pool); ++ r = commit(pool); ++ if (r) ++ return r; + + r = dm_pool_get_free_block_count(pool->pmd, &free_blocks); + if (r) +@@ -1359,7 +1352,7 @@ static void process_deferred_bios(struct + if (bio_list_empty(&bios) && !need_commit_due_to_time(pool)) + return; + +- if (commit_or_fallback(pool)) { ++ if (commit(pool)) { + while ((bio = bio_list_pop(&bios))) + bio_io_error(bio); + return; +@@ -2276,7 +2269,7 @@ static int pool_preresume(struct dm_targ + return r; + + if (need_commit1 || need_commit2) +- (void) commit_or_fallback(pool); ++ (void) commit(pool); + + return 0; + } +@@ -2303,7 +2296,7 @@ static void pool_postsuspend(struct dm_t + + cancel_delayed_work(&pool->waker); + flush_workqueue(pool->wq); +- (void) commit_or_fallback(pool); ++ (void) commit(pool); + } + + static int check_arg_count(unsigned argc, unsigned args_required) +@@ -2437,7 +2430,7 @@ static int process_reserve_metadata_snap + if (r) + return r; + +- (void) commit_or_fallback(pool); ++ (void) commit(pool); + + r = dm_pool_reserve_metadata_snap(pool->pmd); + if (r) +@@ -2499,7 +2492,7 @@ static int pool_message(struct dm_target + DMWARN("Unrecognised thin pool target message received: %s", argv[0]); + + if (!r) +- (void) commit_or_fallback(pool); ++ (void) commit(pool); + + return r; + } +@@ -2554,7 +2547,7 @@ static void pool_status(struct dm_target + + /* Commit to ensure statistics aren't out-of-date */ + if (!(status_flags & DM_STATUS_NOFLUSH_FLAG) && !dm_suspended(ti)) +- (void) commit_or_fallback(pool); ++ (void) commit(pool); + + r = dm_pool_get_metadata_transaction_id(pool->pmd, &transaction_id); + if (r) { diff --git a/queue-3.12/dm-thin-re-establish-read-only-state-when-switching-to-fail-mode.patch b/queue-3.12/dm-thin-re-establish-read-only-state-when-switching-to-fail-mode.patch new file mode 100644 index 00000000000..3b91abd069f --- /dev/null +++ b/queue-3.12/dm-thin-re-establish-read-only-state-when-switching-to-fail-mode.patch @@ -0,0 +1,36 @@ +From 5383ef3a929a1366e2ced45cd6d74be7aa2a2281 Mon Sep 17 00:00:00 2001 +From: Joe Thornber +Date: Wed, 4 Dec 2013 16:30:01 -0500 +Subject: dm thin: re-establish read-only state when switching to fail mode + +From: Joe Thornber + +commit 5383ef3a929a1366e2ced45cd6d74be7aa2a2281 upstream. + +If the thin-pool transitioned to fail mode and the thin-pool's table +were reloaded for some reason: the new table's default pool mode would +be read-write, though it will transition to fail mode during resume. + +When the pool mode transitions directly from PM_WRITE to PM_FAIL we need +to re-establish the intermediate read-only state in both the metadata +and persistent-data block manager (as is usually done with the normal +pool mode transition sequence: PM_WRITE -> PM_READ_ONLY -> PM_FAIL). + +Signed-off-by: Joe Thornber +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/dm-thin.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/md/dm-thin.c ++++ b/drivers/md/dm-thin.c +@@ -1400,6 +1400,7 @@ static void set_pool_mode(struct pool *p + case PM_FAIL: + DMERR("%s: switching pool to failure mode", + dm_device_name(pool->pool_md)); ++ dm_pool_metadata_read_only(pool->pmd); + pool->process_bio = process_bio_fail; + pool->process_discard = process_bio_fail; + pool->process_prepared_mapping = process_prepared_mapping_fail; diff --git a/queue-3.12/dm-thin-switch-to-read-only-mode-if-a-mapping-insert-fails.patch b/queue-3.12/dm-thin-switch-to-read-only-mode-if-a-mapping-insert-fails.patch new file mode 100644 index 00000000000..ce214be2b80 --- /dev/null +++ b/queue-3.12/dm-thin-switch-to-read-only-mode-if-a-mapping-insert-fails.patch @@ -0,0 +1,78 @@ +From fafc7a815e40255d24e80a1cb7365892362fa398 Mon Sep 17 00:00:00 2001 +From: Joe Thornber +Date: Mon, 2 Dec 2013 17:57:42 -0500 +Subject: dm thin: switch to read only mode if a mapping insert fails + +From: Joe Thornber + +commit fafc7a815e40255d24e80a1cb7365892362fa398 upstream. + +Switch the thin pool to read-only mode when dm_thin_insert_block() fails +since there is little reason to expect the cause of the failure to be +resolved without further action by user space. + +This issue was noticed with the device-mapper-test-suite using: +dmtest run --suite thin-provisioning -n /exhausting_metadata_space_causes_fail_mode/ + +The quantity of errors logged in this case must be reduced. + +before patch: + +device-mapper: thin: dm_thin_insert_block() failed +device-mapper: space map metadata: unable to allocate new metadata block +device-mapper: thin: dm_thin_insert_block() failed +device-mapper: space map metadata: unable to allocate new metadata block +device-mapper: thin: dm_thin_insert_block() failed +device-mapper: space map metadata: unable to allocate new metadata block +device-mapper: thin: dm_thin_insert_block() failed +device-mapper: space map metadata: unable to allocate new metadata block +device-mapper: thin: dm_thin_insert_block() failed +device-mapper: space map metadata: unable to allocate new metadata block +device-mapper: thin: dm_thin_insert_block() failed +device-mapper: space map metadata: unable to allocate new metadata block +device-mapper: thin: dm_thin_insert_block() failed +device-mapper: space map metadata: unable to allocate new metadata block +device-mapper: thin: dm_thin_insert_block() failed +device-mapper: space map metadata: unable to allocate new metadata block +device-mapper: thin: dm_thin_insert_block() failed +device-mapper: space map metadata: unable to allocate new metadata block +device-mapper: thin: dm_thin_insert_block() failed +device-mapper: space map metadata: unable to allocate new metadata block +device-mapper: space map metadata: unable to allocate new metadata block +device-mapper: space map metadata: unable to allocate new metadata block +device-mapper: space map metadata: unable to allocate new metadata block +device-mapper: space map metadata: unable to allocate new metadata block +device-mapper: space map metadata: unable to allocate new metadata block + +device-mapper: space map metadata: unable to allocate new metadata block +device-mapper: space map common: dm_tm_shadow_block() failed +device-mapper: thin: 253:4: no free metadata space available. +device-mapper: thin: 253:4: switching pool to read-only mode + +after patch: + +device-mapper: space map metadata: unable to allocate new metadata block +device-mapper: thin: 253:4: dm_thin_insert_block() failed: error = -28 +device-mapper: thin: 253:4: switching pool to read-only mode + +Signed-off-by: Joe Thornber +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/dm-thin.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/md/dm-thin.c ++++ b/drivers/md/dm-thin.c +@@ -640,7 +640,9 @@ static void process_prepared_mapping(str + */ + r = dm_thin_insert_block(tc->td, m->virt_block, m->data_block); + if (r) { +- DMERR_LIMIT("dm_thin_insert_block() failed"); ++ DMERR_LIMIT("%s: dm_thin_insert_block() failed: error = %d", ++ dm_device_name(pool->pool_md), r); ++ set_pool_mode(pool, PM_READ_ONLY); + cell_error(pool, m->cell); + goto out; + } diff --git a/queue-3.12/dm-thin-switch-to-read-only-mode-if-metadata-space-is-exhausted.patch b/queue-3.12/dm-thin-switch-to-read-only-mode-if-metadata-space-is-exhausted.patch new file mode 100644 index 00000000000..95cb0c6233e --- /dev/null +++ b/queue-3.12/dm-thin-switch-to-read-only-mode-if-metadata-space-is-exhausted.patch @@ -0,0 +1,83 @@ +From 4a02b34e0cf1d0d0dd3737702841da4bf615a50a Mon Sep 17 00:00:00 2001 +From: Mike Snitzer +Date: Tue, 3 Dec 2013 12:20:57 -0500 +Subject: dm thin: switch to read-only mode if metadata space is exhausted + +From: Mike Snitzer + +commit 4a02b34e0cf1d0d0dd3737702841da4bf615a50a upstream. + +Switch the thin pool to read-only mode in alloc_data_block() if +dm_pool_alloc_data_block() fails because the pool's metadata space is +exhausted. + +Differentiate between data and metadata space in messages about no +free space available. + +This issue was noticed with the device-mapper-test-suite using: +dmtest run --suite thin-provisioning -n /exhausting_metadata_space_causes_fail_mode/ + +The quantity of errors logged in this case must be reduced. + +before patch: + +device-mapper: thin: 253:4: reached low water mark for metadata device: sending event. +device-mapper: space map metadata: unable to allocate new metadata block +device-mapper: space map common: dm_tm_shadow_block() failed +device-mapper: space map metadata: unable to allocate new metadata block +device-mapper: space map common: dm_tm_shadow_block() failed +device-mapper: space map metadata: unable to allocate new metadata block +device-mapper: space map common: dm_tm_shadow_block() failed +device-mapper: space map metadata: unable to allocate new metadata block +device-mapper: space map common: dm_tm_shadow_block() failed +device-mapper: space map metadata: unable to allocate new metadata block +device-mapper: space map common: dm_tm_shadow_block() failed + +device-mapper: space map metadata: unable to allocate new metadata block +device-mapper: thin: 253:4: commit failed: error = -28 +device-mapper: thin: 253:4: switching pool to read-only mode + +after patch: + +device-mapper: thin: 253:4: reached low water mark for metadata device: sending event. +device-mapper: space map metadata: unable to allocate new metadata block +device-mapper: thin: 253:4: no free metadata space available. +device-mapper: thin: 253:4: switching pool to read-only mode + +Signed-off-by: Mike Snitzer +Acked-by: Joe Thornber +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/dm-thin.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +--- a/drivers/md/dm-thin.c ++++ b/drivers/md/dm-thin.c +@@ -959,7 +959,7 @@ static int alloc_data_block(struct thin_ + * table reload). + */ + if (!free_blocks) { +- DMWARN("%s: no free space available.", ++ DMWARN("%s: no free data space available.", + dm_device_name(pool->pool_md)); + spin_lock_irqsave(&pool->lock, flags); + pool->no_free_space = 1; +@@ -969,8 +969,16 @@ static int alloc_data_block(struct thin_ + } + + r = dm_pool_alloc_data_block(pool->pmd, result); +- if (r) ++ if (r) { ++ if (r == -ENOSPC && ++ !dm_pool_get_free_metadata_block_count(pool->pmd, &free_blocks) && ++ !free_blocks) { ++ DMWARN("%s: no free metadata space available.", ++ dm_device_name(pool->pool_md)); ++ set_pool_mode(pool, PM_READ_ONLY); ++ } + return r; ++ } + + return 0; + } diff --git a/queue-3.12/media-af9033-fix-broken-i2c.patch b/queue-3.12/media-af9033-fix-broken-i2c.patch new file mode 100644 index 00000000000..6f077a3f508 --- /dev/null +++ b/queue-3.12/media-af9033-fix-broken-i2c.patch @@ -0,0 +1,49 @@ +From d18a88b1f535d627412b2a265d71b2f7d464860e Mon Sep 17 00:00:00 2001 +From: Antti Palosaari +Date: Wed, 27 Nov 2013 17:17:43 -0300 +Subject: media: af9033: fix broken I2C + +From: Antti Palosaari + +commit d18a88b1f535d627412b2a265d71b2f7d464860e upstream. + +Driver did not work anymore since I2C has gone broken due +to recent commit: +commit 37ebaf6891ee81687bb558e8375c0712d8264ed8 +[media] dvb-frontends: Don't use dynamic static allocation + +Signed-off-by: Antti Palosaari +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/media/dvb-frontends/af9033.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +--- a/drivers/media/dvb-frontends/af9033.c ++++ b/drivers/media/dvb-frontends/af9033.c +@@ -170,18 +170,18 @@ static int af9033_rd_reg_mask(struct af9 + static int af9033_wr_reg_val_tab(struct af9033_state *state, + const struct reg_val *tab, int tab_len) + { ++#define MAX_TAB_LEN 212 + int ret, i, j; +- u8 buf[MAX_XFER_SIZE]; ++ u8 buf[1 + MAX_TAB_LEN]; ++ ++ dev_dbg(&state->i2c->dev, "%s: tab_len=%d\n", __func__, tab_len); + + if (tab_len > sizeof(buf)) { +- dev_warn(&state->i2c->dev, +- "%s: i2c wr len=%d is too big!\n", +- KBUILD_MODNAME, tab_len); ++ dev_warn(&state->i2c->dev, "%s: tab len %d is too big\n", ++ KBUILD_MODNAME, tab_len); + return -EINVAL; + } + +- dev_dbg(&state->i2c->dev, "%s: tab_len=%d\n", __func__, tab_len); +- + for (i = 0, j = 0; i < tab_len; i++) { + buf[j] = tab[i].val; + diff --git a/queue-3.12/media-af9035-add-leadtek-winfast-dtv-dongle-dual.patch b/queue-3.12/media-af9035-add-leadtek-winfast-dtv-dongle-dual.patch new file mode 100644 index 00000000000..60e591c6241 --- /dev/null +++ b/queue-3.12/media-af9035-add-leadtek-winfast-dtv-dongle-dual.patch @@ -0,0 +1,32 @@ +From 0c413d10515feae02cee967b31bb8afea8aa0d29 Mon Sep 17 00:00:00 2001 +From: Antti Palosaari +Date: Thu, 8 Aug 2013 19:41:06 -0300 +Subject: media: af9035: add [0413:6a05] Leadtek WinFast DTV Dongle Dual + +From: Antti Palosaari + +commit 0c413d10515feae02cee967b31bb8afea8aa0d29 upstream. + +It is IT9135 dual design. +Thanks to Michael Piko for reporting that! + +Reported-by: Michael Piko +Signed-off-by: Antti Palosaari +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/media/usb/dvb-usb-v2/af9035.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/media/usb/dvb-usb-v2/af9035.c ++++ b/drivers/media/usb/dvb-usb-v2/af9035.c +@@ -1534,6 +1534,8 @@ static const struct usb_device_id af9035 + /* XXX: that same ID [0ccd:0099] is used by af9015 driver too */ + { DVB_USB_DEVICE(USB_VID_TERRATEC, 0x0099, + &af9035_props, "TerraTec Cinergy T Stick Dual RC (rev. 2)", NULL) }, ++ { DVB_USB_DEVICE(USB_VID_LEADTEK, 0x6a05, ++ &af9035_props, "Leadtek WinFast DTV Dongle Dual", NULL) }, + { } + }; + MODULE_DEVICE_TABLE(usb, af9035_id_table); diff --git a/queue-3.12/media-af9035-unlock-on-error-in-af9035_i2c_master_xfer.patch b/queue-3.12/media-af9035-unlock-on-error-in-af9035_i2c_master_xfer.patch new file mode 100644 index 00000000000..f04df95254f --- /dev/null +++ b/queue-3.12/media-af9035-unlock-on-error-in-af9035_i2c_master_xfer.patch @@ -0,0 +1,52 @@ +From 3189ef0290dcc9f44782672fade35847cb30da00 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Fri, 22 Nov 2013 04:50:46 -0300 +Subject: media: af9035: unlock on error in af9035_i2c_master_xfer() + +From: Dan Carpenter + +commit 3189ef0290dcc9f44782672fade35847cb30da00 upstream. + +We introduced a couple new error paths which are missing unlocks. +Fixes: 7760e148350b ('[media] af9035: Don't use dynamic static allocation') + +Signed-off-by: Dan Carpenter +Acked-by: Antti Palosaari +Signed-off-by: Antti Palosaari +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/media/usb/dvb-usb-v2/af9035.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/drivers/media/usb/dvb-usb-v2/af9035.c ++++ b/drivers/media/usb/dvb-usb-v2/af9035.c +@@ -245,7 +245,8 @@ static int af9035_i2c_master_xfer(struct + dev_warn(&d->udev->dev, + "%s: i2c xfer: len=%d is too big!\n", + KBUILD_MODNAME, msg[0].len); +- return -EOPNOTSUPP; ++ ret = -EOPNOTSUPP; ++ goto unlock; + } + req.mbox |= ((msg[0].addr & 0x80) >> 3); + buf[0] = msg[1].len; +@@ -281,7 +282,8 @@ static int af9035_i2c_master_xfer(struct + dev_warn(&d->udev->dev, + "%s: i2c xfer: len=%d is too big!\n", + KBUILD_MODNAME, msg[0].len); +- return -EOPNOTSUPP; ++ ret = -EOPNOTSUPP; ++ goto unlock; + } + req.mbox |= ((msg[0].addr & 0x80) >> 3); + buf[0] = msg[0].len; +@@ -319,6 +321,7 @@ static int af9035_i2c_master_xfer(struct + ret = -EOPNOTSUPP; + } + ++unlock: + mutex_unlock(&d->i2c_mutex); + + if (ret < 0) diff --git a/queue-3.12/media-bttv-don-t-setup-the-controls-if-there-are-no-video-devices.patch b/queue-3.12/media-bttv-don-t-setup-the-controls-if-there-are-no-video-devices.patch new file mode 100644 index 00000000000..127deb7b0e3 --- /dev/null +++ b/queue-3.12/media-bttv-don-t-setup-the-controls-if-there-are-no-video-devices.patch @@ -0,0 +1,36 @@ +From f8e1b699a5504a2da05834c7cfdddb125a8ce088 Mon Sep 17 00:00:00 2001 +From: Hans Verkuil +Date: Mon, 11 Nov 2013 08:16:03 -0300 +Subject: media: bttv: don't setup the controls if there are no video devices + +From: Hans Verkuil + +commit f8e1b699a5504a2da05834c7cfdddb125a8ce088 upstream. + +The no_video flag was checked in all other cases except one. Calling +v4l2_ctrl_handler_setup() if no_video is 1 will crash. +This wasn't noticed before since there are only two card types that +set no_video to 1, so this type of hardware is quite rare. + +Signed-off-by: Hans Verkuil +Reported-by: Lorenz Röhrl +Tested-by: Lorenz Röhrl +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/media/pci/bt8xx/bttv-driver.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/media/pci/bt8xx/bttv-driver.c ++++ b/drivers/media/pci/bt8xx/bttv-driver.c +@@ -4182,7 +4182,8 @@ static int bttv_probe(struct pci_dev *de + } + btv->std = V4L2_STD_PAL; + init_irqreg(btv); +- v4l2_ctrl_handler_setup(hdl); ++ if (!bttv_tvcards[btv->c.type].no_video) ++ v4l2_ctrl_handler_setup(hdl); + if (hdl->error) { + result = hdl->error; + goto fail2; diff --git a/queue-3.12/media-saa7164-fix-return-value-check-in-saa7164_initdev.patch b/queue-3.12/media-saa7164-fix-return-value-check-in-saa7164_initdev.patch new file mode 100644 index 00000000000..2a07cf71046 --- /dev/null +++ b/queue-3.12/media-saa7164-fix-return-value-check-in-saa7164_initdev.patch @@ -0,0 +1,37 @@ +From 89f4d45b2752df5d222b5f63919ce59e2d8afaf4 Mon Sep 17 00:00:00 2001 +From: Wei Yongjun +Date: Fri, 25 Oct 2013 06:34:03 -0300 +Subject: media: saa7164: fix return value check in saa7164_initdev() + +From: Wei Yongjun + +commit 89f4d45b2752df5d222b5f63919ce59e2d8afaf4 upstream. + +In case of error, the function kthread_run() returns ERR_PTR() +and never returns NULL. The NULL test in the return value check +should be replaced with IS_ERR(). + +Signed-off-by: Wei Yongjun +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/media/pci/saa7164/saa7164-core.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/media/pci/saa7164/saa7164-core.c ++++ b/drivers/media/pci/saa7164/saa7164-core.c +@@ -1354,9 +1354,11 @@ static int saa7164_initdev(struct pci_de + if (fw_debug) { + dev->kthread = kthread_run(saa7164_thread_function, dev, + "saa7164 debug"); +- if (!dev->kthread) ++ if (IS_ERR(dev->kthread)) { ++ dev->kthread = NULL; + printk(KERN_ERR "%s() Failed to create " + "debug kernel thread\n", __func__); ++ } + } + + } /* != BOARD_UNKNOWN */ diff --git a/queue-3.12/media-tef6862-radio-tea5764-actually-assign-clamp-result.patch b/queue-3.12/media-tef6862-radio-tea5764-actually-assign-clamp-result.patch new file mode 100644 index 00000000000..b77a3e2bb90 --- /dev/null +++ b/queue-3.12/media-tef6862-radio-tea5764-actually-assign-clamp-result.patch @@ -0,0 +1,44 @@ +From 9ba6a91f19b8c118d11c549495fa4f7a20505d80 Mon Sep 17 00:00:00 2001 +From: Hans Verkuil +Date: Mon, 4 Nov 2013 06:28:57 -0300 +Subject: media: tef6862/radio-tea5764: actually assign clamp result + +From: Hans Verkuil + +commit 9ba6a91f19b8c118d11c549495fa4f7a20505d80 upstream. + +When adding frequency clamping to the tef6862 and radio-tea5764 drivers +I forgot to actually *assign* the clamp result to the frequency. + +Signed-off-by: Hans Verkuil +Reported-by: Hans Petter Selasky +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/media/radio/radio-tea5764.c | 2 +- + drivers/media/radio/tef6862.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/media/radio/radio-tea5764.c ++++ b/drivers/media/radio/radio-tea5764.c +@@ -356,7 +356,7 @@ static int vidioc_s_frequency(struct fil + So we keep it as-is. */ + return -EINVAL; + } +- clamp(freq, FREQ_MIN * FREQ_MUL, FREQ_MAX * FREQ_MUL); ++ freq = clamp(freq, FREQ_MIN * FREQ_MUL, FREQ_MAX * FREQ_MUL); + tea5764_power_up(radio); + tea5764_tune(radio, (freq * 125) / 2); + return 0; +--- a/drivers/media/radio/tef6862.c ++++ b/drivers/media/radio/tef6862.c +@@ -112,7 +112,7 @@ static int tef6862_s_frequency(struct v4 + if (f->tuner != 0) + return -EINVAL; + +- clamp(freq, TEF6862_LO_FREQ, TEF6862_HI_FREQ); ++ freq = clamp(freq, TEF6862_LO_FREQ, TEF6862_HI_FREQ); + pll = 1964 + ((freq - TEF6862_LO_FREQ) * 20) / FREQ_MUL; + i2cmsg[0] = (MODE_PRESET << MODE_SHIFT) | WM_SUB_PLLM; + i2cmsg[1] = (pll >> 8) & 0xff; diff --git a/queue-3.12/media-wm8775-fix-broken-audio-routing.patch b/queue-3.12/media-wm8775-fix-broken-audio-routing.patch new file mode 100644 index 00000000000..e559e65138c --- /dev/null +++ b/queue-3.12/media-wm8775-fix-broken-audio-routing.patch @@ -0,0 +1,44 @@ +From 3af41a337a5b270de3e65466a07f106ad97ad0c6 Mon Sep 17 00:00:00 2001 +From: Hans Verkuil +Date: Mon, 11 Nov 2013 11:02:52 -0300 +Subject: media: wm8775: fix broken audio routing + +From: Hans Verkuil + +commit 3af41a337a5b270de3e65466a07f106ad97ad0c6 upstream. + +Commit 5aa9ae5ed5d449a85fbf7aac3d1fdc241c542a79 inverted the mute control +state test in s_routing which caused the audio routing to fail. This broke +ivtv support for the Hauppauge video/audio input bracket (which adds additional +video and audio inputs) all the way back in kernel 2.6.36. +This fix fixes the condition and it also removes a nonsense check on the +balance control. +Bisected-by: Rajil Saraswat + +Signed-off-by: Andy Walls +Reported-by: Rajil Saraswat +Tested-by: Hans Verkuil +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/media/i2c/wm8775.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +--- a/drivers/media/i2c/wm8775.c ++++ b/drivers/media/i2c/wm8775.c +@@ -130,12 +130,10 @@ static int wm8775_s_routing(struct v4l2_ + return -EINVAL; + } + state->input = input; +- if (!v4l2_ctrl_g_ctrl(state->mute)) ++ if (v4l2_ctrl_g_ctrl(state->mute)) + return 0; + if (!v4l2_ctrl_g_ctrl(state->vol)) + return 0; +- if (!v4l2_ctrl_g_ctrl(state->bal)) +- return 0; + wm8775_set_audio(sd, 1); + return 0; + } diff --git a/queue-3.12/series b/queue-3.12/series index 2114eb687d7..76804203a0d 100644 --- a/queue-3.12/series +++ b/queue-3.12/series @@ -68,3 +68,25 @@ x86-efi-don-t-use-u-efi-time-services-on-32-bit.patch x86-uv-fix-null-pointer-dereference-in-uv_flush_tlb_others-if-the-nobau-boot-option-is-used.patch x86-build-pass-in-additional-mno-mmx-mno-sse-options.patch x86-build-icc-remove-uninitialized_var-from-compiler-intel.h.patch +media-saa7164-fix-return-value-check-in-saa7164_initdev.patch +media-tef6862-radio-tea5764-actually-assign-clamp-result.patch +media-bttv-don-t-setup-the-controls-if-there-are-no-video-devices.patch +media-af9033-fix-broken-i2c.patch +media-wm8775-fix-broken-audio-routing.patch +media-af9035-add-leadtek-winfast-dtv-dongle-dual.patch +media-af9035-unlock-on-error-in-af9035_i2c_master_xfer.patch +btrfs-fix-access_ok-check-in-btrfs_ioctl_send.patch +btrfs-call-mnt_drop_write-after-interrupted-subvol-deletion.patch +dm-bufio-initialize-read-only-module-parameters.patch +dm-snapshot-avoid-snapshot-space-leak-on-crash.patch +dm-stats-initialize-read-only-module-parameter.patch +dm-array-fix-a-reference-counting-bug-in-shadow_ablock.patch +dm-delay-fix-a-possible-deadlock-due-to-shared-workqueue.patch +dm-space-map-metadata-return-on-failure-in-sm_metadata_new_block.patch +dm-space-map-disallow-decrementing-a-reference-count-below-zero.patch +dm-table-fail-dm_table_create-on-dm_round_up-overflow.patch +dm-thin-switch-to-read-only-mode-if-a-mapping-insert-fails.patch +dm-thin-switch-to-read-only-mode-if-metadata-space-is-exhausted.patch +dm-thin-always-fallback-the-pool-mode-if-commit-fails.patch +dm-thin-re-establish-read-only-state-when-switching-to-fail-mode.patch +dm-thin-allow-pool-in-read-only-mode-to-transition-to-read-write-mode.patch