diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2023-05-22 22:01:13 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2023-05-22 22:01:13 +0300 |
commit | 421ca22e313871d4104617bab077b275b30950ae (patch) | |
tree | fb0b8145ac3f4a09c4e633afebbbcf9d9ac0fcc6 | |
parent | 44c026a73be8038f03dbdeef028b642880cf1511 (diff) | |
parent | 43439d858bbae244a510de47f9a55f667ca4ed52 (diff) | |
download | linux-421ca22e313871d4104617bab077b275b30950ae.tar.xz |
Merge tag 'nfs-for-6.4-2' of git://git.linux-nfs.org/projects/anna/linux-nfs
Pull NFS client fixes from Anna Schumaker:
"Stable Fix:
- Don't change task->tk_status after the call to rpc_exit_task
Other Bugfixes:
- Convert kmap_atomic() to kmap_local_folio()
- Fix a potential double free with READ_PLUS"
* tag 'nfs-for-6.4-2' of git://git.linux-nfs.org/projects/anna/linux-nfs:
NFSv4.2: Fix a potential double free with READ_PLUS
SUNRPC: Don't change task->tk_status after the call to rpc_exit_task
NFS: Convert kmap_atomic() to kmap_local_folio()
-rw-r--r-- | fs/nfs/dir.c | 4 | ||||
-rw-r--r-- | fs/nfs/nfs4proc.c | 12 | ||||
-rw-r--r-- | net/sunrpc/sched.c | 5 |
3 files changed, 14 insertions, 7 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index e63c1d46f189..8f3112e71a6a 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -317,7 +317,7 @@ static int nfs_readdir_folio_array_append(struct folio *folio, name = nfs_readdir_copy_name(entry->name, entry->len); - array = kmap_atomic(folio_page(folio, 0)); + array = kmap_local_folio(folio, 0); if (!name) goto out; ret = nfs_readdir_array_can_expand(array); @@ -340,7 +340,7 @@ static int nfs_readdir_folio_array_append(struct folio *folio, nfs_readdir_array_set_eof(array); out: *cookie = array->last_cookie; - kunmap_atomic(array); + kunmap_local(array); return ret; } diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 18f25ff4bff7..d3665390c4cb 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -5437,10 +5437,18 @@ static bool nfs4_read_plus_not_supported(struct rpc_task *task, return false; } -static int nfs4_read_done(struct rpc_task *task, struct nfs_pgio_header *hdr) +static inline void nfs4_read_plus_scratch_free(struct nfs_pgio_header *hdr) { - if (hdr->res.scratch) + if (hdr->res.scratch) { kfree(hdr->res.scratch); + hdr->res.scratch = NULL; + } +} + +static int nfs4_read_done(struct rpc_task *task, struct nfs_pgio_header *hdr) +{ + nfs4_read_plus_scratch_free(hdr); + if (!nfs4_sequence_done(task, &hdr->res.seq_res)) return -EAGAIN; if (nfs4_read_stateid_changed(task, &hdr->args)) diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index c8321de341ee..6debf4fd42d4 100644 --- a/net/sunrpc/sched.c +++ b/net/sunrpc/sched.c @@ -927,11 +927,10 @@ static void __rpc_execute(struct rpc_task *task) */ do_action = task->tk_action; /* Tasks with an RPC error status should exit */ - if (do_action != rpc_exit_task && + if (do_action && do_action != rpc_exit_task && (status = READ_ONCE(task->tk_rpc_status)) != 0) { task->tk_status = status; - if (do_action != NULL) - do_action = rpc_exit_task; + do_action = rpc_exit_task; } /* Callbacks override all actions */ if (task->tk_callback) { |