From: Greg Kroah-Hartman Date: Wed, 11 Mar 2015 15:14:06 +0000 (+0100) Subject: 3.19-stable patches X-Git-Tag: v3.10.72~32 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=103e869fba15a9ee2aab8693010017cef2b3635a;p=thirdparty%2Fkernel%2Fstable-queue.git 3.19-stable patches added patches: btrfs-__add_inode_ref-out-of-bounds-memory-read-when-looking-for-extended-ref.patch btrfs-fix-data-loss-in-the-fast-fsync-path.patch btrfs-fix-fsync-race-leading-to-ordered-extent-memory-leaks.patch btrfs-fix-lost-return-value-due-to-variable-shadowing.patch kvm-emulate-fix-cmpxchg8b-on-32-bit-hosts.patch kvm-mips-fix-trace-event-to-save-pc-directly.patch mei-make-device-disabled-on-stop-unconditionally.patch --- diff --git a/queue-3.19/btrfs-__add_inode_ref-out-of-bounds-memory-read-when-looking-for-extended-ref.patch b/queue-3.19/btrfs-__add_inode_ref-out-of-bounds-memory-read-when-looking-for-extended-ref.patch new file mode 100644 index 00000000000..ca7763379f7 --- /dev/null +++ b/queue-3.19/btrfs-__add_inode_ref-out-of-bounds-memory-read-when-looking-for-extended-ref.patch @@ -0,0 +1,32 @@ +From dd9ef135e3542ffc621c4eb7f0091870ec7a1504 Mon Sep 17 00:00:00 2001 +From: Quentin Casasnovas +Date: Tue, 3 Mar 2015 16:31:38 +0100 +Subject: Btrfs:__add_inode_ref: out of bounds memory read when looking for extended ref. + +From: Quentin Casasnovas + +commit dd9ef135e3542ffc621c4eb7f0091870ec7a1504 upstream. + +Improper arithmetics when calculting the address of the extended ref could +lead to an out of bounds memory read and kernel panic. + +Signed-off-by: Quentin Casasnovas +Reviewed-by: David Sterba +Signed-off-by: Chris Mason +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/tree-log.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/btrfs/tree-log.c ++++ b/fs/btrfs/tree-log.c +@@ -1010,7 +1010,7 @@ again: + base = btrfs_item_ptr_offset(leaf, path->slots[0]); + + while (cur_offset < item_size) { +- extref = (struct btrfs_inode_extref *)base + cur_offset; ++ extref = (struct btrfs_inode_extref *)(base + cur_offset); + + victim_name_len = btrfs_inode_extref_name_len(leaf, extref); + diff --git a/queue-3.19/btrfs-fix-data-loss-in-the-fast-fsync-path.patch b/queue-3.19/btrfs-fix-data-loss-in-the-fast-fsync-path.patch new file mode 100644 index 00000000000..34c19dec1a4 --- /dev/null +++ b/queue-3.19/btrfs-fix-data-loss-in-the-fast-fsync-path.patch @@ -0,0 +1,255 @@ +From 3a8b36f378060d20062a0918e99fae39ff077bf0 Mon Sep 17 00:00:00 2001 +From: Filipe Manana +Date: Sun, 1 Mar 2015 20:36:00 +0000 +Subject: Btrfs: fix data loss in the fast fsync path + +From: Filipe Manana + +commit 3a8b36f378060d20062a0918e99fae39ff077bf0 upstream. + +When using the fast file fsync code path we can miss the fact that new +writes happened since the last file fsync and therefore return without +waiting for the IO to finish and write the new extents to the fsync log. + +Here's an example scenario where the fsync will miss the fact that new +file data exists that wasn't yet durably persisted: + +1. fs_info->last_trans_committed == N - 1 and current transaction is + transaction N (fs_info->generation == N); + +2. do a buffered write; + +3. fsync our inode, this clears our inode's full sync flag, starts + an ordered extent and waits for it to complete - when it completes + at btrfs_finish_ordered_io(), the inode's last_trans is set to the + value N (via btrfs_update_inode_fallback -> btrfs_update_inode -> + btrfs_set_inode_last_trans); + +4. transaction N is committed, so fs_info->last_trans_committed is now + set to the value N and fs_info->generation remains with the value N; + +5. do another buffered write, when this happens btrfs_file_write_iter + sets our inode's last_trans to the value N + 1 (that is + fs_info->generation + 1 == N + 1); + +6. transaction N + 1 is started and fs_info->generation now has the + value N + 1; + +7. transaction N + 1 is committed, so fs_info->last_trans_committed + is set to the value N + 1; + +8. fsync our inode - because it doesn't have the full sync flag set, + we only start the ordered extent, we don't wait for it to complete + (only in a later phase) therefore its last_trans field has the + value N + 1 set previously by btrfs_file_write_iter(), and so we + have: + + inode->last_trans <= fs_info->last_trans_committed + (N + 1) (N + 1) + + Which made us not log the last buffered write and exit the fsync + handler immediately, returning success (0) to user space and resulting + in data loss after a crash. + +This can actually be triggered deterministically and the following excerpt +from a testcase I made for xfstests triggers the issue. It moves a dummy +file across directories and then fsyncs the old parent directory - this +is just to trigger a transaction commit, so moving files around isn't +directly related to the issue but it was chosen because running 'sync' for +example does more than just committing the current transaction, as it +flushes/waits for all file data to be persisted. The issue can also happen +at random periods, since the transaction kthread periodicaly commits the +current transaction (about every 30 seconds by default). +The body of the test is: + + _scratch_mkfs >> $seqres.full 2>&1 + _init_flakey + _mount_flakey + + # Create our main test file 'foo', the one we check for data loss. + # By doing an fsync against our file, it makes btrfs clear the 'needs_full_sync' + # bit from its flags (btrfs inode specific flags). + $XFS_IO_PROG -f -c "pwrite -S 0xaa 0 8K" \ + -c "fsync" $SCRATCH_MNT/foo | _filter_xfs_io + + # Now create one other file and 2 directories. We will move this second file + # from one directory to the other later because it forces btrfs to commit its + # currently open transaction if we fsync the old parent directory. This is + # necessary to trigger the data loss bug that affected btrfs. + mkdir $SCRATCH_MNT/testdir_1 + touch $SCRATCH_MNT/testdir_1/bar + mkdir $SCRATCH_MNT/testdir_2 + + # Make sure everything is durably persisted. + sync + + # Write more 8Kb of data to our file. + $XFS_IO_PROG -c "pwrite -S 0xbb 8K 8K" $SCRATCH_MNT/foo | _filter_xfs_io + + # Move our 'bar' file into a new directory. + mv $SCRATCH_MNT/testdir_1/bar $SCRATCH_MNT/testdir_2/bar + + # Fsync our first directory. Because it had a file moved into some other + # directory, this made btrfs commit the currently open transaction. This is + # a condition necessary to trigger the data loss bug. + $XFS_IO_PROG -c "fsync" $SCRATCH_MNT/testdir_1 + + # Now fsync our main test file. If the fsync succeeds, we expect the 8Kb of + # data we wrote previously to be persisted and available if a crash happens. + # This did not happen with btrfs, because of the transaction commit that + # happened when we fsynced the parent directory. + $XFS_IO_PROG -c "fsync" $SCRATCH_MNT/foo + + # Simulate a crash/power loss. + _load_flakey_table $FLAKEY_DROP_WRITES + _unmount_flakey + + _load_flakey_table $FLAKEY_ALLOW_WRITES + _mount_flakey + + # Now check that all data we wrote before are available. + echo "File content after log replay:" + od -t x1 $SCRATCH_MNT/foo + + status=0 + exit + +The expected golden output for the test, which is what we get with this +fix applied (or when running against ext3/4 and xfs), is: + + wrote 8192/8192 bytes at offset 0 + XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + wrote 8192/8192 bytes at offset 8192 + XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + File content after log replay: + 0000000 aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa + * + 0020000 bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb + * + 0040000 + +Without this fix applied, the output shows the test file does not have +the second 8Kb extent that we successfully fsynced: + + wrote 8192/8192 bytes at offset 0 + XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + wrote 8192/8192 bytes at offset 8192 + XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + File content after log replay: + 0000000 aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa + * + 0020000 + +So fix this by skipping the fsync only if we're doing a full sync and +if the inode's last_trans is <= fs_info->last_trans_committed, or if +the inode is already in the log. Also remove setting the inode's +last_trans in btrfs_file_write_iter since it's useless/unreliable. + +Also because btrfs_file_write_iter no longer sets inode->last_trans to +fs_info->generation + 1, don't set last_trans to 0 if we bail out and don't +bail out if last_trans is 0, otherwise something as simple as the following +example wouldn't log the second write on the last fsync: + + 1. write to file + + 2. fsync file + + 3. fsync file + |--> btrfs_inode_in_log() returns true and it set last_trans to 0 + + 4. write to file + |--> btrfs_file_write_iter() no longers sets last_trans, so it + remained with a value of 0 + 5. fsync + |--> inode->last_trans == 0, so it bails out without logging the + second write + +A test case for xfstests will be sent soon. + +Signed-off-by: Filipe Manana +Signed-off-by: Chris Mason +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/file.c | 56 ++++++++++++++++++++++++++++---------------------------- + 1 file changed, 28 insertions(+), 28 deletions(-) + +--- a/fs/btrfs/file.c ++++ b/fs/btrfs/file.c +@@ -1811,22 +1811,10 @@ static ssize_t btrfs_file_write_iter(str + mutex_unlock(&inode->i_mutex); + + /* +- * we want to make sure fsync finds this change +- * but we haven't joined a transaction running right now. +- * +- * Later on, someone is sure to update the inode and get the +- * real transid recorded. +- * +- * We set last_trans now to the fs_info generation + 1, +- * this will either be one more than the running transaction +- * or the generation used for the next transaction if there isn't +- * one running right now. +- * + * We also have to set last_sub_trans to the current log transid, + * otherwise subsequent syncs to a file that's been synced in this + * transaction will appear to have already occured. + */ +- BTRFS_I(inode)->last_trans = root->fs_info->generation + 1; + BTRFS_I(inode)->last_sub_trans = root->log_transid; + if (num_written > 0) { + err = generic_write_sync(file, pos, num_written); +@@ -1959,25 +1947,37 @@ int btrfs_sync_file(struct file *file, l + atomic_inc(&root->log_batch); + + /* +- * check the transaction that last modified this inode +- * and see if its already been committed +- */ +- if (!BTRFS_I(inode)->last_trans) { +- mutex_unlock(&inode->i_mutex); +- goto out; +- } +- +- /* +- * if the last transaction that changed this file was before +- * the current transaction, we can bail out now without any +- * syncing ++ * If the last transaction that changed this file was before the current ++ * transaction and we have the full sync flag set in our inode, we can ++ * bail out now without any syncing. ++ * ++ * Note that we can't bail out if the full sync flag isn't set. This is ++ * because when the full sync flag is set we start all ordered extents ++ * and wait for them to fully complete - when they complete they update ++ * the inode's last_trans field through: ++ * ++ * btrfs_finish_ordered_io() -> ++ * btrfs_update_inode_fallback() -> ++ * btrfs_update_inode() -> ++ * btrfs_set_inode_last_trans() ++ * ++ * So we are sure that last_trans is up to date and can do this check to ++ * bail out safely. For the fast path, when the full sync flag is not ++ * set in our inode, we can not do it because we start only our ordered ++ * extents and don't wait for them to complete (that is when ++ * btrfs_finish_ordered_io runs), so here at this point their last_trans ++ * value might be less than or equals to fs_info->last_trans_committed, ++ * and setting a speculative last_trans for an inode when a buffered ++ * write is made (such as fs_info->generation + 1 for example) would not ++ * be reliable since after setting the value and before fsync is called ++ * any number of transactions can start and commit (transaction kthread ++ * commits the current transaction periodically), and a transaction ++ * commit does not start nor waits for ordered extents to complete. + */ + smp_mb(); + if (btrfs_inode_in_log(inode, root->fs_info->generation) || +- BTRFS_I(inode)->last_trans <= +- root->fs_info->last_trans_committed) { +- BTRFS_I(inode)->last_trans = 0; +- ++ (full_sync && BTRFS_I(inode)->last_trans <= ++ root->fs_info->last_trans_committed)) { + /* + * We'v had everything committed since the last time we were + * modified so clear this flag in case it was set for whatever diff --git a/queue-3.19/btrfs-fix-fsync-race-leading-to-ordered-extent-memory-leaks.patch b/queue-3.19/btrfs-fix-fsync-race-leading-to-ordered-extent-memory-leaks.patch new file mode 100644 index 00000000000..c28d14755bc --- /dev/null +++ b/queue-3.19/btrfs-fix-fsync-race-leading-to-ordered-extent-memory-leaks.patch @@ -0,0 +1,234 @@ +From 4d884fceaa2c838abb598778813e93f6d9fea723 Mon Sep 17 00:00:00 2001 +From: Filipe Manana +Date: Mon, 9 Feb 2015 17:17:43 +0000 +Subject: Btrfs: fix fsync race leading to ordered extent memory leaks + +From: Filipe Manana + +commit 4d884fceaa2c838abb598778813e93f6d9fea723 upstream. + +We can have multiple fsync operations against the same file during the +same transaction and they can collect the same ordered extents while they +don't complete (still accessible from the inode's ordered tree). If this +happens, those ordered extents will never get their reference counts +decremented to 0, leading to memory leaks and inode leaks (an iput for an +ordered extent's inode is scheduled only when the ordered extent's refcount +drops to 0). The following sequence diagram explains this race: + + CPU 1 CPU 2 + +btrfs_sync_file() + + btrfs_sync_file() + + mutex_lock(inode->i_mutex) + btrfs_log_inode() + btrfs_get_logged_extents() + --> collects ordered extent X + --> increments ordered + extent X's refcount + btrfs_submit_logged_extents() + mutex_unlock(inode->i_mutex) + + mutex_lock(inode->i_mutex) + btrfs_sync_log() + btrfs_wait_logged_extents() + --> list_del_init(&ordered->log_list) + btrfs_log_inode() + btrfs_get_logged_extents() + --> Adds ordered extent X + to logged_list because + at this point: + list_empty(&ordered->log_list) + && test_bit(BTRFS_ORDERED_LOGGED, + &ordered->flags) == 0 + --> Increments ordered extent + X's refcount + --> check if ordered extent's io is + finished or not, start it if + necessary and wait for it to finish + --> sets bit BTRFS_ORDERED_LOGGED + on ordered extent X's flags + and adds it to trans->ordered + btrfs_sync_log() finishes + + btrfs_submit_logged_extents() + btrfs_log_inode() finishes + mutex_unlock(inode->i_mutex) + +btrfs_sync_file() finishes + + btrfs_sync_log() + btrfs_wait_logged_extents() + --> Sees ordered extent X has the + bit BTRFS_ORDERED_LOGGED set in + its flags + --> X's refcount is untouched + btrfs_sync_log() finishes + + btrfs_sync_file() finishes + +btrfs_commit_transaction() + --> called by transaction kthread for e.g. + btrfs_wait_pending_ordered() + --> waits for ordered extent X to + complete + --> decrements ordered extent X's + refcount by 1 only, corresponding + to the increment done by the fsync + task ran by CPU 1 + +In the scenario of the above diagram, after the transaction commit, +the ordered extent will remain with a refcount of 1 forever, leaking +the ordered extent structure and preventing the i_count of its inode +from ever decreasing to 0, since the delayed iput is scheduled only +when the ordered extent's refcount drops to 0, preventing the inode +from ever being evicted by the VFS. + +Fix this by using the flag BTRFS_ORDERED_LOGGED differently. Use it to +mean that an ordered extent is already being processed by an fsync call, +which will attach it to the current transaction, preventing it from being +collected by subsequent fsync operations against the same inode. + +This race was introduced with the following change (added in 3.19 and +backported to stable 3.18 and 3.17): + + Btrfs: make sure logged extents complete in the current transaction V3 + commit 50d9aa99bd35c77200e0e3dd7a72274f8304701f + +I ran into this issue while running xfstests/generic/113 in a loop, which +failed about 1 out of 10 runs with the following warning in dmesg: + +[ 2612.440038] WARNING: CPU: 4 PID: 22057 at fs/btrfs/disk-io.c:3558 free_fs_root+0x36/0x133 [btrfs]() +[ 2612.442810] Modules linked in: btrfs crc32c_generic xor raid6_pq nfsd auth_rpcgss oid_registry nfs_acl nfs lockd grace fscache sunrpc loop processor parport_pc parport psmouse therma +l_sys i2c_piix4 serio_raw pcspkr evdev microcode button i2c_core ext4 crc16 jbd2 mbcache sd_mod sg sr_mod cdrom virtio_scsi ata_generic virtio_pci ata_piix virtio_ring libata virtio flo +ppy e1000 scsi_mod [last unloaded: btrfs] +[ 2612.452711] CPU: 4 PID: 22057 Comm: umount Tainted: G W 3.19.0-rc5-btrfs-next-4+ #1 +[ 2612.454921] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.7.5-0-ge51488c-20140602_164612-nilsson.home.kraxel.org 04/01/2014 +[ 2612.457709] 0000000000000009 ffff8801342c3c78 ffffffff8142425e ffff88023ec8f2d8 +[ 2612.459829] 0000000000000000 ffff8801342c3cb8 ffffffff81045308 ffff880046460000 +[ 2612.461564] ffffffffa036da56 ffff88003d07b000 ffff880046460000 ffff880046460068 +[ 2612.463163] Call Trace: +[ 2612.463719] [] dump_stack+0x4c/0x65 +[ 2612.464789] [] warn_slowpath_common+0xa1/0xbb +[ 2612.466026] [] ? free_fs_root+0x36/0x133 [btrfs] +[ 2612.467247] [] warn_slowpath_null+0x1a/0x1c +[ 2612.468416] [] free_fs_root+0x36/0x133 [btrfs] +[ 2612.469625] [] btrfs_drop_and_free_fs_root+0x93/0x9b [btrfs] +[ 2612.471251] [] btrfs_free_fs_roots+0xa4/0xd6 [btrfs] +[ 2612.472536] [] ? wait_for_completion+0x24/0x26 +[ 2612.473742] [] close_ctree+0x1f3/0x33c [btrfs] +[ 2612.475477] [] ? destroy_workqueue+0x148/0x1ba +[ 2612.476695] [] btrfs_put_super+0x19/0x1b [btrfs] +[ 2612.477911] [] generic_shutdown_super+0x73/0xef +[ 2612.479106] [] kill_anon_super+0x13/0x1e +[ 2612.480226] [] btrfs_kill_super+0x17/0x23 [btrfs] +[ 2612.481471] [] deactivate_locked_super+0x3b/0x50 +[ 2612.482686] [] deactivate_super+0x3f/0x43 +[ 2612.483791] [] cleanup_mnt+0x59/0x78 +[ 2612.484842] [] __cleanup_mnt+0x12/0x14 +[ 2612.485900] [] task_work_run+0x8f/0xbc +[ 2612.486960] [] do_notify_resume+0x5a/0x6b +[ 2612.488083] [] ? trace_hardirqs_on_thunk+0x3a/0x3f +[ 2612.489333] [] int_signal+0x12/0x17 +[ 2612.490353] ---[ end trace 54a960a6bdcb8d93 ]--- +[ 2612.557253] VFS: Busy inodes after unmount of sdb. Self-destruct in 5 seconds. Have a nice day... + +Kmemleak confirmed the ordered extent leak (and btrfs inode specific +structures such as delayed nodes): + +$ cat /sys/kernel/debug/kmemleak +unreferenced object 0xffff880154290db0 (size 576): + comm "btrfsck", pid 21980, jiffies 4295542503 (age 1273.412s) + hex dump (first 32 bytes): + 01 40 00 00 01 00 00 00 b0 1d f1 4e 01 88 ff ff .@.........N.... + 00 00 00 00 00 00 00 00 c8 0d 29 54 01 88 ff ff ..........)T.... + backtrace: + [] kmemleak_update_trace+0x4c/0x6a + [] radix_tree_node_alloc+0x6d/0x83 + [] __radix_tree_create+0x109/0x190 + [] radix_tree_insert+0x30/0xac + [] btrfs_get_or_create_delayed_node+0x130/0x187 [btrfs] + [] btrfs_delayed_delete_inode_ref+0x32/0xac [btrfs] + [] __btrfs_unlink_inode+0xee/0x288 [btrfs] + [] btrfs_unlink_inode+0x1e/0x40 [btrfs] + [] btrfs_unlink+0x60/0x9b [btrfs] + [] vfs_unlink+0x9c/0xed + [] do_unlinkat+0x12c/0x1fa + [] SyS_unlinkat+0x29/0x2b + [] system_call_fastpath+0x12/0x17 + [] 0xffffffffffffffff +unreferenced object 0xffff88014ef11db0 (size 576): + comm "rm", pid 22009, jiffies 4295542593 (age 1273.052s) + hex dump (first 32 bytes): + 02 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 ................ + 00 00 00 00 00 00 00 00 c8 1d f1 4e 01 88 ff ff ...........N.... + backtrace: + [] kmemleak_update_trace+0x4c/0x6a + [] radix_tree_node_alloc+0x6d/0x83 + [] __radix_tree_create+0x109/0x190 + [] radix_tree_insert+0x30/0xac + [] btrfs_get_or_create_delayed_node+0x130/0x187 [btrfs] + [] btrfs_delayed_delete_inode_ref+0x32/0xac [btrfs] + [] __btrfs_unlink_inode+0xee/0x288 [btrfs] + [] btrfs_unlink_inode+0x1e/0x40 [btrfs] + [] btrfs_unlink+0x60/0x9b [btrfs] + [] vfs_unlink+0x9c/0xed + [] do_unlinkat+0x12c/0x1fa + [] SyS_unlinkat+0x29/0x2b + [] system_call_fastpath+0x12/0x17 + [] 0xffffffffffffffff +unreferenced object 0xffff8800336feda8 (size 584): + comm "aio-stress", pid 22031, jiffies 4295543006 (age 1271.400s) + hex dump (first 32 bytes): + 00 40 3e 00 00 00 00 00 00 00 8f 42 00 00 00 00 .@>........B.... + 00 00 01 00 00 00 00 00 00 00 01 00 00 00 00 00 ................ + backtrace: + [] create_object+0x172/0x29a + [] kmemleak_alloc+0x25/0x41 + [] kmemleak_alloc_recursive.constprop.52+0x16/0x18 + [] kmem_cache_alloc+0xf7/0x198 + [] __btrfs_add_ordered_extent+0x43/0x309 [btrfs] + [] btrfs_add_ordered_extent_dio+0x12/0x14 [btrfs] + [] btrfs_get_blocks_direct+0x3ef/0x571 [btrfs] + [] do_blockdev_direct_IO+0x62a/0xb47 + [] __blockdev_direct_IO+0x34/0x36 + [] btrfs_direct_IO+0x16a/0x1e8 [btrfs] + [] generic_file_direct_write+0xb8/0x12d + [] btrfs_file_write_iter+0x24b/0x42f [btrfs] + [] aio_run_iocb+0x2b7/0x32e + [] do_io_submit+0x26e/0x2ff + [] SyS_io_submit+0x10/0x12 + [] system_call_fastpath+0x12/0x17 + +Signed-off-by: Filipe Manana +Signed-off-by: Chris Mason +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/ordered-data.c | 7 ++----- + 1 file changed, 2 insertions(+), 5 deletions(-) + +--- a/fs/btrfs/ordered-data.c ++++ b/fs/btrfs/ordered-data.c +@@ -452,9 +452,7 @@ void btrfs_get_logged_extents(struct ino + continue; + if (entry_end(ordered) <= start) + break; +- if (!list_empty(&ordered->log_list)) +- continue; +- if (test_bit(BTRFS_ORDERED_LOGGED, &ordered->flags)) ++ if (test_and_set_bit(BTRFS_ORDERED_LOGGED, &ordered->flags)) + continue; + list_add(&ordered->log_list, logged_list); + atomic_inc(&ordered->refs); +@@ -511,8 +509,7 @@ void btrfs_wait_logged_extents(struct bt + wait_event(ordered->wait, test_bit(BTRFS_ORDERED_IO_DONE, + &ordered->flags)); + +- if (!test_and_set_bit(BTRFS_ORDERED_LOGGED, &ordered->flags)) +- list_add_tail(&ordered->trans_list, &trans->ordered); ++ list_add_tail(&ordered->trans_list, &trans->ordered); + spin_lock_irq(&log->log_extents_lock[index]); + } + spin_unlock_irq(&log->log_extents_lock[index]); diff --git a/queue-3.19/btrfs-fix-lost-return-value-due-to-variable-shadowing.patch b/queue-3.19/btrfs-fix-lost-return-value-due-to-variable-shadowing.patch new file mode 100644 index 00000000000..8af1976c412 --- /dev/null +++ b/queue-3.19/btrfs-fix-lost-return-value-due-to-variable-shadowing.patch @@ -0,0 +1,31 @@ +From 1932b7be973b554ffe20a5bba6ffaed6fa995cdc Mon Sep 17 00:00:00 2001 +From: David Sterba +Date: Tue, 24 Feb 2015 18:57:18 +0100 +Subject: btrfs: fix lost return value due to variable shadowing + +From: David Sterba + +commit 1932b7be973b554ffe20a5bba6ffaed6fa995cdc upstream. + +A block-local variable stores error code but btrfs_get_blocks_direct may +not return it in the end as there's a ret defined in the function scope. + +Fixes: d187663ef24c ("Btrfs: lock extents as we map them in DIO") +Signed-off-by: David Sterba +Signed-off-by: Chris Mason +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/inode.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -7208,7 +7208,6 @@ static int btrfs_get_blocks_direct(struc + ((BTRFS_I(inode)->flags & BTRFS_INODE_NODATACOW) && + em->block_start != EXTENT_MAP_HOLE)) { + int type; +- int ret; + u64 block_start, orig_start, orig_block_len, ram_bytes; + + if (test_bit(EXTENT_FLAG_PREALLOC, &em->flags)) diff --git a/queue-3.19/kvm-emulate-fix-cmpxchg8b-on-32-bit-hosts.patch b/queue-3.19/kvm-emulate-fix-cmpxchg8b-on-32-bit-hosts.patch new file mode 100644 index 00000000000..d287a57b5c5 --- /dev/null +++ b/queue-3.19/kvm-emulate-fix-cmpxchg8b-on-32-bit-hosts.patch @@ -0,0 +1,42 @@ +From 4ff6f8e61eb7f96d3ca535c6d240f863ccd6fb7d Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Thu, 12 Feb 2015 17:04:47 +0100 +Subject: KVM: emulate: fix CMPXCHG8B on 32-bit hosts + +From: Paolo Bonzini + +commit 4ff6f8e61eb7f96d3ca535c6d240f863ccd6fb7d upstream. + +This has been broken for a long time: it broke first in 2.6.35, then was +almost fixed in 2.6.36 but this one-liner slipped through the cracks. +The bug shows up as an infinite loop in Windows 7 (and newer) boot on +32-bit hosts without EPT. + +Windows uses CMPXCHG8B to write to page tables, which causes a +page fault if running without EPT; the emulator is then called from +kvm_mmu_page_fault. The loop then happens if the higher 4 bytes are +not 0; the common case for this is that the NX bit (bit 63) is 1. + +Fixes: 6550e1f165f384f3a46b60a1be9aba4bc3c2adad +Fixes: 16518d5ada690643453eb0aef3cc7841d3623c2d +Reported-by: Erik Rull +Tested-by: Erik Rull +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kvm/emulate.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/arch/x86/kvm/emulate.c ++++ b/arch/x86/kvm/emulate.c +@@ -4863,7 +4863,8 @@ int x86_emulate_insn(struct x86_emulate_ + if (rc != X86EMUL_CONTINUE) + goto done; + } +- ctxt->dst.orig_val = ctxt->dst.val; ++ /* Copy full 64-bit value for CMPXCHG8B. */ ++ ctxt->dst.orig_val64 = ctxt->dst.val64; + + special_insn: + diff --git a/queue-3.19/kvm-mips-fix-trace-event-to-save-pc-directly.patch b/queue-3.19/kvm-mips-fix-trace-event-to-save-pc-directly.patch new file mode 100644 index 00000000000..d0d6fa017d3 --- /dev/null +++ b/queue-3.19/kvm-mips-fix-trace-event-to-save-pc-directly.patch @@ -0,0 +1,63 @@ +From b3cffac04eca9af46e1e23560a8ee22b1bd36d43 Mon Sep 17 00:00:00 2001 +From: James Hogan +Date: Tue, 24 Feb 2015 11:46:20 +0000 +Subject: KVM: MIPS: Fix trace event to save PC directly + +From: James Hogan + +commit b3cffac04eca9af46e1e23560a8ee22b1bd36d43 upstream. + +Currently the guest exit trace event saves the VCPU pointer to the +structure, and the guest PC is retrieved by dereferencing it when the +event is printed rather than directly from the trace record. This isn't +safe as the printing may occur long afterwards, after the PC has changed +and potentially after the VCPU has been freed. Usually this results in +the same (wrong) PC being printed for multiple trace events. It also +isn't portable as userland has no way to access the VCPU data structure +when interpreting the trace record itself. + +Lets save the actual PC in the structure so that the correct value is +accessible later. + +Fixes: 669e846e6c4e ("KVM/MIPS32: MIPS arch specific APIs for KVM") +Signed-off-by: James Hogan +Cc: Paolo Bonzini +Cc: Ralf Baechle +Cc: Marcelo Tosatti +Cc: Gleb Natapov +Cc: Steven Rostedt +Cc: Ingo Molnar +Cc: linux-mips@linux-mips.org +Cc: kvm@vger.kernel.org +Acked-by: Steven Rostedt +Signed-off-by: Marcelo Tosatti +Signed-off-by: Greg Kroah-Hartman + +--- + arch/mips/kvm/trace.h | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/arch/mips/kvm/trace.h ++++ b/arch/mips/kvm/trace.h +@@ -24,18 +24,18 @@ TRACE_EVENT(kvm_exit, + TP_PROTO(struct kvm_vcpu *vcpu, unsigned int reason), + TP_ARGS(vcpu, reason), + TP_STRUCT__entry( +- __field(struct kvm_vcpu *, vcpu) ++ __field(unsigned long, pc) + __field(unsigned int, reason) + ), + + TP_fast_assign( +- __entry->vcpu = vcpu; ++ __entry->pc = vcpu->arch.pc; + __entry->reason = reason; + ), + + TP_printk("[%s]PC: 0x%08lx", + kvm_mips_exit_types_str[__entry->reason], +- __entry->vcpu->arch.pc) ++ __entry->pc) + ); + + #endif /* _TRACE_KVM_H */ diff --git a/queue-3.19/mei-make-device-disabled-on-stop-unconditionally.patch b/queue-3.19/mei-make-device-disabled-on-stop-unconditionally.patch new file mode 100644 index 00000000000..746c39d9425 --- /dev/null +++ b/queue-3.19/mei-make-device-disabled-on-stop-unconditionally.patch @@ -0,0 +1,32 @@ +From 6c15a8516b8118eb19a59fd0bd22df41b9101c32 Mon Sep 17 00:00:00 2001 +From: Alexander Usyskin +Date: Tue, 10 Feb 2015 10:36:36 +0200 +Subject: mei: make device disabled on stop unconditionally + +From: Alexander Usyskin + +commit 6c15a8516b8118eb19a59fd0bd22df41b9101c32 upstream. + +Set the internal device state to to disabled after hardware reset in stop flow. +This will cover cases when driver was not brought to disabled state because of +an error and in stop flow we wish not to retry the reset. + +Signed-off-by: Alexander Usyskin +Signed-off-by: Tomas Winkler +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/misc/mei/init.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/misc/mei/init.c ++++ b/drivers/misc/mei/init.c +@@ -341,6 +341,8 @@ void mei_stop(struct mei_device *dev) + + dev->dev_state = MEI_DEV_POWER_DOWN; + mei_reset(dev); ++ /* move device to disabled state unconditionally */ ++ dev->dev_state = MEI_DEV_DISABLED; + + mutex_unlock(&dev->device_lock); + diff --git a/queue-3.19/series b/queue-3.19/series index 819afaf8763..f1a5c6128d3 100644 --- a/queue-3.19/series +++ b/queue-3.19/series @@ -67,4 +67,11 @@ iio-ad5686-fix-optional-reference-voltage-declaration.patch iio-adc-mcp3422-fix-incorrect-scales-table.patch iio-si7020-allocate-correct-amount-of-memory-in-devm_iio_device_alloc.patch revert-iio-humidity-si7020-fix-pointer-to-i2c-client.patch +mei-make-device-disabled-on-stop-unconditionally.patch +btrfs-fix-fsync-race-leading-to-ordered-extent-memory-leaks.patch +btrfs-fix-lost-return-value-due-to-variable-shadowing.patch +btrfs-fix-data-loss-in-the-fast-fsync-path.patch +btrfs-__add_inode_ref-out-of-bounds-memory-read-when-looking-for-extended-ref.patch +kvm-emulate-fix-cmpxchg8b-on-32-bit-hosts.patch +kvm-mips-fix-trace-event-to-save-pc-directly.patch target-fix-r_holder-bit-usage-for-allregistrants.patch