From: Greg Kroah-Hartman Date: Sun, 17 Apr 2016 12:15:28 +0000 (-0700) Subject: 4.4-stable patches X-Git-Tag: v3.14.67~7 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6542fece09e3f983b3557050689978d1a6010aa2;p=thirdparty%2Fkernel%2Fstable-queue.git 4.4-stable patches added patches: arm64-replace-read_lock-to-rcu-lock-in-call_step_hook.patch btrfs-fix-crash-invalid-memory-access-on-fsync-when-using-overlayfs.patch btrfs-fix-file-data-loss-caused-by-fsync-after-rename-and-new-inode.patch ext4-add-lockdep-annotations-for-i_data_sem.patch ext4-ignore-quota-mount-options-if-the-quota-feature-is-enabled.patch fs-add-file_dentry.patch iommu-don-t-overwrite-domain-pointer-when-there-is-no-default_domain.patch mmc-sdhci-pci-add-support-and-pci-ids-for-more-broxton-host-controllers.patch nfs-use-file_dentry.patch perf-cure-event-pending_disable-race.patch perf-do-not-double-free.patch --- diff --git a/queue-4.4/arm64-replace-read_lock-to-rcu-lock-in-call_step_hook.patch b/queue-4.4/arm64-replace-read_lock-to-rcu-lock-in-call_step_hook.patch new file mode 100644 index 00000000000..ff43b1da72d --- /dev/null +++ b/queue-4.4/arm64-replace-read_lock-to-rcu-lock-in-call_step_hook.patch @@ -0,0 +1,100 @@ +From cf0a25436f05753aca5151891aea4fd130556e2a Mon Sep 17 00:00:00 2001 +From: Yang Shi +Date: Mon, 8 Feb 2016 14:49:24 -0800 +Subject: arm64: replace read_lock to rcu lock in call_step_hook + +From: Yang Shi + +commit cf0a25436f05753aca5151891aea4fd130556e2a upstream. + +BUG: sleeping function called from invalid context at kernel/locking/rtmutex.c:917 +in_atomic(): 1, irqs_disabled(): 128, pid: 383, name: sh +Preemption disabled at:[] kgdb_cpu_enter+0x158/0x6b8 + +CPU: 3 PID: 383 Comm: sh Tainted: G W 4.1.13-rt13 #2 +Hardware name: Freescale Layerscape 2085a RDB Board (DT) +Call trace: +[] dump_backtrace+0x0/0x128 +[] show_stack+0x24/0x30 +[] dump_stack+0x80/0xa0 +[] ___might_sleep+0x18c/0x1a0 +[] __rt_spin_lock+0x2c/0x40 +[] rt_read_lock+0x40/0x58 +[] single_step_handler+0x38/0xd8 +[] do_debug_exception+0x58/0xb8 +Exception stack(0xffff80834a1e7c80 to 0xffff80834a1e7da0) +7c80: ffffff9c ffffffff 92c23ba0 0000ffff 4a1e7e40 ffff8083 001bfcc4 ffff8000 +7ca0: f2000400 00000000 00000000 00000000 4a1e7d80 ffff8083 0049501c ffff8000 +7cc0: 00005402 00000000 00aaa210 ffff8000 4a1e7ea0 ffff8083 000833f4 ffff8000 +7ce0: ffffff9c ffffffff 92c23ba0 0000ffff 4a1e7ea0 ffff8083 001bfcc0 ffff8000 +7d00: 4a0fc400 ffff8083 00005402 00000000 4a1e7d40 ffff8083 00490324 ffff8000 +7d20: ffffff9c 00000000 92c23ba0 0000ffff 000a0000 00000000 00000000 00000000 +7d40: 00000008 00000000 00080000 00000000 92c23b8b 0000ffff 92c23b8e 0000ffff +7d60: 00000038 00000000 00001cb2 00000000 00000005 00000000 92d7b498 0000ffff +7d80: 01010101 01010101 92be9000 0000ffff 00000000 00000000 00000030 00000000 +[] el1_dbg+0x18/0x6c + +This issue is similar with 62c6c61("arm64: replace read_lock to rcu lock in +call_break_hook"), but comes to single_step_handler. + +This also solves kgdbts boot test silent hang issue on 4.4 -rt kernel. + +Signed-off-by: Yang Shi +Acked-by: Will Deacon +Signed-off-by: Catalin Marinas +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm64/kernel/debug-monitors.c | 21 +++++++++++---------- + 1 file changed, 11 insertions(+), 10 deletions(-) + +--- a/arch/arm64/kernel/debug-monitors.c ++++ b/arch/arm64/kernel/debug-monitors.c +@@ -186,20 +186,21 @@ static void clear_regs_spsr_ss(struct pt + + /* EL1 Single Step Handler hooks */ + static LIST_HEAD(step_hook); +-static DEFINE_RWLOCK(step_hook_lock); ++static DEFINE_SPINLOCK(step_hook_lock); + + void register_step_hook(struct step_hook *hook) + { +- write_lock(&step_hook_lock); +- list_add(&hook->node, &step_hook); +- write_unlock(&step_hook_lock); ++ spin_lock(&step_hook_lock); ++ list_add_rcu(&hook->node, &step_hook); ++ spin_unlock(&step_hook_lock); + } + + void unregister_step_hook(struct step_hook *hook) + { +- write_lock(&step_hook_lock); +- list_del(&hook->node); +- write_unlock(&step_hook_lock); ++ spin_lock(&step_hook_lock); ++ list_del_rcu(&hook->node); ++ spin_unlock(&step_hook_lock); ++ synchronize_rcu(); + } + + /* +@@ -213,15 +214,15 @@ static int call_step_hook(struct pt_regs + struct step_hook *hook; + int retval = DBG_HOOK_ERROR; + +- read_lock(&step_hook_lock); ++ rcu_read_lock(); + +- list_for_each_entry(hook, &step_hook, node) { ++ list_for_each_entry_rcu(hook, &step_hook, node) { + retval = hook->fn(regs, esr); + if (retval == DBG_HOOK_HANDLED) + break; + } + +- read_unlock(&step_hook_lock); ++ rcu_read_unlock(); + + return retval; + } diff --git a/queue-4.4/btrfs-fix-crash-invalid-memory-access-on-fsync-when-using-overlayfs.patch b/queue-4.4/btrfs-fix-crash-invalid-memory-access-on-fsync-when-using-overlayfs.patch new file mode 100644 index 00000000000..68684c47642 --- /dev/null +++ b/queue-4.4/btrfs-fix-crash-invalid-memory-access-on-fsync-when-using-overlayfs.patch @@ -0,0 +1,91 @@ +From de17e793b104d690e1d007dfc5cb6b4f649598ca Mon Sep 17 00:00:00 2001 +From: Filipe Manana +Date: Wed, 30 Mar 2016 19:03:13 -0400 +Subject: btrfs: fix crash/invalid memory access on fsync when using overlayfs + +From: Filipe Manana + +commit de17e793b104d690e1d007dfc5cb6b4f649598ca upstream. + +If the lower or upper directory of an overlayfs mount belong to a btrfs +file system and we fsync the file through the overlayfs' merged directory +we ended up accessing an inode that didn't belong to btrfs as if it were +a btrfs inode at btrfs_sync_file() resulting in a crash like the following: + +[ 7782.588845] BUG: unable to handle kernel NULL pointer dereference at 0000000000000544 +[ 7782.590624] IP: [] btrfs_sync_file+0x11b/0x3e9 [btrfs] +[ 7782.591931] PGD 4d954067 PUD 1e878067 PMD 0 +[ 7782.592016] Oops: 0002 [#6] PREEMPT SMP DEBUG_PAGEALLOC +[ 7782.592016] Modules linked in: btrfs overlay ppdev crc32c_generic evdev xor raid6_pq psmouse pcspkr sg serio_raw acpi_cpufreq parport_pc parport tpm_tis i2c_piix4 tpm i2c_core processor button loop autofs4 ext4 crc16 mbcache jbd2 sr_mod cdrom sd_mod ata_generic virtio_scsi ata_piix virtio_pci libata virtio_ring virtio scsi_mod e1000 floppy [last unloaded: btrfs] +[ 7782.592016] CPU: 10 PID: 16437 Comm: xfs_io Tainted: G D 4.5.0-rc6-btrfs-next-26+ #1 +[ 7782.592016] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS by qemu-project.org 04/01/2014 +[ 7782.592016] task: ffff88001b8d40c0 ti: ffff880137488000 task.ti: ffff880137488000 +[ 7782.592016] RIP: 0010:[] [] btrfs_sync_file+0x11b/0x3e9 [btrfs] +[ 7782.592016] RSP: 0018:ffff88013748be40 EFLAGS: 00010286 +[ 7782.592016] RAX: 0000000080000000 RBX: ffff880133b30c88 RCX: 0000000000000001 +[ 7782.592016] RDX: 0000000000000001 RSI: ffffffff8148fec0 RDI: 00000000ffffffff +[ 7782.592016] RBP: ffff88013748bec0 R08: 0000000000000001 R09: 0000000000000000 +[ 7782.624248] R10: ffff88013748be40 R11: 0000000000000246 R12: 0000000000000000 +[ 7782.624248] R13: 0000000000000000 R14: 00000000009305a0 R15: ffff880015e3be40 +[ 7782.624248] FS: 00007fa83b9cb700(0000) GS:ffff88023ed40000(0000) knlGS:0000000000000000 +[ 7782.624248] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 7782.624248] CR2: 0000000000000544 CR3: 00000001fa652000 CR4: 00000000000006e0 +[ 7782.624248] Stack: +[ 7782.624248] ffffffff8108b5cc ffff88013748bec0 0000000000000246 ffff8800b005ded0 +[ 7782.624248] ffff880133b30d60 8000000000000000 7fffffffffffffff 0000000000000246 +[ 7782.624248] 0000000000000246 ffffffff81074f9b ffffffff8104357c ffff880015e3be40 +[ 7782.624248] Call Trace: +[ 7782.624248] [] ? arch_local_irq_save+0x9/0xc +[ 7782.624248] [] ? ___might_sleep+0xce/0x217 +[ 7782.624248] [] ? __do_page_fault+0x3c0/0x43a +[ 7782.624248] [] vfs_fsync_range+0x8c/0x9e +[ 7782.624248] [] vfs_fsync+0x1c/0x1e +[ 7782.624248] [] do_fsync+0x31/0x4a +[ 7782.624248] [] SyS_fsync+0x10/0x14 +[ 7782.624248] [] entry_SYSCALL_64_fastpath+0x12/0x6b +[ 7782.624248] Code: 85 c0 0f 85 e2 02 00 00 48 8b 45 b0 31 f6 4c 29 e8 48 ff c0 48 89 45 a8 48 8d 83 d8 00 00 00 48 89 c7 48 89 45 a0 e8 fc 43 18 e1 41 ff 84 24 44 05 00 00 48 8b 83 58 ff ff ff 48 c1 e8 07 83 +[ 7782.624248] RIP [] btrfs_sync_file+0x11b/0x3e9 [btrfs] +[ 7782.624248] RSP +[ 7782.624248] CR2: 0000000000000544 +[ 7782.661994] ---[ end trace 721e14960eb939bc ]--- + +This started happening since commit 4bacc9c9234 (overlayfs: Make f_path +always point to the overlay and f_inode to the underlay) and even though +after this change we could still access the btrfs inode through +struct file->f_mapping->host or struct file->f_inode, we would end up +resulting in more similar issues later on at check_parent_dirs_for_sync() +because the dentry we got (from struct file->f_path.dentry) was from +overlayfs and not from btrfs, that is, we had no way of getting the dentry +that belonged to btrfs (we always got the dentry that belonged to +overlayfs). + +The new patch from Miklos Szeredi, titled "vfs: add file_dentry()" and +recently submitted to linux-fsdevel, adds a file_dentry() API that allows +us to get the btrfs dentry from the input file and therefore being able +to fsync when the upper and lower directories belong to btrfs filesystems. + +This issue has been reported several times by users in the mailing list +and bugzilla. A test case for xfstests is being submitted as well. + +Fixes: 4bacc9c9234c ("overlayfs: Make f_path always point to the overlay and f_inode to the underlay") +Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=101951 +Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=109791 +Signed-off-by: Filipe Manana +Signed-off-by: Chris Mason +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/file.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/btrfs/file.c ++++ b/fs/btrfs/file.c +@@ -1885,7 +1885,7 @@ static int start_ordered_ops(struct inod + */ + int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) + { +- struct dentry *dentry = file->f_path.dentry; ++ struct dentry *dentry = file_dentry(file); + struct inode *inode = d_inode(dentry); + struct btrfs_root *root = BTRFS_I(inode)->root; + struct btrfs_trans_handle *trans; diff --git a/queue-4.4/btrfs-fix-file-data-loss-caused-by-fsync-after-rename-and-new-inode.patch b/queue-4.4/btrfs-fix-file-data-loss-caused-by-fsync-after-rename-and-new-inode.patch new file mode 100644 index 00000000000..4a42fec8c4a --- /dev/null +++ b/queue-4.4/btrfs-fix-file-data-loss-caused-by-fsync-after-rename-and-new-inode.patch @@ -0,0 +1,290 @@ +From 56f23fdbb600e6087db7b009775b95ce07cc3195 Mon Sep 17 00:00:00 2001 +From: Filipe Manana +Date: Wed, 30 Mar 2016 23:37:21 +0100 +Subject: Btrfs: fix file/data loss caused by fsync after rename and new inode + +From: Filipe Manana + +commit 56f23fdbb600e6087db7b009775b95ce07cc3195 upstream. + +If we rename an inode A (be it a file or a directory), create a new +inode B with the old name of inode A and under the same parent directory, +fsync inode B and then power fail, at log tree replay time we end up +removing inode A completely. If inode A is a directory then all its files +are gone too. + +Example scenarios where this happens: +This is reproducible with the following steps, taken from a couple of +test cases written for fstests which are going to be submitted upstream +soon: + + # Scenario 1 + + mkfs.btrfs -f /dev/sdc + mount /dev/sdc /mnt + mkdir -p /mnt/a/x + echo "hello" > /mnt/a/x/foo + echo "world" > /mnt/a/x/bar + sync + mv /mnt/a/x /mnt/a/y + mkdir /mnt/a/x + xfs_io -c fsync /mnt/a/x + + + The next time the fs is mounted, log tree replay happens and + the directory "y" does not exist nor do the files "foo" and + "bar" exist anywhere (neither in "y" nor in "x", nor the root + nor anywhere). + + # Scenario 2 + + mkfs.btrfs -f /dev/sdc + mount /dev/sdc /mnt + mkdir /mnt/a + echo "hello" > /mnt/a/foo + sync + mv /mnt/a/foo /mnt/a/bar + echo "world" > /mnt/a/foo + xfs_io -c fsync /mnt/a/foo + + + The next time the fs is mounted, log tree replay happens and the + file "bar" does not exists anymore. A file with the name "foo" + exists and it matches the second file we created. + +Another related problem that does not involve file/data loss is when a +new inode is created with the name of a deleted snapshot and we fsync it: + + mkfs.btrfs -f /dev/sdc + mount /dev/sdc /mnt + mkdir /mnt/testdir + btrfs subvolume snapshot /mnt /mnt/testdir/snap + btrfs subvolume delete /mnt/testdir/snap + rmdir /mnt/testdir + mkdir /mnt/testdir + xfs_io -c fsync /mnt/testdir # or fsync some file inside /mnt/testdir + + + The next time the fs is mounted the log replay procedure fails because + it attempts to delete the snapshot entry (which has dir item key type + of BTRFS_ROOT_ITEM_KEY) as if it were a regular (non-root) entry, + resulting in the following error that causes mount to fail: + + [52174.510532] BTRFS info (device dm-0): failed to delete reference to snap, inode 257 parent 257 + [52174.512570] ------------[ cut here ]------------ + [52174.513278] WARNING: CPU: 12 PID: 28024 at fs/btrfs/inode.c:3986 __btrfs_unlink_inode+0x178/0x351 [btrfs]() + [52174.514681] BTRFS: Transaction aborted (error -2) + [52174.515630] Modules linked in: btrfs dm_flakey dm_mod overlay crc32c_generic ppdev xor raid6_pq acpi_cpufreq parport_pc tpm_tis sg parport tpm evdev i2c_piix4 proc + [52174.521568] CPU: 12 PID: 28024 Comm: mount Tainted: G W 4.5.0-rc6-btrfs-next-27+ #1 + [52174.522805] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS by qemu-project.org 04/01/2014 + [52174.524053] 0000000000000000 ffff8801df2a7710 ffffffff81264e93 ffff8801df2a7758 + [52174.524053] 0000000000000009 ffff8801df2a7748 ffffffff81051618 ffffffffa03591cd + [52174.524053] 00000000fffffffe ffff88015e6e5000 ffff88016dbc3c88 ffff88016dbc3c88 + [52174.524053] Call Trace: + [52174.524053] [] dump_stack+0x67/0x90 + [52174.524053] [] warn_slowpath_common+0x99/0xb2 + [52174.524053] [] ? __btrfs_unlink_inode+0x178/0x351 [btrfs] + [52174.524053] [] warn_slowpath_fmt+0x48/0x50 + [52174.524053] [] __btrfs_unlink_inode+0x178/0x351 [btrfs] + [52174.524053] [] ? iput+0xb0/0x284 + [52174.524053] [] btrfs_unlink_inode+0x1c/0x3d [btrfs] + [52174.524053] [] check_item_in_log+0x1fe/0x29b [btrfs] + [52174.524053] [] replay_dir_deletes+0x167/0x1cf [btrfs] + [52174.524053] [] fixup_inode_link_count+0x289/0x2aa [btrfs] + [52174.524053] [] fixup_inode_link_counts+0xcb/0x105 [btrfs] + [52174.524053] [] btrfs_recover_log_trees+0x258/0x32c [btrfs] + [52174.524053] [] ? replay_one_extent+0x511/0x511 [btrfs] + [52174.524053] [] open_ctree+0x1dd4/0x21b9 [btrfs] + [52174.524053] [] btrfs_mount+0x97e/0xaed [btrfs] + [52174.524053] [] ? trace_hardirqs_on+0xd/0xf + [52174.524053] [] mount_fs+0x67/0x131 + [52174.524053] [] vfs_kern_mount+0x6c/0xde + [52174.524053] [] btrfs_mount+0x1ac/0xaed [btrfs] + [52174.524053] [] ? trace_hardirqs_on+0xd/0xf + [52174.524053] [] ? lockdep_init_map+0xb9/0x1b3 + [52174.524053] [] mount_fs+0x67/0x131 + [52174.524053] [] vfs_kern_mount+0x6c/0xde + [52174.524053] [] do_mount+0x8a6/0x9e8 + [52174.524053] [] ? strndup_user+0x3f/0x59 + [52174.524053] [] SyS_mount+0x77/0x9f + [52174.524053] [] entry_SYSCALL_64_fastpath+0x12/0x6b + [52174.561288] ---[ end trace 6b53049efb1a3ea6 ]--- + +Fix this by forcing a transaction commit when such cases happen. +This means we check in the commit root of the subvolume tree if there +was any other inode with the same reference when the inode we are +fsync'ing is a new inode (created in the current transaction). + +Test cases for fstests, covering all the scenarios given above, were +submitted upstream for fstests: + + * fstests: generic test for fsync after renaming directory + https://patchwork.kernel.org/patch/8694281/ + + * fstests: generic test for fsync after renaming file + https://patchwork.kernel.org/patch/8694301/ + + * fstests: add btrfs test for fsync after snapshot deletion + https://patchwork.kernel.org/patch/8670671/ + +Signed-off-by: Filipe Manana +Signed-off-by: Chris Mason +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/tree-log.c | 137 ++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 137 insertions(+) + +--- a/fs/btrfs/tree-log.c ++++ b/fs/btrfs/tree-log.c +@@ -4406,6 +4406,127 @@ static int btrfs_log_trailing_hole(struc + return ret; + } + ++/* ++ * When we are logging a new inode X, check if it doesn't have a reference that ++ * matches the reference from some other inode Y created in a past transaction ++ * and that was renamed in the current transaction. If we don't do this, then at ++ * log replay time we can lose inode Y (and all its files if it's a directory): ++ * ++ * mkdir /mnt/x ++ * echo "hello world" > /mnt/x/foobar ++ * sync ++ * mv /mnt/x /mnt/y ++ * mkdir /mnt/x # or touch /mnt/x ++ * xfs_io -c fsync /mnt/x ++ * ++ * mount fs, trigger log replay ++ * ++ * After the log replay procedure, we would lose the first directory and all its ++ * files (file foobar). ++ * For the case where inode Y is not a directory we simply end up losing it: ++ * ++ * echo "123" > /mnt/foo ++ * sync ++ * mv /mnt/foo /mnt/bar ++ * echo "abc" > /mnt/foo ++ * xfs_io -c fsync /mnt/foo ++ * ++ * ++ * We also need this for cases where a snapshot entry is replaced by some other ++ * entry (file or directory) otherwise we end up with an unreplayable log due to ++ * attempts to delete the snapshot entry (entry of type BTRFS_ROOT_ITEM_KEY) as ++ * if it were a regular entry: ++ * ++ * mkdir /mnt/x ++ * btrfs subvolume snapshot /mnt /mnt/x/snap ++ * btrfs subvolume delete /mnt/x/snap ++ * rmdir /mnt/x ++ * mkdir /mnt/x ++ * fsync /mnt/x or fsync some new file inside it ++ * ++ * ++ * The snapshot delete, rmdir of x, mkdir of a new x and the fsync all happen in ++ * the same transaction. ++ */ ++static int btrfs_check_ref_name_override(struct extent_buffer *eb, ++ const int slot, ++ const struct btrfs_key *key, ++ struct inode *inode) ++{ ++ int ret; ++ struct btrfs_path *search_path; ++ char *name = NULL; ++ u32 name_len = 0; ++ u32 item_size = btrfs_item_size_nr(eb, slot); ++ u32 cur_offset = 0; ++ unsigned long ptr = btrfs_item_ptr_offset(eb, slot); ++ ++ search_path = btrfs_alloc_path(); ++ if (!search_path) ++ return -ENOMEM; ++ search_path->search_commit_root = 1; ++ search_path->skip_locking = 1; ++ ++ while (cur_offset < item_size) { ++ u64 parent; ++ u32 this_name_len; ++ u32 this_len; ++ unsigned long name_ptr; ++ struct btrfs_dir_item *di; ++ ++ if (key->type == BTRFS_INODE_REF_KEY) { ++ struct btrfs_inode_ref *iref; ++ ++ iref = (struct btrfs_inode_ref *)(ptr + cur_offset); ++ parent = key->offset; ++ this_name_len = btrfs_inode_ref_name_len(eb, iref); ++ name_ptr = (unsigned long)(iref + 1); ++ this_len = sizeof(*iref) + this_name_len; ++ } else { ++ struct btrfs_inode_extref *extref; ++ ++ extref = (struct btrfs_inode_extref *)(ptr + ++ cur_offset); ++ parent = btrfs_inode_extref_parent(eb, extref); ++ this_name_len = btrfs_inode_extref_name_len(eb, extref); ++ name_ptr = (unsigned long)&extref->name; ++ this_len = sizeof(*extref) + this_name_len; ++ } ++ ++ if (this_name_len > name_len) { ++ char *new_name; ++ ++ new_name = krealloc(name, this_name_len, GFP_NOFS); ++ if (!new_name) { ++ ret = -ENOMEM; ++ goto out; ++ } ++ name_len = this_name_len; ++ name = new_name; ++ } ++ ++ read_extent_buffer(eb, name, name_ptr, this_name_len); ++ di = btrfs_lookup_dir_item(NULL, BTRFS_I(inode)->root, ++ search_path, parent, ++ name, this_name_len, 0); ++ if (di && !IS_ERR(di)) { ++ ret = 1; ++ goto out; ++ } else if (IS_ERR(di)) { ++ ret = PTR_ERR(di); ++ goto out; ++ } ++ btrfs_release_path(search_path); ++ ++ cur_offset += this_len; ++ } ++ ret = 0; ++out: ++ btrfs_free_path(search_path); ++ kfree(name); ++ return ret; ++} ++ + /* log a single inode in the tree log. + * At least one parent directory for this inode must exist in the tree + * or be logged already. +@@ -4578,6 +4699,22 @@ again: + if (min_key.type == BTRFS_INODE_ITEM_KEY) + need_log_inode_item = false; + ++ if ((min_key.type == BTRFS_INODE_REF_KEY || ++ min_key.type == BTRFS_INODE_EXTREF_KEY) && ++ BTRFS_I(inode)->generation == trans->transid) { ++ ret = btrfs_check_ref_name_override(path->nodes[0], ++ path->slots[0], ++ &min_key, inode); ++ if (ret < 0) { ++ err = ret; ++ goto out_unlock; ++ } else if (ret > 0) { ++ err = 1; ++ btrfs_set_log_full_commit(root->fs_info, trans); ++ goto out_unlock; ++ } ++ } ++ + /* Skip xattrs, we log them later with btrfs_log_all_xattrs() */ + if (min_key.type == BTRFS_XATTR_ITEM_KEY) { + if (ins_nr == 0) diff --git a/queue-4.4/ext4-add-lockdep-annotations-for-i_data_sem.patch b/queue-4.4/ext4-add-lockdep-annotations-for-i_data_sem.patch new file mode 100644 index 00000000000..f68b24dd4b8 --- /dev/null +++ b/queue-4.4/ext4-add-lockdep-annotations-for-i_data_sem.patch @@ -0,0 +1,148 @@ +From daf647d2dd58cec59570d7698a45b98e580f2076 Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Fri, 1 Apr 2016 01:31:28 -0400 +Subject: ext4: add lockdep annotations for i_data_sem + +From: Theodore Ts'o + +commit daf647d2dd58cec59570d7698a45b98e580f2076 upstream. + +With the internal Quota feature, mke2fs creates empty quota inodes and +quota usage tracking is enabled as soon as the file system is mounted. +Since quotacheck is no longer preallocating all of the blocks in the +quota inode that are likely needed to be written to, we are now seeing +a lockdep false positive caused by needing to allocate a quota block +from inside ext4_map_blocks(), while holding i_data_sem for a data +inode. This results in this complaint: + + Possible unsafe locking scenario: + + CPU0 CPU1 + ---- ---- + lock(&ei->i_data_sem); + lock(&s->s_dquot.dqio_mutex); + lock(&ei->i_data_sem); + lock(&s->s_dquot.dqio_mutex); + +Google-Bug-Id: 27907753 + +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/ext4.h | 23 +++++++++++++++++++++++ + fs/ext4/move_extent.c | 11 +++++++++-- + fs/ext4/super.c | 25 +++++++++++++++++++++++-- + 3 files changed, 55 insertions(+), 4 deletions(-) + +--- a/fs/ext4/ext4.h ++++ b/fs/ext4/ext4.h +@@ -850,6 +850,29 @@ do { \ + #include "extents_status.h" + + /* ++ * Lock subclasses for i_data_sem in the ext4_inode_info structure. ++ * ++ * These are needed to avoid lockdep false positives when we need to ++ * allocate blocks to the quota inode during ext4_map_blocks(), while ++ * holding i_data_sem for a normal (non-quota) inode. Since we don't ++ * do quota tracking for the quota inode, this avoids deadlock (as ++ * well as infinite recursion, since it isn't turtles all the way ++ * down...) ++ * ++ * I_DATA_SEM_NORMAL - Used for most inodes ++ * I_DATA_SEM_OTHER - Used by move_inode.c for the second normal inode ++ * where the second inode has larger inode number ++ * than the first ++ * I_DATA_SEM_QUOTA - Used for quota inodes only ++ */ ++enum { ++ I_DATA_SEM_NORMAL = 0, ++ I_DATA_SEM_OTHER, ++ I_DATA_SEM_QUOTA, ++}; ++ ++ ++/* + * fourth extended file system inode data in memory + */ + struct ext4_inode_info { +--- a/fs/ext4/move_extent.c ++++ b/fs/ext4/move_extent.c +@@ -60,10 +60,10 @@ ext4_double_down_write_data_sem(struct i + { + if (first < second) { + down_write(&EXT4_I(first)->i_data_sem); +- down_write_nested(&EXT4_I(second)->i_data_sem, SINGLE_DEPTH_NESTING); ++ down_write_nested(&EXT4_I(second)->i_data_sem, I_DATA_SEM_OTHER); + } else { + down_write(&EXT4_I(second)->i_data_sem); +- down_write_nested(&EXT4_I(first)->i_data_sem, SINGLE_DEPTH_NESTING); ++ down_write_nested(&EXT4_I(first)->i_data_sem, I_DATA_SEM_OTHER); + + } + } +@@ -482,6 +482,13 @@ mext_check_arguments(struct inode *orig_ + orig_inode->i_ino, donor_inode->i_ino); + return -EBUSY; + } ++ ++ if (IS_NOQUOTA(orig_inode) || IS_NOQUOTA(donor_inode)) { ++ ext4_debug("ext4 move extent: The argument files should " ++ "not be quota files [ino:orig %lu, donor %lu]\n", ++ orig_inode->i_ino, donor_inode->i_ino); ++ return -EBUSY; ++ } + + /* Ext4 move extent supports only extent based file */ + if (!(ext4_test_inode_flag(orig_inode, EXT4_INODE_EXTENTS))) { +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -4936,6 +4936,20 @@ static int ext4_quota_on_mount(struct su + EXT4_SB(sb)->s_jquota_fmt, type); + } + ++static void lockdep_set_quota_inode(struct inode *inode, int subclass) ++{ ++ struct ext4_inode_info *ei = EXT4_I(inode); ++ ++ /* The first argument of lockdep_set_subclass has to be ++ * *exactly* the same as the argument to init_rwsem() --- in ++ * this case, in init_once() --- or lockdep gets unhappy ++ * because the name of the lock is set using the ++ * stringification of the argument to init_rwsem(). ++ */ ++ (void) ei; /* shut up clang warning if !CONFIG_LOCKDEP */ ++ lockdep_set_subclass(&ei->i_data_sem, subclass); ++} ++ + /* + * Standard function to be called on quota_on + */ +@@ -4975,8 +4989,12 @@ static int ext4_quota_on(struct super_bl + if (err) + return err; + } +- +- return dquot_quota_on(sb, type, format_id, path); ++ lockdep_set_quota_inode(path->dentry->d_inode, I_DATA_SEM_QUOTA); ++ err = dquot_quota_on(sb, type, format_id, path); ++ if (err) ++ lockdep_set_quota_inode(path->dentry->d_inode, ++ I_DATA_SEM_NORMAL); ++ return err; + } + + static int ext4_quota_enable(struct super_block *sb, int type, int format_id, +@@ -5002,8 +5020,11 @@ static int ext4_quota_enable(struct supe + + /* Don't account quota for quota files to avoid recursion */ + qf_inode->i_flags |= S_NOQUOTA; ++ lockdep_set_quota_inode(qf_inode, I_DATA_SEM_QUOTA); + err = dquot_enable(qf_inode, type, format_id, flags); + iput(qf_inode); ++ if (err) ++ lockdep_set_quota_inode(qf_inode, I_DATA_SEM_NORMAL); + + return err; + } diff --git a/queue-4.4/ext4-ignore-quota-mount-options-if-the-quota-feature-is-enabled.patch b/queue-4.4/ext4-ignore-quota-mount-options-if-the-quota-feature-is-enabled.patch new file mode 100644 index 00000000000..364a263ee29 --- /dev/null +++ b/queue-4.4/ext4-ignore-quota-mount-options-if-the-quota-feature-is-enabled.patch @@ -0,0 +1,70 @@ +From c325a67c72903e1cc30e990a15ce745bda0dbfde Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Sun, 3 Apr 2016 17:03:37 -0400 +Subject: ext4: ignore quota mount options if the quota feature is enabled + +From: Theodore Ts'o + +commit c325a67c72903e1cc30e990a15ce745bda0dbfde upstream. + +Previously, ext4 would fail the mount if the file system had the quota +feature enabled and quota mount options (used for the older quota +setups) were present. This broke xfstests, since xfs silently ignores +the usrquote and grpquota mount options if they are specified. This +commit changes things so that we are consistent with xfs; having the +mount options specified is harmless, so no sense break users by +forbidding them. + +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/super.c | 22 +++++++++++----------- + 1 file changed, 11 insertions(+), 11 deletions(-) + +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -1292,9 +1292,9 @@ static int set_qf_name(struct super_bloc + return -1; + } + if (ext4_has_feature_quota(sb)) { +- ext4_msg(sb, KERN_ERR, "Cannot set journaled quota options " +- "when QUOTA feature is enabled"); +- return -1; ++ ext4_msg(sb, KERN_INFO, "Journaled quota options " ++ "ignored when QUOTA feature is enabled"); ++ return 1; + } + qname = match_strdup(args); + if (!qname) { +@@ -1657,10 +1657,10 @@ static int handle_mount_opt(struct super + return -1; + } + if (ext4_has_feature_quota(sb)) { +- ext4_msg(sb, KERN_ERR, +- "Cannot set journaled quota options " ++ ext4_msg(sb, KERN_INFO, ++ "Quota format mount options ignored " + "when QUOTA feature is enabled"); +- return -1; ++ return 1; + } + sbi->s_jquota_fmt = m->mount_opt; + #endif +@@ -1721,11 +1721,11 @@ static int parse_options(char *options, + #ifdef CONFIG_QUOTA + if (ext4_has_feature_quota(sb) && + (test_opt(sb, USRQUOTA) || test_opt(sb, GRPQUOTA))) { +- ext4_msg(sb, KERN_ERR, "Cannot set quota options when QUOTA " +- "feature is enabled"); +- return 0; +- } +- if (sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA]) { ++ ext4_msg(sb, KERN_INFO, "Quota feature enabled, usrquota and grpquota " ++ "mount options ignored."); ++ clear_opt(sb, USRQUOTA); ++ clear_opt(sb, GRPQUOTA); ++ } else if (sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA]) { + if (test_opt(sb, USRQUOTA) && sbi->s_qf_names[USRQUOTA]) + clear_opt(sb, USRQUOTA); + diff --git a/queue-4.4/fs-add-file_dentry.patch b/queue-4.4/fs-add-file_dentry.patch new file mode 100644 index 00000000000..af96b649cbc --- /dev/null +++ b/queue-4.4/fs-add-file_dentry.patch @@ -0,0 +1,174 @@ +From d101a125954eae1d397adda94ca6319485a50493 Mon Sep 17 00:00:00 2001 +From: Miklos Szeredi +Date: Sat, 26 Mar 2016 16:14:37 -0400 +Subject: fs: add file_dentry() + +From: Miklos Szeredi + +commit d101a125954eae1d397adda94ca6319485a50493 upstream. + +This series fixes bugs in nfs and ext4 due to 4bacc9c9234c ("overlayfs: +Make f_path always point to the overlay and f_inode to the underlay"). + +Regular files opened on overlayfs will result in the file being opened on +the underlying filesystem, while f_path points to the overlayfs +mount/dentry. + +This confuses filesystems which get the dentry from struct file and assume +it's theirs. + +Add a new helper, file_dentry() [*], to get the filesystem's own dentry +from the file. This checks file->f_path.dentry->d_flags against +DCACHE_OP_REAL, and returns file->f_path.dentry if DCACHE_OP_REAL is not +set (this is the common, non-overlayfs case). + +In the uncommon case it will call into overlayfs's ->d_real() to get the +underlying dentry, matching file_inode(file). + +The reason we need to check against the inode is that if the file is copied +up while being open, d_real() would return the upper dentry, while the open +file comes from the lower dentry. + +[*] If possible, it's better simply to use file_inode() instead. + +Signed-off-by: Miklos Szeredi +Signed-off-by: Theodore Ts'o +Tested-by: Goldwyn Rodrigues +Reviewed-by: Trond Myklebust +Cc: David Howells +Cc: Al Viro +Cc: Daniel Axtens +Signed-off-by: Greg Kroah-Hartman + +--- + fs/dcache.c | 5 ++++- + fs/overlayfs/super.c | 33 +++++++++++++++++++++++++++++++++ + include/linux/dcache.h | 10 ++++++++++ + include/linux/fs.h | 10 ++++++++++ + 4 files changed, 57 insertions(+), 1 deletion(-) + +--- a/fs/dcache.c ++++ b/fs/dcache.c +@@ -1666,7 +1666,8 @@ void d_set_d_op(struct dentry *dentry, c + DCACHE_OP_REVALIDATE | + DCACHE_OP_WEAK_REVALIDATE | + DCACHE_OP_DELETE | +- DCACHE_OP_SELECT_INODE)); ++ DCACHE_OP_SELECT_INODE | ++ DCACHE_OP_REAL)); + dentry->d_op = op; + if (!op) + return; +@@ -1684,6 +1685,8 @@ void d_set_d_op(struct dentry *dentry, c + dentry->d_flags |= DCACHE_OP_PRUNE; + if (op->d_select_inode) + dentry->d_flags |= DCACHE_OP_SELECT_INODE; ++ if (op->d_real) ++ dentry->d_flags |= DCACHE_OP_REAL; + + } + EXPORT_SYMBOL(d_set_d_op); +--- a/fs/overlayfs/super.c ++++ b/fs/overlayfs/super.c +@@ -276,6 +276,37 @@ static void ovl_dentry_release(struct de + } + } + ++static struct dentry *ovl_d_real(struct dentry *dentry, struct inode *inode) ++{ ++ struct dentry *real; ++ ++ if (d_is_dir(dentry)) { ++ if (!inode || inode == d_inode(dentry)) ++ return dentry; ++ goto bug; ++ } ++ ++ real = ovl_dentry_upper(dentry); ++ if (real && (!inode || inode == d_inode(real))) ++ return real; ++ ++ real = ovl_dentry_lower(dentry); ++ if (!real) ++ goto bug; ++ ++ if (!inode || inode == d_inode(real)) ++ return real; ++ ++ /* Handle recursion */ ++ if (real->d_flags & DCACHE_OP_REAL) ++ return real->d_op->d_real(real, inode); ++ ++bug: ++ WARN(1, "ovl_d_real(%pd4, %s:%lu\n): real dentry not found\n", dentry, ++ inode ? inode->i_sb->s_id : "NULL", inode ? inode->i_ino : 0); ++ return dentry; ++} ++ + static int ovl_dentry_revalidate(struct dentry *dentry, unsigned int flags) + { + struct ovl_entry *oe = dentry->d_fsdata; +@@ -320,11 +351,13 @@ static int ovl_dentry_weak_revalidate(st + static const struct dentry_operations ovl_dentry_operations = { + .d_release = ovl_dentry_release, + .d_select_inode = ovl_d_select_inode, ++ .d_real = ovl_d_real, + }; + + static const struct dentry_operations ovl_reval_dentry_operations = { + .d_release = ovl_dentry_release, + .d_select_inode = ovl_d_select_inode, ++ .d_real = ovl_d_real, + .d_revalidate = ovl_dentry_revalidate, + .d_weak_revalidate = ovl_dentry_weak_revalidate, + }; +--- a/include/linux/dcache.h ++++ b/include/linux/dcache.h +@@ -161,6 +161,7 @@ struct dentry_operations { + struct vfsmount *(*d_automount)(struct path *); + int (*d_manage)(struct dentry *, bool); + struct inode *(*d_select_inode)(struct dentry *, unsigned); ++ struct dentry *(*d_real)(struct dentry *, struct inode *); + } ____cacheline_aligned; + + /* +@@ -227,6 +228,7 @@ struct dentry_operations { + #define DCACHE_MAY_FREE 0x00800000 + #define DCACHE_FALLTHRU 0x01000000 /* Fall through to lower layer */ + #define DCACHE_OP_SELECT_INODE 0x02000000 /* Unioned entry: dcache op selects inode */ ++#define DCACHE_OP_REAL 0x08000000 + + extern seqlock_t rename_lock; + +@@ -582,4 +584,12 @@ static inline struct dentry *d_backing_d + return upper; + } + ++static inline struct dentry *d_real(struct dentry *dentry) ++{ ++ if (unlikely(dentry->d_flags & DCACHE_OP_REAL)) ++ return dentry->d_op->d_real(dentry, NULL); ++ else ++ return dentry; ++} ++ + #endif /* __LINUX_DCACHE_H */ +--- a/include/linux/fs.h ++++ b/include/linux/fs.h +@@ -1207,6 +1207,16 @@ static inline struct inode *file_inode(c + return f->f_inode; + } + ++static inline struct dentry *file_dentry(const struct file *file) ++{ ++ struct dentry *dentry = file->f_path.dentry; ++ ++ if (unlikely(dentry->d_flags & DCACHE_OP_REAL)) ++ return dentry->d_op->d_real(dentry, file_inode(file)); ++ else ++ return dentry; ++} ++ + static inline int locks_lock_file_wait(struct file *filp, struct file_lock *fl) + { + return locks_lock_inode_wait(file_inode(filp), fl); diff --git a/queue-4.4/iommu-don-t-overwrite-domain-pointer-when-there-is-no-default_domain.patch b/queue-4.4/iommu-don-t-overwrite-domain-pointer-when-there-is-no-default_domain.patch new file mode 100644 index 00000000000..73f4a968ecf --- /dev/null +++ b/queue-4.4/iommu-don-t-overwrite-domain-pointer-when-there-is-no-default_domain.patch @@ -0,0 +1,36 @@ +From eebb8034a5be8c2177cbf07ca2ecd2ff8a058958 Mon Sep 17 00:00:00 2001 +From: Joerg Roedel +Date: Mon, 4 Apr 2016 15:47:48 +0200 +Subject: iommu: Don't overwrite domain pointer when there is no default_domain + +From: Joerg Roedel + +commit eebb8034a5be8c2177cbf07ca2ecd2ff8a058958 upstream. + +IOMMU drivers that do not support default domains, but make +use of the the group->domain pointer can get that pointer +overwritten with NULL on device add/remove. + +Make sure this can't happen by only overwriting the domain +pointer when it is NULL. + +Fixes: 1228236de5f9 ('iommu: Move default domain allocation to iommu_group_get_for_dev()') +Signed-off-by: Joerg Roedel +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iommu/iommu.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/iommu/iommu.c ++++ b/drivers/iommu/iommu.c +@@ -848,7 +848,8 @@ struct iommu_group *iommu_group_get_for_ + if (!group->default_domain) { + group->default_domain = __iommu_domain_alloc(dev->bus, + IOMMU_DOMAIN_DMA); +- group->domain = group->default_domain; ++ if (!group->domain) ++ group->domain = group->default_domain; + } + + ret = iommu_group_add_device(group, dev); diff --git a/queue-4.4/mmc-sdhci-pci-add-support-and-pci-ids-for-more-broxton-host-controllers.patch b/queue-4.4/mmc-sdhci-pci-add-support-and-pci-ids-for-more-broxton-host-controllers.patch new file mode 100644 index 00000000000..14d297cedaf --- /dev/null +++ b/queue-4.4/mmc-sdhci-pci-add-support-and-pci-ids-for-more-broxton-host-controllers.patch @@ -0,0 +1,78 @@ +From 01d6b2a40a0fa73c90e05b1033f181a51fec9292 Mon Sep 17 00:00:00 2001 +From: Adrian Hunter +Date: Mon, 4 Apr 2016 12:40:37 +0300 +Subject: mmc: sdhci-pci: Add support and PCI IDs for more Broxton host controllers + +From: Adrian Hunter + +commit 01d6b2a40a0fa73c90e05b1033f181a51fec9292 upstream. + +Add support and PCI IDs for more Broxton host controllers + +Other BXT IDs were added in v4.4 so cc'ing stable. This patch +is dependent on commit 163cbe31e516 ("mmc: sdhci-pci: Fix card +detect race for Intel BXT/APL") but that is already in stable +since v4.4.4. + +Signed-off-by: Adrian Hunter +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mmc/host/sdhci-pci-core.c | 25 +++++++++++++++++++++++++ + drivers/mmc/host/sdhci-pci.h | 3 +++ + 2 files changed, 28 insertions(+) + +--- a/drivers/mmc/host/sdhci-pci-core.c ++++ b/drivers/mmc/host/sdhci-pci-core.c +@@ -390,6 +390,7 @@ static int byt_sd_probe_slot(struct sdhc + slot->cd_idx = 0; + slot->cd_override_level = true; + if (slot->chip->pdev->device == PCI_DEVICE_ID_INTEL_BXT_SD || ++ slot->chip->pdev->device == PCI_DEVICE_ID_INTEL_BXTM_SD || + slot->chip->pdev->device == PCI_DEVICE_ID_INTEL_APL_SD) + slot->host->mmc_host_ops.get_cd = bxt_get_cd; + +@@ -1169,6 +1170,30 @@ static const struct pci_device_id pci_id + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = (kernel_ulong_t)&sdhci_intel_byt_sd, ++ }, ++ ++ { ++ .vendor = PCI_VENDOR_ID_INTEL, ++ .device = PCI_DEVICE_ID_INTEL_BXTM_EMMC, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ .driver_data = (kernel_ulong_t)&sdhci_intel_byt_emmc, ++ }, ++ ++ { ++ .vendor = PCI_VENDOR_ID_INTEL, ++ .device = PCI_DEVICE_ID_INTEL_BXTM_SDIO, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ .driver_data = (kernel_ulong_t)&sdhci_intel_byt_sdio, ++ }, ++ ++ { ++ .vendor = PCI_VENDOR_ID_INTEL, ++ .device = PCI_DEVICE_ID_INTEL_BXTM_SD, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ .driver_data = (kernel_ulong_t)&sdhci_intel_byt_sd, + }, + + { +--- a/drivers/mmc/host/sdhci-pci.h ++++ b/drivers/mmc/host/sdhci-pci.h +@@ -28,6 +28,9 @@ + #define PCI_DEVICE_ID_INTEL_BXT_SD 0x0aca + #define PCI_DEVICE_ID_INTEL_BXT_EMMC 0x0acc + #define PCI_DEVICE_ID_INTEL_BXT_SDIO 0x0ad0 ++#define PCI_DEVICE_ID_INTEL_BXTM_SD 0x1aca ++#define PCI_DEVICE_ID_INTEL_BXTM_EMMC 0x1acc ++#define PCI_DEVICE_ID_INTEL_BXTM_SDIO 0x1ad0 + #define PCI_DEVICE_ID_INTEL_APL_SD 0x5aca + #define PCI_DEVICE_ID_INTEL_APL_EMMC 0x5acc + #define PCI_DEVICE_ID_INTEL_APL_SDIO 0x5ad0 diff --git a/queue-4.4/nfs-use-file_dentry.patch b/queue-4.4/nfs-use-file_dentry.patch new file mode 100644 index 00000000000..2227baff1e5 --- /dev/null +++ b/queue-4.4/nfs-use-file_dentry.patch @@ -0,0 +1,90 @@ +From be62a1a8fd116f5cd9e53726601f970e16e17558 Mon Sep 17 00:00:00 2001 +From: Miklos Szeredi +Date: Sat, 26 Mar 2016 16:14:39 -0400 +Subject: nfs: use file_dentry() + +From: Miklos Szeredi + +commit be62a1a8fd116f5cd9e53726601f970e16e17558 upstream. + +NFS may be used as lower layer of overlayfs and accessing f_path.dentry can +lead to a crash. + +Fix by replacing direct access of file->f_path.dentry with the +file_dentry() accessor, which will always return a native object. + +Fixes: 4bacc9c9234c ("overlayfs: Make f_path always point to the overlay and f_inode to the underlay") +Signed-off-by: Miklos Szeredi +Tested-by: Goldwyn Rodrigues +Acked-by: Trond Myklebust +Signed-off-by: Theodore Ts'o +Cc: David Howells +Cc: Al Viro +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfs/dir.c | 6 +++--- + fs/nfs/inode.c | 2 +- + fs/nfs/nfs4file.c | 4 ++-- + 3 files changed, 6 insertions(+), 6 deletions(-) + +--- a/fs/nfs/dir.c ++++ b/fs/nfs/dir.c +@@ -377,7 +377,7 @@ int nfs_readdir_xdr_filler(struct page * + again: + timestamp = jiffies; + gencount = nfs_inc_attr_generation_counter(); +- error = NFS_PROTO(inode)->readdir(file->f_path.dentry, cred, entry->cookie, pages, ++ error = NFS_PROTO(inode)->readdir(file_dentry(file), cred, entry->cookie, pages, + NFS_SERVER(inode)->dtsize, desc->plus); + if (error < 0) { + /* We requested READDIRPLUS, but the server doesn't grok it */ +@@ -560,7 +560,7 @@ int nfs_readdir_page_filler(nfs_readdir_ + count++; + + if (desc->plus != 0) +- nfs_prime_dcache(desc->file->f_path.dentry, entry); ++ nfs_prime_dcache(file_dentry(desc->file), entry); + + status = nfs_readdir_add_to_array(entry, page); + if (status != 0) +@@ -864,7 +864,7 @@ static bool nfs_dir_mapping_need_revalid + */ + static int nfs_readdir(struct file *file, struct dir_context *ctx) + { +- struct dentry *dentry = file->f_path.dentry; ++ struct dentry *dentry = file_dentry(file); + struct inode *inode = d_inode(dentry); + nfs_readdir_descriptor_t my_desc, + *desc = &my_desc; +--- a/fs/nfs/inode.c ++++ b/fs/nfs/inode.c +@@ -927,7 +927,7 @@ int nfs_open(struct inode *inode, struct + { + struct nfs_open_context *ctx; + +- ctx = alloc_nfs_open_context(filp->f_path.dentry, filp->f_mode); ++ ctx = alloc_nfs_open_context(file_dentry(filp), filp->f_mode); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); + nfs_file_set_open_context(filp, ctx); +--- a/fs/nfs/nfs4file.c ++++ b/fs/nfs/nfs4file.c +@@ -26,7 +26,7 @@ static int + nfs4_file_open(struct inode *inode, struct file *filp) + { + struct nfs_open_context *ctx; +- struct dentry *dentry = filp->f_path.dentry; ++ struct dentry *dentry = file_dentry(filp); + struct dentry *parent = NULL; + struct inode *dir; + unsigned openflags = filp->f_flags; +@@ -57,7 +57,7 @@ nfs4_file_open(struct inode *inode, stru + parent = dget_parent(dentry); + dir = d_inode(parent); + +- ctx = alloc_nfs_open_context(filp->f_path.dentry, filp->f_mode); ++ ctx = alloc_nfs_open_context(file_dentry(filp), filp->f_mode); + err = PTR_ERR(ctx); + if (IS_ERR(ctx)) + goto out; diff --git a/queue-4.4/perf-cure-event-pending_disable-race.patch b/queue-4.4/perf-cure-event-pending_disable-race.patch new file mode 100644 index 00000000000..d878bed2608 --- /dev/null +++ b/queue-4.4/perf-cure-event-pending_disable-race.patch @@ -0,0 +1,67 @@ +From 28a967c3a2f99fa3b5f762f25cb2a319d933571b Mon Sep 17 00:00:00 2001 +From: Peter Zijlstra +Date: Wed, 24 Feb 2016 18:45:46 +0100 +Subject: perf: Cure event->pending_disable race + +From: Peter Zijlstra + +commit 28a967c3a2f99fa3b5f762f25cb2a319d933571b upstream. + +Because event_sched_out() checks event->pending_disable _before_ +actually disabling the event, it can happen that the event fires after +it checks but before it gets disabled. + +This would leave event->pending_disable set and the queued irq_work +will try and process it. + +However, if the event trigger was during schedule(), the event might +have been de-scheduled by the time the irq_work runs, and +perf_event_disable_local() will fail. + +Fix this by checking event->pending_disable _after_ we call +event->pmu->del(). This depends on the latter being a compiler +barrier, such that the compiler does not lift the load and re-creates +the problem. + +Tested-by: Alexander Shishkin +Signed-off-by: Peter Zijlstra (Intel) +Reviewed-by: Alexander Shishkin +Cc: Arnaldo Carvalho de Melo +Cc: Jiri Olsa +Cc: Linus Torvalds +Cc: Peter Zijlstra +Cc: Thomas Gleixner +Cc: dvyukov@google.com +Cc: eranian@google.com +Cc: oleg@redhat.com +Cc: panand@redhat.com +Cc: sasha.levin@oracle.com +Cc: vince@deater.net +Link: http://lkml.kernel.org/r/20160224174948.040469884@infradead.org +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/events/core.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -1580,14 +1580,14 @@ event_sched_out(struct perf_event *event + + perf_pmu_disable(event->pmu); + ++ event->tstamp_stopped = tstamp; ++ event->pmu->del(event, 0); ++ event->oncpu = -1; + event->state = PERF_EVENT_STATE_INACTIVE; + if (event->pending_disable) { + event->pending_disable = 0; + event->state = PERF_EVENT_STATE_OFF; + } +- event->tstamp_stopped = tstamp; +- event->pmu->del(event, 0); +- event->oncpu = -1; + + if (!is_software_event(event)) + cpuctx->active_oncpu--; diff --git a/queue-4.4/perf-do-not-double-free.patch b/queue-4.4/perf-do-not-double-free.patch new file mode 100644 index 00000000000..0dc61a39e8a --- /dev/null +++ b/queue-4.4/perf-do-not-double-free.patch @@ -0,0 +1,52 @@ +From 130056275ade730e7a79c110212c8815202773ee Mon Sep 17 00:00:00 2001 +From: Peter Zijlstra +Date: Wed, 24 Feb 2016 18:45:41 +0100 +Subject: perf: Do not double free + +From: Peter Zijlstra + +commit 130056275ade730e7a79c110212c8815202773ee upstream. + +In case of: err_file: fput(event_file), we'll end up calling +perf_release() which in turn will free the event. + +Do not then free the event _again_. + +Tested-by: Alexander Shishkin +Signed-off-by: Peter Zijlstra (Intel) +Reviewed-by: Alexander Shishkin +Cc: Arnaldo Carvalho de Melo +Cc: Jiri Olsa +Cc: Linus Torvalds +Cc: Peter Zijlstra +Cc: Thomas Gleixner +Cc: dvyukov@google.com +Cc: eranian@google.com +Cc: oleg@redhat.com +Cc: panand@redhat.com +Cc: sasha.levin@oracle.com +Cc: vince@deater.net +Link: http://lkml.kernel.org/r/20160224174947.697350349@infradead.org +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/events/core.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -8583,7 +8583,12 @@ err_context: + perf_unpin_context(ctx); + put_ctx(ctx); + err_alloc: +- free_event(event); ++ /* ++ * If event_file is set, the fput() above will have called ->release() ++ * and that will take care of freeing the event. ++ */ ++ if (!event_file) ++ free_event(event); + err_cpus: + put_online_cpus(); + err_task: diff --git a/queue-4.4/series b/queue-4.4/series index 1727a2260bb..6d4f05f933e 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -108,3 +108,14 @@ iio-accel-bmc150-fix-endianness-when-reading-axes.patch iio-gyro-bmg160-fix-buffer-read-values.patch iio-gyro-bmg160-fix-endianness-when-reading-axes.patch sd-fix-excessive-capacity-printing-on-devices-with-blocks-bigger-than-512-bytes.patch +fs-add-file_dentry.patch +nfs-use-file_dentry.patch +btrfs-fix-crash-invalid-memory-access-on-fsync-when-using-overlayfs.patch +ext4-add-lockdep-annotations-for-i_data_sem.patch +ext4-ignore-quota-mount-options-if-the-quota-feature-is-enabled.patch +iommu-don-t-overwrite-domain-pointer-when-there-is-no-default_domain.patch +btrfs-fix-file-data-loss-caused-by-fsync-after-rename-and-new-inode.patch +arm64-replace-read_lock-to-rcu-lock-in-call_step_hook.patch +perf-do-not-double-free.patch +perf-cure-event-pending_disable-race.patch +mmc-sdhci-pci-add-support-and-pci-ids-for-more-broxton-host-controllers.patch