From: Sasha Levin Date: Sat, 2 Nov 2024 11:11:41 +0000 (-0400) Subject: Fixes for 6.1 X-Git-Tag: v4.19.323~115 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=79995984ef50dcd9af4573d0e316fe0f79906f93;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 6.1 Signed-off-by: Sasha Levin --- diff --git a/queue-6.1/acpi-cppc-make-rmw_lock-a-raw_spin_lock.patch b/queue-6.1/acpi-cppc-make-rmw_lock-a-raw_spin_lock.patch new file mode 100644 index 00000000000..6728752d9b8 --- /dev/null +++ b/queue-6.1/acpi-cppc-make-rmw_lock-a-raw_spin_lock.patch @@ -0,0 +1,128 @@ +From 4f8e4a34d1b1284effd5155470fa9f7839843886 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 28 Oct 2024 13:56:56 +0100 +Subject: ACPI: CPPC: Make rmw_lock a raw_spin_lock + +From: Pierre Gondois + +[ Upstream commit 1c10941e34c5fdc0357e46a25bd130d9cf40b925 ] + +The following BUG was triggered: + +============================= +[ BUG: Invalid wait context ] +6.12.0-rc2-XXX #406 Not tainted +----------------------------- +kworker/1:1/62 is trying to lock: +ffffff8801593030 (&cpc_ptr->rmw_lock){+.+.}-{3:3}, at: cpc_write+0xcc/0x370 +other info that might help us debug this: +context-{5:5} +2 locks held by kworker/1:1/62: + #0: ffffff897ef5ec98 (&rq->__lock){-.-.}-{2:2}, at: raw_spin_rq_lock_nested+0x2c/0x50 + #1: ffffff880154e238 (&sg_policy->update_lock){....}-{2:2}, at: sugov_update_shared+0x3c/0x280 +stack backtrace: +CPU: 1 UID: 0 PID: 62 Comm: kworker/1:1 Not tainted 6.12.0-rc2-g9654bd3e8806 #406 +Workqueue: 0x0 (events) +Call trace: + dump_backtrace+0xa4/0x130 + show_stack+0x20/0x38 + dump_stack_lvl+0x90/0xd0 + dump_stack+0x18/0x28 + __lock_acquire+0x480/0x1ad8 + lock_acquire+0x114/0x310 + _raw_spin_lock+0x50/0x70 + cpc_write+0xcc/0x370 + cppc_set_perf+0xa0/0x3a8 + cppc_cpufreq_fast_switch+0x40/0xc0 + cpufreq_driver_fast_switch+0x4c/0x218 + sugov_update_shared+0x234/0x280 + update_load_avg+0x6ec/0x7b8 + dequeue_entities+0x108/0x830 + dequeue_task_fair+0x58/0x408 + __schedule+0x4f0/0x1070 + schedule+0x54/0x130 + worker_thread+0xc0/0x2e8 + kthread+0x130/0x148 + ret_from_fork+0x10/0x20 + +sugov_update_shared() locks a raw_spinlock while cpc_write() locks a +spinlock. + +To have a correct wait-type order, update rmw_lock to a raw spinlock and +ensure that interrupts will be disabled on the CPU holding it. + +Fixes: 60949b7b8054 ("ACPI: CPPC: Fix MASK_VAL() usage") +Signed-off-by: Pierre Gondois +Link: https://patch.msgid.link/20241028125657.1271512-1-pierre.gondois@arm.com +[ rjw: Changelog edits ] +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/cppc_acpi.c | 9 +++++---- + include/acpi/cppc_acpi.h | 2 +- + 2 files changed, 6 insertions(+), 5 deletions(-) + +diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c +index 3d9326172af49..31ea76b6fa045 100644 +--- a/drivers/acpi/cppc_acpi.c ++++ b/drivers/acpi/cppc_acpi.c +@@ -857,7 +857,7 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr) + + /* Store CPU Logical ID */ + cpc_ptr->cpu_id = pr->id; +- spin_lock_init(&cpc_ptr->rmw_lock); ++ raw_spin_lock_init(&cpc_ptr->rmw_lock); + + /* Parse PSD data for this CPU */ + ret = acpi_get_psd(cpc_ptr, handle); +@@ -1077,6 +1077,7 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val) + int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu); + struct cpc_reg *reg = ®_res->cpc_entry.reg; + struct cpc_desc *cpc_desc; ++ unsigned long flags; + + size = GET_BIT_WIDTH(reg); + +@@ -1116,7 +1117,7 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val) + return -ENODEV; + } + +- spin_lock(&cpc_desc->rmw_lock); ++ raw_spin_lock_irqsave(&cpc_desc->rmw_lock, flags); + switch (size) { + case 8: + prev_val = readb_relaxed(vaddr); +@@ -1131,7 +1132,7 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val) + prev_val = readq_relaxed(vaddr); + break; + default: +- spin_unlock(&cpc_desc->rmw_lock); ++ raw_spin_unlock_irqrestore(&cpc_desc->rmw_lock, flags); + return -EFAULT; + } + val = MASK_VAL_WRITE(reg, prev_val, val); +@@ -1164,7 +1165,7 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val) + } + + if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) +- spin_unlock(&cpc_desc->rmw_lock); ++ raw_spin_unlock_irqrestore(&cpc_desc->rmw_lock, flags); + + return ret_val; + } +diff --git a/include/acpi/cppc_acpi.h b/include/acpi/cppc_acpi.h +index 2d1ec0e6ee018..de3bda334abfc 100644 +--- a/include/acpi/cppc_acpi.h ++++ b/include/acpi/cppc_acpi.h +@@ -65,7 +65,7 @@ struct cpc_desc { + int write_cmd_status; + int write_cmd_id; + /* Lock used for RMW operations in cpc_write() */ +- spinlock_t rmw_lock; ++ raw_spinlock_t rmw_lock; + struct cpc_register_resource cpc_regs[MAX_CPC_REG_ENT]; + struct acpi_psd_package domain_info; + struct kobject kobj; +-- +2.43.0 + diff --git a/queue-6.1/afs-automatically-generate-trace-tag-enums.patch b/queue-6.1/afs-automatically-generate-trace-tag-enums.patch new file mode 100644 index 00000000000..ab070df561d --- /dev/null +++ b/queue-6.1/afs-automatically-generate-trace-tag-enums.patch @@ -0,0 +1,292 @@ +From abfdb25e35eed65ce4f6d2e1d19bfcb7189733a0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Feb 2023 15:24:24 +0000 +Subject: afs: Automatically generate trace tag enums + +From: David Howells + +[ Upstream commit 2daa6404fd2f00985d5bfeb3c161f4630b46b6bf ] + +Automatically generate trace tag enums from the symbol -> string mapping +tables rather than having the enums as well, thereby reducing duplicated +data. + +Signed-off-by: David Howells +cc: Marc Dionne +cc: Jeff Layton +cc: linux-afs@lists.infradead.org +cc: linux-fsdevel@vger.kernel.org +Stable-dep-of: 247d65fb122a ("afs: Fix missing subdir edit when renamed between parent dirs") +Signed-off-by: Sasha Levin +--- + include/trace/events/afs.h | 233 +++++-------------------------------- + 1 file changed, 27 insertions(+), 206 deletions(-) + +diff --git a/include/trace/events/afs.h b/include/trace/events/afs.h +index e9d412d19dbbb..54d10c69e55ec 100644 +--- a/include/trace/events/afs.h ++++ b/include/trace/events/afs.h +@@ -18,97 +18,6 @@ + #ifndef __AFS_DECLARE_TRACE_ENUMS_ONCE_ONLY + #define __AFS_DECLARE_TRACE_ENUMS_ONCE_ONLY + +-enum afs_call_trace { +- afs_call_trace_alloc, +- afs_call_trace_free, +- afs_call_trace_get, +- afs_call_trace_put, +- afs_call_trace_wake, +- afs_call_trace_work, +-}; +- +-enum afs_server_trace { +- afs_server_trace_alloc, +- afs_server_trace_callback, +- afs_server_trace_destroy, +- afs_server_trace_free, +- afs_server_trace_gc, +- afs_server_trace_get_by_addr, +- afs_server_trace_get_by_uuid, +- afs_server_trace_get_caps, +- afs_server_trace_get_install, +- afs_server_trace_get_new_cbi, +- afs_server_trace_get_probe, +- afs_server_trace_give_up_cb, +- afs_server_trace_purging, +- afs_server_trace_put_call, +- afs_server_trace_put_cbi, +- afs_server_trace_put_find_rsq, +- afs_server_trace_put_probe, +- afs_server_trace_put_slist, +- afs_server_trace_put_slist_isort, +- afs_server_trace_put_uuid_rsq, +- afs_server_trace_update, +-}; +- +- +-enum afs_volume_trace { +- afs_volume_trace_alloc, +- afs_volume_trace_free, +- afs_volume_trace_get_alloc_sbi, +- afs_volume_trace_get_cell_insert, +- afs_volume_trace_get_new_op, +- afs_volume_trace_get_query_alias, +- afs_volume_trace_put_cell_dup, +- afs_volume_trace_put_cell_root, +- afs_volume_trace_put_destroy_sbi, +- afs_volume_trace_put_free_fc, +- afs_volume_trace_put_put_op, +- afs_volume_trace_put_query_alias, +- afs_volume_trace_put_validate_fc, +- afs_volume_trace_remove, +-}; +- +-enum afs_cell_trace { +- afs_cell_trace_alloc, +- afs_cell_trace_free, +- afs_cell_trace_get_queue_dns, +- afs_cell_trace_get_queue_manage, +- afs_cell_trace_get_queue_new, +- afs_cell_trace_get_vol, +- afs_cell_trace_insert, +- afs_cell_trace_manage, +- afs_cell_trace_put_candidate, +- afs_cell_trace_put_destroy, +- afs_cell_trace_put_queue_fail, +- afs_cell_trace_put_queue_work, +- afs_cell_trace_put_vol, +- afs_cell_trace_see_source, +- afs_cell_trace_see_ws, +- afs_cell_trace_unuse_alias, +- afs_cell_trace_unuse_check_alias, +- afs_cell_trace_unuse_delete, +- afs_cell_trace_unuse_fc, +- afs_cell_trace_unuse_lookup, +- afs_cell_trace_unuse_mntpt, +- afs_cell_trace_unuse_no_pin, +- afs_cell_trace_unuse_parse, +- afs_cell_trace_unuse_pin, +- afs_cell_trace_unuse_probe, +- afs_cell_trace_unuse_sbi, +- afs_cell_trace_unuse_ws, +- afs_cell_trace_use_alias, +- afs_cell_trace_use_check_alias, +- afs_cell_trace_use_fc, +- afs_cell_trace_use_fc_alias, +- afs_cell_trace_use_lookup, +- afs_cell_trace_use_mntpt, +- afs_cell_trace_use_pin, +- afs_cell_trace_use_probe, +- afs_cell_trace_use_sbi, +- afs_cell_trace_wait, +-}; +- + enum afs_fs_operation { + afs_FS_FetchData = 130, /* AFS Fetch file data */ + afs_FS_FetchACL = 131, /* AFS Fetch file ACL */ +@@ -202,121 +111,6 @@ enum yfs_cm_operation { + yfs_CB_CallBack = 64204, + }; + +-enum afs_edit_dir_op { +- afs_edit_dir_create, +- afs_edit_dir_create_error, +- afs_edit_dir_create_inval, +- afs_edit_dir_create_nospc, +- afs_edit_dir_delete, +- afs_edit_dir_delete_error, +- afs_edit_dir_delete_inval, +- afs_edit_dir_delete_noent, +-}; +- +-enum afs_edit_dir_reason { +- afs_edit_dir_for_create, +- afs_edit_dir_for_link, +- afs_edit_dir_for_mkdir, +- afs_edit_dir_for_rename_0, +- afs_edit_dir_for_rename_1, +- afs_edit_dir_for_rename_2, +- afs_edit_dir_for_rmdir, +- afs_edit_dir_for_silly_0, +- afs_edit_dir_for_silly_1, +- afs_edit_dir_for_symlink, +- afs_edit_dir_for_unlink, +-}; +- +-enum afs_eproto_cause { +- afs_eproto_bad_status, +- afs_eproto_cb_count, +- afs_eproto_cb_fid_count, +- afs_eproto_cellname_len, +- afs_eproto_file_type, +- afs_eproto_ibulkst_cb_count, +- afs_eproto_ibulkst_count, +- afs_eproto_motd_len, +- afs_eproto_offline_msg_len, +- afs_eproto_volname_len, +- afs_eproto_yvl_fsendpt4_len, +- afs_eproto_yvl_fsendpt6_len, +- afs_eproto_yvl_fsendpt_num, +- afs_eproto_yvl_fsendpt_type, +- afs_eproto_yvl_vlendpt4_len, +- afs_eproto_yvl_vlendpt6_len, +- afs_eproto_yvl_vlendpt_type, +-}; +- +-enum afs_io_error { +- afs_io_error_cm_reply, +- afs_io_error_extract, +- afs_io_error_fs_probe_fail, +- afs_io_error_vl_lookup_fail, +- afs_io_error_vl_probe_fail, +-}; +- +-enum afs_file_error { +- afs_file_error_dir_bad_magic, +- afs_file_error_dir_big, +- afs_file_error_dir_missing_page, +- afs_file_error_dir_name_too_long, +- afs_file_error_dir_over_end, +- afs_file_error_dir_small, +- afs_file_error_dir_unmarked_ext, +- afs_file_error_mntpt, +- afs_file_error_writeback_fail, +-}; +- +-enum afs_flock_event { +- afs_flock_acquired, +- afs_flock_callback_break, +- afs_flock_defer_unlock, +- afs_flock_extend_fail, +- afs_flock_fail_other, +- afs_flock_fail_perm, +- afs_flock_no_lockers, +- afs_flock_release_fail, +- afs_flock_silly_delete, +- afs_flock_timestamp, +- afs_flock_try_to_lock, +- afs_flock_vfs_lock, +- afs_flock_vfs_locking, +- afs_flock_waited, +- afs_flock_waiting, +- afs_flock_work_extending, +- afs_flock_work_retry, +- afs_flock_work_unlocking, +- afs_flock_would_block, +-}; +- +-enum afs_flock_operation { +- afs_flock_op_copy_lock, +- afs_flock_op_flock, +- afs_flock_op_grant, +- afs_flock_op_lock, +- afs_flock_op_release_lock, +- afs_flock_op_return_ok, +- afs_flock_op_return_eagain, +- afs_flock_op_return_edeadlk, +- afs_flock_op_return_error, +- afs_flock_op_set_lock, +- afs_flock_op_unlock, +- afs_flock_op_wake, +-}; +- +-enum afs_cb_break_reason { +- afs_cb_break_no_break, +- afs_cb_break_no_promise, +- afs_cb_break_for_callback, +- afs_cb_break_for_deleted, +- afs_cb_break_for_lapsed, +- afs_cb_break_for_s_reinit, +- afs_cb_break_for_unlink, +- afs_cb_break_for_v_break, +- afs_cb_break_for_volume_callback, +- afs_cb_break_for_zap, +-}; +- + #endif /* end __AFS_DECLARE_TRACE_ENUMS_ONCE_ONLY */ + + /* +@@ -391,6 +185,7 @@ enum afs_cb_break_reason { + EM(afs_cell_trace_unuse_fc, "UNU fc ") \ + EM(afs_cell_trace_unuse_lookup, "UNU lookup") \ + EM(afs_cell_trace_unuse_mntpt, "UNU mntpt ") \ ++ EM(afs_cell_trace_unuse_no_pin, "UNU no-pin") \ + EM(afs_cell_trace_unuse_parse, "UNU parse ") \ + EM(afs_cell_trace_unuse_pin, "UNU pin ") \ + EM(afs_cell_trace_unuse_probe, "UNU probe ") \ +@@ -614,6 +409,32 @@ enum afs_cb_break_reason { + EM(afs_cb_break_for_volume_callback, "break-v-cb") \ + E_(afs_cb_break_for_zap, "break-zap") + ++/* ++ * Generate enums for tracing information. ++ */ ++#ifndef __AFS_GENERATE_TRACE_ENUMS_ONCE_ONLY ++#define __AFS_GENERATE_TRACE_ENUMS_ONCE_ONLY ++ ++#undef EM ++#undef E_ ++#define EM(a, b) a, ++#define E_(a, b) a ++ ++enum afs_call_trace { afs_call_traces } __mode(byte); ++enum afs_cb_break_reason { afs_cb_break_reasons } __mode(byte); ++enum afs_cell_trace { afs_cell_traces } __mode(byte); ++enum afs_edit_dir_op { afs_edit_dir_ops } __mode(byte); ++enum afs_edit_dir_reason { afs_edit_dir_reasons } __mode(byte); ++enum afs_eproto_cause { afs_eproto_causes } __mode(byte); ++enum afs_file_error { afs_file_errors } __mode(byte); ++enum afs_flock_event { afs_flock_events } __mode(byte); ++enum afs_flock_operation { afs_flock_operations } __mode(byte); ++enum afs_io_error { afs_io_errors } __mode(byte); ++enum afs_server_trace { afs_server_traces } __mode(byte); ++enum afs_volume_trace { afs_volume_traces } __mode(byte); ++ ++#endif /* end __AFS_GENERATE_TRACE_ENUMS_ONCE_ONLY */ ++ + /* + * Export enum symbols via userspace. + */ +-- +2.43.0 + diff --git a/queue-6.1/afs-fix-missing-subdir-edit-when-renamed-between-par.patch b/queue-6.1/afs-fix-missing-subdir-edit-when-renamed-between-par.patch new file mode 100644 index 00000000000..881b58ddfab --- /dev/null +++ b/queue-6.1/afs-fix-missing-subdir-edit-when-renamed-between-par.patch @@ -0,0 +1,256 @@ +From ccbad06e6cbd6fd2a4a8908cb0a3a68aa6172c79 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 23 Oct 2024 11:40:10 +0100 +Subject: afs: Fix missing subdir edit when renamed between parent dirs + +From: David Howells + +[ Upstream commit 247d65fb122ad560be1c8c4d87d7374fb28b0770 ] + +When rename moves an AFS subdirectory between parent directories, the +subdir also needs a bit of editing: the ".." entry needs updating to point +to the new parent (though I don't make use of the info) and the DV needs +incrementing by 1 to reflect the change of content. The server also sends +a callback break notification on the subdirectory if we have one, but we +can take care of recovering the promise next time we access the subdir. + +This can be triggered by something like: + + mount -t afs %example.com:xfstest.test20 /xfstest.test/ + mkdir /xfstest.test/{aaa,bbb,aaa/ccc} + touch /xfstest.test/bbb/ccc/d + mv /xfstest.test/{aaa/ccc,bbb/ccc} + touch /xfstest.test/bbb/ccc/e + +When the pathwalk for the second touch hits "ccc", kafs spots that the DV +is incorrect and downloads it again (so the fix is not critical). + +Fix this, if the rename target is a directory and the old and new +parents are different, by: + + (1) Incrementing the DV number of the target locally. + + (2) Editing the ".." entry in the target to refer to its new parent's + vnode ID and uniquifier. + +Link: https://lore.kernel.org/r/3340431.1729680010@warthog.procyon.org.uk +Fixes: 63a4681ff39c ("afs: Locally edit directory data for mkdir/create/unlink/...") +cc: David Howells +cc: Marc Dionne +cc: linux-afs@lists.infradead.org +Signed-off-by: David Howells +Signed-off-by: Christian Brauner +Signed-off-by: Sasha Levin +--- + fs/afs/dir.c | 25 +++++++++++ + fs/afs/dir_edit.c | 91 +++++++++++++++++++++++++++++++++++++- + fs/afs/internal.h | 2 + + include/trace/events/afs.h | 7 ++- + 4 files changed, 122 insertions(+), 3 deletions(-) + +diff --git a/fs/afs/dir.c b/fs/afs/dir.c +index 07dc4ec73520c..38d5260c4614f 100644 +--- a/fs/afs/dir.c ++++ b/fs/afs/dir.c +@@ -12,6 +12,7 @@ + #include + #include + #include ++#include + #include + #include "internal.h" + #include "afs_fs.h" +@@ -1808,6 +1809,8 @@ static int afs_symlink(struct user_namespace *mnt_userns, struct inode *dir, + + static void afs_rename_success(struct afs_operation *op) + { ++ struct afs_vnode *vnode = AFS_FS_I(d_inode(op->dentry)); ++ + _enter("op=%08x", op->debug_id); + + op->ctime = op->file[0].scb.status.mtime_client; +@@ -1817,6 +1820,22 @@ static void afs_rename_success(struct afs_operation *op) + op->ctime = op->file[1].scb.status.mtime_client; + afs_vnode_commit_status(op, &op->file[1]); + } ++ ++ /* If we're moving a subdir between dirs, we need to update ++ * its DV counter too as the ".." will be altered. ++ */ ++ if (S_ISDIR(vnode->netfs.inode.i_mode) && ++ op->file[0].vnode != op->file[1].vnode) { ++ u64 new_dv; ++ ++ write_seqlock(&vnode->cb_lock); ++ ++ new_dv = vnode->status.data_version + 1; ++ vnode->status.data_version = new_dv; ++ inode_set_iversion_raw(&vnode->netfs.inode, new_dv); ++ ++ write_sequnlock(&vnode->cb_lock); ++ } + } + + static void afs_rename_edit_dir(struct afs_operation *op) +@@ -1858,6 +1877,12 @@ static void afs_rename_edit_dir(struct afs_operation *op) + &vnode->fid, afs_edit_dir_for_rename_2); + } + ++ if (S_ISDIR(vnode->netfs.inode.i_mode) && ++ new_dvnode != orig_dvnode && ++ test_bit(AFS_VNODE_DIR_VALID, &vnode->flags)) ++ afs_edit_dir_update_dotdot(vnode, new_dvnode, ++ afs_edit_dir_for_rename_sub); ++ + new_inode = d_inode(new_dentry); + if (new_inode) { + spin_lock(&new_inode->i_lock); +diff --git a/fs/afs/dir_edit.c b/fs/afs/dir_edit.c +index 0ab7752d1b758..e22682c577302 100644 +--- a/fs/afs/dir_edit.c ++++ b/fs/afs/dir_edit.c +@@ -126,10 +126,10 @@ static struct folio *afs_dir_get_folio(struct afs_vnode *vnode, pgoff_t index) + /* + * Scan a directory block looking for a dirent of the right name. + */ +-static int afs_dir_scan_block(union afs_xdr_dir_block *block, struct qstr *name, ++static int afs_dir_scan_block(const union afs_xdr_dir_block *block, const struct qstr *name, + unsigned int blocknum) + { +- union afs_xdr_dirent *de; ++ const union afs_xdr_dirent *de; + u64 bitmap; + int d, len, n; + +@@ -491,3 +491,90 @@ void afs_edit_dir_remove(struct afs_vnode *vnode, + clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags); + goto out_unmap; + } ++ ++/* ++ * Edit a subdirectory that has been moved between directories to update the ++ * ".." entry. ++ */ ++void afs_edit_dir_update_dotdot(struct afs_vnode *vnode, struct afs_vnode *new_dvnode, ++ enum afs_edit_dir_reason why) ++{ ++ union afs_xdr_dir_block *block; ++ union afs_xdr_dirent *de; ++ struct folio *folio; ++ unsigned int nr_blocks, b; ++ pgoff_t index; ++ loff_t i_size; ++ int slot; ++ ++ _enter(""); ++ ++ i_size = i_size_read(&vnode->netfs.inode); ++ if (i_size < AFS_DIR_BLOCK_SIZE) { ++ clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags); ++ return; ++ } ++ nr_blocks = i_size / AFS_DIR_BLOCK_SIZE; ++ ++ /* Find a block that has sufficient slots available. Each folio ++ * contains two or more directory blocks. ++ */ ++ for (b = 0; b < nr_blocks; b++) { ++ index = b / AFS_DIR_BLOCKS_PER_PAGE; ++ folio = afs_dir_get_folio(vnode, index); ++ if (!folio) ++ goto error; ++ ++ block = kmap_local_folio(folio, b * AFS_DIR_BLOCK_SIZE - folio_pos(folio)); ++ ++ /* Abandon the edit if we got a callback break. */ ++ if (!test_bit(AFS_VNODE_DIR_VALID, &vnode->flags)) ++ goto invalidated; ++ ++ slot = afs_dir_scan_block(block, &dotdot_name, b); ++ if (slot >= 0) ++ goto found_dirent; ++ ++ kunmap_local(block); ++ folio_unlock(folio); ++ folio_put(folio); ++ } ++ ++ /* Didn't find the dirent to clobber. Download the directory again. */ ++ trace_afs_edit_dir(vnode, why, afs_edit_dir_update_nodd, ++ 0, 0, 0, 0, ".."); ++ clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags); ++ goto out; ++ ++found_dirent: ++ de = &block->dirents[slot]; ++ de->u.vnode = htonl(new_dvnode->fid.vnode); ++ de->u.unique = htonl(new_dvnode->fid.unique); ++ ++ trace_afs_edit_dir(vnode, why, afs_edit_dir_update_dd, b, slot, ++ ntohl(de->u.vnode), ntohl(de->u.unique), ".."); ++ ++ kunmap_local(block); ++ folio_unlock(folio); ++ folio_put(folio); ++ inode_set_iversion_raw(&vnode->netfs.inode, vnode->status.data_version); ++ ++out: ++ _leave(""); ++ return; ++ ++invalidated: ++ kunmap_local(block); ++ folio_unlock(folio); ++ folio_put(folio); ++ trace_afs_edit_dir(vnode, why, afs_edit_dir_update_inval, ++ 0, 0, 0, 0, ".."); ++ clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags); ++ goto out; ++ ++error: ++ trace_afs_edit_dir(vnode, why, afs_edit_dir_update_error, ++ 0, 0, 0, 0, ".."); ++ clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags); ++ goto out; ++} +diff --git a/fs/afs/internal.h b/fs/afs/internal.h +index a25fdc3e52310..097d5a5f07b1a 100644 +--- a/fs/afs/internal.h ++++ b/fs/afs/internal.h +@@ -1043,6 +1043,8 @@ extern void afs_check_for_remote_deletion(struct afs_operation *); + extern void afs_edit_dir_add(struct afs_vnode *, struct qstr *, struct afs_fid *, + enum afs_edit_dir_reason); + extern void afs_edit_dir_remove(struct afs_vnode *, struct qstr *, enum afs_edit_dir_reason); ++void afs_edit_dir_update_dotdot(struct afs_vnode *vnode, struct afs_vnode *new_dvnode, ++ enum afs_edit_dir_reason why); + + /* + * dir_silly.c +diff --git a/include/trace/events/afs.h b/include/trace/events/afs.h +index 54d10c69e55ec..d1ee4272d1cb8 100644 +--- a/include/trace/events/afs.h ++++ b/include/trace/events/afs.h +@@ -295,7 +295,11 @@ enum yfs_cm_operation { + EM(afs_edit_dir_delete, "delete") \ + EM(afs_edit_dir_delete_error, "d_err ") \ + EM(afs_edit_dir_delete_inval, "d_invl") \ +- E_(afs_edit_dir_delete_noent, "d_nent") ++ EM(afs_edit_dir_delete_noent, "d_nent") \ ++ EM(afs_edit_dir_update_dd, "u_ddot") \ ++ EM(afs_edit_dir_update_error, "u_fail") \ ++ EM(afs_edit_dir_update_inval, "u_invl") \ ++ E_(afs_edit_dir_update_nodd, "u_nodd") + + #define afs_edit_dir_reasons \ + EM(afs_edit_dir_for_create, "Create") \ +@@ -304,6 +308,7 @@ enum yfs_cm_operation { + EM(afs_edit_dir_for_rename_0, "Renam0") \ + EM(afs_edit_dir_for_rename_1, "Renam1") \ + EM(afs_edit_dir_for_rename_2, "Renam2") \ ++ EM(afs_edit_dir_for_rename_sub, "RnmSub") \ + EM(afs_edit_dir_for_rmdir, "RmDir ") \ + EM(afs_edit_dir_for_silly_0, "S_Ren0") \ + EM(afs_edit_dir_for_silly_1, "S_Ren1") \ +-- +2.43.0 + diff --git a/queue-6.1/compiler-gcc-be-consistent-with-underscores-use-for-.patch b/queue-6.1/compiler-gcc-be-consistent-with-underscores-use-for-.patch new file mode 100644 index 00000000000..74a853c37fa --- /dev/null +++ b/queue-6.1/compiler-gcc-be-consistent-with-underscores-use-for-.patch @@ -0,0 +1,73 @@ +From 881113d5093ecf77054b92382666275be8d1d316 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Oct 2022 13:59:52 +0200 +Subject: compiler-gcc: be consistent with underscores use for `no_sanitize` + +From: Miguel Ojeda + +[ Upstream commit 6e2be1f2ebcea42ed6044432f72f32434e60b34d ] + +Patch series "compiler-gcc: be consistent with underscores use for +`no_sanitize`". + +This patch (of 5): + +Other macros that define shorthands for attributes in e.g. +`compiler_attributes.h` and elsewhere use underscores. + +Link: https://lkml.kernel.org/r/20221021115956.9947-1-ojeda@kernel.org +Signed-off-by: Miguel Ojeda +Reviewed-by: Nathan Chancellor +Cc: Marco Elver +Cc: Alexander Potapenko +Cc: Andrey Konovalov +Cc: Arnd Bergmann +Cc: Dan Li +Cc: Kees Cook +Cc: Kumar Kartikeya Dwivedi +Cc: Nick Desaulniers +Cc: Uros Bizjak +Signed-off-by: Andrew Morton +Stable-dep-of: 894b00a3350c ("kasan: Fix Software Tag-Based KASAN with GCC") +Signed-off-by: Sasha Levin +--- + include/linux/compiler-gcc.h | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h +index 149a520515e1d..e6474899250d5 100644 +--- a/include/linux/compiler-gcc.h ++++ b/include/linux/compiler-gcc.h +@@ -103,25 +103,25 @@ + #endif + + #if __has_attribute(__no_sanitize_address__) +-#define __no_sanitize_address __attribute__((no_sanitize_address)) ++#define __no_sanitize_address __attribute__((__no_sanitize_address__)) + #else + #define __no_sanitize_address + #endif + + #if defined(__SANITIZE_THREAD__) && __has_attribute(__no_sanitize_thread__) +-#define __no_sanitize_thread __attribute__((no_sanitize_thread)) ++#define __no_sanitize_thread __attribute__((__no_sanitize_thread__)) + #else + #define __no_sanitize_thread + #endif + + #if __has_attribute(__no_sanitize_undefined__) +-#define __no_sanitize_undefined __attribute__((no_sanitize_undefined)) ++#define __no_sanitize_undefined __attribute__((__no_sanitize_undefined__)) + #else + #define __no_sanitize_undefined + #endif + + #if defined(CONFIG_KCOV) && __has_attribute(__no_sanitize_coverage__) +-#define __no_sanitize_coverage __attribute__((no_sanitize_coverage)) ++#define __no_sanitize_coverage __attribute__((__no_sanitize_coverage__)) + #else + #define __no_sanitize_coverage + #endif +-- +2.43.0 + diff --git a/queue-6.1/compiler-gcc-remove-attribute-support-check-for-__no.patch b/queue-6.1/compiler-gcc-remove-attribute-support-check-for-__no.patch new file mode 100644 index 00000000000..8b8b6b71961 --- /dev/null +++ b/queue-6.1/compiler-gcc-remove-attribute-support-check-for-__no.patch @@ -0,0 +1,54 @@ +From dc3458105861adfb69b9abb03bb2d00b7dd59bfa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Oct 2022 13:59:53 +0200 +Subject: compiler-gcc: remove attribute support check for + `__no_sanitize_address__` + +From: Miguel Ojeda + +[ Upstream commit ae37a9a2c2d0960d643d782b426ea1aa9c05727a ] + +The attribute was added in GCC 4.8, while the minimum GCC version +supported by the kernel is GCC 5.1. + +Therefore, remove the check. + +Link: https://godbolt.org/z/84v56vcn8 +Link: https://lkml.kernel.org/r/20221021115956.9947-2-ojeda@kernel.org +Signed-off-by: Miguel Ojeda +Reviewed-by: Nathan Chancellor +Cc: Alexander Potapenko +Cc: Andrey Konovalov +Cc: Arnd Bergmann +Cc: Dan Li +Cc: Kees Cook +Cc: Kumar Kartikeya Dwivedi +Cc: Marco Elver +Cc: Nick Desaulniers +Cc: Uros Bizjak +Signed-off-by: Andrew Morton +Stable-dep-of: 894b00a3350c ("kasan: Fix Software Tag-Based KASAN with GCC") +Signed-off-by: Sasha Levin +--- + include/linux/compiler-gcc.h | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h +index e6474899250d5..b6050483ba421 100644 +--- a/include/linux/compiler-gcc.h ++++ b/include/linux/compiler-gcc.h +@@ -102,11 +102,7 @@ + #define __noscs __attribute__((__no_sanitize__("shadow-call-stack"))) + #endif + +-#if __has_attribute(__no_sanitize_address__) + #define __no_sanitize_address __attribute__((__no_sanitize_address__)) +-#else +-#define __no_sanitize_address +-#endif + + #if defined(__SANITIZE_THREAD__) && __has_attribute(__no_sanitize_thread__) + #define __no_sanitize_thread __attribute__((__no_sanitize_thread__)) +-- +2.43.0 + diff --git a/queue-6.1/firmware-arm_sdei-fix-the-input-parameter-of-cpuhp_r.patch b/queue-6.1/firmware-arm_sdei-fix-the-input-parameter-of-cpuhp_r.patch new file mode 100644 index 00000000000..ff399e41add --- /dev/null +++ b/queue-6.1/firmware-arm_sdei-fix-the-input-parameter-of-cpuhp_r.patch @@ -0,0 +1,38 @@ +From 96fae6cbe4ec74405c53d54129dfafc143ce0993 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 16 Oct 2024 16:47:40 +0800 +Subject: firmware: arm_sdei: Fix the input parameter of cpuhp_remove_state() + +From: Xiongfeng Wang + +[ Upstream commit c83212d79be2c9886d3e6039759ecd388fd5fed1 ] + +In sdei_device_freeze(), the input parameter of cpuhp_remove_state() is +passed as 'sdei_entry_point' by mistake. Change it to 'sdei_hp_state'. + +Fixes: d2c48b2387eb ("firmware: arm_sdei: Fix sleep from invalid context BUG") +Signed-off-by: Xiongfeng Wang +Reviewed-by: James Morse +Link: https://lore.kernel.org/r/20241016084740.183353-1-wangxiongfeng2@huawei.com +Signed-off-by: Will Deacon +Signed-off-by: Sasha Levin +--- + drivers/firmware/arm_sdei.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/firmware/arm_sdei.c b/drivers/firmware/arm_sdei.c +index 285fe7ad490d1..3e8051fe82965 100644 +--- a/drivers/firmware/arm_sdei.c ++++ b/drivers/firmware/arm_sdei.c +@@ -763,7 +763,7 @@ static int sdei_device_freeze(struct device *dev) + int err; + + /* unregister private events */ +- cpuhp_remove_state(sdei_entry_point); ++ cpuhp_remove_state(sdei_hp_state); + + err = sdei_unregister_shared(); + if (err) +-- +2.43.0 + diff --git a/queue-6.1/fsdax-dax_unshare_iter-needs-to-copy-entire-blocks.patch b/queue-6.1/fsdax-dax_unshare_iter-needs-to-copy-entire-blocks.patch new file mode 100644 index 00000000000..92ba737ccd6 --- /dev/null +++ b/queue-6.1/fsdax-dax_unshare_iter-needs-to-copy-entire-blocks.patch @@ -0,0 +1,112 @@ +From bd7aa22e707813ab819ab022c50b9c6739bd4644 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 3 Oct 2024 08:09:48 -0700 +Subject: fsdax: dax_unshare_iter needs to copy entire blocks + +From: Darrick J. Wong + +[ Upstream commit 50793801fc7f6d08def48754fb0f0706b0cfc394 ] + +The code that copies data from srcmap to iomap in dax_unshare_iter is +very very broken, which bfoster's recent fsx changes have exposed. + +If the pos and len passed to dax_file_unshare are not aligned to an +fsblock boundary, the iter pos and length in the _iter function will +reflect this unalignment. + +dax_iomap_direct_access always returns a pointer to the start of the +kmapped fsdax page, even if its pos argument is in the middle of that +page. This is catastrophic for data integrity when iter->pos is not +aligned to a page, because daddr/saddr do not point to the same byte in +the file as iter->pos. Hence we corrupt user data by copying it to the +wrong place. + +If iter->pos + iomap_length() in the _iter function not aligned to a +page, then we fail to copy a full block, and only partially populate the +destination block. This is catastrophic for data confidentiality +because we expose stale pmem contents. + +Fix both of these issues by aligning copy_pos/copy_len to a page +boundary (remember, this is fsdax so 1 fsblock == 1 base page) so that +we always copy full blocks. + +We're not done yet -- there's no call to invalidate_inode_pages2_range, +so programs that have the file range mmap'd will continue accessing the +old memory mapping after the file metadata updates have completed. + +Be careful with the return value -- if the unshare succeeds, we still +need to return the number of bytes that the iomap iter thinks we're +operating on. + +Cc: ruansy.fnst@fujitsu.com +Fixes: d984648e428b ("fsdax,xfs: port unshare to fsdax") +Signed-off-by: Darrick J. Wong +Link: https://lore.kernel.org/r/172796813328.1131942.16777025316348797355.stgit@frogsfrogsfrogs +Reviewed-by: Christoph Hellwig +Signed-off-by: Christian Brauner +Signed-off-by: Sasha Levin +--- + fs/dax.c | 34 +++++++++++++++++++++++++++------- + 1 file changed, 27 insertions(+), 7 deletions(-) + +diff --git a/fs/dax.c b/fs/dax.c +index fa5a82b27c2f6..ca7138bb1d545 100644 +--- a/fs/dax.c ++++ b/fs/dax.c +@@ -1225,26 +1225,46 @@ static s64 dax_unshare_iter(struct iomap_iter *iter) + { + struct iomap *iomap = &iter->iomap; + const struct iomap *srcmap = iomap_iter_srcmap(iter); +- loff_t pos = iter->pos; +- loff_t length = iomap_length(iter); ++ loff_t copy_pos = iter->pos; ++ u64 copy_len = iomap_length(iter); ++ u32 mod; + int id = 0; + s64 ret = 0; + void *daddr = NULL, *saddr = NULL; + + if (!iomap_want_unshare_iter(iter)) +- return length; ++ return iomap_length(iter); ++ ++ /* ++ * Extend the file range to be aligned to fsblock/pagesize, because ++ * we need to copy entire blocks, not just the byte range specified. ++ * Invalidate the mapping because we're about to CoW. ++ */ ++ mod = offset_in_page(copy_pos); ++ if (mod) { ++ copy_len += mod; ++ copy_pos -= mod; ++ } ++ ++ mod = offset_in_page(copy_pos + copy_len); ++ if (mod) ++ copy_len += PAGE_SIZE - mod; ++ ++ invalidate_inode_pages2_range(iter->inode->i_mapping, ++ copy_pos >> PAGE_SHIFT, ++ (copy_pos + copy_len - 1) >> PAGE_SHIFT); + + id = dax_read_lock(); +- ret = dax_iomap_direct_access(iomap, pos, length, &daddr, NULL); ++ ret = dax_iomap_direct_access(iomap, copy_pos, copy_len, &daddr, NULL); + if (ret < 0) + goto out_unlock; + +- ret = dax_iomap_direct_access(srcmap, pos, length, &saddr, NULL); ++ ret = dax_iomap_direct_access(srcmap, copy_pos, copy_len, &saddr, NULL); + if (ret < 0) + goto out_unlock; + +- if (copy_mc_to_kernel(daddr, saddr, length) == 0) +- ret = length; ++ if (copy_mc_to_kernel(daddr, saddr, copy_len) == 0) ++ ret = iomap_length(iter); + else + ret = -EIO; + +-- +2.43.0 + diff --git a/queue-6.1/fsdax-remove-zeroing-code-from-dax_unshare_iter.patch b/queue-6.1/fsdax-remove-zeroing-code-from-dax_unshare_iter.patch new file mode 100644 index 00000000000..4521fb9e96f --- /dev/null +++ b/queue-6.1/fsdax-remove-zeroing-code-from-dax_unshare_iter.patch @@ -0,0 +1,55 @@ +From 4c2a4388a5fb0bc71c13e1ae370ad491487698de Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 3 Oct 2024 08:09:32 -0700 +Subject: fsdax: remove zeroing code from dax_unshare_iter + +From: Darrick J. Wong + +[ Upstream commit 95472274b6fed8f2d30fbdda304e12174b3d4099 ] + +Remove the code in dax_unshare_iter that zeroes the destination memory +because it's not necessary. + +If srcmap is unwritten, we don't have to do anything because that +unwritten extent came from the regular file mapping, and unwritten +extents cannot be shared. The same applies to holes. + +Furthermore, zeroing to unshare a mapping is just plain wrong because +unsharing means copy on write, and we should be copying data. + +This is effectively a revert of commit 13dd4e04625f ("fsdax: unshare: +zero destination if srcmap is HOLE or UNWRITTEN") + +Cc: ruansy.fnst@fujitsu.com +Signed-off-by: Darrick J. Wong +Link: https://lore.kernel.org/r/172796813311.1131942.16033376284752798632.stgit@frogsfrogsfrogs +Reviewed-by: Christoph Hellwig +Signed-off-by: Christian Brauner +Stable-dep-of: 50793801fc7f ("fsdax: dax_unshare_iter needs to copy entire blocks") +Signed-off-by: Sasha Levin +--- + fs/dax.c | 8 -------- + 1 file changed, 8 deletions(-) + +diff --git a/fs/dax.c b/fs/dax.c +index 74f9a14565f59..fa5a82b27c2f6 100644 +--- a/fs/dax.c ++++ b/fs/dax.c +@@ -1239,14 +1239,6 @@ static s64 dax_unshare_iter(struct iomap_iter *iter) + if (ret < 0) + goto out_unlock; + +- /* zero the distance if srcmap is HOLE or UNWRITTEN */ +- if (srcmap->flags & IOMAP_F_SHARED || srcmap->type == IOMAP_UNWRITTEN) { +- memset(daddr, 0, length); +- dax_flush(iomap->dax_dev, daddr, length); +- ret = length; +- goto out_unlock; +- } +- + ret = dax_iomap_direct_access(srcmap, pos, length, &saddr, NULL); + if (ret < 0) + goto out_unlock; +-- +2.43.0 + diff --git a/queue-6.1/iomap-convert-iomap_unshare_iter-to-use-large-folios.patch b/queue-6.1/iomap-convert-iomap_unshare_iter-to-use-large-folios.patch new file mode 100644 index 00000000000..ec1c5dae8a8 --- /dev/null +++ b/queue-6.1/iomap-convert-iomap_unshare_iter-to-use-large-folios.patch @@ -0,0 +1,80 @@ +From b6ed4dea69fe6fb15a973c1c557cc4013ae325df Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 18 Sep 2023 15:57:40 -0700 +Subject: iomap: convert iomap_unshare_iter to use large folios + +From: Darrick J. Wong + +[ Upstream commit a5f31a5028d1e88e97c3b6cdc3e3bf2da085e232 ] + +Convert iomap_unshare_iter to create large folios if possible, since the +write and zeroing paths already do that. I think this got missed in the +conversion of the write paths that landed in 6.6-rc1. + +Cc: ritesh.list@gmail.com, willy@infradead.org +Signed-off-by: Darrick J. Wong +Reviewed-by: Ritesh Harjani (IBM) +Stable-dep-of: 50793801fc7f ("fsdax: dax_unshare_iter needs to copy entire blocks") +Signed-off-by: Sasha Levin +--- + fs/iomap/buffered-io.c | 24 ++++++++++++++---------- + 1 file changed, 14 insertions(+), 10 deletions(-) + +diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c +index 1833608f39318..674ac79bdb456 100644 +--- a/fs/iomap/buffered-io.c ++++ b/fs/iomap/buffered-io.c +@@ -1090,7 +1090,6 @@ static loff_t iomap_unshare_iter(struct iomap_iter *iter) + const struct iomap *srcmap = iomap_iter_srcmap(iter); + loff_t pos = iter->pos; + loff_t length = iomap_length(iter); +- long status = 0; + loff_t written = 0; + + /* don't bother with blocks that are not shared to start with */ +@@ -1101,28 +1100,33 @@ static loff_t iomap_unshare_iter(struct iomap_iter *iter) + return length; + + do { +- unsigned long offset = offset_in_page(pos); +- unsigned long bytes = min_t(loff_t, PAGE_SIZE - offset, length); + struct folio *folio; ++ int status; ++ size_t offset; ++ size_t bytes = min_t(u64, SIZE_MAX, length); + + status = iomap_write_begin(iter, pos, bytes, &folio); + if (unlikely(status)) + return status; +- if (iter->iomap.flags & IOMAP_F_STALE) ++ if (iomap->flags & IOMAP_F_STALE) + break; + +- status = iomap_write_end(iter, pos, bytes, bytes, folio); +- if (WARN_ON_ONCE(status == 0)) ++ offset = offset_in_folio(folio, pos); ++ if (bytes > folio_size(folio) - offset) ++ bytes = folio_size(folio) - offset; ++ ++ bytes = iomap_write_end(iter, pos, bytes, bytes, folio); ++ if (WARN_ON_ONCE(bytes == 0)) + return -EIO; + + cond_resched(); + +- pos += status; +- written += status; +- length -= status; ++ pos += bytes; ++ written += bytes; ++ length -= bytes; + + balance_dirty_pages_ratelimited(iter->inode->i_mapping); +- } while (length); ++ } while (length > 0); + + return written; + } +-- +2.43.0 + diff --git a/queue-6.1/iomap-don-t-bother-unsharing-delalloc-extents.patch b/queue-6.1/iomap-don-t-bother-unsharing-delalloc-extents.patch new file mode 100644 index 00000000000..e62f5e26d32 --- /dev/null +++ b/queue-6.1/iomap-don-t-bother-unsharing-delalloc-extents.patch @@ -0,0 +1,48 @@ +From 754c8ca84954da928cee758893700ae64add81a0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 2 Oct 2024 08:00:40 -0700 +Subject: iomap: don't bother unsharing delalloc extents + +From: Darrick J. Wong + +[ Upstream commit f7a4874d977bf4202ad575031222e78809a36292 ] + +If unshare encounters a delalloc reservation in the srcmap, that means +that the file range isn't shared because delalloc reservations cannot be +reflinked. Therefore, don't try to unshare them. + +Signed-off-by: Darrick J. Wong +Link: https://lore.kernel.org/r/20241002150040.GB21853@frogsfrogsfrogs +Reviewed-by: Christoph Hellwig +Reviewed-by: Brian Foster +Signed-off-by: Christian Brauner +Stable-dep-of: 50793801fc7f ("fsdax: dax_unshare_iter needs to copy entire blocks") +Signed-off-by: Sasha Levin +--- + fs/iomap/buffered-io.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c +index 527d3bcfc69a7..b1af9001e6db0 100644 +--- a/fs/iomap/buffered-io.c ++++ b/fs/iomap/buffered-io.c +@@ -1096,7 +1096,7 @@ static loff_t iomap_unshare_iter(struct iomap_iter *iter) + return length; + + /* +- * Don't bother with holes or unwritten extents. ++ * Don't bother with delalloc reservations, holes or unwritten extents. + * + * Note that we use srcmap directly instead of iomap_iter_srcmap as + * unsharing requires providing a separate source map, and the presence +@@ -1105,6 +1105,7 @@ static loff_t iomap_unshare_iter(struct iomap_iter *iter) + * fork for XFS. + */ + if (iter->srcmap.type == IOMAP_HOLE || ++ iter->srcmap.type == IOMAP_DELALLOC || + iter->srcmap.type == IOMAP_UNWRITTEN) + return length; + +-- +2.43.0 + diff --git a/queue-6.1/iomap-improve-shared-block-detection-in-iomap_unshar.patch b/queue-6.1/iomap-improve-shared-block-detection-in-iomap_unshar.patch new file mode 100644 index 00000000000..793ba4f4fc4 --- /dev/null +++ b/queue-6.1/iomap-improve-shared-block-detection-in-iomap_unshar.patch @@ -0,0 +1,69 @@ +From e960ddf9a5870e1e981815fdccc4ca825e72a367 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Sep 2024 07:39:04 +0300 +Subject: iomap: improve shared block detection in iomap_unshare_iter + +From: Christoph Hellwig + +[ Upstream commit b53fdb215d13f8e9c29541434bf2d14dac8bcbdc ] + +Currently iomap_unshare_iter relies on the IOMAP_F_SHARED flag to detect +blocks to unshare. This is reasonable, but IOMAP_F_SHARED is also useful +for the file system to do internal book keeping for out of place writes. +XFS used to that, until it got removed in commit 72a048c1056a +("xfs: only set IOMAP_F_SHARED when providing a srcmap to a write") +because unshare for incorrectly unshare such blocks. + +Add an extra safeguard by checking the explicitly provided srcmap instead +of the fallback to the iomap for valid data, as that catches the case +where we'd just copy from the same place we'd write to easily, allowing +to reinstate setting IOMAP_F_SHARED for all XFS writes that go to the +COW fork. + +Signed-off-by: Christoph Hellwig +Link: https://lore.kernel.org/r/20240910043949.3481298-3-hch@lst.de +Reviewed-by: Darrick J. Wong +Signed-off-by: Christian Brauner +Stable-dep-of: 50793801fc7f ("fsdax: dax_unshare_iter needs to copy entire blocks") +Signed-off-by: Sasha Levin +--- + fs/iomap/buffered-io.c | 17 +++++++++++++---- + 1 file changed, 13 insertions(+), 4 deletions(-) + +diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c +index 674ac79bdb456..527d3bcfc69a7 100644 +--- a/fs/iomap/buffered-io.c ++++ b/fs/iomap/buffered-io.c +@@ -1087,16 +1087,25 @@ EXPORT_SYMBOL_GPL(iomap_file_buffered_write_punch_delalloc); + static loff_t iomap_unshare_iter(struct iomap_iter *iter) + { + struct iomap *iomap = &iter->iomap; +- const struct iomap *srcmap = iomap_iter_srcmap(iter); + loff_t pos = iter->pos; + loff_t length = iomap_length(iter); + loff_t written = 0; + +- /* don't bother with blocks that are not shared to start with */ ++ /* Don't bother with blocks that are not shared to start with. */ + if (!(iomap->flags & IOMAP_F_SHARED)) + return length; +- /* don't bother with holes or unwritten extents */ +- if (srcmap->type == IOMAP_HOLE || srcmap->type == IOMAP_UNWRITTEN) ++ ++ /* ++ * Don't bother with holes or unwritten extents. ++ * ++ * Note that we use srcmap directly instead of iomap_iter_srcmap as ++ * unsharing requires providing a separate source map, and the presence ++ * of one is a good indicator that unsharing is needed, unlike ++ * IOMAP_F_SHARED which can be set for any data that goes into the COW ++ * fork for XFS. ++ */ ++ if (iter->srcmap.type == IOMAP_HOLE || ++ iter->srcmap.type == IOMAP_UNWRITTEN) + return length; + + do { +-- +2.43.0 + diff --git a/queue-6.1/iomap-share-iomap_unshare_iter-predicate-code-with-f.patch b/queue-6.1/iomap-share-iomap_unshare_iter-predicate-code-with-f.patch new file mode 100644 index 00000000000..c8ef32f33e1 --- /dev/null +++ b/queue-6.1/iomap-share-iomap_unshare_iter-predicate-code-with-f.patch @@ -0,0 +1,111 @@ +From a3cfed037d67f9823da1291dd36d10fe9e44539c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 3 Oct 2024 08:09:16 -0700 +Subject: iomap: share iomap_unshare_iter predicate code with fsdax + +From: Darrick J. Wong + +[ Upstream commit 6ef6a0e821d3dad6bf8a5d5508762dba9042c84b ] + +The predicate code that iomap_unshare_iter uses to decide if it's really +needs to unshare a file range mapping should be shared with the fsdax +version, because right now they're opencoded and inconsistent. + +Note that we simplify the predicate logic a bit -- we no longer allow +unsharing of inline data mappings, but there aren't any filesystems that +allow shared inline data currently. + +This is a fix in the sense that it should have been ported to fsdax. + +Fixes: b53fdb215d13 ("iomap: improve shared block detection in iomap_unshare_iter") +Signed-off-by: Darrick J. Wong +Link: https://lore.kernel.org/r/172796813294.1131942.15762084021076932620.stgit@frogsfrogsfrogs +Reviewed-by: Christoph Hellwig +Signed-off-by: Christian Brauner +Stable-dep-of: 50793801fc7f ("fsdax: dax_unshare_iter needs to copy entire blocks") +Signed-off-by: Sasha Levin +--- + fs/dax.c | 3 +-- + fs/iomap/buffered-io.c | 30 ++++++++++++++++-------------- + include/linux/iomap.h | 1 + + 3 files changed, 18 insertions(+), 16 deletions(-) + +diff --git a/fs/dax.c b/fs/dax.c +index 72a437892b4a4..74f9a14565f59 100644 +--- a/fs/dax.c ++++ b/fs/dax.c +@@ -1231,8 +1231,7 @@ static s64 dax_unshare_iter(struct iomap_iter *iter) + s64 ret = 0; + void *daddr = NULL, *saddr = NULL; + +- /* don't bother with blocks that are not shared to start with */ +- if (!(iomap->flags & IOMAP_F_SHARED)) ++ if (!iomap_want_unshare_iter(iter)) + return length; + + id = dax_read_lock(); +diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c +index b1af9001e6db0..876273db711d1 100644 +--- a/fs/iomap/buffered-io.c ++++ b/fs/iomap/buffered-io.c +@@ -1084,19 +1084,12 @@ int iomap_file_buffered_write_punch_delalloc(struct inode *inode, + } + EXPORT_SYMBOL_GPL(iomap_file_buffered_write_punch_delalloc); + +-static loff_t iomap_unshare_iter(struct iomap_iter *iter) ++bool iomap_want_unshare_iter(const struct iomap_iter *iter) + { +- struct iomap *iomap = &iter->iomap; +- loff_t pos = iter->pos; +- loff_t length = iomap_length(iter); +- loff_t written = 0; +- +- /* Don't bother with blocks that are not shared to start with. */ +- if (!(iomap->flags & IOMAP_F_SHARED)) +- return length; +- + /* +- * Don't bother with delalloc reservations, holes or unwritten extents. ++ * Don't bother with blocks that are not shared to start with; or ++ * mappings that cannot be shared, such as inline data, delalloc ++ * reservations, holes or unwritten extents. + * + * Note that we use srcmap directly instead of iomap_iter_srcmap as + * unsharing requires providing a separate source map, and the presence +@@ -1104,9 +1097,18 @@ static loff_t iomap_unshare_iter(struct iomap_iter *iter) + * IOMAP_F_SHARED which can be set for any data that goes into the COW + * fork for XFS. + */ +- if (iter->srcmap.type == IOMAP_HOLE || +- iter->srcmap.type == IOMAP_DELALLOC || +- iter->srcmap.type == IOMAP_UNWRITTEN) ++ return (iter->iomap.flags & IOMAP_F_SHARED) && ++ iter->srcmap.type == IOMAP_MAPPED; ++} ++ ++static loff_t iomap_unshare_iter(struct iomap_iter *iter) ++{ ++ struct iomap *iomap = &iter->iomap; ++ loff_t pos = iter->pos; ++ loff_t length = iomap_length(iter); ++ loff_t written = 0; ++ ++ if (!iomap_want_unshare_iter(iter)) + return length; + + do { +diff --git a/include/linux/iomap.h b/include/linux/iomap.h +index 0983dfc9a203c..0a37b54e24926 100644 +--- a/include/linux/iomap.h ++++ b/include/linux/iomap.h +@@ -264,6 +264,7 @@ bool iomap_release_folio(struct folio *folio, gfp_t gfp_flags); + void iomap_invalidate_folio(struct folio *folio, size_t offset, size_t len); + int iomap_file_unshare(struct inode *inode, loff_t pos, loff_t len, + const struct iomap_ops *ops); ++bool iomap_want_unshare_iter(const struct iomap_iter *iter); + int iomap_zero_range(struct inode *inode, loff_t pos, loff_t len, + bool *did_zero, const struct iomap_ops *ops); + int iomap_truncate_page(struct inode *inode, loff_t pos, bool *did_zero, +-- +2.43.0 + diff --git a/queue-6.1/iomap-turn-iomap_want_unshare_iter-into-an-inline-fu.patch b/queue-6.1/iomap-turn-iomap_want_unshare_iter-into-an-inline-fu.patch new file mode 100644 index 00000000000..6ee970648a4 --- /dev/null +++ b/queue-6.1/iomap-turn-iomap_want_unshare_iter-into-an-inline-fu.patch @@ -0,0 +1,98 @@ +From 6867f8cfd3e33f545c3150b8453db5ff809f0738 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 15 Oct 2024 06:13:50 +0200 +Subject: iomap: turn iomap_want_unshare_iter into an inline function +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Christoph Hellwig + +[ Upstream commit 6db388585e486c0261aeef55f8bc63a9b45756c0 ] + +iomap_want_unshare_iter currently sits in fs/iomap/buffered-io.c, which +depends on CONFIG_BLOCK. It is also in used in fs/dax.c whіch has no +such dependency. Given that it is a trivial check turn it into an inline +in include/linux/iomap.h to fix the DAX && !BLOCK build. + +Fixes: 6ef6a0e821d3 ("iomap: share iomap_unshare_iter predicate code with fsdax") +Reported-by: kernel test robot +Signed-off-by: Christoph Hellwig +Link: https://lore.kernel.org/r/20241015041350.118403-1-hch@lst.de +Reviewed-by: Brian Foster +Signed-off-by: Christian Brauner +Signed-off-by: Sasha Levin +--- + fs/iomap/buffered-io.c | 17 ----------------- + include/linux/iomap.h | 20 +++++++++++++++++++- + 2 files changed, 19 insertions(+), 18 deletions(-) + +diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c +index 876273db711d1..47f44b02c17de 100644 +--- a/fs/iomap/buffered-io.c ++++ b/fs/iomap/buffered-io.c +@@ -1084,23 +1084,6 @@ int iomap_file_buffered_write_punch_delalloc(struct inode *inode, + } + EXPORT_SYMBOL_GPL(iomap_file_buffered_write_punch_delalloc); + +-bool iomap_want_unshare_iter(const struct iomap_iter *iter) +-{ +- /* +- * Don't bother with blocks that are not shared to start with; or +- * mappings that cannot be shared, such as inline data, delalloc +- * reservations, holes or unwritten extents. +- * +- * Note that we use srcmap directly instead of iomap_iter_srcmap as +- * unsharing requires providing a separate source map, and the presence +- * of one is a good indicator that unsharing is needed, unlike +- * IOMAP_F_SHARED which can be set for any data that goes into the COW +- * fork for XFS. +- */ +- return (iter->iomap.flags & IOMAP_F_SHARED) && +- iter->srcmap.type == IOMAP_MAPPED; +-} +- + static loff_t iomap_unshare_iter(struct iomap_iter *iter) + { + struct iomap *iomap = &iter->iomap; +diff --git a/include/linux/iomap.h b/include/linux/iomap.h +index 0a37b54e24926..1de65d5d79d4d 100644 +--- a/include/linux/iomap.h ++++ b/include/linux/iomap.h +@@ -251,6 +251,25 @@ static inline const struct iomap *iomap_iter_srcmap(const struct iomap_iter *i) + return &i->iomap; + } + ++/* ++ * Check if the range needs to be unshared for a FALLOC_FL_UNSHARE_RANGE ++ * operation. ++ * ++ * Don't bother with blocks that are not shared to start with; or mappings that ++ * cannot be shared, such as inline data, delalloc reservations, holes or ++ * unwritten extents. ++ * ++ * Note that we use srcmap directly instead of iomap_iter_srcmap as unsharing ++ * requires providing a separate source map, and the presence of one is a good ++ * indicator that unsharing is needed, unlike IOMAP_F_SHARED which can be set ++ * for any data that goes into the COW fork for XFS. ++ */ ++static inline bool iomap_want_unshare_iter(const struct iomap_iter *iter) ++{ ++ return (iter->iomap.flags & IOMAP_F_SHARED) && ++ iter->srcmap.type == IOMAP_MAPPED; ++} ++ + ssize_t iomap_file_buffered_write(struct kiocb *iocb, struct iov_iter *from, + const struct iomap_ops *ops); + int iomap_file_buffered_write_punch_delalloc(struct inode *inode, +@@ -264,7 +283,6 @@ bool iomap_release_folio(struct folio *folio, gfp_t gfp_flags); + void iomap_invalidate_folio(struct folio *folio, size_t offset, size_t len); + int iomap_file_unshare(struct inode *inode, loff_t pos, loff_t len, + const struct iomap_ops *ops); +-bool iomap_want_unshare_iter(const struct iomap_iter *iter); + int iomap_zero_range(struct inode *inode, loff_t pos, loff_t len, + bool *did_zero, const struct iomap_ops *ops); + int iomap_truncate_page(struct inode *inode, loff_t pos, bool *did_zero, +-- +2.43.0 + diff --git a/queue-6.1/kasan-fix-software-tag-based-kasan-with-gcc.patch b/queue-6.1/kasan-fix-software-tag-based-kasan-with-gcc.patch new file mode 100644 index 00000000000..ac1e1dcfcd0 --- /dev/null +++ b/queue-6.1/kasan-fix-software-tag-based-kasan-with-gcc.patch @@ -0,0 +1,53 @@ +From 0087f6b4d493a3985bee4d65ae2f8de3f6e5627c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 21 Oct 2024 14:00:10 +0200 +Subject: kasan: Fix Software Tag-Based KASAN with GCC + +From: Marco Elver + +[ Upstream commit 894b00a3350c560990638bdf89bdf1f3d5491950 ] + +Per [1], -fsanitize=kernel-hwaddress with GCC currently does not disable +instrumentation in functions with __attribute__((no_sanitize_address)). + +However, __attribute__((no_sanitize("hwaddress"))) does correctly +disable instrumentation. Use it instead. + +Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117196 [1] +Link: https://lore.kernel.org/r/000000000000f362e80620e27859@google.com +Link: https://lore.kernel.org/r/ZvFGwKfoC4yVjN_X@J2N7QTR9R3 +Link: https://bugzilla.kernel.org/show_bug.cgi?id=218854 +Reported-by: syzbot+908886656a02769af987@syzkaller.appspotmail.com +Tested-by: Andrey Konovalov +Cc: Andrew Pinski +Cc: Mark Rutland +Cc: Will Deacon +Signed-off-by: Marco Elver +Reviewed-by: Andrey Konovalov +Fixes: 7b861a53e46b ("kasan: Bump required compiler version") +Link: https://lore.kernel.org/r/20241021120013.3209481-1-elver@google.com +Signed-off-by: Will Deacon +Signed-off-by: Sasha Levin +--- + include/linux/compiler-gcc.h | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h +index b6050483ba421..74dc72b2c3a74 100644 +--- a/include/linux/compiler-gcc.h ++++ b/include/linux/compiler-gcc.h +@@ -102,7 +102,11 @@ + #define __noscs __attribute__((__no_sanitize__("shadow-call-stack"))) + #endif + ++#ifdef __SANITIZE_HWADDRESS__ ++#define __no_sanitize_address __attribute__((__no_sanitize__("hwaddress"))) ++#else + #define __no_sanitize_address __attribute__((__no_sanitize_address__)) ++#endif + + #if defined(__SANITIZE_THREAD__) && __has_attribute(__no_sanitize_thread__) + #define __no_sanitize_thread __attribute__((__no_sanitize_thread__)) +-- +2.43.0 + diff --git a/queue-6.1/series b/queue-6.1/series index 61fa79c8059..cad49847f3e 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -39,3 +39,17 @@ net-hns3-fix-missing-features-due-to-dev-features-co.patch net-hns3-resolved-the-issue-that-the-debugfs-query-r.patch net-hns3-initialize-reset_timer-before-hclgevf_misc_.patch net-hns3-fix-kernel-crash-when-1588-is-sent-on-hip08.patch +iomap-convert-iomap_unshare_iter-to-use-large-folios.patch +iomap-improve-shared-block-detection-in-iomap_unshar.patch +iomap-don-t-bother-unsharing-delalloc-extents.patch +iomap-share-iomap_unshare_iter-predicate-code-with-f.patch +fsdax-remove-zeroing-code-from-dax_unshare_iter.patch +fsdax-dax_unshare_iter-needs-to-copy-entire-blocks.patch +iomap-turn-iomap_want_unshare_iter-into-an-inline-fu.patch +compiler-gcc-be-consistent-with-underscores-use-for-.patch +compiler-gcc-remove-attribute-support-check-for-__no.patch +kasan-fix-software-tag-based-kasan-with-gcc.patch +firmware-arm_sdei-fix-the-input-parameter-of-cpuhp_r.patch +afs-automatically-generate-trace-tag-enums.patch +afs-fix-missing-subdir-edit-when-renamed-between-par.patch +acpi-cppc-make-rmw_lock-a-raw_spin_lock.patch