]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - fs/nfs/nfs4proc.c
Merge tag 'usb-5.6-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
[linux.git] / fs / nfs / nfs4proc.c
index caacf5e7f5e1568474feb57f6e4d85aa19efdc8b..69b7ab7a58157f4d7b3e7787d4d2b1dc9750ff7d 100644 (file)
@@ -91,7 +91,6 @@ struct nfs4_opendata;
 static int _nfs4_recover_proc_open(struct nfs4_opendata *data);
 static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *);
 static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr);
-static int nfs4_proc_getattr(struct nfs_server *, struct nfs_fh *, struct nfs_fattr *, struct nfs4_label *label, struct inode *inode);
 static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr, struct nfs4_label *label, struct inode *inode);
 static int nfs4_do_setattr(struct inode *inode, const struct cred *cred,
                            struct nfs_fattr *fattr, struct iattr *sattr,
@@ -476,6 +475,7 @@ static int nfs4_do_handle_exception(struct nfs_server *server,
                case -NFS4ERR_ADMIN_REVOKED:
                case -NFS4ERR_EXPIRED:
                case -NFS4ERR_BAD_STATEID:
+               case -NFS4ERR_PARTNER_NO_AUTH:
                        if (inode != NULL && stateid != NULL) {
                                nfs_inode_find_state_and_recover(inode,
                                                stateid);
@@ -521,9 +521,7 @@ static int nfs4_do_handle_exception(struct nfs_server *server,
                case -NFS4ERR_DEADSESSION:
                case -NFS4ERR_SEQ_FALSE_RETRY:
                case -NFS4ERR_SEQ_MISORDERED:
-                       dprintk("%s ERROR: %d Reset session\n", __func__,
-                               errorcode);
-                       nfs4_schedule_session_recovery(clp->cl_session, errorcode);
+                       /* Handled in nfs41_sequence_process() */
                        goto wait_on_recovery;
 #endif /* defined(CONFIG_NFS_V4_1) */
                case -NFS4ERR_FILE_OPEN:
@@ -782,6 +780,7 @@ static int nfs41_sequence_process(struct rpc_task *task,
        struct nfs4_session *session;
        struct nfs4_slot *slot = res->sr_slot;
        struct nfs_client *clp;
+       int status;
        int ret = 1;
 
        if (slot == NULL)
@@ -793,8 +792,13 @@ static int nfs41_sequence_process(struct rpc_task *task,
        session = slot->table->session;
 
        trace_nfs4_sequence_done(session, res);
+
+       status = res->sr_status;
+       if (task->tk_status == -NFS4ERR_DEADSESSION)
+               status = -NFS4ERR_DEADSESSION;
+
        /* Check the SEQUENCE operation status */
-       switch (res->sr_status) {
+       switch (status) {
        case 0:
                /* Mark this sequence number as having been acked */
                nfs4_slot_sequence_acked(slot, slot->seq_nr);
@@ -866,6 +870,10 @@ static int nfs41_sequence_process(struct rpc_task *task,
                 */
                slot->seq_nr = slot->seq_nr_highest_sent;
                goto out_retry;
+       case -NFS4ERR_BADSESSION:
+       case -NFS4ERR_DEADSESSION:
+       case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
+               goto session_recover;
        default:
                /* Just update the slot sequence no. */
                slot->seq_done = 1;
@@ -876,8 +884,10 @@ static int nfs41_sequence_process(struct rpc_task *task,
 out_noaction:
        return ret;
 session_recover:
-       nfs4_schedule_session_recovery(session, res->sr_status);
-       goto retry_nowait;
+       nfs4_schedule_session_recovery(session, status);
+       dprintk("%s ERROR: %d Reset session\n", __func__, status);
+       nfs41_sequence_free_slot(res);
+       goto out;
 retry_new_seq:
        ++slot->seq_nr;
 retry_nowait:
@@ -1087,11 +1097,12 @@ static int nfs4_call_sync_custom(struct rpc_task_setup *task_setup)
        return ret;
 }
 
-static int nfs4_call_sync_sequence(struct rpc_clnt *clnt,
-                                  struct nfs_server *server,
-                                  struct rpc_message *msg,
-                                  struct nfs4_sequence_args *args,
-                                  struct nfs4_sequence_res *res)
+static int nfs4_do_call_sync(struct rpc_clnt *clnt,
+                            struct nfs_server *server,
+                            struct rpc_message *msg,
+                            struct nfs4_sequence_args *args,
+                            struct nfs4_sequence_res *res,
+                            unsigned short task_flags)
 {
        struct nfs_client *clp = server->nfs_client;
        struct nfs4_call_sync_data data = {
@@ -1103,12 +1114,23 @@ static int nfs4_call_sync_sequence(struct rpc_clnt *clnt,
                .rpc_client = clnt,
                .rpc_message = msg,
                .callback_ops = clp->cl_mvops->call_sync_ops,
-               .callback_data = &data
+               .callback_data = &data,
+               .flags = task_flags,
        };
 
        return nfs4_call_sync_custom(&task_setup);
 }
 
+static int nfs4_call_sync_sequence(struct rpc_clnt *clnt,
+                                  struct nfs_server *server,
+                                  struct rpc_message *msg,
+                                  struct nfs4_sequence_args *args,
+                                  struct nfs4_sequence_res *res)
+{
+       return nfs4_do_call_sync(clnt, server, msg, args, res, 0);
+}
+
+
 int nfs4_call_sync(struct rpc_clnt *clnt,
                   struct nfs_server *server,
                   struct rpc_message *msg,
@@ -1716,7 +1738,7 @@ static void nfs_state_clear_delegation(struct nfs4_state *state)
        write_sequnlock(&state->seqlock);
 }
 
-static int update_open_stateid(struct nfs4_state *state,
+int update_open_stateid(struct nfs4_state *state,
                const nfs4_stateid *open_stateid,
                const nfs4_stateid *delegation,
                fmode_t fmode)
@@ -1737,7 +1759,7 @@ static int update_open_stateid(struct nfs4_state *state,
                ret = 1;
        }
 
-       deleg_cur = rcu_dereference(nfsi->delegation);
+       deleg_cur = nfs4_get_valid_delegation(state->inode);
        if (deleg_cur == NULL)
                goto no_delegation;
 
@@ -1749,7 +1771,7 @@ static int update_open_stateid(struct nfs4_state *state,
 
        if (delegation == NULL)
                delegation = &deleg_cur->stateid;
-       else if (!nfs4_stateid_match(&deleg_cur->stateid, delegation))
+       else if (!nfs4_stateid_match_other(&deleg_cur->stateid, delegation))
                goto no_delegation_unlock;
 
        nfs_mark_delegation_referenced(deleg_cur);
@@ -1796,7 +1818,7 @@ static void nfs4_return_incompatible_delegation(struct inode *inode, fmode_t fmo
 
        fmode &= FMODE_READ|FMODE_WRITE;
        rcu_read_lock();
-       delegation = rcu_dereference(NFS_I(inode)->delegation);
+       delegation = nfs4_get_valid_delegation(inode);
        if (delegation == NULL || (delegation->type & fmode) == fmode) {
                rcu_read_unlock();
                return;
@@ -2188,7 +2210,6 @@ static int nfs4_handle_delegation_recall_error(struct nfs_server *server, struct
                case -NFS4ERR_BAD_HIGH_SLOT:
                case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
                case -NFS4ERR_DEADSESSION:
-                       nfs4_schedule_session_recovery(server->nfs_client->cl_session, err);
                        return -EAGAIN;
                case -NFS4ERR_STALE_CLIENTID:
                case -NFS4ERR_STALE_STATEID:
@@ -2953,10 +2974,13 @@ static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata,
        struct dentry *dentry;
        struct nfs4_state *state;
        fmode_t acc_mode = _nfs4_ctx_to_accessmode(ctx);
+       struct inode *dir = d_inode(opendata->dir);
+       unsigned long dir_verifier;
        unsigned int seq;
        int ret;
 
        seq = raw_seqcount_begin(&sp->so_reclaim_seqcount);
+       dir_verifier = nfs_save_change_attribute(dir);
 
        ret = _nfs4_proc_open(opendata, ctx);
        if (ret != 0)
@@ -2984,8 +3008,19 @@ static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata,
                        dput(ctx->dentry);
                        ctx->dentry = dentry = alias;
                }
-               nfs_set_verifier(dentry,
-                               nfs_save_change_attribute(d_inode(opendata->dir)));
+       }
+
+       switch(opendata->o_arg.claim) {
+       default:
+               break;
+       case NFS4_OPEN_CLAIM_NULL:
+       case NFS4_OPEN_CLAIM_DELEGATE_CUR:
+       case NFS4_OPEN_CLAIM_DELEGATE_PREV:
+               if (!opendata->rpc_done)
+                       break;
+               if (opendata->o_res.delegation_type != 0)
+                       dir_verifier = nfs_save_change_attribute(dir);
+               nfs_set_verifier(dentry, dir_verifier);
        }
 
        /* Parse layoutget results before we check for access */
@@ -3178,6 +3213,11 @@ static struct nfs4_state *nfs4_do_open(struct inode *dir,
                        exception.retry = 1;
                        continue;
                }
+               if (status == -NFS4ERR_EXPIRED) {
+                       nfs4_schedule_lease_recovery(server->nfs_client);
+                       exception.retry = 1;
+                       continue;
+               }
                if (status == -EAGAIN) {
                        /* We must have found a delegation */
                        exception.retry = 1;
@@ -3230,6 +3270,8 @@ static int _nfs4_do_setattr(struct inode *inode,
                nfs_put_lock_context(l_ctx);
                if (status == -EIO)
                        return -EBADF;
+               else if (status == -EAGAIN)
+                       goto zero_stateid;
        } else {
 zero_stateid:
                nfs4_stateid_copy(&arg->stateid, &zero_stateid);
@@ -4055,14 +4097,21 @@ static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
                .rpc_argp = &args,
                .rpc_resp = &res,
        };
+       unsigned short task_flags = 0;
+
+       /* Is this is an attribute revalidation, subject to softreval? */
+       if (inode && (server->flags & NFS_MOUNT_SOFTREVAL))
+               task_flags |= RPC_TASK_TIMEOUT;
 
        nfs4_bitmap_copy_adjust(bitmask, nfs4_bitmask(server, label), inode);
 
        nfs_fattr_init(fattr);
-       return nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0);
+       nfs4_init_sequence(&args.seq_args, &res.seq_res, 0, 0);
+       return nfs4_do_call_sync(server->client, server, &msg,
+                       &args.seq_args, &res.seq_res, task_flags);
 }
 
-static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
+int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
                                struct nfs_fattr *fattr, struct nfs4_label *label,
                                struct inode *inode)
 {
@@ -4147,7 +4196,7 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
 }
 
 static int _nfs4_proc_lookup(struct rpc_clnt *clnt, struct inode *dir,
-               const struct qstr *name, struct nfs_fh *fhandle,
+               struct dentry *dentry, struct nfs_fh *fhandle,
                struct nfs_fattr *fattr, struct nfs4_label *label)
 {
        struct nfs_server *server = NFS_SERVER(dir);
@@ -4155,7 +4204,7 @@ static int _nfs4_proc_lookup(struct rpc_clnt *clnt, struct inode *dir,
        struct nfs4_lookup_arg args = {
                .bitmask = server->attr_bitmask,
                .dir_fh = NFS_FH(dir),
-               .name = name,
+               .name = &dentry->d_name,
        };
        struct nfs4_lookup_res res = {
                .server = server,
@@ -4168,13 +4217,20 @@ static int _nfs4_proc_lookup(struct rpc_clnt *clnt, struct inode *dir,
                .rpc_argp = &args,
                .rpc_resp = &res,
        };
+       unsigned short task_flags = 0;
+
+       /* Is this is an attribute revalidation, subject to softreval? */
+       if (nfs_lookup_is_soft_revalidate(dentry))
+               task_flags |= RPC_TASK_TIMEOUT;
 
        args.bitmask = nfs4_bitmask(server, label);
 
        nfs_fattr_init(fattr);
 
-       dprintk("NFS call  lookup %s\n", name->name);
-       status = nfs4_call_sync(clnt, server, &msg, &args.seq_args, &res.seq_res, 0);
+       dprintk("NFS call  lookup %pd2\n", dentry);
+       nfs4_init_sequence(&args.seq_args, &res.seq_res, 0, 0);
+       status = nfs4_do_call_sync(clnt, server, &msg,
+                       &args.seq_args, &res.seq_res, task_flags);
        dprintk("NFS reply lookup: %d\n", status);
        return status;
 }
@@ -4188,16 +4244,17 @@ static void nfs_fixup_secinfo_attributes(struct nfs_fattr *fattr)
 }
 
 static int nfs4_proc_lookup_common(struct rpc_clnt **clnt, struct inode *dir,
-                                  const struct qstr *name, struct nfs_fh *fhandle,
+                                  struct dentry *dentry, struct nfs_fh *fhandle,
                                   struct nfs_fattr *fattr, struct nfs4_label *label)
 {
        struct nfs4_exception exception = {
                .interruptible = true,
        };
        struct rpc_clnt *client = *clnt;
+       const struct qstr *name = &dentry->d_name;
        int err;
        do {
-               err = _nfs4_proc_lookup(client, dir, name, fhandle, fattr, label);
+               err = _nfs4_proc_lookup(client, dir, dentry, fhandle, fattr, label);
                trace_nfs4_lookup(dir, name, err);
                switch (err) {
                case -NFS4ERR_BADNAME:
@@ -4232,14 +4289,14 @@ static int nfs4_proc_lookup_common(struct rpc_clnt **clnt, struct inode *dir,
        return err;
 }
 
-static int nfs4_proc_lookup(struct inode *dir, const struct qstr *name,
+static int nfs4_proc_lookup(struct inode *dir, struct dentry *dentry,
                            struct nfs_fh *fhandle, struct nfs_fattr *fattr,
                            struct nfs4_label *label)
 {
        int status;
        struct rpc_clnt *client = NFS_CLIENT(dir);
 
-       status = nfs4_proc_lookup_common(&client, dir, name, fhandle, fattr, label);
+       status = nfs4_proc_lookup_common(&client, dir, dentry, fhandle, fattr, label);
        if (client != NFS_CLIENT(dir)) {
                rpc_shutdown_client(client);
                nfs_fixup_secinfo_attributes(fattr);
@@ -4248,13 +4305,13 @@ static int nfs4_proc_lookup(struct inode *dir, const struct qstr *name,
 }
 
 struct rpc_clnt *
-nfs4_proc_lookup_mountpoint(struct inode *dir, const struct qstr *name,
+nfs4_proc_lookup_mountpoint(struct inode *dir, struct dentry *dentry,
                            struct nfs_fh *fhandle, struct nfs_fattr *fattr)
 {
        struct rpc_clnt *client = NFS_CLIENT(dir);
        int status;
 
-       status = nfs4_proc_lookup_common(&client, dir, name, fhandle, fattr, NULL);
+       status = nfs4_proc_lookup_common(&client, dir, dentry, fhandle, fattr, NULL);
        if (status < 0)
                return ERR_PTR(status);
        return (client == NFS_CLIENT(dir)) ? rpc_clone_client(client) : client;
@@ -5010,16 +5067,13 @@ static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, str
        struct nfs4_exception exception = {
                .interruptible = true,
        };
-       unsigned long now = jiffies;
        int err;
 
        do {
                err = _nfs4_do_fsinfo(server, fhandle, fsinfo);
                trace_nfs4_fsinfo(server, fhandle, fsinfo->fattr, err);
                if (err == 0) {
-                       nfs4_set_lease_period(server->nfs_client,
-                                       fsinfo->lease_time * HZ,
-                                       now);
+                       nfs4_set_lease_period(server->nfs_client, fsinfo->lease_time * HZ);
                        break;
                }
                err = nfs4_handle_exception(server, err, &exception);
@@ -5098,12 +5152,12 @@ static bool nfs4_stateid_is_current(nfs4_stateid *stateid,
                const struct nfs_lock_context *l_ctx,
                fmode_t fmode)
 {
-       nfs4_stateid current_stateid;
+       nfs4_stateid _current_stateid;
 
        /* If the current stateid represents a lost lock, then exit */
-       if (nfs4_set_rw_stateid(&current_stateid, ctx, l_ctx, fmode) == -EIO)
+       if (nfs4_set_rw_stateid(&_current_stateid, ctx, l_ctx, fmode) == -EIO)
                return true;
-       return nfs4_stateid_match(stateid, &current_stateid);
+       return nfs4_stateid_match(stateid, &_current_stateid);
 }
 
 static bool nfs4_error_stateid_expired(int err)
@@ -5282,7 +5336,7 @@ static void nfs4_proc_write_setup(struct nfs_pgio_header *hdr,
        hdr->timestamp   = jiffies;
 
        msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_WRITE];
-       nfs4_init_sequence(&hdr->args.seq_args, &hdr->res.seq_res, 1, 0);
+       nfs4_init_sequence(&hdr->args.seq_args, &hdr->res.seq_res, 0, 0);
        nfs4_state_protect_write(server->nfs_client, clnt, msg, hdr);
 }
 
@@ -5573,10 +5627,9 @@ static void nfs4_write_cached_acl(struct inode *inode, struct page **pages, size
  */
 static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen)
 {
-       struct page *pages[NFS4ACL_MAXPAGES + 1] = {NULL, };
+       struct page **pages;
        struct nfs_getaclargs args = {
                .fh = NFS_FH(inode),
-               .acl_pages = pages,
                .acl_len = buflen,
        };
        struct nfs_getaclres res = {
@@ -5587,11 +5640,19 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu
                .rpc_argp = &args,
                .rpc_resp = &res,
        };
-       unsigned int npages = DIV_ROUND_UP(buflen, PAGE_SIZE) + 1;
+       unsigned int npages;
        int ret = -ENOMEM, i;
+       struct nfs_server *server = NFS_SERVER(inode);
 
-       if (npages > ARRAY_SIZE(pages))
-               return -ERANGE;
+       if (buflen == 0)
+               buflen = server->rsize;
+
+       npages = DIV_ROUND_UP(buflen, PAGE_SIZE) + 1;
+       pages = kmalloc_array(npages, sizeof(struct page *), GFP_NOFS);
+       if (!pages)
+               return -ENOMEM;
+
+       args.acl_pages = pages;
 
        for (i = 0; i < npages; i++) {
                pages[i] = alloc_page(GFP_KERNEL);
@@ -5637,6 +5698,7 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu
                        __free_page(pages[i]);
        if (res.acl_scratch)
                __free_page(res.acl_scratch);
+       kfree(pages);
        return ret;
 }
 
@@ -6075,6 +6137,7 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program,
                .callback_data = &setclientid,
                .flags = RPC_TASK_TIMEOUT | RPC_TASK_NO_ROUND_ROBIN,
        };
+       unsigned long now = jiffies;
        int status;
 
        /* nfs_client_id4 */
@@ -6107,6 +6170,9 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program,
                clp->cl_acceptor = rpcauth_stringify_acceptor(setclientid.sc_cred);
                put_rpccred(setclientid.sc_cred);
        }
+
+       if (status == 0)
+               do_renew_lease(clp, now);
 out:
        trace_nfs4_setclientid(clp, status);
        dprintk("NFS reply setclientid: %d\n", status);
@@ -6196,10 +6262,13 @@ static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata)
                task->tk_status = 0;
                break;
        case -NFS4ERR_OLD_STATEID:
-               if (nfs4_refresh_delegation_stateid(&data->stateid, data->inode))
-                       goto out_restart;
-               task->tk_status = 0;
-               break;
+               if (!nfs4_refresh_delegation_stateid(&data->stateid, data->inode))
+                       nfs4_stateid_seqid_inc(&data->stateid);
+               if (data->args.bitmask) {
+                       data->args.bitmask = NULL;
+                       data->res.fattr = NULL;
+               }
+               goto out_restart;
        case -NFS4ERR_ACCESS:
                if (data->args.bitmask) {
                        data->args.bitmask = NULL;
@@ -6214,6 +6283,7 @@ static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata)
                if (exception.retry)
                        goto out_restart;
        }
+       nfs_delegation_mark_returned(data->inode, data->args.stateid);
        data->rpc_status = task->tk_status;
        return;
 out_restart:
@@ -6243,8 +6313,10 @@ static void nfs4_delegreturn_prepare(struct rpc_task *task, void *data)
 
        d_data = (struct nfs4_delegreturndata *)data;
 
-       if (!d_data->lr.roc && nfs4_wait_on_layoutreturn(d_data->inode, task))
+       if (!d_data->lr.roc && nfs4_wait_on_layoutreturn(d_data->inode, task)) {
+               nfs4_sequence_done(task, &d_data->res.seq_res);
                return;
+       }
 
        lo = d_data->args.lr_args ? d_data->args.lr_args->layout : NULL;
        if (lo && !pnfs_layout_is_valid(lo)) {
@@ -6844,7 +6916,7 @@ static void nfs4_handle_setlk_error(struct nfs_server *server, struct nfs4_lock_
        case -NFS4ERR_STALE_STATEID:
                lsp->ls_seqid.flags &= ~NFS_SEQID_CONFIRMED;
                nfs4_schedule_lease_recovery(server->nfs_client);
-       };
+       }
 }
 
 static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *fl, int recovery_type)
@@ -7820,6 +7892,15 @@ nfs41_same_server_scope(struct nfs41_server_scope *a,
 static void
 nfs4_bind_one_conn_to_session_done(struct rpc_task *task, void *calldata)
 {
+       struct nfs41_bind_conn_to_session_args *args = task->tk_msg.rpc_argp;
+       struct nfs_client *clp = args->client;
+
+       switch (task->tk_status) {
+       case -NFS4ERR_BADSESSION:
+       case -NFS4ERR_DEADSESSION:
+               nfs4_schedule_session_recovery(clp->cl_session,
+                               task->tk_status);
+       }
 }
 
 static const struct rpc_call_ops nfs4_bind_one_conn_to_session_ops = {
@@ -8179,6 +8260,7 @@ static int _nfs4_proc_exchange_id(struct nfs_client *clp, const struct cred *cre
        struct rpc_task *task;
        struct nfs41_exchange_id_args *argp;
        struct nfs41_exchange_id_res *resp;
+       unsigned long now = jiffies;
        int status;
 
        task = nfs4_run_exchange_id(clp, cred, sp4_how, NULL);
@@ -8199,6 +8281,8 @@ static int _nfs4_proc_exchange_id(struct nfs_client *clp, const struct cred *cre
        if (status != 0)
                goto out;
 
+       do_renew_lease(clp, now);
+
        clp->cl_clientid = resp->clientid;
        clp->cl_exchange_flags = resp->flags;
        clp->cl_seqid = resp->seqid;
@@ -8602,7 +8686,7 @@ static int _nfs4_proc_create_session(struct nfs_client *clp,
        case -EACCES:
        case -EAGAIN:
                goto out;
-       };
+       }
 
        clp->cl_seqid++;
        if (!status) {
@@ -8867,8 +8951,6 @@ static int nfs41_reclaim_complete_handle_errors(struct rpc_task *task, struct nf
        case -NFS4ERR_BADSESSION:
        case -NFS4ERR_DEADSESSION:
        case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
-               nfs4_schedule_session_recovery(clp->cl_session,
-                               task->tk_status);
                break;
        default:
                nfs4_schedule_lease_recovery(clp);
@@ -9897,6 +9979,7 @@ static const struct nfs4_minor_version_ops nfs_v4_2_minor_ops = {
                | NFS_CAP_ALLOCATE
                | NFS_CAP_COPY
                | NFS_CAP_OFFLOAD_CANCEL
+               | NFS_CAP_COPY_NOTIFY
                | NFS_CAP_DEALLOCATE
                | NFS_CAP_SEEK
                | NFS_CAP_LAYOUTSTATS
@@ -9978,7 +10061,7 @@ const struct nfs_rpc_ops nfs_v4_clientops = {
        .file_ops       = &nfs4_file_operations,
        .getroot        = nfs4_proc_get_root,
        .submount       = nfs4_submount,
-       .try_mount      = nfs4_try_mount,
+       .try_get_tree   = nfs4_try_get_tree,
        .getattr        = nfs4_proc_getattr,
        .setattr        = nfs4_proc_setattr,
        .lookup         = nfs4_proc_lookup,