From: Greg Kroah-Hartman Date: Thu, 22 Feb 2024 06:17:24 +0000 (+0100) Subject: drop some nfsd patches that were not needed X-Git-Tag: v4.19.307~6 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ac969ecef366532b2998cc4b3cc2eee9d0075c9c;p=thirdparty%2Fkernel%2Fstable-queue.git drop some nfsd patches that were not needed --- diff --git a/queue-5.10/nfsd-add-documenting-comment-for-nfsd4_release_locko.patch b/queue-5.10/nfsd-add-documenting-comment-for-nfsd4_release_locko.patch deleted file mode 100644 index 00d47109b5f..00000000000 --- a/queue-5.10/nfsd-add-documenting-comment-for-nfsd4_release_locko.patch +++ /dev/null @@ -1,73 +0,0 @@ -From a2cb252f9ce3c3a5d8e92e88b23550e02c0e0b22 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Sun, 22 May 2022 12:34:38 -0400 -Subject: NFSD: Add documenting comment for nfsd4_release_lockowner() - -From: Chuck Lever - -[ Upstream commit 043862b09cc00273e35e6c3a6389957953a34207 ] - -And return explicit nfserr values that match what is documented in the -new comment / API contract. - -Signed-off-by: Chuck Lever -Stable-dep-of: edcf9725150e ("nfsd: fix RELEASE_LOCKOWNER") -Signed-off-by: Sasha Levin ---- - fs/nfsd/nfs4state.c | 23 ++++++++++++++++++++--- - 1 file changed, 20 insertions(+), 3 deletions(-) - -diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c -index 1b40b2197ce6..b6480be7b5e6 100644 ---- a/fs/nfsd/nfs4state.c -+++ b/fs/nfsd/nfs4state.c -@@ -7107,6 +7107,23 @@ check_for_locks(struct nfs4_file *fp, struct nfs4_lockowner *lowner) - return status; - } - -+/** -+ * nfsd4_release_lockowner - process NFSv4.0 RELEASE_LOCKOWNER operations -+ * @rqstp: RPC transaction -+ * @cstate: NFSv4 COMPOUND state -+ * @u: RELEASE_LOCKOWNER arguments -+ * -+ * The lockowner's so_count is bumped when a lock record is added -+ * or when copying a conflicting lock. The latter case is brief, -+ * but can lead to fleeting false positives when looking for -+ * locks-in-use. -+ * -+ * Return values: -+ * %nfs_ok: lockowner released or not found -+ * %nfserr_locks_held: lockowner still in use -+ * %nfserr_stale_clientid: clientid no longer active -+ * %nfserr_expired: clientid not recognized -+ */ - __be32 - nfsd4_release_lockowner(struct svc_rqst *rqstp, - struct nfsd4_compound_state *cstate, -@@ -7133,7 +7150,7 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp, - lo = find_lockowner_str_locked(clp, &rlockowner->rl_owner); - if (!lo) { - spin_unlock(&clp->cl_lock); -- return status; -+ return nfs_ok; - } - if (atomic_read(&lo->lo_owner.so_count) != 2) { - spin_unlock(&clp->cl_lock); -@@ -7149,11 +7166,11 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp, - put_ol_stateid_locked(stp, &reaplist); - } - spin_unlock(&clp->cl_lock); -+ - free_ol_stateid_reaplist(&reaplist); - remove_blocked_locks(lo); - nfs4_put_stateowner(&lo->lo_owner); -- -- return status; -+ return nfs_ok; - } - - static inline struct nfs4_client_reclaim * --- -2.43.0 - diff --git a/queue-5.10/nfsd-modernize-nfsd4_release_lockowner.patch b/queue-5.10/nfsd-modernize-nfsd4_release_lockowner.patch deleted file mode 100644 index 93544a58484..00000000000 --- a/queue-5.10/nfsd-modernize-nfsd4_release_lockowner.patch +++ /dev/null @@ -1,86 +0,0 @@ -From f49f08cf70085090d80b1e00688a7d4ffa3f7c94 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Sun, 22 May 2022 12:07:18 -0400 -Subject: NFSD: Modernize nfsd4_release_lockowner() - -From: Chuck Lever - -[ Upstream commit bd8fdb6e545f950f4654a9a10d7e819ad48146e5 ] - -Refactor: Use existing helpers that other lock operations use. This -change removes several automatic variables, so re-organize the -variable declarations for readability. - -Signed-off-by: Chuck Lever -Stable-dep-of: edcf9725150e ("nfsd: fix RELEASE_LOCKOWNER") -Signed-off-by: Sasha Levin ---- - fs/nfsd/nfs4state.c | 36 +++++++++++------------------------- - 1 file changed, 11 insertions(+), 25 deletions(-) - -diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c -index d402ca0b535f..1b40b2197ce6 100644 ---- a/fs/nfsd/nfs4state.c -+++ b/fs/nfsd/nfs4state.c -@@ -7113,16 +7113,13 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp, - union nfsd4_op_u *u) - { - struct nfsd4_release_lockowner *rlockowner = &u->release_lockowner; -+ struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); - clientid_t *clid = &rlockowner->rl_clientid; -- struct nfs4_stateowner *sop; -- struct nfs4_lockowner *lo = NULL; - struct nfs4_ol_stateid *stp; -- struct xdr_netobj *owner = &rlockowner->rl_owner; -- unsigned int hashval = ownerstr_hashval(owner); -- __be32 status; -- struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); -+ struct nfs4_lockowner *lo; - struct nfs4_client *clp; -- LIST_HEAD (reaplist); -+ LIST_HEAD(reaplist); -+ __be32 status; - - dprintk("nfsd4_release_lockowner clientid: (%08x/%08x):\n", - clid->cl_boot, clid->cl_id); -@@ -7130,30 +7127,19 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp, - status = lookup_clientid(clid, cstate, nn, false); - if (status) - return status; -- - clp = cstate->clp; -- /* Find the matching lock stateowner */ -- spin_lock(&clp->cl_lock); -- list_for_each_entry(sop, &clp->cl_ownerstr_hashtbl[hashval], -- so_strhash) { - -- if (sop->so_is_open_owner || !same_owner_str(sop, owner)) -- continue; -- -- if (atomic_read(&sop->so_count) != 1) { -- spin_unlock(&clp->cl_lock); -- return nfserr_locks_held; -- } -- -- lo = lockowner(sop); -- nfs4_get_stateowner(sop); -- break; -- } -+ spin_lock(&clp->cl_lock); -+ lo = find_lockowner_str_locked(clp, &rlockowner->rl_owner); - if (!lo) { - spin_unlock(&clp->cl_lock); - return status; - } -- -+ if (atomic_read(&lo->lo_owner.so_count) != 2) { -+ spin_unlock(&clp->cl_lock); -+ nfs4_put_stateowner(&lo->lo_owner); -+ return nfserr_locks_held; -+ } - unhash_lockowner_locked(lo); - while (!list_empty(&lo->lo_owner.so_stateids)) { - stp = list_first_entry(&lo->lo_owner.so_stateids, --- -2.43.0 - diff --git a/queue-5.10/series b/queue-5.10/series index f84227d13d3..30d8a76aa1a 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -88,8 +88,6 @@ mm-use-__pfn_to_section-instead-of-open-coding-it.patch mm-sparsemem-fix-race-in-accessing-memory_section-us.patch btrfs-remove-err-variable-from-btrfs_delete_subvolum.patch btrfs-avoid-copying-btrfs_root_subvol_dead-flag-to-s.patch -nfsd-modernize-nfsd4_release_lockowner.patch -nfsd-add-documenting-comment-for-nfsd4_release_locko.patch drm-panel-simple-add-missing-bus-flags-for-tianma-tm.patch drm-exynos-fix-accidental-on-stack-copy-of-exynos_dr.patch drm-exynos-gsc-minor-fix-for-loop-iteration-in-gsc_r.patch diff --git a/queue-5.15/nfsd-add-documenting-comment-for-nfsd4_release_locko.patch b/queue-5.15/nfsd-add-documenting-comment-for-nfsd4_release_locko.patch deleted file mode 100644 index ad2737c5c1d..00000000000 --- a/queue-5.15/nfsd-add-documenting-comment-for-nfsd4_release_locko.patch +++ /dev/null @@ -1,73 +0,0 @@ -From bfc7f89d24d6164689aed7061a97879ef05fd861 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Sun, 22 May 2022 12:34:38 -0400 -Subject: NFSD: Add documenting comment for nfsd4_release_lockowner() - -From: Chuck Lever - -[ Upstream commit 043862b09cc00273e35e6c3a6389957953a34207 ] - -And return explicit nfserr values that match what is documented in the -new comment / API contract. - -Signed-off-by: Chuck Lever -Stable-dep-of: edcf9725150e ("nfsd: fix RELEASE_LOCKOWNER") -Signed-off-by: Sasha Levin ---- - fs/nfsd/nfs4state.c | 23 ++++++++++++++++++++--- - 1 file changed, 20 insertions(+), 3 deletions(-) - -diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c -index 798063b9b96f..f8533299db1c 100644 ---- a/fs/nfsd/nfs4state.c -+++ b/fs/nfsd/nfs4state.c -@@ -7284,6 +7284,23 @@ check_for_locks(struct nfs4_file *fp, struct nfs4_lockowner *lowner) - return status; - } - -+/** -+ * nfsd4_release_lockowner - process NFSv4.0 RELEASE_LOCKOWNER operations -+ * @rqstp: RPC transaction -+ * @cstate: NFSv4 COMPOUND state -+ * @u: RELEASE_LOCKOWNER arguments -+ * -+ * The lockowner's so_count is bumped when a lock record is added -+ * or when copying a conflicting lock. The latter case is brief, -+ * but can lead to fleeting false positives when looking for -+ * locks-in-use. -+ * -+ * Return values: -+ * %nfs_ok: lockowner released or not found -+ * %nfserr_locks_held: lockowner still in use -+ * %nfserr_stale_clientid: clientid no longer active -+ * %nfserr_expired: clientid not recognized -+ */ - __be32 - nfsd4_release_lockowner(struct svc_rqst *rqstp, - struct nfsd4_compound_state *cstate, -@@ -7310,7 +7327,7 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp, - lo = find_lockowner_str_locked(clp, &rlockowner->rl_owner); - if (!lo) { - spin_unlock(&clp->cl_lock); -- return status; -+ return nfs_ok; - } - if (atomic_read(&lo->lo_owner.so_count) != 2) { - spin_unlock(&clp->cl_lock); -@@ -7326,11 +7343,11 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp, - put_ol_stateid_locked(stp, &reaplist); - } - spin_unlock(&clp->cl_lock); -+ - free_ol_stateid_reaplist(&reaplist); - remove_blocked_locks(lo); - nfs4_put_stateowner(&lo->lo_owner); -- -- return status; -+ return nfs_ok; - } - - static inline struct nfs4_client_reclaim * --- -2.43.0 - diff --git a/queue-5.15/nfsd-modernize-nfsd4_release_lockowner.patch b/queue-5.15/nfsd-modernize-nfsd4_release_lockowner.patch deleted file mode 100644 index 5c1ac7d883b..00000000000 --- a/queue-5.15/nfsd-modernize-nfsd4_release_lockowner.patch +++ /dev/null @@ -1,86 +0,0 @@ -From 05aaa4892314880beb9474adeb0dd95d3b8086ad Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Sun, 22 May 2022 12:07:18 -0400 -Subject: NFSD: Modernize nfsd4_release_lockowner() - -From: Chuck Lever - -[ Upstream commit bd8fdb6e545f950f4654a9a10d7e819ad48146e5 ] - -Refactor: Use existing helpers that other lock operations use. This -change removes several automatic variables, so re-organize the -variable declarations for readability. - -Signed-off-by: Chuck Lever -Stable-dep-of: edcf9725150e ("nfsd: fix RELEASE_LOCKOWNER") -Signed-off-by: Sasha Levin ---- - fs/nfsd/nfs4state.c | 36 +++++++++++------------------------- - 1 file changed, 11 insertions(+), 25 deletions(-) - -diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c -index 9b660491f393..798063b9b96f 100644 ---- a/fs/nfsd/nfs4state.c -+++ b/fs/nfsd/nfs4state.c -@@ -7290,16 +7290,13 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp, - union nfsd4_op_u *u) - { - struct nfsd4_release_lockowner *rlockowner = &u->release_lockowner; -+ struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); - clientid_t *clid = &rlockowner->rl_clientid; -- struct nfs4_stateowner *sop; -- struct nfs4_lockowner *lo = NULL; - struct nfs4_ol_stateid *stp; -- struct xdr_netobj *owner = &rlockowner->rl_owner; -- unsigned int hashval = ownerstr_hashval(owner); -- __be32 status; -- struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); -+ struct nfs4_lockowner *lo; - struct nfs4_client *clp; -- LIST_HEAD (reaplist); -+ LIST_HEAD(reaplist); -+ __be32 status; - - dprintk("nfsd4_release_lockowner clientid: (%08x/%08x):\n", - clid->cl_boot, clid->cl_id); -@@ -7307,30 +7304,19 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp, - status = set_client(clid, cstate, nn); - if (status) - return status; -- - clp = cstate->clp; -- /* Find the matching lock stateowner */ -- spin_lock(&clp->cl_lock); -- list_for_each_entry(sop, &clp->cl_ownerstr_hashtbl[hashval], -- so_strhash) { - -- if (sop->so_is_open_owner || !same_owner_str(sop, owner)) -- continue; -- -- if (atomic_read(&sop->so_count) != 1) { -- spin_unlock(&clp->cl_lock); -- return nfserr_locks_held; -- } -- -- lo = lockowner(sop); -- nfs4_get_stateowner(sop); -- break; -- } -+ spin_lock(&clp->cl_lock); -+ lo = find_lockowner_str_locked(clp, &rlockowner->rl_owner); - if (!lo) { - spin_unlock(&clp->cl_lock); - return status; - } -- -+ if (atomic_read(&lo->lo_owner.so_count) != 2) { -+ spin_unlock(&clp->cl_lock); -+ nfs4_put_stateowner(&lo->lo_owner); -+ return nfserr_locks_held; -+ } - unhash_lockowner_locked(lo); - while (!list_empty(&lo->lo_owner.so_stateids)) { - stp = list_first_entry(&lo->lo_owner.so_stateids, --- -2.43.0 - diff --git a/queue-5.15/series b/queue-5.15/series index de09b5fb434..9fd0d871255 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -108,8 +108,6 @@ mm-use-__pfn_to_section-instead-of-open-coding-it.patch mm-sparsemem-fix-race-in-accessing-memory_section-us.patch pm-devfreq-fix-buffer-overflow-in-trans_stat_show.patch btrfs-add-definition-for-extent_tree_v2.patch -nfsd-modernize-nfsd4_release_lockowner.patch -nfsd-add-documenting-comment-for-nfsd4_release_locko.patch ksmbd-fix-global-oob-in-ksmbd_nl_policy.patch cpufreq-intel_pstate-drop-redundant-intel_pstate_get.patch cpufreq-intel_pstate-refine-computation-of-p-state-f.patch diff --git a/queue-5.4/nfsd-add-documenting-comment-for-nfsd4_release_locko.patch b/queue-5.4/nfsd-add-documenting-comment-for-nfsd4_release_locko.patch deleted file mode 100644 index a6c6b774159..00000000000 --- a/queue-5.4/nfsd-add-documenting-comment-for-nfsd4_release_locko.patch +++ /dev/null @@ -1,73 +0,0 @@ -From b0b0ed9987913fc43f27c84225455f6fcac0e2ad Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Sun, 22 May 2022 12:34:38 -0400 -Subject: NFSD: Add documenting comment for nfsd4_release_lockowner() - -From: Chuck Lever - -[ Upstream commit 043862b09cc00273e35e6c3a6389957953a34207 ] - -And return explicit nfserr values that match what is documented in the -new comment / API contract. - -Signed-off-by: Chuck Lever -Stable-dep-of: edcf9725150e ("nfsd: fix RELEASE_LOCKOWNER") -Signed-off-by: Sasha Levin ---- - fs/nfsd/nfs4state.c | 23 ++++++++++++++++++++--- - 1 file changed, 20 insertions(+), 3 deletions(-) - -diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c -index 9a77a3eac4ac..0dfc45d37658 100644 ---- a/fs/nfsd/nfs4state.c -+++ b/fs/nfsd/nfs4state.c -@@ -6867,6 +6867,23 @@ check_for_locks(struct nfs4_file *fp, struct nfs4_lockowner *lowner) - return status; - } - -+/** -+ * nfsd4_release_lockowner - process NFSv4.0 RELEASE_LOCKOWNER operations -+ * @rqstp: RPC transaction -+ * @cstate: NFSv4 COMPOUND state -+ * @u: RELEASE_LOCKOWNER arguments -+ * -+ * The lockowner's so_count is bumped when a lock record is added -+ * or when copying a conflicting lock. The latter case is brief, -+ * but can lead to fleeting false positives when looking for -+ * locks-in-use. -+ * -+ * Return values: -+ * %nfs_ok: lockowner released or not found -+ * %nfserr_locks_held: lockowner still in use -+ * %nfserr_stale_clientid: clientid no longer active -+ * %nfserr_expired: clientid not recognized -+ */ - __be32 - nfsd4_release_lockowner(struct svc_rqst *rqstp, - struct nfsd4_compound_state *cstate, -@@ -6893,7 +6910,7 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp, - lo = find_lockowner_str_locked(clp, &rlockowner->rl_owner); - if (!lo) { - spin_unlock(&clp->cl_lock); -- return status; -+ return nfs_ok; - } - if (atomic_read(&lo->lo_owner.so_count) != 2) { - spin_unlock(&clp->cl_lock); -@@ -6909,11 +6926,11 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp, - put_ol_stateid_locked(stp, &reaplist); - } - spin_unlock(&clp->cl_lock); -+ - free_ol_stateid_reaplist(&reaplist); - remove_blocked_locks(lo); - nfs4_put_stateowner(&lo->lo_owner); -- -- return status; -+ return nfs_ok; - } - - static inline struct nfs4_client_reclaim * --- -2.43.0 - diff --git a/queue-5.4/nfsd-modernize-nfsd4_release_lockowner.patch b/queue-5.4/nfsd-modernize-nfsd4_release_lockowner.patch deleted file mode 100644 index 65a2d9be62e..00000000000 --- a/queue-5.4/nfsd-modernize-nfsd4_release_lockowner.patch +++ /dev/null @@ -1,86 +0,0 @@ -From 4f0fca8c3fa2d6fa3e875c131af1c4cfbb8125f7 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Sun, 22 May 2022 12:07:18 -0400 -Subject: NFSD: Modernize nfsd4_release_lockowner() - -From: Chuck Lever - -[ Upstream commit bd8fdb6e545f950f4654a9a10d7e819ad48146e5 ] - -Refactor: Use existing helpers that other lock operations use. This -change removes several automatic variables, so re-organize the -variable declarations for readability. - -Signed-off-by: Chuck Lever -Stable-dep-of: edcf9725150e ("nfsd: fix RELEASE_LOCKOWNER") -Signed-off-by: Sasha Levin ---- - fs/nfsd/nfs4state.c | 36 +++++++++++------------------------- - 1 file changed, 11 insertions(+), 25 deletions(-) - -diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c -index a0aa7e63739d..9a77a3eac4ac 100644 ---- a/fs/nfsd/nfs4state.c -+++ b/fs/nfsd/nfs4state.c -@@ -6873,16 +6873,13 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp, - union nfsd4_op_u *u) - { - struct nfsd4_release_lockowner *rlockowner = &u->release_lockowner; -+ struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); - clientid_t *clid = &rlockowner->rl_clientid; -- struct nfs4_stateowner *sop; -- struct nfs4_lockowner *lo = NULL; - struct nfs4_ol_stateid *stp; -- struct xdr_netobj *owner = &rlockowner->rl_owner; -- unsigned int hashval = ownerstr_hashval(owner); -- __be32 status; -- struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); -+ struct nfs4_lockowner *lo; - struct nfs4_client *clp; -- LIST_HEAD (reaplist); -+ LIST_HEAD(reaplist); -+ __be32 status; - - dprintk("nfsd4_release_lockowner clientid: (%08x/%08x):\n", - clid->cl_boot, clid->cl_id); -@@ -6890,30 +6887,19 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp, - status = lookup_clientid(clid, cstate, nn); - if (status) - return status; -- - clp = cstate->clp; -- /* Find the matching lock stateowner */ -- spin_lock(&clp->cl_lock); -- list_for_each_entry(sop, &clp->cl_ownerstr_hashtbl[hashval], -- so_strhash) { - -- if (sop->so_is_open_owner || !same_owner_str(sop, owner)) -- continue; -- -- if (atomic_read(&sop->so_count) != 1) { -- spin_unlock(&clp->cl_lock); -- return nfserr_locks_held; -- } -- -- lo = lockowner(sop); -- nfs4_get_stateowner(sop); -- break; -- } -+ spin_lock(&clp->cl_lock); -+ lo = find_lockowner_str_locked(clp, &rlockowner->rl_owner); - if (!lo) { - spin_unlock(&clp->cl_lock); - return status; - } -- -+ if (atomic_read(&lo->lo_owner.so_count) != 2) { -+ spin_unlock(&clp->cl_lock); -+ nfs4_put_stateowner(&lo->lo_owner); -+ return nfserr_locks_held; -+ } - unhash_lockowner_locked(lo); - while (!list_empty(&lo->lo_owner.so_stateids)) { - stp = list_first_entry(&lo->lo_owner.so_stateids, --- -2.43.0 - diff --git a/queue-5.4/series b/queue-5.4/series index 40ce1c0d01e..ca13922059c 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -49,8 +49,6 @@ gpiolib-acpi-ignore-touchpad-wakeup-on-gpd-g1619-04.patch drm-don-t-unref-the-same-fb-many-times-by-mistake-due-to-deadlock-handling.patch drm-bridge-nxp-ptn3460-fix-i2c_master_send-error-checking.patch drm-bridge-nxp-ptn3460-simplify-some-error-checking.patch -nfsd-modernize-nfsd4_release_lockowner.patch -nfsd-add-documenting-comment-for-nfsd4_release_locko.patch drm-exynos-fix-accidental-on-stack-copy-of-exynos_dr.patch drm-exynos-gsc-minor-fix-for-loop-iteration-in-gsc_r.patch gpio-eic-sprd-clear-interrupt-after-set-the-interrup.patch