From: Greg Kroah-Hartman Date: Sun, 17 Apr 2016 11:49:51 +0000 (-0700) Subject: 4.5-stable patches X-Git-Tag: v3.14.67~9 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3e0a7b417fb02fbdc6af55c479f5bdd22d428d5c;p=thirdparty%2Fkernel%2Fstable-queue.git 4.5-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-crypto-use-dget_parent-in-ext4_d_revalidate.patch ext4-ignore-quota-mount-options-if-the-quota-feature-is-enabled.patch ext4-use-dget_parent-in-ext4_file_open.patch ext4-use-file_dentry.patch fs-add-file_dentry.patch iommu-don-t-overwrite-domain-pointer-when-there-is-no-default_domain.patch mmc-sdhci-fix-regression-setting-power-on-trats2-board.patch mmc-sdhci-pci-add-support-and-pci-ids-for-more-broxton-host-controllers.patch nfs-use-file_dentry.patch --- diff --git a/queue-4.5/arm64-replace-read_lock-to-rcu-lock-in-call_step_hook.patch b/queue-4.5/arm64-replace-read_lock-to-rcu-lock-in-call_step_hook.patch new file mode 100644 index 00000000000..ff43b1da72d --- /dev/null +++ b/queue-4.5/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.5/btrfs-fix-crash-invalid-memory-access-on-fsync-when-using-overlayfs.patch b/queue-4.5/btrfs-fix-crash-invalid-memory-access-on-fsync-when-using-overlayfs.patch new file mode 100644 index 00000000000..a59da30e841 --- /dev/null +++ b/queue-4.5/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 +@@ -1883,7 +1883,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.5/btrfs-fix-file-data-loss-caused-by-fsync-after-rename-and-new-inode.patch b/queue-4.5/btrfs-fix-file-data-loss-caused-by-fsync-after-rename-and-new-inode.patch new file mode 100644 index 00000000000..7ea8a0d299a --- /dev/null +++ b/queue-4.5/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 +@@ -4414,6 +4414,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. +@@ -4586,6 +4707,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.5/ext4-add-lockdep-annotations-for-i_data_sem.patch b/queue-4.5/ext4-add-lockdep-annotations-for-i_data_sem.patch new file mode 100644 index 00000000000..aeb9a19cc7d --- /dev/null +++ b/queue-4.5/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 +@@ -900,6 +900,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); + + } + } +@@ -483,6 +483,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 +@@ -5021,6 +5021,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 + */ +@@ -5060,8 +5074,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, +@@ -5088,8 +5106,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.5/ext4-crypto-use-dget_parent-in-ext4_d_revalidate.patch b/queue-4.5/ext4-crypto-use-dget_parent-in-ext4_d_revalidate.patch new file mode 100644 index 00000000000..8a49dc51635 --- /dev/null +++ b/queue-4.5/ext4-crypto-use-dget_parent-in-ext4_d_revalidate.patch @@ -0,0 +1,53 @@ +From 3d43bcfef5f0548845a425365011c499875491b0 Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Sat, 26 Mar 2016 16:15:42 -0400 +Subject: ext4 crypto: use dget_parent() in ext4_d_revalidate() + +From: Theodore Ts'o + +commit 3d43bcfef5f0548845a425365011c499875491b0 upstream. + +This avoids potential problems caused by a race where the inode gets +renamed out from its parent directory and the parent directory is +deleted while ext4_d_revalidate() is running. + +Fixes: 28b4c263961c +Reported-by: Al Viro +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/crypto.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +--- a/fs/ext4/crypto.c ++++ b/fs/ext4/crypto.c +@@ -475,13 +475,16 @@ uint32_t ext4_validate_encryption_key_si + */ + static int ext4_d_revalidate(struct dentry *dentry, unsigned int flags) + { +- struct inode *dir = d_inode(dentry->d_parent); +- struct ext4_crypt_info *ci = EXT4_I(dir)->i_crypt_info; ++ struct dentry *dir; ++ struct ext4_crypt_info *ci; + int dir_has_key, cached_with_key; + +- if (!ext4_encrypted_inode(dir)) ++ dir = dget_parent(dentry); ++ if (!ext4_encrypted_inode(d_inode(dir))) { ++ dput(dir); + return 0; +- ++ } ++ ci = EXT4_I(d_inode(dir))->i_crypt_info; + if (ci && ci->ci_keyring_key && + (ci->ci_keyring_key->flags & ((1 << KEY_FLAG_INVALIDATED) | + (1 << KEY_FLAG_REVOKED) | +@@ -491,6 +494,7 @@ static int ext4_d_revalidate(struct dent + /* this should eventually be an flag in d_flags */ + cached_with_key = dentry->d_fsdata != NULL; + dir_has_key = (ci != NULL); ++ dput(dir); + + /* + * If the dentry was cached without the key, and it is a diff --git a/queue-4.5/ext4-ignore-quota-mount-options-if-the-quota-feature-is-enabled.patch b/queue-4.5/ext4-ignore-quota-mount-options-if-the-quota-feature-is-enabled.patch new file mode 100644 index 00000000000..801a7f5626c --- /dev/null +++ b/queue-4.5/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 +@@ -1324,9 +1324,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) { +@@ -1689,10 +1689,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 +@@ -1753,11 +1753,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.5/ext4-use-dget_parent-in-ext4_file_open.patch b/queue-4.5/ext4-use-dget_parent-in-ext4_file_open.patch new file mode 100644 index 00000000000..87e29cb1f8e --- /dev/null +++ b/queue-4.5/ext4-use-dget_parent-in-ext4_file_open.patch @@ -0,0 +1,57 @@ +From 9dd78d8c9a7bd4bc341f5864db32d4331b8eae4c Mon Sep 17 00:00:00 2001 +From: Miklos Szeredi +Date: Sat, 26 Mar 2016 16:14:41 -0400 +Subject: ext4: use dget_parent() in ext4_file_open() + +From: Miklos Szeredi + +commit 9dd78d8c9a7bd4bc341f5864db32d4331b8eae4c upstream. + +In f_op->open() lock on parent is not held, so there's no guarantee that +parent dentry won't go away at any time. + +Even after this patch there's no guarantee that 'dir' will stay the parent +of 'inode', but at least it won't be freed while being used. + +Fixes: ff978b09f973 ("ext4 crypto: move context consistency check to ext4_file_open()") +Signed-off-by: Miklos Szeredi +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/file.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +--- a/fs/ext4/file.c ++++ b/fs/ext4/file.c +@@ -335,7 +335,7 @@ static int ext4_file_open(struct inode * + struct super_block *sb = inode->i_sb; + struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); + struct vfsmount *mnt = filp->f_path.mnt; +- struct inode *dir = filp->f_path.dentry->d_parent->d_inode; ++ struct dentry *dir; + struct path path; + char buf[64], *cp; + int ret; +@@ -379,14 +379,18 @@ static int ext4_file_open(struct inode * + if (ext4_encryption_info(inode) == NULL) + return -ENOKEY; + } +- if (ext4_encrypted_inode(dir) && +- !ext4_is_child_context_consistent_with_parent(dir, inode)) { ++ ++ dir = dget_parent(filp->f_path.dentry); ++ if (ext4_encrypted_inode(d_inode(dir)) && ++ !ext4_is_child_context_consistent_with_parent(d_inode(dir), inode)) { + ext4_warning(inode->i_sb, + "Inconsistent encryption contexts: %lu/%lu\n", +- (unsigned long) dir->i_ino, ++ (unsigned long) d_inode(dir)->i_ino, + (unsigned long) inode->i_ino); ++ dput(dir); + return -EPERM; + } ++ dput(dir); + /* + * Set up the jbd2_inode if we are opening the inode for + * writing and the journal is present diff --git a/queue-4.5/ext4-use-file_dentry.patch b/queue-4.5/ext4-use-file_dentry.patch new file mode 100644 index 00000000000..84de800785d --- /dev/null +++ b/queue-4.5/ext4-use-file_dentry.patch @@ -0,0 +1,39 @@ +From c0a37d48788475d0a2cf4fbfaa28559a9de612fc Mon Sep 17 00:00:00 2001 +From: Miklos Szeredi +Date: Sat, 26 Mar 2016 16:14:42 -0400 +Subject: ext4: use file_dentry() + +From: Miklos Szeredi + +commit c0a37d48788475d0a2cf4fbfaa28559a9de612fc upstream. + +EXT4 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. + +Reported-by: Daniel Axtens +Fixes: 4bacc9c9234c ("overlayfs: Make f_path always point to the overlay and f_inode to the underlay") +Fixes: ff978b09f973 ("ext4 crypto: move context consistency check to ext4_file_open()") +Signed-off-by: Miklos Szeredi +Signed-off-by: Theodore Ts'o +Cc: David Howells +Cc: Al Viro +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/file.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/ext4/file.c ++++ b/fs/ext4/file.c +@@ -380,7 +380,7 @@ static int ext4_file_open(struct inode * + return -ENOKEY; + } + +- dir = dget_parent(filp->f_path.dentry); ++ dir = dget_parent(file_dentry(filp)); + if (ext4_encrypted_inode(d_inode(dir)) && + !ext4_is_child_context_consistent_with_parent(d_inode(dir), inode)) { + ext4_warning(inode->i_sb, diff --git a/queue-4.5/fs-add-file_dentry.patch b/queue-4.5/fs-add-file_dentry.patch new file mode 100644 index 00000000000..3c256bf3b35 --- /dev/null +++ b/queue-4.5/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 +@@ -1667,7 +1667,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; +@@ -1685,6 +1686,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 +@@ -295,6 +295,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; +@@ -339,11 +370,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 +@@ -1234,6 +1234,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.5/iommu-don-t-overwrite-domain-pointer-when-there-is-no-default_domain.patch b/queue-4.5/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.5/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.5/mmc-sdhci-fix-regression-setting-power-on-trats2-board.patch b/queue-4.5/mmc-sdhci-fix-regression-setting-power-on-trats2-board.patch new file mode 100644 index 00000000000..81c9f13113e --- /dev/null +++ b/queue-4.5/mmc-sdhci-fix-regression-setting-power-on-trats2-board.patch @@ -0,0 +1,208 @@ +From 1dceb0415aa0c6bc11dacdab47c9ef83a3604166 Mon Sep 17 00:00:00 2001 +From: Adrian Hunter +Date: Tue, 29 Mar 2016 12:45:43 +0300 +Subject: mmc: sdhci: Fix regression setting power on Trats2 board + +From: Adrian Hunter + +commit 1dceb0415aa0c6bc11dacdab47c9ef83a3604166 upstream. + +Several commits relating to setting power have been introducing +problems by putting driver-specific rules into generic SDHCI code. + +Krzysztof Kozlowski reported that after commit 918f4cbd4340 ("mmc: +sdhci: restore behavior when setting VDD via external regulator") +on Trats2 board there are warnings for invalid VDD value (2.8V): + +[ 3.119656] ------------[ cut here ]------------ +[ 3.119666] WARNING: CPU: 3 PID: 90 at +../drivers/mmc/host/sdhci.c:1234 sdhci_do_set_ios+0x4cc/0x5e0 +[ 3.119669] mmc0: Invalid vdd 0x10 +[ 3.119673] Modules linked in: +[ 3.119679] CPU: 3 PID: 90 Comm: kworker/3:1 Tainted: G W + 4.5.0-next-20160324 #23 +[ 3.119681] Hardware name: SAMSUNG EXYNOS (Flattened Device Tree) +[ 3.119690] Workqueue: events_freezable mmc_rescan +[ 3.119708] [] (unwind_backtrace) from [] +(show_stack+0x10/0x14) +[ 3.119719] [] (show_stack) from [] +(dump_stack+0x88/0x9c) +[ 3.119728] [] (dump_stack) from [] (__warn+0xe8/0x100) +[ 3.119734] [] (__warn) from [] +(warn_slowpath_fmt+0x38/0x48) +[ 3.119740] [] (warn_slowpath_fmt) from [] +(sdhci_do_set_ios+0x4cc/0x5e0) +[ 3.119748] [] (sdhci_do_set_ios) from [] +(sdhci_runtime_resume_host+0x60/0x114) +[ 3.119758] [] (sdhci_runtime_resume_host) from +[] (__rpm_callback+0x2c/0x60) +[ 3.119767] [] (__rpm_callback) from [] +(rpm_callback+0x20/0x80) +[ 3.119773] [] (rpm_callback) from [] +(rpm_resume+0x36c/0x558) +[ 3.119780] [] (rpm_resume) from [] +(__pm_runtime_resume+0x4c/0x64) +[ 3.119788] [] (__pm_runtime_resume) from [] +(__mmc_claim_host+0x170/0x1b0) +[ 3.119795] [] (__mmc_claim_host) from [] +(mmc_rescan+0x54/0x348) +[ 3.119807] [] (mmc_rescan) from [] +(process_one_work+0x120/0x3f4) +[ 3.119815] [] (process_one_work) from [] +(worker_thread+0x38/0x554) +[ 3.119823] [] (worker_thread) from [] +(kthread+0xdc/0xf4) +[ 3.119831] [] (kthread) from [] +(ret_from_fork+0x14/0x3c) +[ 3.119834] ---[ end trace a22d652aa3276886 ]--- + +Fix by adding a 'set_power' callback and restoring the default +behaviour prior to commit 918f4cbd4340 ("mmc: sdhci: restore +behavior when setting VDD via external regulator"). The desired +behaviour of that commit is gotten by having sdhci-pxav3 provide +its own set_power callback. + +Reported-by: Krzysztof Kozlowski +Link: http://lkml.kernel.org/r/CAJKOXPcGDnPm-Ykh6wHqV1YxfTaov5E8iVqBoBn4OJc7BnhgEQ@mail.gmail.com +Fixes: 918f4cbd4340 ("mmc: sdhci: restore behavior when setting VDD...) +Tested-by: Krzysztof Kozlowski +Tested-by: Ludovic Desroches +Signed-off-by: Adrian Hunter +Reviewed-by: Jisheng Zhang +Tested-by: Jisheng Zhang +Tested-by: Jaehoon Chung +Tested-by: Anand Moon +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mmc/host/sdhci-pxav3.c | 22 ++++++++++++++++++++++ + drivers/mmc/host/sdhci.c | 39 ++++++++++++++++++++++++++++++--------- + drivers/mmc/host/sdhci.h | 4 ++++ + 3 files changed, 56 insertions(+), 9 deletions(-) + +--- a/drivers/mmc/host/sdhci-pxav3.c ++++ b/drivers/mmc/host/sdhci-pxav3.c +@@ -309,8 +309,30 @@ static void pxav3_set_uhs_signaling(stru + __func__, uhs, ctrl_2); + } + ++static void pxav3_set_power(struct sdhci_host *host, unsigned char mode, ++ unsigned short vdd) ++{ ++ struct mmc_host *mmc = host->mmc; ++ u8 pwr = host->pwr; ++ ++ sdhci_set_power(host, mode, vdd); ++ ++ if (host->pwr == pwr) ++ return; ++ ++ if (host->pwr == 0) ++ vdd = 0; ++ ++ if (!IS_ERR(mmc->supply.vmmc)) { ++ spin_unlock_irq(&host->lock); ++ mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd); ++ spin_lock_irq(&host->lock); ++ } ++} ++ + static const struct sdhci_ops pxav3_sdhci_ops = { + .set_clock = sdhci_set_clock, ++ .set_power = pxav3_set_power, + .platform_send_init_74_clocks = pxav3_gen_init_74_clocks, + .get_max_clock = sdhci_pltfm_clk_get_max_clock, + .set_bus_width = sdhci_set_bus_width, +--- a/drivers/mmc/host/sdhci.c ++++ b/drivers/mmc/host/sdhci.c +@@ -1250,10 +1250,24 @@ clock_set: + } + EXPORT_SYMBOL_GPL(sdhci_set_clock); + +-static void sdhci_set_power(struct sdhci_host *host, unsigned char mode, +- unsigned short vdd) ++static void sdhci_set_power_reg(struct sdhci_host *host, unsigned char mode, ++ unsigned short vdd) + { + struct mmc_host *mmc = host->mmc; ++ ++ spin_unlock_irq(&host->lock); ++ mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd); ++ spin_lock_irq(&host->lock); ++ ++ if (mode != MMC_POWER_OFF) ++ sdhci_writeb(host, SDHCI_POWER_ON, SDHCI_POWER_CONTROL); ++ else ++ sdhci_writeb(host, 0, SDHCI_POWER_CONTROL); ++} ++ ++void sdhci_set_power(struct sdhci_host *host, unsigned char mode, ++ unsigned short vdd) ++{ + u8 pwr = 0; + + if (mode != MMC_POWER_OFF) { +@@ -1285,7 +1299,6 @@ static void sdhci_set_power(struct sdhci + sdhci_writeb(host, 0, SDHCI_POWER_CONTROL); + if (host->quirks2 & SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON) + sdhci_runtime_pm_bus_off(host); +- vdd = 0; + } else { + /* + * Spec says that we should clear the power reg before setting +@@ -1316,12 +1329,20 @@ static void sdhci_set_power(struct sdhci + if (host->quirks & SDHCI_QUIRK_DELAY_AFTER_POWER) + mdelay(10); + } ++} ++EXPORT_SYMBOL_GPL(sdhci_set_power); + +- if (!IS_ERR(mmc->supply.vmmc)) { +- spin_unlock_irq(&host->lock); +- mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd); +- spin_lock_irq(&host->lock); +- } ++static void __sdhci_set_power(struct sdhci_host *host, unsigned char mode, ++ unsigned short vdd) ++{ ++ struct mmc_host *mmc = host->mmc; ++ ++ if (host->ops->set_power) ++ host->ops->set_power(host, mode, vdd); ++ else if (!IS_ERR(mmc->supply.vmmc)) ++ sdhci_set_power_reg(host, mode, vdd); ++ else ++ sdhci_set_power(host, mode, vdd); + } + + /*****************************************************************************\ +@@ -1471,7 +1492,7 @@ static void sdhci_do_set_ios(struct sdhc + } + } + +- sdhci_set_power(host, ios->power_mode, ios->vdd); ++ __sdhci_set_power(host, ios->power_mode, ios->vdd); + + if (host->ops->platform_send_init_74_clocks) + host->ops->platform_send_init_74_clocks(host, ios->power_mode); +--- a/drivers/mmc/host/sdhci.h ++++ b/drivers/mmc/host/sdhci.h +@@ -529,6 +529,8 @@ struct sdhci_ops { + #endif + + void (*set_clock)(struct sdhci_host *host, unsigned int clock); ++ void (*set_power)(struct sdhci_host *host, unsigned char mode, ++ unsigned short vdd); + + int (*enable_dma)(struct sdhci_host *host); + unsigned int (*get_max_clock)(struct sdhci_host *host); +@@ -660,6 +662,8 @@ static inline bool sdhci_sdio_irq_enable + } + + void sdhci_set_clock(struct sdhci_host *host, unsigned int clock); ++void sdhci_set_power(struct sdhci_host *host, unsigned char mode, ++ unsigned short vdd); + void sdhci_set_bus_width(struct sdhci_host *host, int width); + void sdhci_reset(struct sdhci_host *host, u8 mask); + void sdhci_set_uhs_signaling(struct sdhci_host *host, unsigned timing); diff --git a/queue-4.5/mmc-sdhci-pci-add-support-and-pci-ids-for-more-broxton-host-controllers.patch b/queue-4.5/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.5/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.5/nfs-use-file_dentry.patch b/queue-4.5/nfs-use-file_dentry.patch new file mode 100644 index 00000000000..f3dffde49fa --- /dev/null +++ b/queue-4.5/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 +@@ -940,7 +940,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.5/series b/queue-4.5/series index 3c210a58c74..84a712ccc50 100644 --- a/queue-4.5/series +++ b/queue-4.5/series @@ -101,3 +101,16 @@ 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 +ext4-crypto-use-dget_parent-in-ext4_d_revalidate.patch +ext4-use-dget_parent-in-ext4_file_open.patch +ext4-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 +mmc-sdhci-fix-regression-setting-power-on-trats2-board.patch +mmc-sdhci-pci-add-support-and-pci-ids-for-more-broxton-host-controllers.patch