aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4proc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r--fs/nfs/nfs4proc.c76
1 files changed, 66 insertions, 10 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 14881594dd07..327b8c34d360 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -2461,14 +2461,15 @@ static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata,
2461 2461
2462 dentry = opendata->dentry; 2462 dentry = opendata->dentry;
2463 if (d_really_is_negative(dentry)) { 2463 if (d_really_is_negative(dentry)) {
2464 /* FIXME: Is this d_drop() ever needed? */ 2464 struct dentry *alias;
2465 d_drop(dentry); 2465 d_drop(dentry);
2466 dentry = d_add_unique(dentry, igrab(state->inode)); 2466 alias = d_exact_alias(dentry, state->inode);
2467 if (dentry == NULL) { 2467 if (!alias)
2468 dentry = opendata->dentry; 2468 alias = d_splice_alias(igrab(state->inode), dentry);
2469 } else { 2469 /* d_splice_alias() can't fail here - it's a non-directory */
2470 if (alias) {
2470 dput(ctx->dentry); 2471 dput(ctx->dentry);
2471 ctx->dentry = dentry; 2472 ctx->dentry = dentry = alias;
2472 } 2473 }
2473 nfs_set_verifier(dentry, 2474 nfs_set_verifier(dentry,
2474 nfs_save_change_attribute(d_inode(opendata->dir))); 2475 nfs_save_change_attribute(d_inode(opendata->dir)));
@@ -6782,13 +6783,26 @@ nfs41_same_server_scope(struct nfs41_server_scope *a,
6782 return false; 6783 return false;
6783} 6784}
6784 6785
6786static void
6787nfs4_bind_one_conn_to_session_done(struct rpc_task *task, void *calldata)
6788{
6789}
6790
6791static const struct rpc_call_ops nfs4_bind_one_conn_to_session_ops = {
6792 .rpc_call_done = &nfs4_bind_one_conn_to_session_done,
6793};
6794
6785/* 6795/*
6786 * nfs4_proc_bind_conn_to_session() 6796 * nfs4_proc_bind_one_conn_to_session()
6787 * 6797 *
6788 * The 4.1 client currently uses the same TCP connection for the 6798 * The 4.1 client currently uses the same TCP connection for the
6789 * fore and backchannel. 6799 * fore and backchannel.
6790 */ 6800 */
6791int nfs4_proc_bind_conn_to_session(struct nfs_client *clp, struct rpc_cred *cred) 6801static
6802int nfs4_proc_bind_one_conn_to_session(struct rpc_clnt *clnt,
6803 struct rpc_xprt *xprt,
6804 struct nfs_client *clp,
6805 struct rpc_cred *cred)
6792{ 6806{
6793 int status; 6807 int status;
6794 struct nfs41_bind_conn_to_session_args args = { 6808 struct nfs41_bind_conn_to_session_args args = {
@@ -6803,6 +6817,14 @@ int nfs4_proc_bind_conn_to_session(struct nfs_client *clp, struct rpc_cred *cred
6803 .rpc_resp = &res, 6817 .rpc_resp = &res,
6804 .rpc_cred = cred, 6818 .rpc_cred = cred,
6805 }; 6819 };
6820 struct rpc_task_setup task_setup_data = {
6821 .rpc_client = clnt,
6822 .rpc_xprt = xprt,
6823 .callback_ops = &nfs4_bind_one_conn_to_session_ops,
6824 .rpc_message = &msg,
6825 .flags = RPC_TASK_TIMEOUT,
6826 };
6827 struct rpc_task *task;
6806 6828
6807 dprintk("--> %s\n", __func__); 6829 dprintk("--> %s\n", __func__);
6808 6830
@@ -6810,7 +6832,16 @@ int nfs4_proc_bind_conn_to_session(struct nfs_client *clp, struct rpc_cred *cred
6810 if (!(clp->cl_session->flags & SESSION4_BACK_CHAN)) 6832 if (!(clp->cl_session->flags & SESSION4_BACK_CHAN))
6811 args.dir = NFS4_CDFC4_FORE; 6833 args.dir = NFS4_CDFC4_FORE;
6812 6834
6813 status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); 6835 /* Do not set the backchannel flag unless this is clnt->cl_xprt */
6836 if (xprt != rcu_access_pointer(clnt->cl_xprt))
6837 args.dir = NFS4_CDFC4_FORE;
6838
6839 task = rpc_run_task(&task_setup_data);
6840 if (!IS_ERR(task)) {
6841 status = task->tk_status;
6842 rpc_put_task(task);
6843 } else
6844 status = PTR_ERR(task);
6814 trace_nfs4_bind_conn_to_session(clp, status); 6845 trace_nfs4_bind_conn_to_session(clp, status);
6815 if (status == 0) { 6846 if (status == 0) {
6816 if (memcmp(res.sessionid.data, 6847 if (memcmp(res.sessionid.data,
@@ -6837,6 +6868,31 @@ out:
6837 return status; 6868 return status;
6838} 6869}
6839 6870
6871struct rpc_bind_conn_calldata {
6872 struct nfs_client *clp;
6873 struct rpc_cred *cred;
6874};
6875
6876static int
6877nfs4_proc_bind_conn_to_session_callback(struct rpc_clnt *clnt,
6878 struct rpc_xprt *xprt,
6879 void *calldata)
6880{
6881 struct rpc_bind_conn_calldata *p = calldata;
6882
6883 return nfs4_proc_bind_one_conn_to_session(clnt, xprt, p->clp, p->cred);
6884}
6885
6886int nfs4_proc_bind_conn_to_session(struct nfs_client *clp, struct rpc_cred *cred)
6887{
6888 struct rpc_bind_conn_calldata data = {
6889 .clp = clp,
6890 .cred = cred,
6891 };
6892 return rpc_clnt_iterate_for_each_xprt(clp->cl_rpcclient,
6893 nfs4_proc_bind_conn_to_session_callback, &data);
6894}
6895
6840/* 6896/*
6841 * Minimum set of SP4_MACH_CRED operations from RFC 5661 in the enforce map 6897 * Minimum set of SP4_MACH_CRED operations from RFC 5661 in the enforce map
6842 * and operations we'd like to see to enable certain features in the allow map 6898 * and operations we'd like to see to enable certain features in the allow map
@@ -7319,7 +7375,7 @@ static void nfs4_init_channel_attrs(struct nfs41_create_session_args *args)
7319 args->bc_attrs.max_resp_sz = PAGE_SIZE; 7375 args->bc_attrs.max_resp_sz = PAGE_SIZE;
7320 args->bc_attrs.max_resp_sz_cached = 0; 7376 args->bc_attrs.max_resp_sz_cached = 0;
7321 args->bc_attrs.max_ops = NFS4_MAX_BACK_CHANNEL_OPS; 7377 args->bc_attrs.max_ops = NFS4_MAX_BACK_CHANNEL_OPS;
7322 args->bc_attrs.max_reqs = 1; 7378 args->bc_attrs.max_reqs = NFS41_BC_MAX_CALLBACKS;
7323 7379
7324 dprintk("%s: Back Channel : max_rqst_sz=%u max_resp_sz=%u " 7380 dprintk("%s: Back Channel : max_rqst_sz=%u max_resp_sz=%u "
7325 "max_resp_sz_cached=%u max_ops=%u max_reqs=%u\n", 7381 "max_resp_sz_cached=%u max_ops=%u max_reqs=%u\n",