Commit 421ca22e authored by Linus Torvalds's avatar Linus Torvalds

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()
parents 44c026a7 43439d85
......@@ -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;
}
......
......@@ -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))
......
......@@ -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) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment