* [PATCH] SUNRPC: Clean up xprt_release()
@ 2010-04-16 20:47 Trond Myklebust
2010-04-16 20:47 ` [PATCH] SUNRPC: Cleanup - make rpc_new_task() call rpc_release_calldata on failure Trond Myklebust
0 siblings, 1 reply; 8+ messages in thread
From: Trond Myklebust @ 2010-04-16 20:47 UTC (permalink / raw)
To: linux-nfs
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
---
net/sunrpc/xprt.c | 32 ++++++++++++++++----------------
1 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index 42f09ad..18415cc 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -62,7 +62,6 @@
* Local functions
*/
static void xprt_request_init(struct rpc_task *, struct rpc_xprt *);
-static inline void do_xprt_reserve(struct rpc_task *);
static void xprt_connect_status(struct rpc_task *task);
static int __xprt_get_cong(struct rpc_xprt *, struct rpc_task *);
@@ -935,7 +934,7 @@ void xprt_transmit(struct rpc_task *task)
spin_unlock_bh(&xprt->transport_lock);
}
-static inline void do_xprt_reserve(struct rpc_task *task)
+static void xprt_alloc_slot(struct rpc_task *task)
{
struct rpc_xprt *xprt = task->tk_xprt;
@@ -955,6 +954,16 @@ static inline void do_xprt_reserve(struct rpc_task *task)
rpc_sleep_on(&xprt->backlog, task, NULL);
}
+static void xprt_free_slot(struct rpc_xprt *xprt, struct rpc_rqst *req)
+{
+ memset(req, 0, sizeof(*req)); /* mark unused */
+
+ spin_lock(&xprt->reserve_lock);
+ list_add(&req->rq_list, &xprt->free);
+ rpc_wake_up_next(&xprt->backlog);
+ spin_unlock(&xprt->reserve_lock);
+}
+
/**
* xprt_reserve - allocate an RPC request slot
* @task: RPC task requesting a slot allocation
@@ -968,7 +977,7 @@ void xprt_reserve(struct rpc_task *task)
task->tk_status = -EIO;
spin_lock(&xprt->reserve_lock);
- do_xprt_reserve(task);
+ xprt_alloc_slot(task);
spin_unlock(&xprt->reserve_lock);
}
@@ -1006,14 +1015,10 @@ void xprt_release(struct rpc_task *task)
{
struct rpc_xprt *xprt;
struct rpc_rqst *req;
- int is_bc_request;
if (!(req = task->tk_rqstp))
return;
- /* Preallocated backchannel request? */
- is_bc_request = bc_prealloc(req);
-
xprt = req->rq_xprt;
rpc_count_iostats(task);
spin_lock_bh(&xprt->transport_lock);
@@ -1027,21 +1032,16 @@ void xprt_release(struct rpc_task *task)
mod_timer(&xprt->timer,
xprt->last_used + xprt->idle_timeout);
spin_unlock_bh(&xprt->transport_lock);
- if (!bc_prealloc(req))
+ if (req->rq_buffer)
xprt->ops->buf_free(req->rq_buffer);
task->tk_rqstp = NULL;
if (req->rq_release_snd_buf)
req->rq_release_snd_buf(req);
dprintk("RPC: %5u release request %p\n", task->tk_pid, req);
- if (likely(!is_bc_request)) {
- memset(req, 0, sizeof(*req)); /* mark unused */
-
- spin_lock(&xprt->reserve_lock);
- list_add(&req->rq_list, &xprt->free);
- rpc_wake_up_next(&xprt->backlog);
- spin_unlock(&xprt->reserve_lock);
- } else
+ if (likely(!bc_prealloc(req)))
+ xprt_free_slot(xprt, req);
+ else
xprt_free_bc_request(req);
}
--
1.6.6.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH] SUNRPC: Cleanup - make rpc_new_task() call rpc_release_calldata on failure
2010-04-16 20:47 [PATCH] SUNRPC: Clean up xprt_release() Trond Myklebust
@ 2010-04-16 20:47 ` Trond Myklebust
2010-04-16 20:47 ` [PATCH] SUNRPC: Move the test for XPRT_CONNECTING into xprt_connect() Trond Myklebust
0 siblings, 1 reply; 8+ messages in thread
From: Trond Myklebust @ 2010-04-16 20:47 UTC (permalink / raw)
To: linux-nfs
Also have it return an ERR_PTR(-ENOMEM) instead of a null pointer.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
---
net/sunrpc/clnt.c | 19 ++++---------------
net/sunrpc/sched.c | 13 ++++++++++---
2 files changed, 14 insertions(+), 18 deletions(-)
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 19c9983..8c7b543 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -556,26 +556,16 @@ static const struct rpc_call_ops rpc_default_ops = {
*/
struct rpc_task *rpc_run_task(const struct rpc_task_setup *task_setup_data)
{
- struct rpc_task *task, *ret;
+ struct rpc_task *task;
task = rpc_new_task(task_setup_data);
- if (task == NULL) {
- rpc_release_calldata(task_setup_data->callback_ops,
- task_setup_data->callback_data);
- ret = ERR_PTR(-ENOMEM);
+ if (IS_ERR(task))
goto out;
- }
- if (task->tk_status != 0) {
- ret = ERR_PTR(task->tk_status);
- rpc_put_task(task);
- goto out;
- }
atomic_inc(&task->tk_count);
rpc_execute(task);
- ret = task;
out:
- return ret;
+ return task;
}
EXPORT_SYMBOL_GPL(rpc_run_task);
@@ -657,9 +647,8 @@ struct rpc_task *rpc_run_bc_task(struct rpc_rqst *req,
* Create an rpc_task to send the data
*/
task = rpc_new_task(&task_setup_data);
- if (!task) {
+ if (IS_ERR(task)) {
xprt_free_bc_request(req);
- task = ERR_PTR(-ENOMEM);
goto out;
}
task->tk_rqstp = req;
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index aae6907..c8979ce 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -856,16 +856,23 @@ struct rpc_task *rpc_new_task(const struct rpc_task_setup *setup_data)
if (task == NULL) {
task = rpc_alloc_task();
- if (task == NULL)
- goto out;
+ if (task == NULL) {
+ rpc_release_calldata(setup_data->callback_ops,
+ setup_data->callback_data);
+ return ERR_PTR(-ENOMEM);
+ }
flags = RPC_TASK_DYNAMIC;
}
rpc_init_task(task, setup_data);
+ if (task->tk_status < 0) {
+ int err = task->tk_status;
+ rpc_put_task(task);
+ return ERR_PTR(err);
+ }
task->tk_flags |= flags;
dprintk("RPC: allocated task %p\n", task);
-out:
return task;
}
--
1.6.6.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH] SUNRPC: Move the test for XPRT_CONNECTING into xprt_connect()
2010-04-16 20:47 ` [PATCH] SUNRPC: Cleanup - make rpc_new_task() call rpc_release_calldata on failure Trond Myklebust
@ 2010-04-16 20:47 ` Trond Myklebust
2010-04-16 20:47 ` [PATCH] SUNRPC: Fail over more quickly on connect errors Trond Myklebust
0 siblings, 1 reply; 8+ messages in thread
From: Trond Myklebust @ 2010-04-16 20:47 UTC (permalink / raw)
To: linux-nfs
This fixes a bug with setting xprt->stat.connect_start.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
---
net/sunrpc/xprt.c | 6 +++++-
net/sunrpc/xprtrdma/transport.c | 28 +++++++++++++---------------
net/sunrpc/xprtsock.c | 15 +--------------
3 files changed, 19 insertions(+), 30 deletions(-)
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index 18415cc..c71d835 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -712,10 +712,14 @@ void xprt_connect(struct rpc_task *task)
task->tk_timeout = xprt->connect_timeout;
rpc_sleep_on(&xprt->pending, task, xprt_connect_status);
+
+ if (test_bit(XPRT_CLOSING, &xprt->state))
+ return;
+ if (xprt_test_and_set_connecting(xprt))
+ return;
xprt->stat.connect_start = jiffies;
xprt->ops->connect(task);
}
- return;
}
static void xprt_connect_status(struct rpc_task *task)
diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c
index 187257b..0607b9a 100644
--- a/net/sunrpc/xprtrdma/transport.c
+++ b/net/sunrpc/xprtrdma/transport.c
@@ -449,21 +449,19 @@ xprt_rdma_connect(struct rpc_task *task)
struct rpc_xprt *xprt = (struct rpc_xprt *)task->tk_xprt;
struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt);
- if (!xprt_test_and_set_connecting(xprt)) {
- if (r_xprt->rx_ep.rep_connected != 0) {
- /* Reconnect */
- schedule_delayed_work(&r_xprt->rdma_connect,
- xprt->reestablish_timeout);
- xprt->reestablish_timeout <<= 1;
- if (xprt->reestablish_timeout > (30 * HZ))
- xprt->reestablish_timeout = (30 * HZ);
- else if (xprt->reestablish_timeout < (5 * HZ))
- xprt->reestablish_timeout = (5 * HZ);
- } else {
- schedule_delayed_work(&r_xprt->rdma_connect, 0);
- if (!RPC_IS_ASYNC(task))
- flush_scheduled_work();
- }
+ if (r_xprt->rx_ep.rep_connected != 0) {
+ /* Reconnect */
+ schedule_delayed_work(&r_xprt->rdma_connect,
+ xprt->reestablish_timeout);
+ xprt->reestablish_timeout <<= 1;
+ if (xprt->reestablish_timeout > (30 * HZ))
+ xprt->reestablish_timeout = (30 * HZ);
+ else if (xprt->reestablish_timeout < (5 * HZ))
+ xprt->reestablish_timeout = (5 * HZ);
+ } else {
+ schedule_delayed_work(&r_xprt->rdma_connect, 0);
+ if (!RPC_IS_ASYNC(task))
+ flush_scheduled_work();
}
}
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 9847c30..d138afa 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -2016,9 +2016,6 @@ static void xs_connect(struct rpc_task *task)
struct rpc_xprt *xprt = task->tk_xprt;
struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
- if (xprt_test_and_set_connecting(xprt))
- return;
-
if (transport->sock != NULL && !RPC_IS_SOFTCONN(task)) {
dprintk("RPC: xs_connect delayed xprt %p for %lu "
"seconds\n",
@@ -2038,16 +2035,6 @@ static void xs_connect(struct rpc_task *task)
}
}
-static void xs_tcp_connect(struct rpc_task *task)
-{
- struct rpc_xprt *xprt = task->tk_xprt;
-
- /* Exit if we need to wait for socket shutdown to complete */
- if (test_bit(XPRT_CLOSING, &xprt->state))
- return;
- xs_connect(task);
-}
-
/**
* xs_udp_print_stats - display UDP socket-specifc stats
* @xprt: rpc_xprt struct containing statistics
@@ -2246,7 +2233,7 @@ static struct rpc_xprt_ops xs_tcp_ops = {
.release_xprt = xs_tcp_release_xprt,
.rpcbind = rpcb_getport_async,
.set_port = xs_set_port,
- .connect = xs_tcp_connect,
+ .connect = xs_connect,
.buf_alloc = rpc_malloc,
.buf_free = rpc_free,
.send_request = xs_tcp_send_request,
--
1.6.6.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH] SUNRPC: Fail over more quickly on connect errors
2010-04-16 20:47 ` [PATCH] SUNRPC: Move the test for XPRT_CONNECTING into xprt_connect() Trond Myklebust
@ 2010-04-16 20:47 ` Trond Myklebust
2010-04-16 20:47 ` [PATCH] NFSv4: Allow attribute caching with 'noac' mounts if client holds a delegation Trond Myklebust
2010-04-16 22:29 ` [PATCH] SUNRPC: Fail over more quickly on connect errors Trond Myklebust
0 siblings, 2 replies; 8+ messages in thread
From: Trond Myklebust @ 2010-04-16 20:47 UTC (permalink / raw)
To: linux-nfs
We should not allow soft tasks to wait for longer than the major timeout
period when waiting for a reconnect to occur.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
---
net/sunrpc/xprt.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index c71d835..01449a3 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -710,7 +710,7 @@ void xprt_connect(struct rpc_task *task)
if (task->tk_rqstp)
task->tk_rqstp->rq_bytes_sent = 0;
- task->tk_timeout = xprt->connect_timeout;
+ task->tk_timeout = min(req->rq_timeout, xprt->connect_timeout);
rpc_sleep_on(&xprt->pending, task, xprt_connect_status);
if (test_bit(XPRT_CLOSING, &xprt->state))
--
1.6.6.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH] NFSv4: Allow attribute caching with 'noac' mounts if client holds a delegation
2010-04-16 20:47 ` [PATCH] SUNRPC: Fail over more quickly on connect errors Trond Myklebust
@ 2010-04-16 20:47 ` Trond Myklebust
2010-04-16 20:47 ` [PATCH] NFSv4: Clean up the NFSv4 setclientid operation Trond Myklebust
2010-04-16 22:29 ` [PATCH] SUNRPC: Fail over more quickly on connect errors Trond Myklebust
1 sibling, 1 reply; 8+ messages in thread
From: Trond Myklebust @ 2010-04-16 20:47 UTC (permalink / raw)
To: linux-nfs
If the server has given us a delegation on a file, we _know_ that we can
cache the attribute information even when the user has specified 'noac'.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
---
fs/nfs/file.c | 15 +++++++++------
fs/nfs/inode.c | 12 +++++++++---
2 files changed, 18 insertions(+), 9 deletions(-)
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 8d965bd..cac96bc 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -161,14 +161,17 @@ static int nfs_revalidate_file_size(struct inode *inode, struct file *filp)
struct nfs_server *server = NFS_SERVER(inode);
struct nfs_inode *nfsi = NFS_I(inode);
- if (server->flags & NFS_MOUNT_NOAC)
- goto force_reval;
+ if (nfs_have_delegated_attributes(inode))
+ goto out_noreval;
+
if (filp->f_flags & O_DIRECT)
goto force_reval;
- if (nfsi->npages != 0)
- return 0;
- if (!(nfsi->cache_validity & NFS_INO_REVAL_PAGECACHE) && !nfs_attribute_timeout(inode))
- return 0;
+ if (nfsi->cache_validity & NFS_INO_REVAL_PAGECACHE)
+ goto force_reval;
+ if (nfs_attribute_timeout(inode))
+ goto force_reval;
+out_noreval:
+ return 0;
force_reval:
return __nfs_revalidate_inode(server, inode);
}
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 50a56ed..69da585 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -730,9 +730,14 @@ int nfs_attribute_timeout(struct inode *inode)
{
struct nfs_inode *nfsi = NFS_I(inode);
+ return !time_in_range_open(jiffies, nfsi->read_cache_jiffies, nfsi->read_cache_jiffies + nfsi->attrtimeo);
+}
+
+static int nfs_attribute_cache_expired(struct inode *inode)
+{
if (nfs_have_delegated_attributes(inode))
return 0;
- return !time_in_range_open(jiffies, nfsi->read_cache_jiffies, nfsi->read_cache_jiffies + nfsi->attrtimeo);
+ return nfs_attribute_timeout(inode);
}
/**
@@ -745,7 +750,7 @@ int nfs_attribute_timeout(struct inode *inode)
int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
{
if (!(NFS_I(inode)->cache_validity & NFS_INO_INVALID_ATTR)
- && !nfs_attribute_timeout(inode))
+ && !nfs_attribute_cache_expired(inode))
return NFS_STALE(inode) ? -ESTALE : 0;
return __nfs_revalidate_inode(server, inode);
}
@@ -782,7 +787,8 @@ int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping)
int ret = 0;
if ((nfsi->cache_validity & NFS_INO_REVAL_PAGECACHE)
- || nfs_attribute_timeout(inode) || NFS_STALE(inode)) {
+ || nfs_attribute_cache_expired(inode)
+ || NFS_STALE(inode)) {
ret = __nfs_revalidate_inode(NFS_SERVER(inode), inode);
if (ret < 0)
goto out;
--
1.6.6.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH] NFSv4: Clean up the NFSv4 setclientid operation
2010-04-16 20:47 ` [PATCH] NFSv4: Allow attribute caching with 'noac' mounts if client holds a delegation Trond Myklebust
@ 2010-04-16 20:47 ` Trond Myklebust
0 siblings, 0 replies; 8+ messages in thread
From: Trond Myklebust @ 2010-04-16 20:47 UTC (permalink / raw)
To: linux-nfs
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
---
fs/nfs/nfs4_fs.h | 4 ++--
fs/nfs/nfs4proc.c | 18 ++++++++++++------
fs/nfs/nfs4state.c | 15 ++++++++++-----
fs/nfs/nfs4xdr.c | 20 ++++++++++----------
include/linux/nfs_fs_sb.h | 1 -
include/linux/nfs_xdr.h | 5 +++++
6 files changed, 39 insertions(+), 24 deletions(-)
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index a187200..5099306 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -206,8 +206,8 @@ extern ssize_t nfs4_listxattr(struct dentry *, char *, size_t);
/* nfs4proc.c */
-extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struct rpc_cred *);
-extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct rpc_cred *);
+extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struct rpc_cred *, struct nfs4_setclientid_res *);
+extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct nfs4_setclientid_res *arg, struct rpc_cred *);
extern int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred);
extern int nfs4_proc_async_renew(struct nfs_client *, struct rpc_cred *);
extern int nfs4_proc_renew(struct nfs_client *, struct rpc_cred *);
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 6380670..8a9a412 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -3494,7 +3494,9 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
return _nfs4_async_handle_error(task, server, server->nfs_client, state);
}
-int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, unsigned short port, struct rpc_cred *cred)
+int nfs4_proc_setclientid(struct nfs_client *clp, u32 program,
+ unsigned short port, struct rpc_cred *cred,
+ struct nfs4_setclientid_res *res)
{
nfs4_verifier sc_verifier;
struct nfs4_setclientid setclientid = {
@@ -3504,7 +3506,7 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, unsigned short po
struct rpc_message msg = {
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID],
.rpc_argp = &setclientid,
- .rpc_resp = clp,
+ .rpc_resp = res,
.rpc_cred = cred,
};
__be32 *p;
@@ -3547,12 +3549,14 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, unsigned short po
return status;
}
-static int _nfs4_proc_setclientid_confirm(struct nfs_client *clp, struct rpc_cred *cred)
+static int _nfs4_proc_setclientid_confirm(struct nfs_client *clp,
+ struct nfs4_setclientid_res *arg,
+ struct rpc_cred *cred)
{
struct nfs_fsinfo fsinfo;
struct rpc_message msg = {
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID_CONFIRM],
- .rpc_argp = clp,
+ .rpc_argp = arg,
.rpc_resp = &fsinfo,
.rpc_cred = cred,
};
@@ -3570,12 +3574,14 @@ static int _nfs4_proc_setclientid_confirm(struct nfs_client *clp, struct rpc_cre
return status;
}
-int nfs4_proc_setclientid_confirm(struct nfs_client *clp, struct rpc_cred *cred)
+int nfs4_proc_setclientid_confirm(struct nfs_client *clp,
+ struct nfs4_setclientid_res *arg,
+ struct rpc_cred *cred)
{
long timeout = 0;
int err;
do {
- err = _nfs4_proc_setclientid_confirm(clp, cred);
+ err = _nfs4_proc_setclientid_confirm(clp, arg, cred);
switch (err) {
case 0:
return err;
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 6c5ed51..cd2d904 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -62,6 +62,7 @@ static LIST_HEAD(nfs4_clientid_list);
int nfs4_init_clientid(struct nfs_client *clp, struct rpc_cred *cred)
{
+ struct nfs4_setclientid_res clid;
unsigned short port;
int status;
@@ -69,11 +70,15 @@ int nfs4_init_clientid(struct nfs_client *clp, struct rpc_cred *cred)
if (clp->cl_addr.ss_family == AF_INET6)
port = nfs_callback_tcpport6;
- status = nfs4_proc_setclientid(clp, NFS4_CALLBACK, port, cred);
- if (status == 0)
- status = nfs4_proc_setclientid_confirm(clp, cred);
- if (status == 0)
- nfs4_schedule_state_renewal(clp);
+ status = nfs4_proc_setclientid(clp, NFS4_CALLBACK, port, cred, &clid);
+ if (status != 0)
+ goto out;
+ status = nfs4_proc_setclientid_confirm(clp, &clid, cred);
+ if (status != 0)
+ goto out;
+ clp->cl_clientid = clid.clientid;
+ nfs4_schedule_state_renewal(clp);
+out:
return status;
}
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 38f3b58..d66f9ac 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -1504,14 +1504,14 @@ static void encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclie
hdr->replen += decode_setclientid_maxsz;
}
-static void encode_setclientid_confirm(struct xdr_stream *xdr, const struct nfs_client *client_state, struct compound_hdr *hdr)
+static void encode_setclientid_confirm(struct xdr_stream *xdr, const struct nfs4_setclientid_res *arg, struct compound_hdr *hdr)
{
__be32 *p;
p = reserve_space(xdr, 12 + NFS4_VERIFIER_SIZE);
*p++ = cpu_to_be32(OP_SETCLIENTID_CONFIRM);
- p = xdr_encode_hyper(p, client_state->cl_clientid);
- xdr_encode_opaque_fixed(p, client_state->cl_confirm.data, NFS4_VERIFIER_SIZE);
+ p = xdr_encode_hyper(p, arg->clientid);
+ xdr_encode_opaque_fixed(p, arg->confirm.data, NFS4_VERIFIER_SIZE);
hdr->nops++;
hdr->replen += decode_setclientid_confirm_maxsz;
}
@@ -2324,7 +2324,7 @@ static int nfs4_xdr_enc_setclientid(struct rpc_rqst *req, __be32 *p, struct nfs4
/*
* a SETCLIENTID_CONFIRM request
*/
-static int nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req, __be32 *p, struct nfs_client *clp)
+static int nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req, __be32 *p, struct nfs4_setclientid_res *arg)
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
@@ -2334,7 +2334,7 @@ static int nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req, __be32 *p, str
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
encode_compound_hdr(&xdr, req, &hdr);
- encode_setclientid_confirm(&xdr, clp, &hdr);
+ encode_setclientid_confirm(&xdr, arg, &hdr);
encode_putrootfh(&xdr, &hdr);
encode_fsinfo(&xdr, lease_bitmap, &hdr);
encode_nops(&hdr);
@@ -4397,7 +4397,7 @@ out_overflow:
return -EIO;
}
-static int decode_setclientid(struct xdr_stream *xdr, struct nfs_client *clp)
+static int decode_setclientid(struct xdr_stream *xdr, struct nfs4_setclientid_res *res)
{
__be32 *p;
uint32_t opnum;
@@ -4417,8 +4417,8 @@ static int decode_setclientid(struct xdr_stream *xdr, struct nfs_client *clp)
p = xdr_inline_decode(xdr, 8 + NFS4_VERIFIER_SIZE);
if (unlikely(!p))
goto out_overflow;
- p = xdr_decode_hyper(p, &clp->cl_clientid);
- memcpy(clp->cl_confirm.data, p, NFS4_VERIFIER_SIZE);
+ p = xdr_decode_hyper(p, &res->clientid);
+ memcpy(res->confirm.data, p, NFS4_VERIFIER_SIZE);
} else if (nfserr == NFSERR_CLID_INUSE) {
uint32_t len;
@@ -5498,7 +5498,7 @@ static int nfs4_xdr_dec_renew(struct rpc_rqst *rqstp, __be32 *p, void *dummy)
* Decode SETCLIENTID response
*/
static int nfs4_xdr_dec_setclientid(struct rpc_rqst *req, __be32 *p,
- struct nfs_client *clp)
+ struct nfs4_setclientid_res *res)
{
struct xdr_stream xdr;
struct compound_hdr hdr;
@@ -5507,7 +5507,7 @@ static int nfs4_xdr_dec_setclientid(struct rpc_rqst *req, __be32 *p,
xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
status = decode_compound_hdr(&xdr, &hdr);
if (!status)
- status = decode_setclientid(&xdr, clp);
+ status = decode_setclientid(&xdr, res);
return status;
}
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index e82957a..d6e10a4 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -44,7 +44,6 @@ struct nfs_client {
#ifdef CONFIG_NFS_V4
u64 cl_clientid; /* constant */
- nfs4_verifier cl_confirm;
unsigned long cl_state;
struct rb_root cl_openowner_id;
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index 89b2881..6b31645 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -824,6 +824,11 @@ struct nfs4_setclientid {
u32 sc_cb_ident;
};
+struct nfs4_setclientid_res {
+ u64 clientid;
+ nfs4_verifier confirm;
+};
+
struct nfs4_statfs_arg {
const struct nfs_fh * fh;
const u32 * bitmask;
--
1.6.6.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH] SUNRPC: Fail over more quickly on connect errors
2010-04-16 20:47 ` [PATCH] SUNRPC: Fail over more quickly on connect errors Trond Myklebust
2010-04-16 20:47 ` [PATCH] NFSv4: Allow attribute caching with 'noac' mounts if client holds a delegation Trond Myklebust
@ 2010-04-16 22:29 ` Trond Myklebust
2010-04-19 23:35 ` Chuck Lever
1 sibling, 1 reply; 8+ messages in thread
From: Trond Myklebust @ 2010-04-16 22:29 UTC (permalink / raw)
To: linux-nfs
On Fri, 2010-04-16 at 16:47 -0400, Trond Myklebust wrote:
> We should not allow soft tasks to wait for longer than the major timeout
> period when waiting for a reconnect to occur.
>
> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
> ---
> net/sunrpc/xprt.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
> index c71d835..01449a3 100644
> --- a/net/sunrpc/xprt.c
> +++ b/net/sunrpc/xprt.c
> @@ -710,7 +710,7 @@ void xprt_connect(struct rpc_task *task)
> if (task->tk_rqstp)
> task->tk_rqstp->rq_bytes_sent = 0;
>
> - task->tk_timeout = xprt->connect_timeout;
> + task->tk_timeout = min(req->rq_timeout, xprt->connect_timeout);
^^^ task->tk_rqstp->rq_timeout
Apologies. I though I had tested that...
> rpc_sleep_on(&xprt->pending, task, xprt_connect_status);
>
> if (test_bit(XPRT_CLOSING, &xprt->state))
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] SUNRPC: Fail over more quickly on connect errors
2010-04-16 22:29 ` [PATCH] SUNRPC: Fail over more quickly on connect errors Trond Myklebust
@ 2010-04-19 23:35 ` Chuck Lever
0 siblings, 0 replies; 8+ messages in thread
From: Chuck Lever @ 2010-04-19 23:35 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-nfs
On 04/16/2010 06:29 PM, Trond Myklebust wrote:
> On Fri, 2010-04-16 at 16:47 -0400, Trond Myklebust wrote:
>> We should not allow soft tasks to wait for longer than the major timeout
>> period when waiting for a reconnect to occur.
>>
>> Signed-off-by: Trond Myklebust<Trond.Myklebust@netapp.com>
>> ---
>> net/sunrpc/xprt.c | 2 +-
>> 1 files changed, 1 insertions(+), 1 deletions(-)
>>
>> diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
>> index c71d835..01449a3 100644
>> --- a/net/sunrpc/xprt.c
>> +++ b/net/sunrpc/xprt.c
>> @@ -710,7 +710,7 @@ void xprt_connect(struct rpc_task *task)
>> if (task->tk_rqstp)
>> task->tk_rqstp->rq_bytes_sent = 0;
>>
>> - task->tk_timeout = xprt->connect_timeout;
>> + task->tk_timeout = min(req->rq_timeout, xprt->connect_timeout);
> ^^^ task->tk_rqstp->rq_timeout
>
> Apologies. I though I had tested that...
>
>> rpc_sleep_on(&xprt->pending, task, xprt_connect_status);
>>
>> if (test_bit(XPRT_CLOSING,&xprt->state))
I tested this series of patches with soft mounts, and RPC requests now
fail, after the timeout period, if the client can't reconnect.
I also observed appropriate exponential back-off behavior as the client
attempts to reconnect. I would suggest one more patch to reduce the
reestablish timeout maximum to 30 seconds.
For the series:
Reviewed-by: Chuck Lever <chuck.lever@oracle.com>
and/or
Tested-by: Chuck Lever <chuck.lever@oracle.com>
--
chuck[dot]lever[at]oracle[dot]com
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2010-04-19 23:36 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-04-16 20:47 [PATCH] SUNRPC: Clean up xprt_release() Trond Myklebust
2010-04-16 20:47 ` [PATCH] SUNRPC: Cleanup - make rpc_new_task() call rpc_release_calldata on failure Trond Myklebust
2010-04-16 20:47 ` [PATCH] SUNRPC: Move the test for XPRT_CONNECTING into xprt_connect() Trond Myklebust
2010-04-16 20:47 ` [PATCH] SUNRPC: Fail over more quickly on connect errors Trond Myklebust
2010-04-16 20:47 ` [PATCH] NFSv4: Allow attribute caching with 'noac' mounts if client holds a delegation Trond Myklebust
2010-04-16 20:47 ` [PATCH] NFSv4: Clean up the NFSv4 setclientid operation Trond Myklebust
2010-04-16 22:29 ` [PATCH] SUNRPC: Fail over more quickly on connect errors Trond Myklebust
2010-04-19 23:35 ` Chuck Lever
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.