From: Greg Kroah-Hartman Date: Wed, 20 Sep 2023 10:29:25 +0000 (+0200) Subject: 5.4-stable patches X-Git-Tag: v5.10.196~24 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f6c206394204cd0998d3d2e29cc569fd0b335be6;p=thirdparty%2Fkernel%2Fstable-queue.git 5.4-stable patches added patches: attr-block-mode-changes-of-symlinks.patch btrfs-fix-lockdep-splat-and-potential-deadlock-after-failure-running-delayed-items.patch ext4-fix-rec_len-verify-error.patch i2c-aspeed-reset-the-i2c-controller-when-timeout-occurs.patch nfsd-fix-change_info-in-nfsv4-rename-replies.patch scsi-megaraid_sas-fix-deadlock-on-firmware-crashdump.patch tracefs-add-missing-lockdown-check-to-tracefs_create_dir.patch tracing-have-current_trace-inc-the-trace-array-ref-count.patch tracing-have-option-files-inc-the-trace-array-ref-count.patch --- diff --git a/queue-5.4/attr-block-mode-changes-of-symlinks.patch b/queue-5.4/attr-block-mode-changes-of-symlinks.patch new file mode 100644 index 00000000000..b2a80d37838 --- /dev/null +++ b/queue-5.4/attr-block-mode-changes-of-symlinks.patch @@ -0,0 +1,140 @@ +From 5d1f903f75a80daa4dfb3d84e114ec8ecbf29956 Mon Sep 17 00:00:00 2001 +From: Christian Brauner +Date: Wed, 12 Jul 2023 20:58:49 +0200 +Subject: attr: block mode changes of symlinks + +From: Christian Brauner + +commit 5d1f903f75a80daa4dfb3d84e114ec8ecbf29956 upstream. + +Changing the mode of symlinks is meaningless as the vfs doesn't take the +mode of a symlink into account during path lookup permission checking. + +However, the vfs doesn't block mode changes on symlinks. This however, +has lead to an untenable mess roughly classifiable into the following +two categories: + +(1) Filesystems that don't implement a i_op->setattr() for symlinks. + + Such filesystems may or may not know that without i_op->setattr() + defined, notify_change() falls back to simple_setattr() causing the + inode's mode in the inode cache to be changed. + + That's a generic issue as this will affect all non-size changing + inode attributes including ownership changes. + + Example: afs + +(2) Filesystems that fail with EOPNOTSUPP but change the mode of the + symlink nonetheless. + + Some filesystems will happily update the mode of a symlink but still + return EOPNOTSUPP. This is the biggest source of confusion for + userspace. + + The EOPNOTSUPP in this case comes from POSIX ACLs. Specifically it + comes from filesystems that call posix_acl_chmod(), e.g., btrfs via + + if (!err && attr->ia_valid & ATTR_MODE) + err = posix_acl_chmod(idmap, dentry, inode->i_mode); + + Filesystems including btrfs don't implement i_op->set_acl() so + posix_acl_chmod() will report EOPNOTSUPP. + + When posix_acl_chmod() is called, most filesystems will have + finished updating the inode. + + Perversely, this has the consequences that this behavior may depend + on two kconfig options and mount options: + + * CONFIG_POSIX_ACL={y,n} + * CONFIG_${FSTYPE}_POSIX_ACL={y,n} + * Opt_acl, Opt_noacl + + Example: btrfs, ext4, xfs + +The only way to change the mode on a symlink currently involves abusing +an O_PATH file descriptor in the following manner: + + fd = openat(-1, "/path/to/link", O_CLOEXEC | O_PATH | O_NOFOLLOW); + + char path[PATH_MAX]; + snprintf(path, sizeof(path), "/proc/self/fd/%d", fd); + chmod(path, 0000); + +But for most major filesystems with POSIX ACL support such as btrfs, +ext4, ceph, tmpfs, xfs and others this will fail with EOPNOTSUPP with +the mode still updated due to the aforementioned posix_acl_chmod() +nonsense. + +So, given that for all major filesystems this would fail with EOPNOTSUPP +and that both glibc (cf. [1]) and musl (cf. [2]) outright block mode +changes on symlinks we should just try and block mode changes on +symlinks directly in the vfs and have a clean break with this nonsense. + +If this causes any regressions, we do the next best thing and fix up all +filesystems that do return EOPNOTSUPP with the mode updated to not call +posix_acl_chmod() on symlinks. + +But as usual, let's try the clean cut solution first. It's a simple +patch that can be easily reverted. Not marking this for backport as I'll +do that manually if we're reasonably sure that this works and there are +no strong objections. + +We could block this in chmod_common() but it's more appropriate to do it +notify_change() as it will also mean that we catch filesystems that +change symlink permissions explicitly or accidently. + +Similar proposals were floated in the past as in [3] and [4] and again +recently in [5]. There's also a couple of bugs about this inconsistency +as in [6] and [7]. + +Link: https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/fchmodat.c;h=99527a3727e44cb8661ee1f743068f108ec93979;hb=HEAD [1] +Link: https://git.musl-libc.org/cgit/musl/tree/src/stat/fchmodat.c [2] +Link: https://lore.kernel.org/all/20200911065733.GA31579@infradead.org [3] +Link: https://sourceware.org/legacy-ml/libc-alpha/2020-02/msg00518.html [4] +Link: https://lore.kernel.org/lkml/87lefmbppo.fsf@oldenburg.str.redhat.com [5] +Link: https://sourceware.org/legacy-ml/libc-alpha/2020-02/msg00467.html [6] +Link: https://sourceware.org/bugzilla/show_bug.cgi?id=14578#c17 [7] +Reviewed-by: Aleksa Sarai +Reviewed-by: Christoph Hellwig +Cc: stable@vger.kernel.org # please backport to all LTSes but not before v6.6-rc2 is tagged +Suggested-by: Christoph Hellwig +Suggested-by: Florian Weimer +Message-Id: <20230712-vfs-chmod-symlinks-v2-1-08cfb92b61dd@kernel.org> +Signed-off-by: Christian Brauner +Signed-off-by: Greg Kroah-Hartman +--- + fs/attr.c | 20 ++++++++++++++++++-- + 1 file changed, 18 insertions(+), 2 deletions(-) + +--- a/fs/attr.c ++++ b/fs/attr.c +@@ -253,9 +253,25 @@ int notify_change(struct dentry * dentry + } + + if ((ia_valid & ATTR_MODE)) { +- umode_t amode = attr->ia_mode; ++ /* ++ * Don't allow changing the mode of symlinks: ++ * ++ * (1) The vfs doesn't take the mode of symlinks into account ++ * during permission checking. ++ * (2) This has never worked correctly. Most major filesystems ++ * did return EOPNOTSUPP due to interactions with POSIX ACLs ++ * but did still updated the mode of the symlink. ++ * This inconsistency led system call wrapper providers such ++ * as libc to block changing the mode of symlinks with ++ * EOPNOTSUPP already. ++ * (3) To even do this in the first place one would have to use ++ * specific file descriptors and quite some effort. ++ */ ++ if (S_ISLNK(inode->i_mode)) ++ return -EOPNOTSUPP; ++ + /* Flag setting protected by i_mutex */ +- if (is_sxid(amode)) ++ if (is_sxid(attr->ia_mode)) + inode->i_flags &= ~S_NOSEC; + } + diff --git a/queue-5.4/btrfs-fix-lockdep-splat-and-potential-deadlock-after-failure-running-delayed-items.patch b/queue-5.4/btrfs-fix-lockdep-splat-and-potential-deadlock-after-failure-running-delayed-items.patch new file mode 100644 index 00000000000..2cde3ec5b6e --- /dev/null +++ b/queue-5.4/btrfs-fix-lockdep-splat-and-potential-deadlock-after-failure-running-delayed-items.patch @@ -0,0 +1,188 @@ +From e110f8911ddb93e6f55da14ccbbe705397b30d0b Mon Sep 17 00:00:00 2001 +From: Filipe Manana +Date: Tue, 29 Aug 2023 11:34:52 +0100 +Subject: btrfs: fix lockdep splat and potential deadlock after failure running delayed items + +From: Filipe Manana + +commit e110f8911ddb93e6f55da14ccbbe705397b30d0b upstream. + +When running delayed items we are holding a delayed node's mutex and then +we will attempt to modify a subvolume btree to insert/update/delete the +delayed items. However if have an error during the insertions for example, +btrfs_insert_delayed_items() may return with a path that has locked extent +buffers (a leaf at the very least), and then we attempt to release the +delayed node at __btrfs_run_delayed_items(), which requires taking the +delayed node's mutex, causing an ABBA type of deadlock. This was reported +by syzbot and the lockdep splat is the following: + + WARNING: possible circular locking dependency detected + 6.5.0-rc7-syzkaller-00024-g93f5de5f648d #0 Not tainted + ------------------------------------------------------ + syz-executor.2/13257 is trying to acquire lock: + ffff88801835c0c0 (&delayed_node->mutex){+.+.}-{3:3}, at: __btrfs_release_delayed_node+0x9a/0xaa0 fs/btrfs/delayed-inode.c:256 + + but task is already holding lock: + ffff88802a5ab8e8 (btrfs-tree-00){++++}-{3:3}, at: __btrfs_tree_lock+0x3c/0x2a0 fs/btrfs/locking.c:198 + + which lock already depends on the new lock. + + the existing dependency chain (in reverse order) is: + + -> #1 (btrfs-tree-00){++++}-{3:3}: + __lock_release kernel/locking/lockdep.c:5475 [inline] + lock_release+0x36f/0x9d0 kernel/locking/lockdep.c:5781 + up_write+0x79/0x580 kernel/locking/rwsem.c:1625 + btrfs_tree_unlock_rw fs/btrfs/locking.h:189 [inline] + btrfs_unlock_up_safe+0x179/0x3b0 fs/btrfs/locking.c:239 + search_leaf fs/btrfs/ctree.c:1986 [inline] + btrfs_search_slot+0x2511/0x2f80 fs/btrfs/ctree.c:2230 + btrfs_insert_empty_items+0x9c/0x180 fs/btrfs/ctree.c:4376 + btrfs_insert_delayed_item fs/btrfs/delayed-inode.c:746 [inline] + btrfs_insert_delayed_items fs/btrfs/delayed-inode.c:824 [inline] + __btrfs_commit_inode_delayed_items+0xd24/0x2410 fs/btrfs/delayed-inode.c:1111 + __btrfs_run_delayed_items+0x1db/0x430 fs/btrfs/delayed-inode.c:1153 + flush_space+0x269/0xe70 fs/btrfs/space-info.c:723 + btrfs_async_reclaim_metadata_space+0x106/0x350 fs/btrfs/space-info.c:1078 + process_one_work+0x92c/0x12c0 kernel/workqueue.c:2600 + worker_thread+0xa63/0x1210 kernel/workqueue.c:2751 + kthread+0x2b8/0x350 kernel/kthread.c:389 + ret_from_fork+0x2e/0x60 arch/x86/kernel/process.c:145 + ret_from_fork_asm+0x11/0x20 arch/x86/entry/entry_64.S:304 + + -> #0 (&delayed_node->mutex){+.+.}-{3:3}: + check_prev_add kernel/locking/lockdep.c:3142 [inline] + check_prevs_add kernel/locking/lockdep.c:3261 [inline] + validate_chain kernel/locking/lockdep.c:3876 [inline] + __lock_acquire+0x39ff/0x7f70 kernel/locking/lockdep.c:5144 + lock_acquire+0x1e3/0x520 kernel/locking/lockdep.c:5761 + __mutex_lock_common+0x1d8/0x2530 kernel/locking/mutex.c:603 + __mutex_lock kernel/locking/mutex.c:747 [inline] + mutex_lock_nested+0x1b/0x20 kernel/locking/mutex.c:799 + __btrfs_release_delayed_node+0x9a/0xaa0 fs/btrfs/delayed-inode.c:256 + btrfs_release_delayed_node fs/btrfs/delayed-inode.c:281 [inline] + __btrfs_run_delayed_items+0x2b5/0x430 fs/btrfs/delayed-inode.c:1156 + btrfs_commit_transaction+0x859/0x2ff0 fs/btrfs/transaction.c:2276 + btrfs_sync_file+0xf56/0x1330 fs/btrfs/file.c:1988 + vfs_fsync_range fs/sync.c:188 [inline] + vfs_fsync fs/sync.c:202 [inline] + do_fsync fs/sync.c:212 [inline] + __do_sys_fsync fs/sync.c:220 [inline] + __se_sys_fsync fs/sync.c:218 [inline] + __x64_sys_fsync+0x196/0x1e0 fs/sync.c:218 + do_syscall_x64 arch/x86/entry/common.c:50 [inline] + do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80 + entry_SYSCALL_64_after_hwframe+0x63/0xcd + + other info that might help us debug this: + + Possible unsafe locking scenario: + + CPU0 CPU1 + ---- ---- + lock(btrfs-tree-00); + lock(&delayed_node->mutex); + lock(btrfs-tree-00); + lock(&delayed_node->mutex); + + *** DEADLOCK *** + + 3 locks held by syz-executor.2/13257: + #0: ffff88802c1ee370 (btrfs_trans_num_writers){++++}-{0:0}, at: spin_unlock include/linux/spinlock.h:391 [inline] + #0: ffff88802c1ee370 (btrfs_trans_num_writers){++++}-{0:0}, at: join_transaction+0xb87/0xe00 fs/btrfs/transaction.c:287 + #1: ffff88802c1ee398 (btrfs_trans_num_extwriters){++++}-{0:0}, at: join_transaction+0xbb2/0xe00 fs/btrfs/transaction.c:288 + #2: ffff88802a5ab8e8 (btrfs-tree-00){++++}-{3:3}, at: __btrfs_tree_lock+0x3c/0x2a0 fs/btrfs/locking.c:198 + + stack backtrace: + CPU: 0 PID: 13257 Comm: syz-executor.2 Not tainted 6.5.0-rc7-syzkaller-00024-g93f5de5f648d #0 + Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/26/2023 + Call Trace: + + __dump_stack lib/dump_stack.c:88 [inline] + dump_stack_lvl+0x1e7/0x2d0 lib/dump_stack.c:106 + check_noncircular+0x375/0x4a0 kernel/locking/lockdep.c:2195 + check_prev_add kernel/locking/lockdep.c:3142 [inline] + check_prevs_add kernel/locking/lockdep.c:3261 [inline] + validate_chain kernel/locking/lockdep.c:3876 [inline] + __lock_acquire+0x39ff/0x7f70 kernel/locking/lockdep.c:5144 + lock_acquire+0x1e3/0x520 kernel/locking/lockdep.c:5761 + __mutex_lock_common+0x1d8/0x2530 kernel/locking/mutex.c:603 + __mutex_lock kernel/locking/mutex.c:747 [inline] + mutex_lock_nested+0x1b/0x20 kernel/locking/mutex.c:799 + __btrfs_release_delayed_node+0x9a/0xaa0 fs/btrfs/delayed-inode.c:256 + btrfs_release_delayed_node fs/btrfs/delayed-inode.c:281 [inline] + __btrfs_run_delayed_items+0x2b5/0x430 fs/btrfs/delayed-inode.c:1156 + btrfs_commit_transaction+0x859/0x2ff0 fs/btrfs/transaction.c:2276 + btrfs_sync_file+0xf56/0x1330 fs/btrfs/file.c:1988 + vfs_fsync_range fs/sync.c:188 [inline] + vfs_fsync fs/sync.c:202 [inline] + do_fsync fs/sync.c:212 [inline] + __do_sys_fsync fs/sync.c:220 [inline] + __se_sys_fsync fs/sync.c:218 [inline] + __x64_sys_fsync+0x196/0x1e0 fs/sync.c:218 + do_syscall_x64 arch/x86/entry/common.c:50 [inline] + do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80 + entry_SYSCALL_64_after_hwframe+0x63/0xcd + RIP: 0033:0x7f3ad047cae9 + Code: 28 00 00 00 75 (...) + RSP: 002b:00007f3ad12510c8 EFLAGS: 00000246 ORIG_RAX: 000000000000004a + RAX: ffffffffffffffda RBX: 00007f3ad059bf80 RCX: 00007f3ad047cae9 + RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000005 + RBP: 00007f3ad04c847a R08: 0000000000000000 R09: 0000000000000000 + R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 + R13: 000000000000000b R14: 00007f3ad059bf80 R15: 00007ffe56af92f8 + + ------------[ cut here ]------------ + +Fix this by releasing the path before releasing the delayed node in the +error path at __btrfs_run_delayed_items(). + +Reported-by: syzbot+a379155f07c134ea9879@syzkaller.appspotmail.com +Link: https://lore.kernel.org/linux-btrfs/000000000000abba27060403b5bd@google.com/ +CC: stable@vger.kernel.org # 4.14+ +Signed-off-by: Filipe Manana +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman +--- + fs/btrfs/delayed-inode.c | 19 ++++++++++++++++--- + 1 file changed, 16 insertions(+), 3 deletions(-) + +--- a/fs/btrfs/delayed-inode.c ++++ b/fs/btrfs/delayed-inode.c +@@ -1175,20 +1175,33 @@ static int __btrfs_run_delayed_items(str + ret = __btrfs_commit_inode_delayed_items(trans, path, + curr_node); + if (ret) { +- btrfs_release_delayed_node(curr_node); +- curr_node = NULL; + btrfs_abort_transaction(trans, ret); + break; + } + + prev_node = curr_node; + curr_node = btrfs_next_delayed_node(curr_node); ++ /* ++ * See the comment below about releasing path before releasing ++ * node. If the commit of delayed items was successful the path ++ * should always be released, but in case of an error, it may ++ * point to locked extent buffers (a leaf at the very least). ++ */ ++ ASSERT(path->nodes[0] == NULL); + btrfs_release_delayed_node(prev_node); + } + ++ /* ++ * Release the path to avoid a potential deadlock and lockdep splat when ++ * releasing the delayed node, as that requires taking the delayed node's ++ * mutex. If another task starts running delayed items before we take ++ * the mutex, it will first lock the mutex and then it may try to lock ++ * the same btree path (leaf). ++ */ ++ btrfs_free_path(path); ++ + if (curr_node) + btrfs_release_delayed_node(curr_node); +- btrfs_free_path(path); + trans->block_rsv = block_rsv; + + return ret; diff --git a/queue-5.4/ext4-fix-rec_len-verify-error.patch b/queue-5.4/ext4-fix-rec_len-verify-error.patch new file mode 100644 index 00000000000..db74c65444c --- /dev/null +++ b/queue-5.4/ext4-fix-rec_len-verify-error.patch @@ -0,0 +1,122 @@ +From 7fda67e8c3ab6069f75888f67958a6d30454a9f6 Mon Sep 17 00:00:00 2001 +From: Shida Zhang +Date: Thu, 3 Aug 2023 14:09:38 +0800 +Subject: ext4: fix rec_len verify error + +From: Shida Zhang + +commit 7fda67e8c3ab6069f75888f67958a6d30454a9f6 upstream. + +With the configuration PAGE_SIZE 64k and filesystem blocksize 64k, +a problem occurred when more than 13 million files were directly created +under a directory: + +EXT4-fs error (device xx): ext4_dx_csum_set:492: inode #xxxx: comm xxxxx: dir seems corrupt? Run e2fsck -D. +EXT4-fs error (device xx): ext4_dx_csum_verify:463: inode #xxxx: comm xxxxx: dir seems corrupt? Run e2fsck -D. +EXT4-fs error (device xx): dx_probe:856: inode #xxxx: block 8188: comm xxxxx: Directory index failed checksum + +When enough files are created, the fake_dirent->reclen will be 0xffff. +it doesn't equal to the blocksize 65536, i.e. 0x10000. + +But it is not the same condition when blocksize equals to 4k. +when enough files are created, the fake_dirent->reclen will be 0x1000. +it equals to the blocksize 4k, i.e. 0x1000. + +The problem seems to be related to the limitation of the 16-bit field +when the blocksize is set to 64k. +To address this, helpers like ext4_rec_len_{from,to}_disk has already +been introduced to complete the conversion between the encoded and the +plain form of rec_len. + +So fix this one by using the helper, and all the other in this file too. + +Cc: stable@kernel.org +Fixes: dbe89444042a ("ext4: Calculate and verify checksums for htree nodes") +Suggested-by: Andreas Dilger +Suggested-by: Darrick J. Wong +Signed-off-by: Shida Zhang +Reviewed-by: Andreas Dilger +Reviewed-by: Darrick J. Wong +Link: https://lore.kernel.org/r/20230803060938.1929759-1-zhangshida@kylinos.cn +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/namei.c | 26 +++++++++++++++----------- + 1 file changed, 15 insertions(+), 11 deletions(-) + +--- a/fs/ext4/namei.c ++++ b/fs/ext4/namei.c +@@ -325,17 +325,17 @@ static struct ext4_dir_entry_tail *get_d + struct buffer_head *bh) + { + struct ext4_dir_entry_tail *t; ++ int blocksize = EXT4_BLOCK_SIZE(inode->i_sb); + + #ifdef PARANOID + struct ext4_dir_entry *d, *top; + + d = (struct ext4_dir_entry *)bh->b_data; + top = (struct ext4_dir_entry *)(bh->b_data + +- (EXT4_BLOCK_SIZE(inode->i_sb) - +- sizeof(struct ext4_dir_entry_tail))); +- while (d < top && d->rec_len) ++ (blocksize - sizeof(struct ext4_dir_entry_tail))); ++ while (d < top && ext4_rec_len_from_disk(d->rec_len, blocksize)) + d = (struct ext4_dir_entry *)(((void *)d) + +- le16_to_cpu(d->rec_len)); ++ ext4_rec_len_from_disk(d->rec_len, blocksize)); + + if (d != top) + return NULL; +@@ -346,7 +346,8 @@ static struct ext4_dir_entry_tail *get_d + #endif + + if (t->det_reserved_zero1 || +- le16_to_cpu(t->det_rec_len) != sizeof(struct ext4_dir_entry_tail) || ++ (ext4_rec_len_from_disk(t->det_rec_len, blocksize) != ++ sizeof(struct ext4_dir_entry_tail)) || + t->det_reserved_zero2 || + t->det_reserved_ft != EXT4_FT_DIR_CSUM) + return NULL; +@@ -427,13 +428,14 @@ static struct dx_countlimit *get_dx_coun + struct ext4_dir_entry *dp; + struct dx_root_info *root; + int count_offset; ++ int blocksize = EXT4_BLOCK_SIZE(inode->i_sb); ++ unsigned int rlen = ext4_rec_len_from_disk(dirent->rec_len, blocksize); + +- if (le16_to_cpu(dirent->rec_len) == EXT4_BLOCK_SIZE(inode->i_sb)) ++ if (rlen == blocksize) + count_offset = 8; +- else if (le16_to_cpu(dirent->rec_len) == 12) { ++ else if (rlen == 12) { + dp = (struct ext4_dir_entry *)(((void *)dirent) + 12); +- if (le16_to_cpu(dp->rec_len) != +- EXT4_BLOCK_SIZE(inode->i_sb) - 12) ++ if (ext4_rec_len_from_disk(dp->rec_len, blocksize) != blocksize - 12) + return NULL; + root = (struct dx_root_info *)(((void *)dp + 12)); + if (root->reserved_zero || +@@ -1246,6 +1248,7 @@ static int dx_make_map(struct inode *dir + unsigned int buflen = bh->b_size; + char *base = bh->b_data; + struct dx_hash_info h = *hinfo; ++ int blocksize = EXT4_BLOCK_SIZE(dir->i_sb); + + if (ext4_has_metadata_csum(dir->i_sb)) + buflen -= sizeof(struct ext4_dir_entry_tail); +@@ -1259,11 +1262,12 @@ static int dx_make_map(struct inode *dir + map_tail--; + map_tail->hash = h.hash; + map_tail->offs = ((char *) de - base)>>2; +- map_tail->size = le16_to_cpu(de->rec_len); ++ map_tail->size = ext4_rec_len_from_disk(de->rec_len, ++ blocksize); + count++; + cond_resched(); + } +- de = ext4_next_entry(de, dir->i_sb->s_blocksize); ++ de = ext4_next_entry(de, blocksize); + } + return count; + } diff --git a/queue-5.4/i2c-aspeed-reset-the-i2c-controller-when-timeout-occurs.patch b/queue-5.4/i2c-aspeed-reset-the-i2c-controller-when-timeout-occurs.patch new file mode 100644 index 00000000000..572493e6507 --- /dev/null +++ b/queue-5.4/i2c-aspeed-reset-the-i2c-controller-when-timeout-occurs.patch @@ -0,0 +1,44 @@ +From fee465150b458351b6d9b9f66084f3cc3022b88b Mon Sep 17 00:00:00 2001 +From: Tommy Huang +Date: Wed, 6 Sep 2023 08:49:10 +0800 +Subject: i2c: aspeed: Reset the i2c controller when timeout occurs + +From: Tommy Huang + +commit fee465150b458351b6d9b9f66084f3cc3022b88b upstream. + +Reset the i2c controller when an i2c transfer timeout occurs. +The remaining interrupts and device should be reset to avoid +unpredictable controller behavior. + +Fixes: 2e57b7cebb98 ("i2c: aspeed: Add multi-master use case support") +Cc: # v5.1+ +Signed-off-by: Tommy Huang +Reviewed-by: Andi Shyti +Signed-off-by: Wolfram Sang +Signed-off-by: Greg Kroah-Hartman +--- + drivers/i2c/busses/i2c-aspeed.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/drivers/i2c/busses/i2c-aspeed.c ++++ b/drivers/i2c/busses/i2c-aspeed.c +@@ -693,13 +693,16 @@ static int aspeed_i2c_master_xfer(struct + + if (time_left == 0) { + /* +- * If timed out and bus is still busy in a multi master +- * environment, attempt recovery at here. ++ * In a multi-master setup, if a timeout occurs, attempt ++ * recovery. But if the bus is idle, we still need to reset the ++ * i2c controller to clear the remaining interrupts. + */ + if (bus->multi_master && + (readl(bus->base + ASPEED_I2C_CMD_REG) & + ASPEED_I2CD_BUS_BUSY_STS)) + aspeed_i2c_recover_bus(bus); ++ else ++ aspeed_i2c_reset(bus); + + /* + * If timed out and the state is still pending, drop the pending diff --git a/queue-5.4/nfsd-fix-change_info-in-nfsv4-rename-replies.patch b/queue-5.4/nfsd-fix-change_info-in-nfsv4-rename-replies.patch new file mode 100644 index 00000000000..a88c270c52c --- /dev/null +++ b/queue-5.4/nfsd-fix-change_info-in-nfsv4-rename-replies.patch @@ -0,0 +1,36 @@ +From fdd2630a7398191e84822612e589062063bd4f3d Mon Sep 17 00:00:00 2001 +From: Jeff Layton +Date: Sat, 9 Sep 2023 07:12:30 -0400 +Subject: nfsd: fix change_info in NFSv4 RENAME replies + +From: Jeff Layton + +commit fdd2630a7398191e84822612e589062063bd4f3d upstream. + +nfsd sends the transposed directory change info in the RENAME reply. The +source directory is in save_fh and the target is in current_fh. + +Reported-by: Zhi Li +Reported-by: Benjamin Coddington +Closes: https://bugzilla.redhat.com/show_bug.cgi?id=2218844 +Signed-off-by: Jeff Layton +Cc: +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfsd/nfs4proc.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/fs/nfsd/nfs4proc.c ++++ b/fs/nfsd/nfs4proc.c +@@ -865,8 +865,8 @@ nfsd4_rename(struct svc_rqst *rqstp, str + rename->rn_tname, rename->rn_tnamelen); + if (status) + return status; +- set_change_info(&rename->rn_sinfo, &cstate->current_fh); +- set_change_info(&rename->rn_tinfo, &cstate->save_fh); ++ set_change_info(&rename->rn_sinfo, &cstate->save_fh); ++ set_change_info(&rename->rn_tinfo, &cstate->current_fh); + return nfs_ok; + } + diff --git a/queue-5.4/scsi-megaraid_sas-fix-deadlock-on-firmware-crashdump.patch b/queue-5.4/scsi-megaraid_sas-fix-deadlock-on-firmware-crashdump.patch new file mode 100644 index 00000000000..aeb5ca8d015 --- /dev/null +++ b/queue-5.4/scsi-megaraid_sas-fix-deadlock-on-firmware-crashdump.patch @@ -0,0 +1,175 @@ +From 0b0747d507bffb827e40fc0f9fb5883fffc23477 Mon Sep 17 00:00:00 2001 +From: Junxiao Bi +Date: Mon, 28 Aug 2023 15:10:18 -0700 +Subject: scsi: megaraid_sas: Fix deadlock on firmware crashdump + +From: Junxiao Bi + +commit 0b0747d507bffb827e40fc0f9fb5883fffc23477 upstream. + +The following processes run into a deadlock. CPU 41 was waiting for CPU 29 +to handle a CSD request while holding spinlock "crashdump_lock", but CPU 29 +was hung by that spinlock with IRQs disabled. + + PID: 17360 TASK: ffff95c1090c5c40 CPU: 41 COMMAND: "mrdiagd" + !# 0 [ffffb80edbf37b58] __read_once_size at ffffffff9b871a40 include/linux/compiler.h:185:0 + !# 1 [ffffb80edbf37b58] atomic_read at ffffffff9b871a40 arch/x86/include/asm/atomic.h:27:0 + !# 2 [ffffb80edbf37b58] dump_stack at ffffffff9b871a40 lib/dump_stack.c:54:0 + # 3 [ffffb80edbf37b78] csd_lock_wait_toolong at ffffffff9b131ad5 kernel/smp.c:364:0 + # 4 [ffffb80edbf37b78] __csd_lock_wait at ffffffff9b131ad5 kernel/smp.c:384:0 + # 5 [ffffb80edbf37bf8] csd_lock_wait at ffffffff9b13267a kernel/smp.c:394:0 + # 6 [ffffb80edbf37bf8] smp_call_function_many at ffffffff9b13267a kernel/smp.c:843:0 + # 7 [ffffb80edbf37c50] smp_call_function at ffffffff9b13279d kernel/smp.c:867:0 + # 8 [ffffb80edbf37c50] on_each_cpu at ffffffff9b13279d kernel/smp.c:976:0 + # 9 [ffffb80edbf37c78] flush_tlb_kernel_range at ffffffff9b085c4b arch/x86/mm/tlb.c:742:0 + #10 [ffffb80edbf37cb8] __purge_vmap_area_lazy at ffffffff9b23a1e0 mm/vmalloc.c:701:0 + #11 [ffffb80edbf37ce0] try_purge_vmap_area_lazy at ffffffff9b23a2cc mm/vmalloc.c:722:0 + #12 [ffffb80edbf37ce0] free_vmap_area_noflush at ffffffff9b23a2cc mm/vmalloc.c:754:0 + #13 [ffffb80edbf37cf8] free_unmap_vmap_area at ffffffff9b23bb3b mm/vmalloc.c:764:0 + #14 [ffffb80edbf37cf8] remove_vm_area at ffffffff9b23bb3b mm/vmalloc.c:1509:0 + #15 [ffffb80edbf37d18] __vunmap at ffffffff9b23bb8a mm/vmalloc.c:1537:0 + #16 [ffffb80edbf37d40] vfree at ffffffff9b23bc85 mm/vmalloc.c:1612:0 + #17 [ffffb80edbf37d58] megasas_free_host_crash_buffer [megaraid_sas] at ffffffffc020b7f2 drivers/scsi/megaraid/megaraid_sas_fusion.c:3932:0 + #18 [ffffb80edbf37d80] fw_crash_state_store [megaraid_sas] at ffffffffc01f804d drivers/scsi/megaraid/megaraid_sas_base.c:3291:0 + #19 [ffffb80edbf37dc0] dev_attr_store at ffffffff9b56dd7b drivers/base/core.c:758:0 + #20 [ffffb80edbf37dd0] sysfs_kf_write at ffffffff9b326acf fs/sysfs/file.c:144:0 + #21 [ffffb80edbf37de0] kernfs_fop_write at ffffffff9b325fd4 fs/kernfs/file.c:316:0 + #22 [ffffb80edbf37e20] __vfs_write at ffffffff9b29418a fs/read_write.c:480:0 + #23 [ffffb80edbf37ea8] vfs_write at ffffffff9b294462 fs/read_write.c:544:0 + #24 [ffffb80edbf37ee8] SYSC_write at ffffffff9b2946ec fs/read_write.c:590:0 + #25 [ffffb80edbf37ee8] SyS_write at ffffffff9b2946ec fs/read_write.c:582:0 + #26 [ffffb80edbf37f30] do_syscall_64 at ffffffff9b003ca9 arch/x86/entry/common.c:298:0 + #27 [ffffb80edbf37f58] entry_SYSCALL_64 at ffffffff9ba001b1 arch/x86/entry/entry_64.S:238:0 + + PID: 17355 TASK: ffff95c1090c3d80 CPU: 29 COMMAND: "mrdiagd" + !# 0 [ffffb80f2d3c7d30] __read_once_size at ffffffff9b0f2ab0 include/linux/compiler.h:185:0 + !# 1 [ffffb80f2d3c7d30] native_queued_spin_lock_slowpath at ffffffff9b0f2ab0 kernel/locking/qspinlock.c:368:0 + # 2 [ffffb80f2d3c7d58] pv_queued_spin_lock_slowpath at ffffffff9b0f244b arch/x86/include/asm/paravirt.h:674:0 + # 3 [ffffb80f2d3c7d58] queued_spin_lock_slowpath at ffffffff9b0f244b arch/x86/include/asm/qspinlock.h:53:0 + # 4 [ffffb80f2d3c7d68] queued_spin_lock at ffffffff9b8961a6 include/asm-generic/qspinlock.h:90:0 + # 5 [ffffb80f2d3c7d68] do_raw_spin_lock_flags at ffffffff9b8961a6 include/linux/spinlock.h:173:0 + # 6 [ffffb80f2d3c7d68] __raw_spin_lock_irqsave at ffffffff9b8961a6 include/linux/spinlock_api_smp.h:122:0 + # 7 [ffffb80f2d3c7d68] _raw_spin_lock_irqsave at ffffffff9b8961a6 kernel/locking/spinlock.c:160:0 + # 8 [ffffb80f2d3c7d88] fw_crash_buffer_store [megaraid_sas] at ffffffffc01f8129 drivers/scsi/megaraid/megaraid_sas_base.c:3205:0 + # 9 [ffffb80f2d3c7dc0] dev_attr_store at ffffffff9b56dd7b drivers/base/core.c:758:0 + #10 [ffffb80f2d3c7dd0] sysfs_kf_write at ffffffff9b326acf fs/sysfs/file.c:144:0 + #11 [ffffb80f2d3c7de0] kernfs_fop_write at ffffffff9b325fd4 fs/kernfs/file.c:316:0 + #12 [ffffb80f2d3c7e20] __vfs_write at ffffffff9b29418a fs/read_write.c:480:0 + #13 [ffffb80f2d3c7ea8] vfs_write at ffffffff9b294462 fs/read_write.c:544:0 + #14 [ffffb80f2d3c7ee8] SYSC_write at ffffffff9b2946ec fs/read_write.c:590:0 + #15 [ffffb80f2d3c7ee8] SyS_write at ffffffff9b2946ec fs/read_write.c:582:0 + #16 [ffffb80f2d3c7f30] do_syscall_64 at ffffffff9b003ca9 arch/x86/entry/common.c:298:0 + #17 [ffffb80f2d3c7f58] entry_SYSCALL_64 at ffffffff9ba001b1 arch/x86/entry/entry_64.S:238:0 + +The lock is used to synchronize different sysfs operations, it doesn't +protect any resource that will be touched by an interrupt. Consequently +it's not required to disable IRQs. Replace the spinlock with a mutex to fix +the deadlock. + +Signed-off-by: Junxiao Bi +Link: https://lore.kernel.org/r/20230828221018.19471-1-junxiao.bi@oracle.com +Reviewed-by: Mike Christie +Cc: stable@vger.kernel.org +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/megaraid/megaraid_sas.h | 2 +- + drivers/scsi/megaraid/megaraid_sas_base.c | 21 +++++++++------------ + 2 files changed, 10 insertions(+), 13 deletions(-) + +--- a/drivers/scsi/megaraid/megaraid_sas.h ++++ b/drivers/scsi/megaraid/megaraid_sas.h +@@ -2324,7 +2324,7 @@ struct megasas_instance { + u32 support_morethan256jbod; /* FW support for more than 256 PD/JBOD */ + bool use_seqnum_jbod_fp; /* Added for PD sequence */ + bool smp_affinity_enable; +- spinlock_t crashdump_lock; ++ struct mutex crashdump_lock; + + struct megasas_register_set __iomem *reg_set; + u32 __iomem *reply_post_host_index_addr[MR_MAX_MSIX_REG_ARRAY]; +--- a/drivers/scsi/megaraid/megaraid_sas_base.c ++++ b/drivers/scsi/megaraid/megaraid_sas_base.c +@@ -3208,14 +3208,13 @@ fw_crash_buffer_store(struct device *cde + struct megasas_instance *instance = + (struct megasas_instance *) shost->hostdata; + int val = 0; +- unsigned long flags; + + if (kstrtoint(buf, 0, &val) != 0) + return -EINVAL; + +- spin_lock_irqsave(&instance->crashdump_lock, flags); ++ mutex_lock(&instance->crashdump_lock); + instance->fw_crash_buffer_offset = val; +- spin_unlock_irqrestore(&instance->crashdump_lock, flags); ++ mutex_unlock(&instance->crashdump_lock); + return strlen(buf); + } + +@@ -3230,24 +3229,23 @@ fw_crash_buffer_show(struct device *cdev + unsigned long dmachunk = CRASH_DMA_BUF_SIZE; + unsigned long chunk_left_bytes; + unsigned long src_addr; +- unsigned long flags; + u32 buff_offset; + +- spin_lock_irqsave(&instance->crashdump_lock, flags); ++ mutex_lock(&instance->crashdump_lock); + buff_offset = instance->fw_crash_buffer_offset; + if (!instance->crash_dump_buf || + !((instance->fw_crash_state == AVAILABLE) || + (instance->fw_crash_state == COPYING))) { + dev_err(&instance->pdev->dev, + "Firmware crash dump is not available\n"); +- spin_unlock_irqrestore(&instance->crashdump_lock, flags); ++ mutex_unlock(&instance->crashdump_lock); + return -EINVAL; + } + + if (buff_offset > (instance->fw_crash_buffer_size * dmachunk)) { + dev_err(&instance->pdev->dev, + "Firmware crash dump offset is out of range\n"); +- spin_unlock_irqrestore(&instance->crashdump_lock, flags); ++ mutex_unlock(&instance->crashdump_lock); + return 0; + } + +@@ -3259,7 +3257,7 @@ fw_crash_buffer_show(struct device *cdev + src_addr = (unsigned long)instance->crash_buf[buff_offset / dmachunk] + + (buff_offset % dmachunk); + memcpy(buf, (void *)src_addr, size); +- spin_unlock_irqrestore(&instance->crashdump_lock, flags); ++ mutex_unlock(&instance->crashdump_lock); + + return size; + } +@@ -3284,7 +3282,6 @@ fw_crash_state_store(struct device *cdev + struct megasas_instance *instance = + (struct megasas_instance *) shost->hostdata; + int val = 0; +- unsigned long flags; + + if (kstrtoint(buf, 0, &val) != 0) + return -EINVAL; +@@ -3298,9 +3295,9 @@ fw_crash_state_store(struct device *cdev + instance->fw_crash_state = val; + + if ((val == COPIED) || (val == COPY_ERROR)) { +- spin_lock_irqsave(&instance->crashdump_lock, flags); ++ mutex_lock(&instance->crashdump_lock); + megasas_free_host_crash_buffer(instance); +- spin_unlock_irqrestore(&instance->crashdump_lock, flags); ++ mutex_unlock(&instance->crashdump_lock); + if (val == COPY_ERROR) + dev_info(&instance->pdev->dev, "application failed to " + "copy Firmware crash dump\n"); +@@ -7301,7 +7298,7 @@ static inline void megasas_init_ctrl_par + init_waitqueue_head(&instance->int_cmd_wait_q); + init_waitqueue_head(&instance->abort_cmd_wait_q); + +- spin_lock_init(&instance->crashdump_lock); ++ mutex_init(&instance->crashdump_lock); + spin_lock_init(&instance->mfi_pool_lock); + spin_lock_init(&instance->hba_lock); + spin_lock_init(&instance->stream_lock); diff --git a/queue-5.4/series b/queue-5.4/series index 95488e34af9..4e50014000b 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -353,3 +353,12 @@ btrfs-add-a-helper-to-read-the-superblock-metadata_u.patch btrfs-compare-the-correct-fsid-metadata_uuid-in-btrf.patch selftests-tracing-fix-to-unmount-tracefs-for-recover.patch md-raid1-fix-error-iso-c90-forbids-mixed-declaration.patch +attr-block-mode-changes-of-symlinks.patch +btrfs-fix-lockdep-splat-and-potential-deadlock-after-failure-running-delayed-items.patch +tracing-have-current_trace-inc-the-trace-array-ref-count.patch +tracing-have-option-files-inc-the-trace-array-ref-count.patch +nfsd-fix-change_info-in-nfsv4-rename-replies.patch +tracefs-add-missing-lockdown-check-to-tracefs_create_dir.patch +i2c-aspeed-reset-the-i2c-controller-when-timeout-occurs.patch +scsi-megaraid_sas-fix-deadlock-on-firmware-crashdump.patch +ext4-fix-rec_len-verify-error.patch diff --git a/queue-5.4/tracefs-add-missing-lockdown-check-to-tracefs_create_dir.patch b/queue-5.4/tracefs-add-missing-lockdown-check-to-tracefs_create_dir.patch new file mode 100644 index 00000000000..a0842a9588e --- /dev/null +++ b/queue-5.4/tracefs-add-missing-lockdown-check-to-tracefs_create_dir.patch @@ -0,0 +1,43 @@ +From 51aab5ffceb43e05119eb059048fd75765d2bc21 Mon Sep 17 00:00:00 2001 +From: "Steven Rostedt (Google)" +Date: Tue, 5 Sep 2023 14:26:08 -0400 +Subject: tracefs: Add missing lockdown check to tracefs_create_dir() + +From: Steven Rostedt (Google) + +commit 51aab5ffceb43e05119eb059048fd75765d2bc21 upstream. + +The function tracefs_create_dir() was missing a lockdown check and was +called by the RV code. This gave an inconsistent behavior of this function +returning success while other tracefs functions failed. This caused the +inode being freed by the wrong kmem_cache. + +Link: https://lkml.kernel.org/r/20230905182711.692687042@goodmis.org +Link: https://lore.kernel.org/all/202309050916.58201dc6-oliver.sang@intel.com/ + +Cc: stable@vger.kernel.org +Cc: Masami Hiramatsu +Cc: Mark Rutland +Cc: Andrew Morton +Cc: Ajay Kaher +Cc: Ching-lin Yu +Fixes: bf8e602186ec4 ("tracing: Do not create tracefs files if tracefs lockdown is in effect") +Reported-by: kernel test robot +Signed-off-by: Steven Rostedt (Google) +Signed-off-by: Greg Kroah-Hartman +--- + fs/tracefs/inode.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/fs/tracefs/inode.c ++++ b/fs/tracefs/inode.c +@@ -551,6 +551,9 @@ static struct dentry *__create_dir(const + */ + struct dentry *tracefs_create_dir(const char *name, struct dentry *parent) + { ++ if (security_locked_down(LOCKDOWN_TRACEFS)) ++ return NULL; ++ + return __create_dir(name, parent, &simple_dir_inode_operations); + } + diff --git a/queue-5.4/tracing-have-current_trace-inc-the-trace-array-ref-count.patch b/queue-5.4/tracing-have-current_trace-inc-the-trace-array-ref-count.patch new file mode 100644 index 00000000000..8e176fc9dfd --- /dev/null +++ b/queue-5.4/tracing-have-current_trace-inc-the-trace-array-ref-count.patch @@ -0,0 +1,47 @@ +From 9b37febc578b2e1ad76a105aab11d00af5ec3d27 Mon Sep 17 00:00:00 2001 +From: "Steven Rostedt (Google)" +Date: Wed, 6 Sep 2023 22:47:14 -0400 +Subject: tracing: Have current_trace inc the trace array ref count + +From: Steven Rostedt (Google) + +commit 9b37febc578b2e1ad76a105aab11d00af5ec3d27 upstream. + +The current_trace updates the trace array tracer. For an instance, if the +file is opened and the instance is deleted, reading or writing to the file +will cause a use after free. + +Up the ref count of the trace array when current_trace is opened. + +Link: https://lkml.kernel.org/r/20230907024803.877687227@goodmis.org +Link: https://lore.kernel.org/all/1cb3aee2-19af-c472-e265-05176fe9bd84@huawei.com/ + +Cc: stable@vger.kernel.org +Cc: Masami Hiramatsu +Cc: Mark Rutland +Cc: Andrew Morton +Cc: Zheng Yejian +Fixes: 8530dec63e7b4 ("tracing: Add tracing_check_open_get_tr()") +Tested-by: Linux Kernel Functional Testing +Tested-by: Naresh Kamboju +Signed-off-by: Steven Rostedt (Google) +Signed-off-by: Greg Kroah-Hartman +--- + kernel/trace/trace.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -6951,10 +6951,11 @@ static const struct file_operations trac + #endif + + static const struct file_operations set_tracer_fops = { +- .open = tracing_open_generic, ++ .open = tracing_open_generic_tr, + .read = tracing_set_trace_read, + .write = tracing_set_trace_write, + .llseek = generic_file_llseek, ++ .release = tracing_release_generic_tr, + }; + + static const struct file_operations tracing_pipe_fops = { diff --git a/queue-5.4/tracing-have-option-files-inc-the-trace-array-ref-count.patch b/queue-5.4/tracing-have-option-files-inc-the-trace-array-ref-count.patch new file mode 100644 index 00000000000..051bd32dbff --- /dev/null +++ b/queue-5.4/tracing-have-option-files-inc-the-trace-array-ref-count.patch @@ -0,0 +1,69 @@ +From 7e2cfbd2d3c86afcd5c26b5c4b1dd251f63c5838 Mon Sep 17 00:00:00 2001 +From: "Steven Rostedt (Google)" +Date: Wed, 6 Sep 2023 22:47:15 -0400 +Subject: tracing: Have option files inc the trace array ref count + +From: Steven Rostedt (Google) + +commit 7e2cfbd2d3c86afcd5c26b5c4b1dd251f63c5838 upstream. + +The option files update the options for a given trace array. For an +instance, if the file is opened and the instance is deleted, reading or +writing to the file will cause a use after free. + +Up the ref count of the trace_array when an option file is opened. + +Link: https://lkml.kernel.org/r/20230907024804.086679464@goodmis.org +Link: https://lore.kernel.org/all/1cb3aee2-19af-c472-e265-05176fe9bd84@huawei.com/ + +Cc: stable@vger.kernel.org +Cc: Masami Hiramatsu +Cc: Mark Rutland +Cc: Andrew Morton +Cc: Zheng Yejian +Fixes: 8530dec63e7b4 ("tracing: Add tracing_check_open_get_tr()") +Tested-by: Linux Kernel Functional Testing +Tested-by: Naresh Kamboju +Signed-off-by: Steven Rostedt (Google) +Signed-off-by: Greg Kroah-Hartman +--- + kernel/trace/trace.c | 23 ++++++++++++++++++++++- + 1 file changed, 22 insertions(+), 1 deletion(-) + +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -7996,12 +7996,33 @@ trace_options_write(struct file *filp, c + return cnt; + } + ++static int tracing_open_options(struct inode *inode, struct file *filp) ++{ ++ struct trace_option_dentry *topt = inode->i_private; ++ int ret; ++ ++ ret = tracing_check_open_get_tr(topt->tr); ++ if (ret) ++ return ret; ++ ++ filp->private_data = inode->i_private; ++ return 0; ++} ++ ++static int tracing_release_options(struct inode *inode, struct file *file) ++{ ++ struct trace_option_dentry *topt = file->private_data; ++ ++ trace_array_put(topt->tr); ++ return 0; ++} + + static const struct file_operations trace_options_fops = { +- .open = tracing_open_generic, ++ .open = tracing_open_options, + .read = trace_options_read, + .write = trace_options_write, + .llseek = generic_file_llseek, ++ .release = tracing_release_options, + }; + + /*