From 04364b8722a121c7296315d4377ace6ff897a532 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 4 Mar 2013 12:30:57 +0800 Subject: [PATCH] 3.8-stable patches added patches: btrfs-copy-everything-if-we-ve-created-an-inline-extent.patch btrfs-delete-inline-extents-when-we-find-them-during-logging.patch btrfs-init-io_lock-after-cloning-btrfs-device-struct.patch cifs-ensure-that-cifs_get_root-only-traverses-directories.patch dm-do-not-replace-bioset-for-request-based-dm.patch dm-fix-limits-initialization-when-there-are-no-data-devices.patch dm-fix-truncated-status-strings.patch dm-snapshot-add-missing-module-aliases.patch ext4-convert-number-of-blocks-to-clusters-properly.patch iscsi-target-fix-immediate-queue-starvation-regression-with-datain.patch nfs-don-t-allow-nfs-silly-renamed-files-to-be-deleted-no-signal.patch nfsv4.1-hold-reference-to-layout-hdr-in-layoutget.patch pnfs-fix-resend_to_mds-for-directio.patch scsi-dc395x-uninitialized-variable-in-device_alloc.patch scsi-storvsc-initialize-the-sglist.patch sony-laptop-fully-enable-sny-controlled-modems.patch sunrpc-don-t-start-the-retransmission-timer-when-out-of-socket-space.patch target-pscsi-fix-page-increment.patch usb-ehci-revert-remove-ass-pss-polling-timeout.patch watchdog-da9055_wdt-needs-to-select-watchdog_core.patch watchdog-sp5100_tco-fix-wrong-indirect-i-o-access-for-getting-value-of-reserved-bits.patch watchdog-sp5100_tco-write-back-the-original-value-to-reserved-bits-instead-of-zero.patch xenbus-fix-compile-failure-on-arm-with-xen-enabled.patch xen-pat-disable-pat-using-pat_enabled-value.patch xen-pci-we-don-t-do-multiple-msi-s.patch --- ...ng-if-we-ve-created-an-inline-extent.patch | 32 + ...nts-when-we-find-them-during-logging.patch | 59 ++ ...ck-after-cloning-btrfs-device-struct.patch | 37 + ..._get_root-only-traverses-directories.patch | 92 +++ ...-replace-bioset-for-request-based-dm.patch | 108 +++ ...ation-when-there-are-no-data-devices.patch | 57 ++ .../dm-fix-truncated-status-strings.patch | 645 ++++++++++++++++++ ...-snapshot-add-missing-module-aliases.patch | 31 + ...umber-of-blocks-to-clusters-properly.patch | 109 +++ ...ue-starvation-regression-with-datain.patch | 78 +++ ...enamed-files-to-be-deleted-no-signal.patch | 90 +++ ...reference-to-layout-hdr-in-layoutget.patch | 92 +++ .../pnfs-fix-resend_to_mds-for-directio.patch | 184 +++++ ...initialized-variable-in-device_alloc.patch | 38 ++ .../scsi-storvsc-initialize-the-sglist.patch | 29 + queue-3.8/series | 25 + ...p-fully-enable-sny-controlled-modems.patch | 33 + ...ssion-timer-when-out-of-socket-space.patch | 45 ++ .../target-pscsi-fix-page-increment.patch | 31 + ...evert-remove-ass-pss-polling-timeout.patch | 84 +++ ...55_wdt-needs-to-select-watchdog_core.patch | 35 + ...s-for-getting-value-of-reserved-bits.patch | 50 ++ ...lue-to-reserved-bits-instead-of-zero.patch | 77 +++ ...-disable-pat-using-pat_enabled-value.patch | 121 ++++ .../xen-pci-we-don-t-do-multiple-msi-s.patch | 74 ++ ...pile-failure-on-arm-with-xen-enabled.patch | 31 + 26 files changed, 2287 insertions(+) create mode 100644 queue-3.8/btrfs-copy-everything-if-we-ve-created-an-inline-extent.patch create mode 100644 queue-3.8/btrfs-delete-inline-extents-when-we-find-them-during-logging.patch create mode 100644 queue-3.8/btrfs-init-io_lock-after-cloning-btrfs-device-struct.patch create mode 100644 queue-3.8/cifs-ensure-that-cifs_get_root-only-traverses-directories.patch create mode 100644 queue-3.8/dm-do-not-replace-bioset-for-request-based-dm.patch create mode 100644 queue-3.8/dm-fix-limits-initialization-when-there-are-no-data-devices.patch create mode 100644 queue-3.8/dm-fix-truncated-status-strings.patch create mode 100644 queue-3.8/dm-snapshot-add-missing-module-aliases.patch create mode 100644 queue-3.8/ext4-convert-number-of-blocks-to-clusters-properly.patch create mode 100644 queue-3.8/iscsi-target-fix-immediate-queue-starvation-regression-with-datain.patch create mode 100644 queue-3.8/nfs-don-t-allow-nfs-silly-renamed-files-to-be-deleted-no-signal.patch create mode 100644 queue-3.8/nfsv4.1-hold-reference-to-layout-hdr-in-layoutget.patch create mode 100644 queue-3.8/pnfs-fix-resend_to_mds-for-directio.patch create mode 100644 queue-3.8/scsi-dc395x-uninitialized-variable-in-device_alloc.patch create mode 100644 queue-3.8/scsi-storvsc-initialize-the-sglist.patch create mode 100644 queue-3.8/sony-laptop-fully-enable-sny-controlled-modems.patch create mode 100644 queue-3.8/sunrpc-don-t-start-the-retransmission-timer-when-out-of-socket-space.patch create mode 100644 queue-3.8/target-pscsi-fix-page-increment.patch create mode 100644 queue-3.8/usb-ehci-revert-remove-ass-pss-polling-timeout.patch create mode 100644 queue-3.8/watchdog-da9055_wdt-needs-to-select-watchdog_core.patch create mode 100644 queue-3.8/watchdog-sp5100_tco-fix-wrong-indirect-i-o-access-for-getting-value-of-reserved-bits.patch create mode 100644 queue-3.8/watchdog-sp5100_tco-write-back-the-original-value-to-reserved-bits-instead-of-zero.patch create mode 100644 queue-3.8/xen-pat-disable-pat-using-pat_enabled-value.patch create mode 100644 queue-3.8/xen-pci-we-don-t-do-multiple-msi-s.patch create mode 100644 queue-3.8/xenbus-fix-compile-failure-on-arm-with-xen-enabled.patch diff --git a/queue-3.8/btrfs-copy-everything-if-we-ve-created-an-inline-extent.patch b/queue-3.8/btrfs-copy-everything-if-we-ve-created-an-inline-extent.patch new file mode 100644 index 00000000000..d3ca468c5c2 --- /dev/null +++ b/queue-3.8/btrfs-copy-everything-if-we-ve-created-an-inline-extent.patch @@ -0,0 +1,32 @@ +From bdc20e67e82cfc4901d3a5a0d79104b0e2296d83 Mon Sep 17 00:00:00 2001 +From: Josef Bacik +Date: Thu, 28 Feb 2013 13:23:38 -0500 +Subject: Btrfs: copy everything if we've created an inline extent + +From: Josef Bacik + +commit bdc20e67e82cfc4901d3a5a0d79104b0e2296d83 upstream. + +I noticed while looking into a tree logging bug that we aren't logging inline +extents properly. Since this requires copying and it shouldn't happen too often +just force us to copy everything for the inode into the tree log when we have an +inline extent. With this patch we have valid data after a crash when we write +an inline extent. Thanks, + +Signed-off-by: Josef Bacik +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/inode.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -265,6 +265,7 @@ static noinline int cow_file_range_inlin + return 1; + } + ++ set_bit(BTRFS_INODE_NEEDS_FULL_SYNC, &BTRFS_I(inode)->runtime_flags); + btrfs_delalloc_release_metadata(inode, end + 1 - start); + btrfs_drop_extent_cache(inode, start, aligned_end - 1, 0); + return 0; diff --git a/queue-3.8/btrfs-delete-inline-extents-when-we-find-them-during-logging.patch b/queue-3.8/btrfs-delete-inline-extents-when-we-find-them-during-logging.patch new file mode 100644 index 00000000000..1f245f5452b --- /dev/null +++ b/queue-3.8/btrfs-delete-inline-extents-when-we-find-them-during-logging.patch @@ -0,0 +1,59 @@ +From 124fe663f93162d17b7e391705cac122101e93d8 Mon Sep 17 00:00:00 2001 +From: Josef Bacik +Date: Fri, 1 Mar 2013 11:47:21 -0500 +Subject: Btrfs: delete inline extents when we find them during logging + +From: Josef Bacik + +commit 124fe663f93162d17b7e391705cac122101e93d8 upstream. + +Apparently when we do inline extents we allow the data to overlap the last chunk +of the btrfs_file_extent_item, which means that we can possibly have a +btrfs_file_extent_item that isn't actually as large as a btrfs_file_extent_item. +This messes with us when we try to overwrite the extent when logging new extents +since we expect for it to be the right size. To fix this just delete the item +and try to do the insert again which will give us the proper sized +btrfs_file_extent_item. This fixes a panic where map_private_extent_buffer +would blow up because we're trying to write past the end of the leaf. Thanks, + +Signed-off-by: Josef Bacik +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/tree-log.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +--- a/fs/btrfs/tree-log.c ++++ b/fs/btrfs/tree-log.c +@@ -3281,6 +3281,7 @@ static int log_one_extent(struct btrfs_t + int ret; + bool skip_csum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM; + ++insert: + INIT_LIST_HEAD(&ordered_sums); + btrfs_init_map_token(&token); + key.objectid = btrfs_ino(inode); +@@ -3296,6 +3297,23 @@ static int log_one_extent(struct btrfs_t + leaf = path->nodes[0]; + fi = btrfs_item_ptr(leaf, path->slots[0], + struct btrfs_file_extent_item); ++ ++ /* ++ * If we are overwriting an inline extent with a real one then we need ++ * to just delete the inline extent as it may not be large enough to ++ * have the entire file_extent_item. ++ */ ++ if (ret && btrfs_token_file_extent_type(leaf, fi, &token) == ++ BTRFS_FILE_EXTENT_INLINE) { ++ ret = btrfs_del_item(trans, log, path); ++ btrfs_release_path(path); ++ if (ret) { ++ path->really_keep_locks = 0; ++ return ret; ++ } ++ goto insert; ++ } ++ + btrfs_set_token_file_extent_generation(leaf, fi, em->generation, + &token); + if (test_bit(EXTENT_FLAG_PREALLOC, &em->flags)) { diff --git a/queue-3.8/btrfs-init-io_lock-after-cloning-btrfs-device-struct.patch b/queue-3.8/btrfs-init-io_lock-after-cloning-btrfs-device-struct.patch new file mode 100644 index 00000000000..bea20b6df68 --- /dev/null +++ b/queue-3.8/btrfs-init-io_lock-after-cloning-btrfs-device-struct.patch @@ -0,0 +1,37 @@ +From 1cba0cdf5e4dbcd9e5fa5b54d7a028e55e2ca057 Mon Sep 17 00:00:00 2001 +From: Thomas Gleixner +Date: Wed, 20 Feb 2013 14:06:20 -0500 +Subject: btrfs: Init io_lock after cloning btrfs device struct + +From: Thomas Gleixner + +commit 1cba0cdf5e4dbcd9e5fa5b54d7a028e55e2ca057 upstream. + +__btrfs_close_devices() clones btrfs device structs with +memcpy(). Some of the fields in the clone are reinitialized, but it's +missing to init io_lock. In mainline this goes unnoticed, but on RT it +leaves the plist pointing to the original about to be freed lock +struct. + +Initialize io_lock after cloning, so no references to the original +struct are left. + +Reported-and-tested-by: Mike Galbraith +Signed-off-by: Thomas Gleixner +Signed-off-by: Chris Mason +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/volumes.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/fs/btrfs/volumes.c ++++ b/fs/btrfs/volumes.c +@@ -647,6 +647,7 @@ static int __btrfs_close_devices(struct + new_device->writeable = 0; + new_device->in_fs_metadata = 0; + new_device->can_discard = 0; ++ spin_lock_init(&new_device->io_lock); + list_replace_rcu(&device->dev_list, &new_device->dev_list); + + call_rcu(&device->rcu, free_device); diff --git a/queue-3.8/cifs-ensure-that-cifs_get_root-only-traverses-directories.patch b/queue-3.8/cifs-ensure-that-cifs_get_root-only-traverses-directories.patch new file mode 100644 index 00000000000..1ae86a61882 --- /dev/null +++ b/queue-3.8/cifs-ensure-that-cifs_get_root-only-traverses-directories.patch @@ -0,0 +1,92 @@ +From ce2ac52105aa663056dfc17966ebed1bf93e6e64 Mon Sep 17 00:00:00 2001 +From: Jeff Layton +Date: Fri, 1 Feb 2013 15:11:01 -0500 +Subject: cifs: ensure that cifs_get_root() only traverses directories + +From: Jeff Layton + +commit ce2ac52105aa663056dfc17966ebed1bf93e6e64 upstream. + +Kjell Braden reported this oops: + +[ 833.211970] BUG: unable to handle kernel NULL pointer dereference at (null) +[ 833.212816] IP: [< (null)>] (null) +[ 833.213280] PGD 1b9b2067 PUD e9f7067 PMD 0 +[ 833.213874] Oops: 0010 [#1] SMP +[ 833.214344] CPU 0 +[ 833.214458] Modules linked in: des_generic md4 nls_utf8 cifs vboxvideo drm snd_intel8x0 snd_ac97_codec ac97_bus snd_pcm snd_seq_midi snd_rawmidi snd_seq_midi_event snd_seq bnep rfcomm snd_timer bluetooth snd_seq_device ppdev snd vboxguest parport_pc joydev mac_hid soundcore snd_page_alloc psmouse i2c_piix4 serio_raw lp parport usbhid hid e1000 +[ 833.215629] +[ 833.215629] Pid: 1752, comm: mount.cifs Not tainted 3.0.0-rc7-bisectcifs-fec11dd9a0+ #18 innotek GmbH VirtualBox/VirtualBox +[ 833.215629] RIP: 0010:[<0000000000000000>] [< (null)>] (null) +[ 833.215629] RSP: 0018:ffff8800119c9c50 EFLAGS: 00010282 +[ 833.215629] RAX: ffffffffa02186c0 RBX: ffff88000c427780 RCX: 0000000000000000 +[ 833.215629] RDX: 0000000000000000 RSI: ffff88000c427780 RDI: ffff88000c4362e8 +[ 833.215629] RBP: ffff8800119c9c88 R08: ffff88001fc15e30 R09: 00000000d69515c7 +[ 833.215629] R10: ffffffffa0201972 R11: ffff88000e8f6a28 R12: ffff88000c4362e8 +[ 833.215629] R13: 0000000000000000 R14: 0000000000000000 R15: ffff88001181aaa6 +[ 833.215629] FS: 00007f2986171700(0000) GS:ffff88001fc00000(0000) knlGS:0000000000000000 +[ 833.215629] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b +[ 833.215629] CR2: 0000000000000000 CR3: 000000001b982000 CR4: 00000000000006f0 +[ 833.215629] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +[ 833.215629] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 +[ 833.215629] Process mount.cifs (pid: 1752, threadinfo ffff8800119c8000, task ffff88001c1c16f0) +[ 833.215629] Stack: +[ 833.215629] ffffffff8116a9b5 ffff8800119c9c88 ffffffff81178075 0000000000000286 +[ 833.215629] 0000000000000000 ffff88000c4276c0 ffff8800119c9ce8 ffff8800119c9cc8 +[ 833.215629] ffffffff8116b06e ffff88001bc6fc00 ffff88000c4276c0 ffff88000c4276c0 +[ 833.215629] Call Trace: +[ 833.215629] [] ? d_alloc_and_lookup+0x45/0x90 +[ 833.215629] [] ? d_lookup+0x35/0x60 +[ 833.215629] [] __lookup_hash.part.14+0x9e/0xc0 +[ 833.215629] [] lookup_one_len+0x146/0x1e0 +[ 833.215629] [] ? _raw_spin_lock+0xe/0x20 +[ 833.215629] [] cifs_do_mount+0x26d/0x500 [cifs] +[ 833.215629] [] mount_fs+0x43/0x1b0 +[ 833.215629] [] vfs_kern_mount+0x6a/0xd0 +[ 833.215629] [] do_kern_mount+0x54/0x110 +[ 833.215629] [] do_mount+0x262/0x840 +[ 833.215629] [] ? __get_free_pages+0xe/0x50 +[ 833.215629] [] ? copy_mount_options+0x3a/0x180 +[ 833.215629] [] sys_mount+0x8d/0xe0 +[ 833.215629] [] system_call_fastpath+0x16/0x1b +[ 833.215629] Code: Bad RIP value. +[ 833.215629] RIP [< (null)>] (null) +[ 833.215629] RSP +[ 833.215629] CR2: 0000000000000000 +[ 833.238525] ---[ end trace ec00758b8d44f529 ]--- + +When walking down the path on the server, it's possible to hit a +symlink. The path walking code assumes that the caller will handle that +situation properly, but cifs_get_root() isn't set up for it. This patch +prevents the oops by simply returning an error. + +A better solution would be to try and chase the symlinks here, but that's +fairly complicated to handle. + +Fixes: + + https://bugzilla.kernel.org/show_bug.cgi?id=53221 + +Reported-and-tested-by: Kjell Braden +Signed-off-by: Jeff Layton +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman + +--- + fs/cifs/cifsfs.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/fs/cifs/cifsfs.c ++++ b/fs/cifs/cifsfs.c +@@ -558,6 +558,11 @@ cifs_get_root(struct smb_vol *vol, struc + dentry = ERR_PTR(-ENOENT); + break; + } ++ if (!S_ISDIR(dir->i_mode)) { ++ dput(dentry); ++ dentry = ERR_PTR(-ENOTDIR); ++ break; ++ } + + /* skip separators */ + while (*s == sep) diff --git a/queue-3.8/dm-do-not-replace-bioset-for-request-based-dm.patch b/queue-3.8/dm-do-not-replace-bioset-for-request-based-dm.patch new file mode 100644 index 00000000000..6c6365aabc6 --- /dev/null +++ b/queue-3.8/dm-do-not-replace-bioset-for-request-based-dm.patch @@ -0,0 +1,108 @@ +From 16245bdc9d3e22d1460341a655c8b5288953bc14 Mon Sep 17 00:00:00 2001 +From: Jun'ichi Nomura +Date: Fri, 1 Mar 2013 22:45:44 +0000 +Subject: dm: do not replace bioset for request based dm + +From: Jun'ichi Nomura + +commit 16245bdc9d3e22d1460341a655c8b5288953bc14 upstream. + +This patch fixes a regression introduced in v3.8, which causes oops +like this when dm-multipath is used: + +general protection fault: 0000 [#1] SMP +RIP: 0010:[] [] mempool_free+0x24/0xb0 +Call Trace: + + [] bio_put+0x97/0xc0 + [] end_clone_bio+0x35/0x90 [dm_mod] + [] bio_endio+0x1d/0x30 + [] req_bio_endio.isra.51+0xa3/0xe0 + [] blk_update_request+0x118/0x520 + [] blk_update_bidi_request+0x27/0xa0 + [] blk_end_bidi_request+0x2c/0x80 + [] blk_end_request+0x10/0x20 + [] scsi_io_completion+0xfb/0x6c0 [scsi_mod] + [] scsi_finish_command+0xbd/0x120 [scsi_mod] + [] scsi_softirq_done+0x13f/0x160 [scsi_mod] + [] blk_done_softirq+0x80/0xa0 + [] __do_softirq+0xf1/0x250 + [] call_softirq+0x1c/0x30 + [] do_softirq+0x8d/0xc0 + [] irq_exit+0xd5/0xe0 + [] do_IRQ+0x63/0xe0 + [] common_interrupt+0x6f/0x6f + + [] srp_queuecommand+0x8c/0xcb0 [ib_srp] + [] scsi_dispatch_cmd+0x148/0x310 [scsi_mod] + [] scsi_request_fn+0x31e/0x520 [scsi_mod] + [] __blk_run_queue+0x37/0x50 + [] blk_delay_work+0x29/0x40 + [] process_one_work+0x1c3/0x5c0 + [] worker_thread+0x15e/0x440 + [] kthread+0xdb/0xe0 + [] ret_from_fork+0x7c/0xb0 + +The regression was introduced by the change +c0820cf5 "dm: introduce per_bio_data", where dm started to replace +bioset during table replacement. +For bio-based dm, it is good because clone bios do not exist during the +table replacement. +For request-based dm, however, (not-yet-mapped) clone bios may stay in +request queue and survive during the table replacement. +So freeing the old bioset could cause the oops in bio_put(). + +Since the size of front_pad may change only with bio-based dm, +it is not necessary to replace bioset for request-based dm. + +Reported-by: Bart Van Assche +Tested-by: Bart Van Assche +Signed-off-by: Jun'ichi Nomura +Acked-by: Mikulas Patocka +Acked-by: Mike Snitzer +Signed-off-by: Alasdair G Kergon +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/dm.c | 30 +++++++++++++++++++++--------- + 1 file changed, 21 insertions(+), 9 deletions(-) + +--- a/drivers/md/dm.c ++++ b/drivers/md/dm.c +@@ -1973,15 +1973,27 @@ static void __bind_mempools(struct mappe + { + struct dm_md_mempools *p = dm_table_get_md_mempools(t); + +- if (md->io_pool && (md->tio_pool || dm_table_get_type(t) == DM_TYPE_BIO_BASED) && md->bs) { +- /* +- * The md already has necessary mempools. Reload just the +- * bioset because front_pad may have changed because +- * a different table was loaded. +- */ +- bioset_free(md->bs); +- md->bs = p->bs; +- p->bs = NULL; ++ if (md->io_pool && md->bs) { ++ /* The md already has necessary mempools. */ ++ if (dm_table_get_type(t) == DM_TYPE_BIO_BASED) { ++ /* ++ * Reload bioset because front_pad may have changed ++ * because a different table was loaded. ++ */ ++ bioset_free(md->bs); ++ md->bs = p->bs; ++ p->bs = NULL; ++ } else if (dm_table_get_type(t) == DM_TYPE_REQUEST_BASED) { ++ BUG_ON(!md->tio_pool); ++ /* ++ * There's no need to reload with request-based dm ++ * because the size of front_pad doesn't change. ++ * Note for future: If you are to reload bioset, ++ * prep-ed requests in the queue may refer ++ * to bio from the old bioset, so you must walk ++ * through the queue to unprep. ++ */ ++ } + goto out; + } + diff --git a/queue-3.8/dm-fix-limits-initialization-when-there-are-no-data-devices.patch b/queue-3.8/dm-fix-limits-initialization-when-there-are-no-data-devices.patch new file mode 100644 index 00000000000..29dd208a01c --- /dev/null +++ b/queue-3.8/dm-fix-limits-initialization-when-there-are-no-data-devices.patch @@ -0,0 +1,57 @@ +From 87eb5b21d92a92ac2da3163039d62df88c2b8422 Mon Sep 17 00:00:00 2001 +From: Mike Christie +Date: Fri, 1 Mar 2013 22:45:48 +0000 +Subject: dm: fix limits initialization when there are no data devices + +From: Mike Christie + +commit 87eb5b21d92a92ac2da3163039d62df88c2b8422 upstream. + +dm_calculate_queue_limits will first reset the provided limits to +defaults using blk_set_stacking_limits; whereby defeating the purpose of +retaining the original live table's limits -- as was intended via commit +3ae706561637331aa578e52bb89ecbba5edcb7a9 ("dm: retain table limits when +swapping to new table with no devices"). + +Fix this improper limits initialization (in the no data devices case) by +avoiding the call to dm_calculate_queue_limits. + +[patch header revised by Mike Snitzer] + +Signed-off-by: Mike Christie +Signed-off-by: Mike Snitzer +Signed-off-by: Alasdair G Kergon +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/dm.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +--- a/drivers/md/dm.c ++++ b/drivers/md/dm.c +@@ -2433,7 +2433,7 @@ static void dm_queue_flush(struct mapped + */ + struct dm_table *dm_swap_table(struct mapped_device *md, struct dm_table *table) + { +- struct dm_table *live_map, *map = ERR_PTR(-EINVAL); ++ struct dm_table *live_map = NULL, *map = ERR_PTR(-EINVAL); + struct queue_limits limits; + int r; + +@@ -2456,10 +2456,12 @@ struct dm_table *dm_swap_table(struct ma + dm_table_put(live_map); + } + +- r = dm_calculate_queue_limits(table, &limits); +- if (r) { +- map = ERR_PTR(r); +- goto out; ++ if (!live_map) { ++ r = dm_calculate_queue_limits(table, &limits); ++ if (r) { ++ map = ERR_PTR(r); ++ goto out; ++ } + } + + map = __bind(md, table, &limits); diff --git a/queue-3.8/dm-fix-truncated-status-strings.patch b/queue-3.8/dm-fix-truncated-status-strings.patch new file mode 100644 index 00000000000..89bfaa47f1f --- /dev/null +++ b/queue-3.8/dm-fix-truncated-status-strings.patch @@ -0,0 +1,645 @@ +From fd7c092e711ebab55b2688d3859d95dfd0301f73 Mon Sep 17 00:00:00 2001 +From: Mikulas Patocka +Date: Fri, 1 Mar 2013 22:45:44 +0000 +Subject: dm: fix truncated status strings + +From: Mikulas Patocka + +commit fd7c092e711ebab55b2688d3859d95dfd0301f73 upstream. + +Avoid returning a truncated table or status string instead of setting +the DM_BUFFER_FULL_FLAG when the last target of a table fills the +buffer. + +When processing a table or status request, the function retrieve_status +calls ti->type->status. If ti->type->status returns non-zero, +retrieve_status assumes that the buffer overflowed and sets +DM_BUFFER_FULL_FLAG. + +However, targets don't return non-zero values from their status method +on overflow. Most targets returns always zero. + +If a buffer overflow happens in a target that is not the last in the +table, it gets noticed during the next iteration of the loop in +retrieve_status; but if a buffer overflow happens in the last target, it +goes unnoticed and erroneously truncated data is returned. + +In the current code, the targets behave in the following way: +* dm-crypt returns -ENOMEM if there is not enough space to store the + key, but it returns 0 on all other overflows. +* dm-thin returns errors from the status method if a disk error happened. + This is incorrect because retrieve_status doesn't check the error + code, it assumes that all non-zero values mean buffer overflow. +* all the other targets always return 0. + +This patch changes the ti->type->status function to return void (because +most targets don't use the return code). Overflow is detected in +retrieve_status: if the status method fills up the remaining space +completely, it is assumed that buffer overflow happened. + +Signed-off-by: Mikulas Patocka +Signed-off-by: Alasdair G Kergon +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/dm-crypt.c | 39 ++++--------------- + drivers/md/dm-delay.c | 8 +--- + drivers/md/dm-flakey.c | 7 +-- + drivers/md/dm-ioctl.c | 14 ++++--- + drivers/md/dm-linear.c | 7 +-- + drivers/md/dm-mpath.c | 8 +--- + drivers/md/dm-raid.c | 8 +--- + drivers/md/dm-raid1.c | 8 +--- + drivers/md/dm-snap.c | 16 +++----- + drivers/md/dm-stripe.c | 7 +-- + drivers/md/dm-thin.c | 82 +++++++++++++++++++++++++----------------- + drivers/md/dm-verity.c | 8 +--- + include/linux/device-mapper.h | 4 +- + 13 files changed, 100 insertions(+), 116 deletions(-) + +--- a/drivers/md/dm-crypt.c ++++ b/drivers/md/dm-crypt.c +@@ -1234,20 +1234,6 @@ static int crypt_decode_key(u8 *key, cha + return 0; + } + +-/* +- * Encode key into its hex representation +- */ +-static void crypt_encode_key(char *hex, u8 *key, unsigned int size) +-{ +- unsigned int i; +- +- for (i = 0; i < size; i++) { +- sprintf(hex, "%02x", *key); +- hex += 2; +- key++; +- } +-} +- + static void crypt_free_tfms(struct crypt_config *cc) + { + unsigned i; +@@ -1717,11 +1703,11 @@ static int crypt_map(struct dm_target *t + return DM_MAPIO_SUBMITTED; + } + +-static int crypt_status(struct dm_target *ti, status_type_t type, +- unsigned status_flags, char *result, unsigned maxlen) ++static void crypt_status(struct dm_target *ti, status_type_t type, ++ unsigned status_flags, char *result, unsigned maxlen) + { + struct crypt_config *cc = ti->private; +- unsigned int sz = 0; ++ unsigned i, sz = 0; + + switch (type) { + case STATUSTYPE_INFO: +@@ -1731,17 +1717,11 @@ static int crypt_status(struct dm_target + case STATUSTYPE_TABLE: + DMEMIT("%s ", cc->cipher_string); + +- if (cc->key_size > 0) { +- if ((maxlen - sz) < ((cc->key_size << 1) + 1)) +- return -ENOMEM; +- +- crypt_encode_key(result + sz, cc->key, cc->key_size); +- sz += cc->key_size << 1; +- } else { +- if (sz >= maxlen) +- return -ENOMEM; +- result[sz++] = '-'; +- } ++ if (cc->key_size > 0) ++ for (i = 0; i < cc->key_size; i++) ++ DMEMIT("%02x", cc->key[i]); ++ else ++ DMEMIT("-"); + + DMEMIT(" %llu %s %llu", (unsigned long long)cc->iv_offset, + cc->dev->name, (unsigned long long)cc->start); +@@ -1751,7 +1731,6 @@ static int crypt_status(struct dm_target + + break; + } +- return 0; + } + + static void crypt_postsuspend(struct dm_target *ti) +@@ -1845,7 +1824,7 @@ static int crypt_iterate_devices(struct + + static struct target_type crypt_target = { + .name = "crypt", +- .version = {1, 12, 0}, ++ .version = {1, 12, 1}, + .module = THIS_MODULE, + .ctr = crypt_ctr, + .dtr = crypt_dtr, +--- a/drivers/md/dm-delay.c ++++ b/drivers/md/dm-delay.c +@@ -293,8 +293,8 @@ static int delay_map(struct dm_target *t + return delay_bio(dc, dc->read_delay, bio); + } + +-static int delay_status(struct dm_target *ti, status_type_t type, +- unsigned status_flags, char *result, unsigned maxlen) ++static void delay_status(struct dm_target *ti, status_type_t type, ++ unsigned status_flags, char *result, unsigned maxlen) + { + struct delay_c *dc = ti->private; + int sz = 0; +@@ -314,8 +314,6 @@ static int delay_status(struct dm_target + dc->write_delay); + break; + } +- +- return 0; + } + + static int delay_iterate_devices(struct dm_target *ti, +@@ -337,7 +335,7 @@ out: + + static struct target_type delay_target = { + .name = "delay", +- .version = {1, 2, 0}, ++ .version = {1, 2, 1}, + .module = THIS_MODULE, + .ctr = delay_ctr, + .dtr = delay_dtr, +--- a/drivers/md/dm-flakey.c ++++ b/drivers/md/dm-flakey.c +@@ -337,8 +337,8 @@ static int flakey_end_io(struct dm_targe + return error; + } + +-static int flakey_status(struct dm_target *ti, status_type_t type, +- unsigned status_flags, char *result, unsigned maxlen) ++static void flakey_status(struct dm_target *ti, status_type_t type, ++ unsigned status_flags, char *result, unsigned maxlen) + { + unsigned sz = 0; + struct flakey_c *fc = ti->private; +@@ -368,7 +368,6 @@ static int flakey_status(struct dm_targe + + break; + } +- return 0; + } + + static int flakey_ioctl(struct dm_target *ti, unsigned int cmd, unsigned long arg) +@@ -411,7 +410,7 @@ static int flakey_iterate_devices(struct + + static struct target_type flakey_target = { + .name = "flakey", +- .version = {1, 3, 0}, ++ .version = {1, 3, 1}, + .module = THIS_MODULE, + .ctr = flakey_ctr, + .dtr = flakey_dtr, +--- a/drivers/md/dm-ioctl.c ++++ b/drivers/md/dm-ioctl.c +@@ -1067,6 +1067,7 @@ static void retrieve_status(struct dm_ta + num_targets = dm_table_get_num_targets(table); + for (i = 0; i < num_targets; i++) { + struct dm_target *ti = dm_table_get_target(table, i); ++ size_t l; + + remaining = len - (outptr - outbuf); + if (remaining <= sizeof(struct dm_target_spec)) { +@@ -1093,14 +1094,17 @@ static void retrieve_status(struct dm_ta + if (ti->type->status) { + if (param->flags & DM_NOFLUSH_FLAG) + status_flags |= DM_STATUS_NOFLUSH_FLAG; +- if (ti->type->status(ti, type, status_flags, outptr, remaining)) { +- param->flags |= DM_BUFFER_FULL_FLAG; +- break; +- } ++ ti->type->status(ti, type, status_flags, outptr, remaining); + } else + outptr[0] = '\0'; + +- outptr += strlen(outptr) + 1; ++ l = strlen(outptr) + 1; ++ if (l == remaining) { ++ param->flags |= DM_BUFFER_FULL_FLAG; ++ break; ++ } ++ ++ outptr += l; + used = param->data_start + (outptr - outbuf); + + outptr = align_ptr(outptr); +--- a/drivers/md/dm-linear.c ++++ b/drivers/md/dm-linear.c +@@ -95,8 +95,8 @@ static int linear_map(struct dm_target * + return DM_MAPIO_REMAPPED; + } + +-static int linear_status(struct dm_target *ti, status_type_t type, +- unsigned status_flags, char *result, unsigned maxlen) ++static void linear_status(struct dm_target *ti, status_type_t type, ++ unsigned status_flags, char *result, unsigned maxlen) + { + struct linear_c *lc = (struct linear_c *) ti->private; + +@@ -110,7 +110,6 @@ static int linear_status(struct dm_targe + (unsigned long long)lc->start); + break; + } +- return 0; + } + + static int linear_ioctl(struct dm_target *ti, unsigned int cmd, +@@ -155,7 +154,7 @@ static int linear_iterate_devices(struct + + static struct target_type linear_target = { + .name = "linear", +- .version = {1, 2, 0}, ++ .version = {1, 2, 1}, + .module = THIS_MODULE, + .ctr = linear_ctr, + .dtr = linear_dtr, +--- a/drivers/md/dm-mpath.c ++++ b/drivers/md/dm-mpath.c +@@ -1378,8 +1378,8 @@ static void multipath_resume(struct dm_t + * [priority selector-name num_ps_args [ps_args]* + * num_paths num_selector_args [path_dev [selector_args]* ]+ ]+ + */ +-static int multipath_status(struct dm_target *ti, status_type_t type, +- unsigned status_flags, char *result, unsigned maxlen) ++static void multipath_status(struct dm_target *ti, status_type_t type, ++ unsigned status_flags, char *result, unsigned maxlen) + { + int sz = 0; + unsigned long flags; +@@ -1485,8 +1485,6 @@ static int multipath_status(struct dm_ta + } + + spin_unlock_irqrestore(&m->lock, flags); +- +- return 0; + } + + static int multipath_message(struct dm_target *ti, unsigned argc, char **argv) +@@ -1695,7 +1693,7 @@ out: + *---------------------------------------------------------------*/ + static struct target_type multipath_target = { + .name = "multipath", +- .version = {1, 5, 0}, ++ .version = {1, 5, 1}, + .module = THIS_MODULE, + .ctr = multipath_ctr, + .dtr = multipath_dtr, +--- a/drivers/md/dm-raid.c ++++ b/drivers/md/dm-raid.c +@@ -1201,8 +1201,8 @@ static int raid_map(struct dm_target *ti + return DM_MAPIO_SUBMITTED; + } + +-static int raid_status(struct dm_target *ti, status_type_t type, +- unsigned status_flags, char *result, unsigned maxlen) ++static void raid_status(struct dm_target *ti, status_type_t type, ++ unsigned status_flags, char *result, unsigned maxlen) + { + struct raid_set *rs = ti->private; + unsigned raid_param_cnt = 1; /* at least 1 for chunksize */ +@@ -1344,8 +1344,6 @@ static int raid_status(struct dm_target + DMEMIT(" -"); + } + } +- +- return 0; + } + + static int raid_iterate_devices(struct dm_target *ti, iterate_devices_callout_fn fn, void *data) +@@ -1405,7 +1403,7 @@ static void raid_resume(struct dm_target + + static struct target_type raid_target = { + .name = "raid", +- .version = {1, 4, 1}, ++ .version = {1, 4, 2}, + .module = THIS_MODULE, + .ctr = raid_ctr, + .dtr = raid_dtr, +--- a/drivers/md/dm-raid1.c ++++ b/drivers/md/dm-raid1.c +@@ -1347,8 +1347,8 @@ static char device_status_char(struct mi + } + + +-static int mirror_status(struct dm_target *ti, status_type_t type, +- unsigned status_flags, char *result, unsigned maxlen) ++static void mirror_status(struct dm_target *ti, status_type_t type, ++ unsigned status_flags, char *result, unsigned maxlen) + { + unsigned int m, sz = 0; + struct mirror_set *ms = (struct mirror_set *) ti->private; +@@ -1383,8 +1383,6 @@ static int mirror_status(struct dm_targe + if (ms->features & DM_RAID1_HANDLE_ERRORS) + DMEMIT(" 1 handle_errors"); + } +- +- return 0; + } + + static int mirror_iterate_devices(struct dm_target *ti, +@@ -1403,7 +1401,7 @@ static int mirror_iterate_devices(struct + + static struct target_type mirror_target = { + .name = "mirror", +- .version = {1, 13, 1}, ++ .version = {1, 13, 2}, + .module = THIS_MODULE, + .ctr = mirror_ctr, + .dtr = mirror_dtr, +--- a/drivers/md/dm-snap.c ++++ b/drivers/md/dm-snap.c +@@ -1837,8 +1837,8 @@ static void snapshot_merge_resume(struct + start_merge(s); + } + +-static int snapshot_status(struct dm_target *ti, status_type_t type, +- unsigned status_flags, char *result, unsigned maxlen) ++static void snapshot_status(struct dm_target *ti, status_type_t type, ++ unsigned status_flags, char *result, unsigned maxlen) + { + unsigned sz = 0; + struct dm_snapshot *snap = ti->private; +@@ -1884,8 +1884,6 @@ static int snapshot_status(struct dm_tar + maxlen - sz); + break; + } +- +- return 0; + } + + static int snapshot_iterate_devices(struct dm_target *ti, +@@ -2139,8 +2137,8 @@ static void origin_resume(struct dm_targ + ti->max_io_len = get_origin_minimum_chunksize(dev->bdev); + } + +-static int origin_status(struct dm_target *ti, status_type_t type, +- unsigned status_flags, char *result, unsigned maxlen) ++static void origin_status(struct dm_target *ti, status_type_t type, ++ unsigned status_flags, char *result, unsigned maxlen) + { + struct dm_dev *dev = ti->private; + +@@ -2153,8 +2151,6 @@ static int origin_status(struct dm_targe + snprintf(result, maxlen, "%s", dev->name); + break; + } +- +- return 0; + } + + static int origin_merge(struct dm_target *ti, struct bvec_merge_data *bvm, +@@ -2181,7 +2177,7 @@ static int origin_iterate_devices(struct + + static struct target_type origin_target = { + .name = "snapshot-origin", +- .version = {1, 8, 0}, ++ .version = {1, 8, 1}, + .module = THIS_MODULE, + .ctr = origin_ctr, + .dtr = origin_dtr, +@@ -2194,7 +2190,7 @@ static struct target_type origin_target + + static struct target_type snapshot_target = { + .name = "snapshot", +- .version = {1, 11, 0}, ++ .version = {1, 11, 1}, + .module = THIS_MODULE, + .ctr = snapshot_ctr, + .dtr = snapshot_dtr, +--- a/drivers/md/dm-stripe.c ++++ b/drivers/md/dm-stripe.c +@@ -312,8 +312,8 @@ static int stripe_map(struct dm_target * + * + */ + +-static int stripe_status(struct dm_target *ti, status_type_t type, +- unsigned status_flags, char *result, unsigned maxlen) ++static void stripe_status(struct dm_target *ti, status_type_t type, ++ unsigned status_flags, char *result, unsigned maxlen) + { + struct stripe_c *sc = (struct stripe_c *) ti->private; + char buffer[sc->stripes + 1]; +@@ -340,7 +340,6 @@ static int stripe_status(struct dm_targe + (unsigned long long)sc->stripe[i].physical_start); + break; + } +- return 0; + } + + static int stripe_end_io(struct dm_target *ti, struct bio *bio, int error) +@@ -428,7 +427,7 @@ static int stripe_merge(struct dm_target + + static struct target_type stripe_target = { + .name = "striped", +- .version = {1, 5, 0}, ++ .version = {1, 5, 1}, + .module = THIS_MODULE, + .ctr = stripe_ctr, + .dtr = stripe_dtr, +--- a/drivers/md/dm-thin.c ++++ b/drivers/md/dm-thin.c +@@ -2299,8 +2299,8 @@ static void emit_flags(struct pool_featu + * / + * / + */ +-static int pool_status(struct dm_target *ti, status_type_t type, +- unsigned status_flags, char *result, unsigned maxlen) ++static void pool_status(struct dm_target *ti, status_type_t type, ++ unsigned status_flags, char *result, unsigned maxlen) + { + int r; + unsigned sz = 0; +@@ -2326,32 +2326,41 @@ static int pool_status(struct dm_target + if (!(status_flags & DM_STATUS_NOFLUSH_FLAG) && !dm_suspended(ti)) + (void) commit_or_fallback(pool); + +- r = dm_pool_get_metadata_transaction_id(pool->pmd, +- &transaction_id); +- if (r) +- return r; +- +- r = dm_pool_get_free_metadata_block_count(pool->pmd, +- &nr_free_blocks_metadata); +- if (r) +- return r; ++ r = dm_pool_get_metadata_transaction_id(pool->pmd, &transaction_id); ++ if (r) { ++ DMERR("dm_pool_get_metadata_transaction_id returned %d", r); ++ goto err; ++ } ++ ++ r = dm_pool_get_free_metadata_block_count(pool->pmd, &nr_free_blocks_metadata); ++ if (r) { ++ DMERR("dm_pool_get_free_metadata_block_count returned %d", r); ++ goto err; ++ } + + r = dm_pool_get_metadata_dev_size(pool->pmd, &nr_blocks_metadata); +- if (r) +- return r; ++ if (r) { ++ DMERR("dm_pool_get_metadata_dev_size returned %d", r); ++ goto err; ++ } + +- r = dm_pool_get_free_block_count(pool->pmd, +- &nr_free_blocks_data); +- if (r) +- return r; ++ r = dm_pool_get_free_block_count(pool->pmd, &nr_free_blocks_data); ++ if (r) { ++ DMERR("dm_pool_get_free_block_count returned %d", r); ++ goto err; ++ } + + r = dm_pool_get_data_dev_size(pool->pmd, &nr_blocks_data); +- if (r) +- return r; ++ if (r) { ++ DMERR("dm_pool_get_data_dev_size returned %d", r); ++ goto err; ++ } + + r = dm_pool_get_metadata_snap(pool->pmd, &held_root); +- if (r) +- return r; ++ if (r) { ++ DMERR("dm_pool_get_metadata_snap returned %d", r); ++ goto err; ++ } + + DMEMIT("%llu %llu/%llu %llu/%llu ", + (unsigned long long)transaction_id, +@@ -2388,8 +2397,10 @@ static int pool_status(struct dm_target + emit_flags(&pt->requested_pf, result, sz, maxlen); + break; + } ++ return; + +- return 0; ++err: ++ DMEMIT("Error"); + } + + static int pool_iterate_devices(struct dm_target *ti, +@@ -2468,7 +2479,7 @@ static struct target_type pool_target = + .name = "thin-pool", + .features = DM_TARGET_SINGLETON | DM_TARGET_ALWAYS_WRITEABLE | + DM_TARGET_IMMUTABLE, +- .version = {1, 6, 0}, ++ .version = {1, 6, 1}, + .module = THIS_MODULE, + .ctr = pool_ctr, + .dtr = pool_dtr, +@@ -2676,8 +2687,8 @@ static void thin_postsuspend(struct dm_t + /* + * + */ +-static int thin_status(struct dm_target *ti, status_type_t type, +- unsigned status_flags, char *result, unsigned maxlen) ++static void thin_status(struct dm_target *ti, status_type_t type, ++ unsigned status_flags, char *result, unsigned maxlen) + { + int r; + ssize_t sz = 0; +@@ -2687,7 +2698,7 @@ static int thin_status(struct dm_target + + if (get_pool_mode(tc->pool) == PM_FAIL) { + DMEMIT("Fail"); +- return 0; ++ return; + } + + if (!tc->td) +@@ -2696,12 +2707,16 @@ static int thin_status(struct dm_target + switch (type) { + case STATUSTYPE_INFO: + r = dm_thin_get_mapped_count(tc->td, &mapped); +- if (r) +- return r; ++ if (r) { ++ DMERR("dm_thin_get_mapped_count returned %d", r); ++ goto err; ++ } + + r = dm_thin_get_highest_mapped_block(tc->td, &highest); +- if (r < 0) +- return r; ++ if (r < 0) { ++ DMERR("dm_thin_get_highest_mapped_block returned %d", r); ++ goto err; ++ } + + DMEMIT("%llu ", mapped * tc->pool->sectors_per_block); + if (r) +@@ -2721,7 +2736,10 @@ static int thin_status(struct dm_target + } + } + +- return 0; ++ return; ++ ++err: ++ DMEMIT("Error"); + } + + static int thin_iterate_devices(struct dm_target *ti, +@@ -2748,7 +2766,7 @@ static int thin_iterate_devices(struct d + + static struct target_type thin_target = { + .name = "thin", +- .version = {1, 7, 0}, ++ .version = {1, 7, 1}, + .module = THIS_MODULE, + .ctr = thin_ctr, + .dtr = thin_dtr, +--- a/drivers/md/dm-verity.c ++++ b/drivers/md/dm-verity.c +@@ -508,8 +508,8 @@ static int verity_map(struct dm_target * + /* + * Status: V (valid) or C (corruption found) + */ +-static int verity_status(struct dm_target *ti, status_type_t type, +- unsigned status_flags, char *result, unsigned maxlen) ++static void verity_status(struct dm_target *ti, status_type_t type, ++ unsigned status_flags, char *result, unsigned maxlen) + { + struct dm_verity *v = ti->private; + unsigned sz = 0; +@@ -540,8 +540,6 @@ static int verity_status(struct dm_targe + DMEMIT("%02x", v->salt[x]); + break; + } +- +- return 0; + } + + static int verity_ioctl(struct dm_target *ti, unsigned cmd, +@@ -860,7 +858,7 @@ bad: + + static struct target_type verity_target = { + .name = "verity", +- .version = {1, 1, 0}, ++ .version = {1, 1, 1}, + .module = THIS_MODULE, + .ctr = verity_ctr, + .dtr = verity_dtr, +--- a/include/linux/device-mapper.h ++++ b/include/linux/device-mapper.h +@@ -68,8 +68,8 @@ typedef void (*dm_postsuspend_fn) (struc + typedef int (*dm_preresume_fn) (struct dm_target *ti); + typedef void (*dm_resume_fn) (struct dm_target *ti); + +-typedef int (*dm_status_fn) (struct dm_target *ti, status_type_t status_type, +- unsigned status_flags, char *result, unsigned maxlen); ++typedef void (*dm_status_fn) (struct dm_target *ti, status_type_t status_type, ++ unsigned status_flags, char *result, unsigned maxlen); + + typedef int (*dm_message_fn) (struct dm_target *ti, unsigned argc, char **argv); + diff --git a/queue-3.8/dm-snapshot-add-missing-module-aliases.patch b/queue-3.8/dm-snapshot-add-missing-module-aliases.patch new file mode 100644 index 00000000000..90f0f42fe5f --- /dev/null +++ b/queue-3.8/dm-snapshot-add-missing-module-aliases.patch @@ -0,0 +1,31 @@ +From 23cb21092eb9dcec9d3604b68d95192b79915890 Mon Sep 17 00:00:00 2001 +From: Mikulas Patocka +Date: Fri, 1 Mar 2013 22:45:47 +0000 +Subject: dm snapshot: add missing module aliases + +From: Mikulas Patocka + +commit 23cb21092eb9dcec9d3604b68d95192b79915890 upstream. + +Add module aliases so that autoloading works correctly if the user +tries to activate "snapshot-origin" or "snapshot-merge" targets. + +Reference: https://bugzilla.redhat.com/889973 + +Reported-by: Chao Yang +Signed-off-by: Mikulas Patocka +Signed-off-by: Alasdair G Kergon +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/dm-snap.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/md/dm-snap.c ++++ b/drivers/md/dm-snap.c +@@ -2303,3 +2303,5 @@ module_exit(dm_snapshot_exit); + MODULE_DESCRIPTION(DM_NAME " snapshot target"); + MODULE_AUTHOR("Joe Thornber"); + MODULE_LICENSE("GPL"); ++MODULE_ALIAS("dm-snapshot-origin"); ++MODULE_ALIAS("dm-snapshot-merge"); diff --git a/queue-3.8/ext4-convert-number-of-blocks-to-clusters-properly.patch b/queue-3.8/ext4-convert-number-of-blocks-to-clusters-properly.patch new file mode 100644 index 00000000000..1100af9cf33 --- /dev/null +++ b/queue-3.8/ext4-convert-number-of-blocks-to-clusters-properly.patch @@ -0,0 +1,109 @@ +From 810da240f221d64bf90020f25941b05b378186fe Mon Sep 17 00:00:00 2001 +From: Lukas Czerner +Date: Sat, 2 Mar 2013 17:18:58 -0500 +Subject: ext4: convert number of blocks to clusters properly + +From: Lukas Czerner + +commit 810da240f221d64bf90020f25941b05b378186fe upstream. + +We're using macro EXT4_B2C() to convert number of blocks to number of +clusters for bigalloc file systems. However, we should be using +EXT4_NUM_B2C(). + +Signed-off-by: Lukas Czerner +Signed-off-by: "Theodore Ts'o" +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/balloc.c | 2 +- + fs/ext4/mballoc.c | 8 ++++---- + fs/ext4/resize.c | 6 +++--- + fs/ext4/super.c | 2 +- + 4 files changed, 9 insertions(+), 9 deletions(-) + +--- a/fs/ext4/balloc.c ++++ b/fs/ext4/balloc.c +@@ -635,7 +635,7 @@ ext4_fsblk_t ext4_count_free_clusters(st + brelse(bitmap_bh); + printk(KERN_DEBUG "ext4_count_free_clusters: stored = %llu" + ", computed = %llu, %llu\n", +- EXT4_B2C(EXT4_SB(sb), ext4_free_blocks_count(es)), ++ EXT4_NUM_B2C(EXT4_SB(sb), ext4_free_blocks_count(es)), + desc_count, bitmap_count); + return bitmap_count; + #else +--- a/fs/ext4/mballoc.c ++++ b/fs/ext4/mballoc.c +@@ -3444,7 +3444,7 @@ ext4_mb_new_inode_pa(struct ext4_allocat + win = offs; + + ac->ac_b_ex.fe_logical = ac->ac_o_ex.fe_logical - +- EXT4_B2C(sbi, win); ++ EXT4_NUM_B2C(sbi, win); + BUG_ON(ac->ac_o_ex.fe_logical < ac->ac_b_ex.fe_logical); + BUG_ON(ac->ac_o_ex.fe_len > ac->ac_b_ex.fe_len); + } +@@ -4590,7 +4590,7 @@ do_more: + EXT4_BLOCKS_PER_GROUP(sb); + count -= overflow; + } +- count_clusters = EXT4_B2C(sbi, count); ++ count_clusters = EXT4_NUM_B2C(sbi, count); + bitmap_bh = ext4_read_block_bitmap(sb, block_group); + if (!bitmap_bh) { + err = -EIO; +@@ -4832,11 +4832,11 @@ int ext4_group_add_blocks(handle_t *hand + ext4_group_desc_csum_set(sb, block_group, desc); + ext4_unlock_group(sb, block_group); + percpu_counter_add(&sbi->s_freeclusters_counter, +- EXT4_B2C(sbi, blocks_freed)); ++ EXT4_NUM_B2C(sbi, blocks_freed)); + + if (sbi->s_log_groups_per_flex) { + ext4_group_t flex_group = ext4_flex_group(sbi, block_group); +- atomic_add(EXT4_B2C(sbi, blocks_freed), ++ atomic_add(EXT4_NUM_B2C(sbi, blocks_freed), + &sbi->s_flex_groups[flex_group].free_clusters); + } + +--- a/fs/ext4/resize.c ++++ b/fs/ext4/resize.c +@@ -1247,7 +1247,7 @@ static int ext4_setup_new_descs(handle_t + + ext4_inode_table_set(sb, gdp, group_data->inode_table); + ext4_free_group_clusters_set(sb, gdp, +- EXT4_B2C(sbi, group_data->free_blocks_count)); ++ EXT4_NUM_B2C(sbi, group_data->free_blocks_count)); + ext4_free_inodes_set(sb, gdp, EXT4_INODES_PER_GROUP(sb)); + if (ext4_has_group_desc_csum(sb)) + ext4_itable_unused_set(sb, gdp, +@@ -1349,7 +1349,7 @@ static void ext4_update_super(struct sup + + /* Update the free space counts */ + percpu_counter_add(&sbi->s_freeclusters_counter, +- EXT4_B2C(sbi, free_blocks)); ++ EXT4_NUM_B2C(sbi, free_blocks)); + percpu_counter_add(&sbi->s_freeinodes_counter, + EXT4_INODES_PER_GROUP(sb) * flex_gd->count); + +@@ -1360,7 +1360,7 @@ static void ext4_update_super(struct sup + sbi->s_log_groups_per_flex) { + ext4_group_t flex_group; + flex_group = ext4_flex_group(sbi, group_data[0].group); +- atomic_add(EXT4_B2C(sbi, free_blocks), ++ atomic_add(EXT4_NUM_B2C(sbi, free_blocks), + &sbi->s_flex_groups[flex_group].free_clusters); + atomic_add(EXT4_INODES_PER_GROUP(sb) * flex_gd->count, + &sbi->s_flex_groups[flex_group].free_inodes); +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -3235,7 +3235,7 @@ int ext4_calculate_overhead(struct super + } + /* Add the journal blocks as well */ + if (sbi->s_journal) +- overhead += EXT4_B2C(sbi, sbi->s_journal->j_maxlen); ++ overhead += EXT4_NUM_B2C(sbi, sbi->s_journal->j_maxlen); + + sbi->s_overhead = overhead; + smp_wmb(); diff --git a/queue-3.8/iscsi-target-fix-immediate-queue-starvation-regression-with-datain.patch b/queue-3.8/iscsi-target-fix-immediate-queue-starvation-regression-with-datain.patch new file mode 100644 index 00000000000..aadc945880a --- /dev/null +++ b/queue-3.8/iscsi-target-fix-immediate-queue-starvation-regression-with-datain.patch @@ -0,0 +1,78 @@ +From fd3a9025c0349bc9b01d627529f54e6e1e389015 Mon Sep 17 00:00:00 2001 +From: Nicholas Bellinger +Date: Wed, 27 Feb 2013 17:53:52 -0800 +Subject: iscsi-target: Fix immediate queue starvation regression with DATAIN + +From: Nicholas Bellinger + +commit fd3a9025c0349bc9b01d627529f54e6e1e389015 upstream. + +This patch addresses a v3.5+ regression in iscsi-target where TX thread +process context -> handle_response_queue() execution is allowed to run +unbounded while servicing constant outgoing flow of ISTATE_SEND_DATAIN +response state. + +This ends up preventing memory release of StatSN acknowledged commands +in a timely manner when under heavy large block streaming DATAIN +workloads. + +The regression bug was initially introduced with: + +commit 6f3c0e69a9c20441bdc6d3b2d18b83b244384ec6 +Author: Andy Grover +Date: Tue Apr 3 15:51:09 2012 -0700 + + target/iscsi: Refactor target_tx_thread immediate+response queue loops + +Go ahead and follow original iscsi_target_tx_thread() logic and check +to break for immediate queue processing after each DataIN Sequence and/or +Response PDU has been sent. + +Reported-by: Benjamin ESTRABAUD +Cc: Andy Grover +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/iscsi/iscsi_target.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +--- a/drivers/target/iscsi/iscsi_target.c ++++ b/drivers/target/iscsi/iscsi_target.c +@@ -3570,6 +3570,10 @@ check_rsp_state: + spin_lock_bh(&cmd->istate_lock); + cmd->i_state = ISTATE_SENT_STATUS; + spin_unlock_bh(&cmd->istate_lock); ++ ++ if (atomic_read(&conn->check_immediate_queue)) ++ return 1; ++ + continue; + } else if (ret == 2) { + /* Still must send status, +@@ -3659,7 +3663,7 @@ check_rsp_state: + } + + if (atomic_read(&conn->check_immediate_queue)) +- break; ++ return 1; + } + + return 0; +@@ -3703,12 +3707,15 @@ restart: + signal_pending(current)) + goto transport_err; + ++get_immediate: + ret = handle_immediate_queue(conn); + if (ret < 0) + goto transport_err; + + ret = handle_response_queue(conn); +- if (ret == -EAGAIN) ++ if (ret == 1) ++ goto get_immediate; ++ else if (ret == -EAGAIN) + goto restart; + else if (ret < 0) + goto transport_err; diff --git a/queue-3.8/nfs-don-t-allow-nfs-silly-renamed-files-to-be-deleted-no-signal.patch b/queue-3.8/nfs-don-t-allow-nfs-silly-renamed-files-to-be-deleted-no-signal.patch new file mode 100644 index 00000000000..1776071a34f --- /dev/null +++ b/queue-3.8/nfs-don-t-allow-nfs-silly-renamed-files-to-be-deleted-no-signal.patch @@ -0,0 +1,90 @@ +From 5a7a613a47a715711b3f2d3322a0eac21d459166 Mon Sep 17 00:00:00 2001 +From: Trond Myklebust +Date: Fri, 22 Feb 2013 12:53:43 -0500 +Subject: NFS: Don't allow NFS silly-renamed files to be deleted, no signal + +From: Trond Myklebust + +commit 5a7a613a47a715711b3f2d3322a0eac21d459166 upstream. + +Commit 73ca100 broke the code that prevents the client from deleting +a silly renamed dentry. This affected "delete on last close" +semantics as after that commit, nothing prevented removal of +silly-renamed files. As a result, a process holding a file open +could easily get an ESTALE on the file in a directory where some +other process issued 'rm -rf some_dir_containing_the_file' twice. +Before the commit, any attempt at unlinking silly renamed files would +fail inside may_delete() with -EBUSY because of the +DCACHE_NFSFS_RENAMED flag. The following testcase demonstrates +the problem: + tail -f /nfsmnt/dir/file & + rm -rf /nfsmnt/dir + rm -rf /nfsmnt/dir + # second removal does not fail, 'tail' process receives ESTALE + +The problem with the above commit is that it unhashes the old and +new dentries from the lookup path, even in the normal case when +a signal is not encountered and it would have been safe to call +d_move. Unfortunately the old dentry has the special +DCACHE_NFSFS_RENAMED flag set on it. Unhashing has the +side-effect that future lookups call d_alloc(), allocating a new +dentry without the special flag for any silly-renamed files. As a +result, subsequent calls to unlink silly renamed files do not fail +but allow the removal to go through. This will result in ESTALE +errors for any other process doing operations on the file. + +To fix this, go back to using d_move on success. +For the signal case, it's unclear what we may safely do beyond d_drop. + +Reported-by: Dave Wysochanski +Signed-off-by: Trond Myklebust +Acked-by: Jeff Layton +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfs/unlink.c | 20 +++++++++++++------- + 1 file changed, 13 insertions(+), 7 deletions(-) + +--- a/fs/nfs/unlink.c ++++ b/fs/nfs/unlink.c +@@ -336,20 +336,14 @@ static void nfs_async_rename_done(struct + struct inode *old_dir = data->old_dir; + struct inode *new_dir = data->new_dir; + struct dentry *old_dentry = data->old_dentry; +- struct dentry *new_dentry = data->new_dentry; + + if (!NFS_PROTO(old_dir)->rename_done(task, old_dir, new_dir)) { + rpc_restart_call_prepare(task); + return; + } + +- if (task->tk_status != 0) { ++ if (task->tk_status != 0) + nfs_cancel_async_unlink(old_dentry); +- return; +- } +- +- d_drop(old_dentry); +- d_drop(new_dentry); + } + + /** +@@ -550,6 +544,18 @@ nfs_sillyrename(struct inode *dir, struc + error = rpc_wait_for_completion_task(task); + if (error == 0) + error = task->tk_status; ++ switch (error) { ++ case 0: ++ /* The rename succeeded */ ++ nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); ++ d_move(dentry, sdentry); ++ break; ++ case -ERESTARTSYS: ++ /* The result of the rename is unknown. Play it safe by ++ * forcing a new lookup */ ++ d_drop(dentry); ++ d_drop(sdentry); ++ } + rpc_put_task(task); + out_dput: + dput(sdentry); diff --git a/queue-3.8/nfsv4.1-hold-reference-to-layout-hdr-in-layoutget.patch b/queue-3.8/nfsv4.1-hold-reference-to-layout-hdr-in-layoutget.patch new file mode 100644 index 00000000000..ce02764ca59 --- /dev/null +++ b/queue-3.8/nfsv4.1-hold-reference-to-layout-hdr-in-layoutget.patch @@ -0,0 +1,92 @@ +From a47970ff7814718fec31b7d966747c6aa1a3545f Mon Sep 17 00:00:00 2001 +From: Weston Andros Adamson +Date: Mon, 25 Feb 2013 21:27:33 -0500 +Subject: NFSv4.1: Hold reference to layout hdr in layoutget + +From: Weston Andros Adamson + +commit a47970ff7814718fec31b7d966747c6aa1a3545f upstream. + +This fixes an oops where a LAYOUTGET is in still in the rpciod queue, +but the requesting processes has been killed. Without this, killing +the process does the final pnfs_put_layout_hdr() and sets NFS_I(inode)->layout +to NULL while the LAYOUTGET rpc task still references it. + +Example oops: + +BUG: unable to handle kernel NULL pointer dereference at 0000000000000080 +IP: [] pnfs_choose_layoutget_stateid+0x37/0xef [nfsv4] +PGD 7365b067 PUD 7365d067 PMD 0 +Oops: 0000 [#1] SMP DEBUG_PAGEALLOC +Modules linked in: nfs_layout_nfsv41_files nfsv4 auth_rpcgss nfs lockd sunrpc ipt_MASQUERADE ip6table_mangle ip6t_REJECT nf_conntrack_ipv6 nf_defrag_ipv6 iptable_nat nf_nat_ipv4 nf_nat iptable_mangle ip6table_filter ip6_tables ppdev e1000 i2c_piix4 i2c_core shpchp parport_pc parport crc32c_intel aesni_intel xts aes_x86_64 lrw gf128mul ablk_helper cryptd mptspi scsi_transport_spi mptscsih mptbase floppy autofs4 +CPU 0 +Pid: 27, comm: kworker/0:1 Not tainted 3.8.0-dros_cthon2013+ #4 VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform +RIP: 0010:[] [] pnfs_choose_layoutget_stateid+0x37/0xef [nfsv4] +RSP: 0018:ffff88007b0c1c88 EFLAGS: 00010246 +RAX: ffff88006ed36678 RBX: 0000000000000000 RCX: 0000000ea877e3bc +RDX: ffff88007a729da8 RSI: 0000000000000000 RDI: ffff88007a72b958 +RBP: ffff88007b0c1ca8 R08: 0000000000000002 R09: 0000000000000000 +R10: 0000000000000000 R11: 0000000000000000 R12: ffff88007a72b958 +R13: ffff88007a729da8 R14: 0000000000000000 R15: ffffffffa011077e +FS: 0000000000000000(0000) GS:ffff88007f600000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 0000000000000080 CR3: 00000000735f8000 CR4: 00000000001407f0 +DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 +Process kworker/0:1 (pid: 27, threadinfo ffff88007b0c0000, task ffff88007c2fa0c0) +Stack: + ffff88006fc05388 ffff88007a72b908 ffff88007b240900 ffff88006fc05388 + ffff88007b0c1cd8 ffffffffa01a2170 ffff88007b240900 ffff88007b240900 + ffff88007b240970 ffffffffa011077e ffff88007b0c1ce8 ffffffffa0110791 +Call Trace: + [] nfs4_layoutget_prepare+0x7b/0x92 [nfsv4] + [] ? __rpc_atrun+0x15/0x15 [sunrpc] + [] rpc_prepare_task+0x13/0x15 [sunrpc] + +Reported-by: Tigran Mkrtchyan +Signed-off-by: Weston Andros Adamson +Signed-off-by: Trond Myklebust +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfs/nfs4proc.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -6087,11 +6087,13 @@ static struct page **nfs4_alloc_pages(si + static void nfs4_layoutget_release(void *calldata) + { + struct nfs4_layoutget *lgp = calldata; +- struct nfs_server *server = NFS_SERVER(lgp->args.inode); ++ struct inode *inode = lgp->args.inode; ++ struct nfs_server *server = NFS_SERVER(inode); + size_t max_pages = max_response_pages(server); + + dprintk("--> %s\n", __func__); + nfs4_free_pages(lgp->args.layout.pages, max_pages); ++ pnfs_put_layout_hdr(NFS_I(inode)->layout); + put_nfs_open_context(lgp->args.ctx); + kfree(calldata); + dprintk("<-- %s\n", __func__); +@@ -6106,7 +6108,8 @@ static const struct rpc_call_ops nfs4_la + struct pnfs_layout_segment * + nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags) + { +- struct nfs_server *server = NFS_SERVER(lgp->args.inode); ++ struct inode *inode = lgp->args.inode; ++ struct nfs_server *server = NFS_SERVER(inode); + size_t max_pages = max_response_pages(server); + struct rpc_task *task; + struct rpc_message msg = { +@@ -6136,6 +6139,10 @@ nfs4_proc_layoutget(struct nfs4_layoutge + lgp->res.layoutp = &lgp->args.layout; + lgp->res.seq_res.sr_slot = NULL; + nfs41_init_sequence(&lgp->args.seq_args, &lgp->res.seq_res, 0); ++ ++ /* nfs4_layoutget_release calls pnfs_put_layout_hdr */ ++ pnfs_get_layout_hdr(NFS_I(inode)->layout); ++ + task = rpc_run_task(&task_setup_data); + if (IS_ERR(task)) + return ERR_CAST(task); diff --git a/queue-3.8/pnfs-fix-resend_to_mds-for-directio.patch b/queue-3.8/pnfs-fix-resend_to_mds-for-directio.patch new file mode 100644 index 00000000000..4fd09aca444 --- /dev/null +++ b/queue-3.8/pnfs-fix-resend_to_mds-for-directio.patch @@ -0,0 +1,184 @@ +From 78f33277f96430ea001c39e952f6b8200b2ab850 Mon Sep 17 00:00:00 2001 +From: Benny Halevy +Date: Sun, 24 Feb 2013 09:55:57 -0500 +Subject: pnfs: fix resend_to_mds for directio + +From: Benny Halevy + +commit 78f33277f96430ea001c39e952f6b8200b2ab850 upstream. + +Pass the directio request on pageio_init to clean up the API. + +Percolate pg_dreq from original nfs_pageio_descriptor to the +pnfs_{read,write}_done_resend_to_mds and use it on respective +call to nfs_pageio_init_{read,write} on the newly created +nfs_pageio_descriptor. + +Reproduced by command: + mount -o vers=4.1 server:/ /mnt + dd bs=128k count=8 if=/dev/zero of=/mnt/dd.out oflag=direct + +BUG: unable to handle kernel NULL pointer dereference at 0000000000000028 +IP: [] atomic_inc+0x4/0x9 [nfs] +PGD 34786067 PUD 34794067 PMD 0 +Oops: 0002 [#1] SMP +Modules linked in: nfs_layout_nfsv41_files nfsv4 nfs nfsd lockd nfs_acl auth_rpcgss exportfs sunrpc btrfs zlib_deflate libcrc32c ipv6 autofs4 +CPU 1 +Pid: 259, comm: kworker/1:2 Not tainted 3.8.0-rc6 #2 Bochs Bochs +RIP: 0010:[] [] atomic_inc+0x4/0x9 [nfs] +RSP: 0018:ffff880038f8fa68 EFLAGS: 00010206 +RAX: ffffffffa021a6a9 RBX: ffff880038f8fb48 RCX: 00000000000a0000 +RDX: ffffffffa021e616 RSI: ffff8800385e9a40 RDI: 0000000000000028 +RBP: ffff880038f8fa68 R08: ffffffff81ad6720 R09: ffff8800385e9510 +R10: ffffffffa0228450 R11: ffff880038e87418 R12: ffff8800385e9a40 +R13: ffff8800385e9a70 R14: ffff880038f8fb38 R15: ffffffffa0148878 +FS: 0000000000000000(0000) GS:ffff88003e400000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b +CR2: 0000000000000028 CR3: 0000000034789000 CR4: 00000000000006e0 +DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 +Process kworker/1:2 (pid: 259, threadinfo ffff880038f8e000, task ffff880038302480) +Stack: + ffff880038f8fa78 ffffffffa021a6bf ffff880038f8fa88 ffffffffa021bb82 + ffff880038f8fae8 ffffffffa021f454 ffff880038f8fae8 ffffffff8109689d + ffff880038f8fab8 ffffffff00000006 0000000000000000 ffff880038f8fb48 +Call Trace: + [] nfs_direct_pgio_init+0x16/0x18 [nfs] + [] nfs_pgheader_init+0x6a/0x6c [nfs] + [] nfs_generic_pg_writepages+0x51/0xf8 [nfs] + [] ? mark_held_locks+0x71/0x99 + [] ? rpc_release_resources_task+0x37/0x37 [sunrpc] + [] nfs_pageio_doio+0x1a/0x43 [nfs] + [] nfs_pageio_complete+0x16/0x2c [nfs] + [] pnfs_write_done_resend_to_mds+0x95/0xc5 [nfsv4] + [] ? rpc_release_resources_task+0x37/0x37 [sunrpc] + [] filelayout_reset_write+0x8c/0x99 [nfs_layout_nfsv41_files] + [] filelayout_write_done_cb+0x4d/0xc1 [nfs_layout_nfsv41_files] + [] nfs4_write_done+0x36/0x49 [nfsv4] + [] nfs_writeback_done+0x53/0x1cc [nfs] + [] nfs_writeback_done_common+0xe/0x10 [nfs] + [] filelayout_write_call_done+0x28/0x2a [nfs_layout_nfsv41_files] + [] rpc_exit_task+0x29/0x87 [sunrpc] + [] __rpc_execute+0x11d/0x3cc [sunrpc] + [] ? trace_hardirqs_on_caller+0x117/0x173 + [] rpc_async_schedule+0x27/0x32 [sunrpc] + [] ? __rpc_execute+0x3cc/0x3cc [sunrpc] + [] process_one_work+0x226/0x422 + [] ? process_one_work+0x159/0x422 + [] ? lock_acquired+0x210/0x249 + [] ? __rpc_execute+0x3cc/0x3cc [sunrpc] + [] worker_thread+0x126/0x1c4 + [] ? manage_workers+0x240/0x240 + [] kthread+0xb1/0xb9 + [] ? __kthread_parkme+0x65/0x65 + [] ret_from_fork+0x7c/0xb0 + [] ? __kthread_parkme+0x65/0x65 +Code: 00 83 38 02 74 12 48 81 4b 50 00 00 01 00 c7 83 60 07 00 00 01 00 00 00 48 89 df e8 55 fe ff ff 5b 41 5c 5d c3 66 90 55 48 89 e5 ff 07 5d c3 55 48 89 e5 f0 ff 0f 0f 94 c0 84 c0 0f 95 c0 0f +RIP [] atomic_inc+0x4/0x9 [nfs] + RSP +CR2: 0000000000000028 + +Signed-off-by: Benny Halevy +Signed-off-by: Trond Myklebust +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfs/nfs4filelayout.c | 6 ++++-- + fs/nfs/pnfs.c | 14 ++++++++++---- + fs/nfs/pnfs.h | 6 ++++-- + 3 files changed, 18 insertions(+), 8 deletions(-) + +--- a/fs/nfs/nfs4filelayout.c ++++ b/fs/nfs/nfs4filelayout.c +@@ -99,7 +99,8 @@ static void filelayout_reset_write(struc + + task->tk_status = pnfs_write_done_resend_to_mds(hdr->inode, + &hdr->pages, +- hdr->completion_ops); ++ hdr->completion_ops, ++ hdr->dreq); + } + } + +@@ -119,7 +120,8 @@ static void filelayout_reset_read(struct + + task->tk_status = pnfs_read_done_resend_to_mds(hdr->inode, + &hdr->pages, +- hdr->completion_ops); ++ hdr->completion_ops, ++ hdr->dreq); + } + } + +--- a/fs/nfs/pnfs.c ++++ b/fs/nfs/pnfs.c +@@ -1422,13 +1422,15 @@ EXPORT_SYMBOL_GPL(pnfs_generic_pg_test); + + int pnfs_write_done_resend_to_mds(struct inode *inode, + struct list_head *head, +- const struct nfs_pgio_completion_ops *compl_ops) ++ const struct nfs_pgio_completion_ops *compl_ops, ++ struct nfs_direct_req *dreq) + { + struct nfs_pageio_descriptor pgio; + LIST_HEAD(failed); + + /* Resend all requests through the MDS */ + nfs_pageio_init_write(&pgio, inode, FLUSH_STABLE, compl_ops); ++ pgio.pg_dreq = dreq; + while (!list_empty(head)) { + struct nfs_page *req = nfs_list_entry(head->next); + +@@ -1463,7 +1465,8 @@ static void pnfs_ld_handle_write_error(s + if (!test_and_set_bit(NFS_IOHDR_REDO, &hdr->flags)) + data->task.tk_status = pnfs_write_done_resend_to_mds(hdr->inode, + &hdr->pages, +- hdr->completion_ops); ++ hdr->completion_ops, ++ hdr->dreq); + } + + /* +@@ -1578,13 +1581,15 @@ EXPORT_SYMBOL_GPL(pnfs_generic_pg_writep + + int pnfs_read_done_resend_to_mds(struct inode *inode, + struct list_head *head, +- const struct nfs_pgio_completion_ops *compl_ops) ++ const struct nfs_pgio_completion_ops *compl_ops, ++ struct nfs_direct_req *dreq) + { + struct nfs_pageio_descriptor pgio; + LIST_HEAD(failed); + + /* Resend all requests through the MDS */ + nfs_pageio_init_read(&pgio, inode, compl_ops); ++ pgio.pg_dreq = dreq; + while (!list_empty(head)) { + struct nfs_page *req = nfs_list_entry(head->next); + +@@ -1615,7 +1620,8 @@ static void pnfs_ld_handle_read_error(st + if (!test_and_set_bit(NFS_IOHDR_REDO, &hdr->flags)) + data->task.tk_status = pnfs_read_done_resend_to_mds(hdr->inode, + &hdr->pages, +- hdr->completion_ops); ++ hdr->completion_ops, ++ hdr->dreq); + } + + /* +--- a/fs/nfs/pnfs.h ++++ b/fs/nfs/pnfs.h +@@ -230,9 +230,11 @@ struct pnfs_layout_segment *pnfs_update_ + + void nfs4_deviceid_mark_client_invalid(struct nfs_client *clp); + int pnfs_read_done_resend_to_mds(struct inode *inode, struct list_head *head, +- const struct nfs_pgio_completion_ops *compl_ops); ++ const struct nfs_pgio_completion_ops *compl_ops, ++ struct nfs_direct_req *dreq); + int pnfs_write_done_resend_to_mds(struct inode *inode, struct list_head *head, +- const struct nfs_pgio_completion_ops *compl_ops); ++ const struct nfs_pgio_completion_ops *compl_ops, ++ struct nfs_direct_req *dreq); + struct nfs4_threshold *pnfs_mdsthreshold_alloc(void); + + /* nfs4_deviceid_flags */ diff --git a/queue-3.8/scsi-dc395x-uninitialized-variable-in-device_alloc.patch b/queue-3.8/scsi-dc395x-uninitialized-variable-in-device_alloc.patch new file mode 100644 index 00000000000..9bed4a20aeb --- /dev/null +++ b/queue-3.8/scsi-dc395x-uninitialized-variable-in-device_alloc.patch @@ -0,0 +1,38 @@ +From 208afec4f3be8c51ad6eebe6611dd6d2ad2fa298 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Mon, 11 Feb 2013 22:03:18 +0300 +Subject: SCSI: dc395x: uninitialized variable in device_alloc() + +From: Dan Carpenter + +commit 208afec4f3be8c51ad6eebe6611dd6d2ad2fa298 upstream. + +This bug was introduced back in bitkeeper days in 2003. We use +"dcb->dev_mode" before it has been initialized. + +Signed-off-by: Dan Carpenter +Acked-by: Oliver Neukum +Signed-off-by: James Bottomley +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/dc395x.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/scsi/dc395x.c ++++ b/drivers/scsi/dc395x.c +@@ -3747,13 +3747,13 @@ static struct DeviceCtlBlk *device_alloc + dcb->max_command = 1; + dcb->target_id = target; + dcb->target_lun = lun; ++ dcb->dev_mode = eeprom->target[target].cfg0; + #ifndef DC395x_NO_DISCONNECT + dcb->identify_msg = + IDENTIFY(dcb->dev_mode & NTC_DO_DISCONNECT, lun); + #else + dcb->identify_msg = IDENTIFY(0, lun); + #endif +- dcb->dev_mode = eeprom->target[target].cfg0; + dcb->inquiry7 = 0; + dcb->sync_mode = 0; + dcb->min_nego_period = clock_period[period_index]; diff --git a/queue-3.8/scsi-storvsc-initialize-the-sglist.patch b/queue-3.8/scsi-storvsc-initialize-the-sglist.patch new file mode 100644 index 00000000000..bcc97c6c092 --- /dev/null +++ b/queue-3.8/scsi-storvsc-initialize-the-sglist.patch @@ -0,0 +1,29 @@ +From 9d2696e658ef4f209955ddaa987d43f1a1bd81a1 Mon Sep 17 00:00:00 2001 +From: "K. Y. Srinivasan" +Date: Wed, 6 Feb 2013 05:15:28 -0800 +Subject: SCSI: storvsc: Initialize the sglist + +From: "K. Y. Srinivasan" + +commit 9d2696e658ef4f209955ddaa987d43f1a1bd81a1 upstream. + +Properly initialize scatterlist before using it. + +Signed-off-by: K. Y. Srinivasan +Signed-off-by: James Bottomley +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/storvsc_drv.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/scsi/storvsc_drv.c ++++ b/drivers/scsi/storvsc_drv.c +@@ -467,6 +467,7 @@ static struct scatterlist *create_bounce + if (!bounce_sgl) + return NULL; + ++ sg_init_table(bounce_sgl, num_pages); + for (i = 0; i < num_pages; i++) { + page_buf = alloc_page(GFP_ATOMIC); + if (!page_buf) diff --git a/queue-3.8/series b/queue-3.8/series index 756b7118c9c..4e5dd74fec9 100644 --- a/queue-3.8/series +++ b/queue-3.8/series @@ -2,3 +2,28 @@ arm-vfp-fix-emulation-of-second-vfp-instruction.patch arm-fix-scheduling-while-atomic-warning-in-alignment-handling-code.patch arm-7653-2-do-not-scale-loops_per_jiffy-when-using-a-constant-delay-clock.patch arm-7654-1-preserve-l_pte_valid-in-pte_modify.patch +usb-ehci-revert-remove-ass-pss-polling-timeout.patch +xenbus-fix-compile-failure-on-arm-with-xen-enabled.patch +xen-pat-disable-pat-using-pat_enabled-value.patch +xen-pci-we-don-t-do-multiple-msi-s.patch +watchdog-da9055_wdt-needs-to-select-watchdog_core.patch +watchdog-sp5100_tco-fix-wrong-indirect-i-o-access-for-getting-value-of-reserved-bits.patch +watchdog-sp5100_tco-write-back-the-original-value-to-reserved-bits-instead-of-zero.patch +sony-laptop-fully-enable-sny-controlled-modems.patch +scsi-dc395x-uninitialized-variable-in-device_alloc.patch +scsi-storvsc-initialize-the-sglist.patch +target-pscsi-fix-page-increment.patch +iscsi-target-fix-immediate-queue-starvation-regression-with-datain.patch +ext4-convert-number-of-blocks-to-clusters-properly.patch +btrfs-init-io_lock-after-cloning-btrfs-device-struct.patch +btrfs-copy-everything-if-we-ve-created-an-inline-extent.patch +btrfs-delete-inline-extents-when-we-find-them-during-logging.patch +cifs-ensure-that-cifs_get_root-only-traverses-directories.patch +dm-fix-truncated-status-strings.patch +dm-do-not-replace-bioset-for-request-based-dm.patch +dm-fix-limits-initialization-when-there-are-no-data-devices.patch +dm-snapshot-add-missing-module-aliases.patch +nfs-don-t-allow-nfs-silly-renamed-files-to-be-deleted-no-signal.patch +sunrpc-don-t-start-the-retransmission-timer-when-out-of-socket-space.patch +pnfs-fix-resend_to_mds-for-directio.patch +nfsv4.1-hold-reference-to-layout-hdr-in-layoutget.patch diff --git a/queue-3.8/sony-laptop-fully-enable-sny-controlled-modems.patch b/queue-3.8/sony-laptop-fully-enable-sny-controlled-modems.patch new file mode 100644 index 00000000000..e4e86166997 --- /dev/null +++ b/queue-3.8/sony-laptop-fully-enable-sny-controlled-modems.patch @@ -0,0 +1,33 @@ +From 3ec1c3983d73b1e3d4cfd72afab94c34eceafe8a Mon Sep 17 00:00:00 2001 +From: Mattia Dongili +Date: Fri, 21 Dec 2012 07:21:08 +0900 +Subject: sony-laptop: fully enable SNY controlled modems + +From: Mattia Dongili + +commit 3ec1c3983d73b1e3d4cfd72afab94c34eceafe8a upstream. + +The call to handlers 0x124 and 0x135 (rfkill control) seems to take a +bitmask to control various states of the device. For our rfkill we need +a fully on/off. SVZ1311Z9R/X's LTE modem needs more bits up. + +Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=47751 +Signed-off-by: Mattia Dongili +Signed-off-by: Matthew Garrett +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/platform/x86/sony-laptop.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/platform/x86/sony-laptop.c ++++ b/drivers/platform/x86/sony-laptop.c +@@ -1534,7 +1534,7 @@ static int sony_nc_rfkill_set(void *data + int argument = sony_rfkill_address[(long) data] + 0x100; + + if (!blocked) +- argument |= 0x030000; ++ argument |= 0x070000; + + return sony_call_snc_handle(sony_rfkill_handle, argument, &result); + } diff --git a/queue-3.8/sunrpc-don-t-start-the-retransmission-timer-when-out-of-socket-space.patch b/queue-3.8/sunrpc-don-t-start-the-retransmission-timer-when-out-of-socket-space.patch new file mode 100644 index 00000000000..9f31e793d9f --- /dev/null +++ b/queue-3.8/sunrpc-don-t-start-the-retransmission-timer-when-out-of-socket-space.patch @@ -0,0 +1,45 @@ +From a9a6b52ee1baa865283a91eb8d443ee91adfca56 Mon Sep 17 00:00:00 2001 +From: Trond Myklebust +Date: Fri, 22 Feb 2013 14:57:57 -0500 +Subject: SUNRPC: Don't start the retransmission timer when out of socket space + +From: Trond Myklebust + +commit a9a6b52ee1baa865283a91eb8d443ee91adfca56 upstream. + +If the socket is full, we're better off just waiting until it empties, +or until the connection is broken. The reason why we generally don't +want to time out is that the call to xprt->ops->release_xprt() will +trigger a connection reset, which isn't helpful... + +Let's make an exception for soft RPC calls, since they have to provide +timeout guarantees. + +Signed-off-by: Trond Myklebust +Signed-off-by: Greg Kroah-Hartman + +--- + net/sunrpc/xprt.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/net/sunrpc/xprt.c ++++ b/net/sunrpc/xprt.c +@@ -485,13 +485,17 @@ EXPORT_SYMBOL_GPL(xprt_wake_pending_task + * xprt_wait_for_buffer_space - wait for transport output buffer to clear + * @task: task to be put to sleep + * @action: function pointer to be executed after wait ++ * ++ * Note that we only set the timer for the case of RPC_IS_SOFT(), since ++ * we don't in general want to force a socket disconnection due to ++ * an incomplete RPC call transmission. + */ + void xprt_wait_for_buffer_space(struct rpc_task *task, rpc_action action) + { + struct rpc_rqst *req = task->tk_rqstp; + struct rpc_xprt *xprt = req->rq_xprt; + +- task->tk_timeout = req->rq_timeout; ++ task->tk_timeout = RPC_IS_SOFT(task) ? req->rq_timeout : 0; + rpc_sleep_on(&xprt->pending, task, action); + } + EXPORT_SYMBOL_GPL(xprt_wait_for_buffer_space); diff --git a/queue-3.8/target-pscsi-fix-page-increment.patch b/queue-3.8/target-pscsi-fix-page-increment.patch new file mode 100644 index 00000000000..02db63cbaaf --- /dev/null +++ b/queue-3.8/target-pscsi-fix-page-increment.patch @@ -0,0 +1,31 @@ +From 472b72f2db7831d7dbe22ffdff4adee3bd49b05d Mon Sep 17 00:00:00 2001 +From: Asias He +Date: Wed, 27 Feb 2013 13:29:29 +0800 +Subject: target/pscsi: Fix page increment + +From: Asias He + +commit 472b72f2db7831d7dbe22ffdff4adee3bd49b05d upstream. + +The page++ is wrong. It makes bio_add_pc_page() pointing to a wrong page +address if the 'while (len > 0 && data_len > 0) { ... }' loop is +executed more than one once. + +Signed-off-by: Asias He +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/target_core_pscsi.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/target/target_core_pscsi.c ++++ b/drivers/target/target_core_pscsi.c +@@ -940,7 +940,6 @@ pscsi_map_sg(struct se_cmd *cmd, struct + bio = NULL; + } + +- page++; + len -= bytes; + data_len -= bytes; + off = 0; diff --git a/queue-3.8/usb-ehci-revert-remove-ass-pss-polling-timeout.patch b/queue-3.8/usb-ehci-revert-remove-ass-pss-polling-timeout.patch new file mode 100644 index 00000000000..12adf16c4c1 --- /dev/null +++ b/queue-3.8/usb-ehci-revert-remove-ass-pss-polling-timeout.patch @@ -0,0 +1,84 @@ +From 221f8dfca89276d8aec54c6d07fbe20c281668f0 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Tue, 26 Feb 2013 13:43:41 -0500 +Subject: USB: EHCI: revert "remove ASS/PSS polling timeout" + +From: Alan Stern + +commit 221f8dfca89276d8aec54c6d07fbe20c281668f0 upstream. + +This patch (as1649) reverts commit +55bcdce8a8228223ec4d17d8ded8134ed265d2c5 (USB: EHCI: remove ASS/PSS +polling timeout). That commit was written under the assumption that +some controllers may take a very long time to turn off their async and +periodic schedules. It now appears that in fact the schedules do get +turned off reasonably quickly, but some controllers occasionally leave +the schedules' status bits turned on and consequently ehci-hcd can't +tell that the schedules are off. + +VIA controllers in particular have this problem. ehci-hcd tells the +hardware to turn off the async schedule, the schedule does get turned +off, but the status bit remains on. Since the EHCI spec requires that +the schedules not be re-enabled until the previous disable has taken +effect, with an unlimited timeout the async schedule never gets turned +back on. The resulting symptom is that the system is unable to +communicate with USB devices. + +Signed-off-by: Alan Stern +Reported-and-tested-by: Ronald +Reported-and-tested-by: Paul Hartman +Reported-and-tested-by: Dieter Nützel +Reported-and-tested-by: Jean Delvare +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/ehci-timer.c | 29 ++++++++++++++--------------- + 1 file changed, 14 insertions(+), 15 deletions(-) + +--- a/drivers/usb/host/ehci-timer.c ++++ b/drivers/usb/host/ehci-timer.c +@@ -113,15 +113,14 @@ static void ehci_poll_ASS(struct ehci_hc + + if (want != actual) { + +- /* Poll again later */ +- ehci_enable_event(ehci, EHCI_HRTIMER_POLL_ASS, true); +- ++ehci->ASS_poll_count; +- return; ++ /* Poll again later, but give up after about 20 ms */ ++ if (ehci->ASS_poll_count++ < 20) { ++ ehci_enable_event(ehci, EHCI_HRTIMER_POLL_ASS, true); ++ return; ++ } ++ ehci_dbg(ehci, "Waited too long for the async schedule status (%x/%x), giving up\n", ++ want, actual); + } +- +- if (ehci->ASS_poll_count > 20) +- ehci_dbg(ehci, "ASS poll count reached %d\n", +- ehci->ASS_poll_count); + ehci->ASS_poll_count = 0; + + /* The status is up-to-date; restart or stop the schedule as needed */ +@@ -160,14 +159,14 @@ static void ehci_poll_PSS(struct ehci_hc + + if (want != actual) { + +- /* Poll again later */ +- ehci_enable_event(ehci, EHCI_HRTIMER_POLL_PSS, true); +- return; ++ /* Poll again later, but give up after about 20 ms */ ++ if (ehci->PSS_poll_count++ < 20) { ++ ehci_enable_event(ehci, EHCI_HRTIMER_POLL_PSS, true); ++ return; ++ } ++ ehci_dbg(ehci, "Waited too long for the periodic schedule status (%x/%x), giving up\n", ++ want, actual); + } +- +- if (ehci->PSS_poll_count > 20) +- ehci_dbg(ehci, "PSS poll count reached %d\n", +- ehci->PSS_poll_count); + ehci->PSS_poll_count = 0; + + /* The status is up-to-date; restart or stop the schedule as needed */ diff --git a/queue-3.8/watchdog-da9055_wdt-needs-to-select-watchdog_core.patch b/queue-3.8/watchdog-da9055_wdt-needs-to-select-watchdog_core.patch new file mode 100644 index 00000000000..2d95fe5c26c --- /dev/null +++ b/queue-3.8/watchdog-da9055_wdt-needs-to-select-watchdog_core.patch @@ -0,0 +1,35 @@ +From 12a5c05cb143105d989abf728a8c769830670e54 Mon Sep 17 00:00:00 2001 +From: Randy Dunlap +Date: Mon, 28 Jan 2013 08:29:48 -0800 +Subject: watchdog: da9055_wdt needs to select WATCHDOG_CORE + +From: Randy Dunlap + +commit 12a5c05cb143105d989abf728a8c769830670e54 upstream. + +DA9055_WATCHDOG (introduced in v3.8) needs to select WATCHDOG_CORE so that it will +build cleanly. Fixes these build errors: + +da9055_wdt.c:(.text+0xe9bc7): undefined reference to `watchdog_unregister_device' +da9055_wdt.c:(.text+0xe9f4b): undefined reference to `watchdog_register_device' + +Signed-off-by: Randy Dunlap +Cc: David Dajun Chen +Signed-off-by: Wim Van Sebroeck +Cc: linux-watchdog@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/watchdog/Kconfig | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/watchdog/Kconfig ++++ b/drivers/watchdog/Kconfig +@@ -79,6 +79,7 @@ config DA9052_WATCHDOG + config DA9055_WATCHDOG + tristate "Dialog Semiconductor DA9055 Watchdog" + depends on MFD_DA9055 ++ select WATCHDOG_CORE + help + If you say yes here you get support for watchdog on the Dialog + Semiconductor DA9055 PMIC. diff --git a/queue-3.8/watchdog-sp5100_tco-fix-wrong-indirect-i-o-access-for-getting-value-of-reserved-bits.patch b/queue-3.8/watchdog-sp5100_tco-fix-wrong-indirect-i-o-access-for-getting-value-of-reserved-bits.patch new file mode 100644 index 00000000000..f127d1d0f0a --- /dev/null +++ b/queue-3.8/watchdog-sp5100_tco-fix-wrong-indirect-i-o-access-for-getting-value-of-reserved-bits.patch @@ -0,0 +1,50 @@ +From 10ab329b5db7e592a3a60b4594e4e5f40b60c45c Mon Sep 17 00:00:00 2001 +From: Takahisa Tanaka +Date: Mon, 14 Jan 2013 11:01:57 +0900 +Subject: watchdog: sp5100_tco: Fix wrong indirect I/O access for getting value of reserved bits + +From: Takahisa Tanaka + +commit 10ab329b5db7e592a3a60b4594e4e5f40b60c45c upstream. + +In case of SB800 or later chipset and re-programming MMIO address(*), +sp5100_tco module may read incorrect value of reserved bit, because the module +reads a value from an incorrect I/O address. However, this bug doesn't cause +a problem, because when re-programming MMIO address, by chance the module +writes zero (this is BIOS's default value) to the low three bits of register. +* In most cases, PC with SB8x0 or later chipset doesn't need to re-programming + MMIO address, because such PC can enable AcpiMmio and can use 0xfed80b00 for + watchdog register base address. + +This patch fixes this bug. + +Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=43176 +Signed-off-by: Takahisa Tanaka +Tested-by: Paul Menzel +Signed-off-by: Wim Van Sebroeck +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/watchdog/sp5100_tco.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/watchdog/sp5100_tco.c ++++ b/drivers/watchdog/sp5100_tco.c +@@ -500,14 +500,15 @@ static unsigned char sp5100_tco_setupdev + /* Restore to the low three bits, if chipset is SB8x0(or later) */ + if (sp5100_tco_pci->revision >= 0x40) { + u8 reserved_bit; +- reserved_bit = inb(base_addr) & 0x7; ++ outb(base_addr+0, index_reg); ++ reserved_bit = inb(data_reg) & 0x7; + val |= (u32)reserved_bit; + } + + /* Re-programming the watchdog timer base address */ + outb(base_addr+0, index_reg); + /* Low three bits of BASE are reserved */ +- outb((val >> 0) & 0xf8, data_reg); ++ outb((val >> 0) & 0xff, data_reg); + outb(base_addr+1, index_reg); + outb((val >> 8) & 0xff, data_reg); + outb(base_addr+2, index_reg); diff --git a/queue-3.8/watchdog-sp5100_tco-write-back-the-original-value-to-reserved-bits-instead-of-zero.patch b/queue-3.8/watchdog-sp5100_tco-write-back-the-original-value-to-reserved-bits-instead-of-zero.patch new file mode 100644 index 00000000000..29238a95484 --- /dev/null +++ b/queue-3.8/watchdog-sp5100_tco-write-back-the-original-value-to-reserved-bits-instead-of-zero.patch @@ -0,0 +1,77 @@ +From 41adafbd7b84c66c2cdad857b75d5d45032310a6 Mon Sep 17 00:00:00 2001 +From: Takahisa Tanaka +Date: Mon, 14 Jan 2013 11:01:58 +0900 +Subject: watchdog: sp5100_tco: Write back the original value to reserved bits, instead of zero + +From: Takahisa Tanaka + +commit 41adafbd7b84c66c2cdad857b75d5d45032310a6 upstream. + +In case of SP5100 or SB7x0 chipsets, the sp5100_tco module writes zero to +reserved bits. The module, however, shouldn't depend on specific default +value, and should perform a read-merge-write operation for the reserved +bits. + +This patch makes the sp5100_tco module perform a read-merge-write operation +on all the chipset (sp5100, sb7x0, sb8x0 or later). + +Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=43176 +Signed-off-by: Takahisa Tanaka +Tested-by: Paul Menzel +Signed-off-by: Wim Van Sebroeck +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/watchdog/sp5100_tco.c | 28 ++++++++-------------------- + 1 file changed, 8 insertions(+), 20 deletions(-) + +--- a/drivers/watchdog/sp5100_tco.c ++++ b/drivers/watchdog/sp5100_tco.c +@@ -361,7 +361,7 @@ static unsigned char sp5100_tco_setupdev + { + struct pci_dev *dev = NULL; + const char *dev_name = NULL; +- u32 val; ++ u32 val, tmp_val; + u32 index_reg, data_reg, base_addr; + + /* Match the PCI device */ +@@ -497,31 +497,19 @@ static unsigned char sp5100_tco_setupdev + pr_debug("Got 0x%04x from resource tree\n", val); + } + +- /* Restore to the low three bits, if chipset is SB8x0(or later) */ +- if (sp5100_tco_pci->revision >= 0x40) { +- u8 reserved_bit; +- outb(base_addr+0, index_reg); +- reserved_bit = inb(data_reg) & 0x7; +- val |= (u32)reserved_bit; +- } ++ /* Restore to the low three bits */ ++ outb(base_addr+0, index_reg); ++ tmp_val = val | (inb(data_reg) & 0x7); + + /* Re-programming the watchdog timer base address */ + outb(base_addr+0, index_reg); +- /* Low three bits of BASE are reserved */ +- outb((val >> 0) & 0xff, data_reg); ++ outb((tmp_val >> 0) & 0xff, data_reg); + outb(base_addr+1, index_reg); +- outb((val >> 8) & 0xff, data_reg); ++ outb((tmp_val >> 8) & 0xff, data_reg); + outb(base_addr+2, index_reg); +- outb((val >> 16) & 0xff, data_reg); ++ outb((tmp_val >> 16) & 0xff, data_reg); + outb(base_addr+3, index_reg); +- outb((val >> 24) & 0xff, data_reg); +- +- /* +- * Clear unnecessary the low three bits, +- * if chipset is SB8x0(or later) +- */ +- if (sp5100_tco_pci->revision >= 0x40) +- val &= ~0x7; ++ outb((tmp_val >> 24) & 0xff, data_reg); + + if (!request_mem_region_exclusive(val, SP5100_WDT_MEM_MAP_SIZE, + dev_name)) { diff --git a/queue-3.8/xen-pat-disable-pat-using-pat_enabled-value.patch b/queue-3.8/xen-pat-disable-pat-using-pat_enabled-value.patch new file mode 100644 index 00000000000..852f4a17bd1 --- /dev/null +++ b/queue-3.8/xen-pat-disable-pat-using-pat_enabled-value.patch @@ -0,0 +1,121 @@ +From c79c49826270b8b0061b2fca840fc3f013c8a78a Mon Sep 17 00:00:00 2001 +From: Konrad Rzeszutek Wilk +Date: Tue, 26 Feb 2013 12:51:27 -0500 +Subject: xen/pat: Disable PAT using pat_enabled value. + +From: Konrad Rzeszutek Wilk + +commit c79c49826270b8b0061b2fca840fc3f013c8a78a upstream. + +The git commit 8eaffa67b43e99ae581622c5133e20b0f48bcef1 +(xen/pat: Disable PAT support for now) explains in details why +we want to disable PAT for right now. However that +change was not enough and we should have also disabled +the pat_enabled value. Otherwise we end up with: + +mmap-example:3481 map pfn expected mapping type write-back for +[mem 0x00010000-0x00010fff], got uncached-minus + ------------[ cut here ]------------ +WARNING: at /build/buildd/linux-3.8.0/arch/x86/mm/pat.c:774 untrack_pfn+0xb8/0xd0() +mem 0x00010000-0x00010fff], got uncached-minus +------------[ cut here ]------------ +WARNING: at /build/buildd/linux-3.8.0/arch/x86/mm/pat.c:774 +untrack_pfn+0xb8/0xd0() +... +Pid: 3481, comm: mmap-example Tainted: GF 3.8.0-6-generic #13-Ubuntu +Call Trace: + [] warn_slowpath_common+0x7f/0xc0 + [] warn_slowpath_null+0x1a/0x20 + [] untrack_pfn+0xb8/0xd0 + [] unmap_single_vma+0xac/0x100 + [] unmap_vmas+0x49/0x90 + [] exit_mmap+0x98/0x170 + [] mmput+0x64/0x100 + [] dup_mm+0x445/0x660 + [] copy_process.part.22+0xa5f/0x1510 + [] do_fork+0x91/0x350 + [] sys_clone+0x16/0x20 + [] stub_clone+0x69/0x90 + [] ? system_call_fastpath+0x1a/0x1f +---[ end trace 4918cdd0a4c9fea4 ]--- + +(a similar message shows up if you end up launching 'mcelog') + +The call chain is (as analyzed by Liu, Jinsong): +do_fork + --> copy_process + --> dup_mm + --> dup_mmap + --> copy_page_range + --> track_pfn_copy + --> reserve_pfn_range + --> line 624: flags != want_flags +It comes from different memory types of page table (_PAGE_CACHE_WB) and MTRR +(_PAGE_CACHE_UC_MINUS). + +Stefan Bader dug in this deep and found out that: +"That makes it clearer as this will do + +reserve_memtype(...) +--> pat_x_mtrr_type + --> mtrr_type_lookup + --> __mtrr_type_lookup + +And that can return -1/0xff in case of MTRR not being enabled/initialized. Which +is not the case (given there are no messages for it in dmesg). This is not equal +to MTRR_TYPE_WRBACK and thus becomes _PAGE_CACHE_UC_MINUS. + +It looks like the problem starts early in reserve_memtype: + + if (!pat_enabled) { + /* This is identical to page table setting without PAT */ + if (new_type) { + if (req_type == _PAGE_CACHE_WC) + *new_type = _PAGE_CACHE_UC_MINUS; + else + *new_type = req_type & _PAGE_CACHE_MASK; + } + return 0; + } + +This would be what we want, that is clearing the PWT and PCD flags from the +supported flags - if pat_enabled is disabled." + +This patch does that - disabling PAT. + +Reported-by: Sander Eikelenboom +Reported-and-Tested-by: Konrad Rzeszutek Wilk +Reported-and-Tested-by: Stefan Bader +Signed-off-by: Konrad Rzeszutek Wilk +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/xen/enlighten.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +--- a/arch/x86/xen/enlighten.c ++++ b/arch/x86/xen/enlighten.c +@@ -67,6 +67,7 @@ + #include + #include + #include ++#include + + #ifdef CONFIG_ACPI + #include +@@ -1417,7 +1418,14 @@ asmlinkage void __init xen_start_kernel( + */ + acpi_numa = -1; + #endif +- ++#ifdef CONFIG_X86_PAT ++ /* ++ * For right now disable the PAT. We should remove this once ++ * git commit 8eaffa67b43e99ae581622c5133e20b0f48bcef1 ++ * (xen/pat: Disable PAT support for now) is reverted. ++ */ ++ pat_enabled = 0; ++#endif + /* Don't do the full vcpu_info placement stuff until we have a + possible map and a non-dummy shared_info. */ + per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0]; diff --git a/queue-3.8/xen-pci-we-don-t-do-multiple-msi-s.patch b/queue-3.8/xen-pci-we-don-t-do-multiple-msi-s.patch new file mode 100644 index 00000000000..c49e8883510 --- /dev/null +++ b/queue-3.8/xen-pci-we-don-t-do-multiple-msi-s.patch @@ -0,0 +1,74 @@ +From 884ac2978a295b7df3c4a686d3bff6932bbbb460 Mon Sep 17 00:00:00 2001 +From: Konrad Rzeszutek Wilk +Date: Thu, 28 Feb 2013 09:05:41 -0500 +Subject: xen/pci: We don't do multiple MSI's. + +From: Konrad Rzeszutek Wilk + +commit 884ac2978a295b7df3c4a686d3bff6932bbbb460 upstream. + +There is no hypercall to setup multiple MSI per PCI device. +As such with these two new commits: +- 08261d87f7d1b6253ab3223756625a5c74532293 + PCI/MSI: Enable multiple MSIs with pci_enable_msi_block_auto() +- 5ca72c4f7c412c2002363218901eba5516c476b1 + AHCI: Support multiple MSIs + +we would call the PHYSDEVOP_map_pirq 'nvec' times with the same +contents of the PCI device. Sander discovered that we would get +the same PIRQ value 'nvec' times and return said values to the +caller. That of course meant that the device was configured only +with one MSI and AHCI would fail with: + +ahci 0000:00:11.0: version 3.0 +xen: registering gsi 19 triggering 0 polarity 1 +xen: --> pirq=19 -> irq=19 (gsi=19) +(XEN) [2013-02-27 19:43:07] IOAPIC[0]: Set PCI routing entry (6-19 -> 0x99 -> IRQ 19 Mode:1 Active:1) +ahci 0000:00:11.0: AHCI 0001.0200 32 slots 4 ports 6 Gbps 0xf impl SATA mode +ahci 0000:00:11.0: flags: 64bit ncq sntf ilck pm led clo pmp pio slum part +ahci: probe of 0000:00:11.0 failed with error -22 + +That is b/c in ahci_host_activate the second call to +devm_request_threaded_irq would return -EINVAL as we passed in +(on the second run) an IRQ that was never initialized. + +Reported-and-Tested-by: Sander Eikelenboom +Signed-off-by: Konrad Rzeszutek Wilk +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/pci/xen.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/arch/x86/pci/xen.c ++++ b/arch/x86/pci/xen.c +@@ -162,6 +162,9 @@ static int xen_setup_msi_irqs(struct pci + struct msi_desc *msidesc; + int *v; + ++ if (type == PCI_CAP_ID_MSI && nvec > 1) ++ return 1; ++ + v = kzalloc(sizeof(int) * max(1, nvec), GFP_KERNEL); + if (!v) + return -ENOMEM; +@@ -220,6 +223,9 @@ static int xen_hvm_setup_msi_irqs(struct + struct msi_desc *msidesc; + struct msi_msg msg; + ++ if (type == PCI_CAP_ID_MSI && nvec > 1) ++ return 1; ++ + list_for_each_entry(msidesc, &dev->msi_list, list) { + __read_msi_msg(msidesc, &msg); + pirq = MSI_ADDR_EXT_DEST_ID(msg.address_hi) | +@@ -263,6 +269,9 @@ static int xen_initdom_setup_msi_irqs(st + int ret = 0; + struct msi_desc *msidesc; + ++ if (type == PCI_CAP_ID_MSI && nvec > 1) ++ return 1; ++ + list_for_each_entry(msidesc, &dev->msi_list, list) { + struct physdev_map_pirq map_irq; + domid_t domid; diff --git a/queue-3.8/xenbus-fix-compile-failure-on-arm-with-xen-enabled.patch b/queue-3.8/xenbus-fix-compile-failure-on-arm-with-xen-enabled.patch new file mode 100644 index 00000000000..0ef794adb18 --- /dev/null +++ b/queue-3.8/xenbus-fix-compile-failure-on-arm-with-xen-enabled.patch @@ -0,0 +1,31 @@ +From 45e27161c62216c163880d7aed751cb55a65c8e9 Mon Sep 17 00:00:00 2001 +From: Steven Noonan +Date: Fri, 1 Mar 2013 05:14:59 -0800 +Subject: xenbus: fix compile failure on ARM with Xen enabled + +From: Steven Noonan + +commit 45e27161c62216c163880d7aed751cb55a65c8e9 upstream. + +Adding an include of linux/mm.h resolves this: + drivers/xen/xenbus/xenbus_client.c: In function ‘xenbus_map_ring_valloc_hvm’: + drivers/xen/xenbus/xenbus_client.c:532:66: error: implicit declaration of function ‘page_to_section’ [-Werror=implicit-function-declaration] + +Signed-off-by: Steven Noonan +Signed-off-by: Konrad Rzeszutek Wilk +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/xen/xenbus/xenbus_client.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/xen/xenbus/xenbus_client.c ++++ b/drivers/xen/xenbus/xenbus_client.c +@@ -30,6 +30,7 @@ + * IN THE SOFTWARE. + */ + ++#include + #include + #include + #include -- 2.47.3