Merge tag 'nfs-for-4.13-4' of git://git.linux-nfs.org/projects/anna/linux-nfs
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 3 Aug 2017 03:56:44 +0000 (20:56 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 3 Aug 2017 03:56:44 +0000 (20:56 -0700)
Pull NFS client fixes from Anna Schumaker:
 "Two fixes from Trond this time, now that he's back from his vacation.
  The first is a stable fix for the EXCHANGE_ID issue on the mailing
  list, and the other fixes a double-free situation that he found at the
  same time.

  Stable fix:
   - Fix EXCHANGE_ID corrupt verifier issue

  Other fix:
   - Fix double frees in nfs4_test_session_trunk()"

* tag 'nfs-for-4.13-4' of git://git.linux-nfs.org/projects/anna/linux-nfs:
  NFSv4: Fix double frees in nfs4_test_session_trunk()
  NFSv4: Fix EXCHANGE_ID corrupt verifier issue

1  2 
fs/nfs/nfs4proc.c

diff --combined fs/nfs/nfs4proc.c
index 18ca6879d8de9ecebf22d0f4f9ba73b66fdeeddc,3e46be8c9be14384d412c57cca01fd80ac177aa6..ffd2e712595d8ac875dc2780b52731543c687ca8
@@@ -2596,8 -2596,7 +2596,8 @@@ static inline void nfs4_exclusive_attrs
  
        /* Except MODE, it seems harmless of setting twice. */
        if (opendata->o_arg.createmode != NFS4_CREATE_EXCLUSIVE &&
 -              attrset[1] & FATTR4_WORD1_MODE)
 +              (attrset[1] & FATTR4_WORD1_MODE ||
 +               attrset[2] & FATTR4_WORD2_MODE_UMASK))
                sattr->ia_valid &= ~ATTR_MODE;
  
        if (attrset[2] & FATTR4_WORD2_SECURITY_LABEL)
@@@ -6428,7 -6427,7 +6428,7 @@@ struct nfs4_lock_waiter 
  };
  
  static int
 -nfs4_wake_lock_waiter(wait_queue_t *wait, unsigned int mode, int flags, void *key)
 +nfs4_wake_lock_waiter(wait_queue_entry_t *wait, unsigned int mode, int flags, void *key)
  {
        int ret;
        struct cb_notify_lock_args *cbnl = key;
@@@ -6471,7 -6470,7 +6471,7 @@@ nfs4_retry_setlk(struct nfs4_state *sta
                                           .inode = state->inode,
                                           .owner = &owner,
                                           .notified = false };
 -      wait_queue_t wait;
 +      wait_queue_entry_t wait;
  
        /* Don't bother with waitqueue if we don't expect a callback */
        if (!test_bit(NFS_STATE_MAY_NOTIFY_LOCK, &state->flags))
@@@ -7461,7 -7460,7 +7461,7 @@@ static void nfs4_exchange_id_done(struc
                        cdata->res.server_scope = NULL;
                }
                /* Save the EXCHANGE_ID verifier session trunk tests */
-               memcpy(clp->cl_confirm.data, cdata->args.verifier->data,
+               memcpy(clp->cl_confirm.data, cdata->args.verifier.data,
                       sizeof(clp->cl_confirm.data));
        }
  out:
@@@ -7474,10 -7473,6 +7474,6 @@@ static void nfs4_exchange_id_release(vo
        struct nfs41_exchange_id_data *cdata =
                                        (struct nfs41_exchange_id_data *)data;
  
-       if (cdata->xprt) {
-               xprt_put(cdata->xprt);
-               rpc_clnt_xprt_switch_put(cdata->args.client->cl_rpcclient);
-       }
        nfs_put_client(cdata->args.client);
        kfree(cdata->res.impl_id);
        kfree(cdata->res.server_scope);
@@@ -7498,7 -7493,6 +7494,6 @@@ static const struct rpc_call_ops nfs4_e
  static int _nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred,
                        u32 sp4_how, struct rpc_xprt *xprt)
  {
-       nfs4_verifier verifier;
        struct rpc_message msg = {
                .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_EXCHANGE_ID],
                .rpc_cred = cred,
                .rpc_client = clp->cl_rpcclient,
                .callback_ops = &nfs4_exchange_id_call_ops,
                .rpc_message = &msg,
-               .flags = RPC_TASK_ASYNC | RPC_TASK_TIMEOUT,
+               .flags = RPC_TASK_TIMEOUT,
        };
        struct nfs41_exchange_id_data *calldata;
        struct rpc_task *task;
                return -ENOMEM;
        }
  
-       if (!xprt)
-               nfs4_init_boot_verifier(clp, &verifier);
+       nfs4_init_boot_verifier(clp, &calldata->args.verifier);
  
        status = nfs4_init_uniform_client_string(clp);
        if (status)
        if (xprt) {
                calldata->xprt = xprt;
                task_setup_data.rpc_xprt = xprt;
-               task_setup_data.flags =
-                               RPC_TASK_SOFT|RPC_TASK_SOFTCONN|RPC_TASK_ASYNC;
-               calldata->args.verifier = &clp->cl_confirm;
-       } else {
-               calldata->args.verifier = &verifier;
+               task_setup_data.flags |= RPC_TASK_SOFTCONN;
+               memcpy(calldata->args.verifier.data, clp->cl_confirm.data,
+                               sizeof(calldata->args.verifier.data));
        }
        calldata->args.client = clp;
  #ifdef CONFIG_NFS_V4_1_MIGRATION
        if (IS_ERR(task))
                return PTR_ERR(task);
  
-       if (!xprt) {
-               status = rpc_wait_for_completion_task(task);
-               if (!status)
-                       status = calldata->rpc_status;
-       } else  /* session trunking test */
-               status = calldata->rpc_status;
+       status = calldata->rpc_status;
  
        rpc_put_task(task);
  out:
@@@ -8471,7 -8457,6 +8458,7 @@@ static void nfs4_layoutget_release(voi
        size_t max_pages = max_response_pages(server);
  
        dprintk("--> %s\n", __func__);
 +      nfs4_sequence_free_slot(&lgp->res.seq_res);
        nfs4_free_pages(lgp->args.layout.pages, max_pages);
        pnfs_put_layout_hdr(NFS_I(inode)->layout);
        put_nfs_open_context(lgp->args.ctx);
@@@ -8546,6 -8531,7 +8533,6 @@@ nfs4_proc_layoutget(struct nfs4_layoutg
        /* if layoutp->len is 0, nfs4_layoutget_prepare called rpc_exit */
        if (status == 0 && lgp->res.layoutp->len)
                lseg = pnfs_layout_process(lgp);
 -      nfs4_sequence_free_slot(&lgp->res.seq_res);
        rpc_put_task(task);
        dprintk("<-- %s status=%d\n", __func__, status);
        if (status)