* [PATCH 1/1 v2] nfs41: pass state recovery error back to caller @ 2009-09-02 7:48 Benny Halevy 2009-09-02 17:52 ` Trond Myklebust 0 siblings, 1 reply; 13+ messages in thread From: Benny Halevy @ 2009-09-02 7:48 UTC (permalink / raw) To: Trond Myklebust; +Cc: pnfs, linux-nfs Currently the error returned from create_session is ignored by nfs4_check_client_ready and mis-translated to -EPROTONOSUPPORT if the client has a session. Record the error returned from create_session to the state manager in cl_cons_state via nfs_mark_client_ready and pass it upstream in nfs4_recover_expired_lease. Signed-off-by: Benny Halevy <bhalevy@panasas.com> --- This version of the patch is based on top of commit a78cb57a106fceeba26da2907db9d8886700e1dc NFSv4: Don't loop forever on state recovery failure... that's queued for 2.6.32 Benny fs/nfs/client.c | 10 +++------- fs/nfs/nfs4proc.c | 6 ++++++ fs/nfs/nfs4state.c | 2 ++ 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/fs/nfs/client.c b/fs/nfs/client.c index d36925f..79c3ee3 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c @@ -149,6 +149,7 @@ static struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_ clp->cl_boot_time = CURRENT_TIME; clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED; clp->cl_minorversion = cl_init->minorversion; + clp->cl_lease_time = 0; #endif cred = rpc_lookup_machine_cred(); if (!IS_ERR(cred)) @@ -535,16 +536,11 @@ void nfs_mark_client_ready(struct nfs_client *clp, int state) /* * With sessions, the client is not marked ready until after a * successful EXCHANGE_ID and CREATE_SESSION. - * - * Map errors cl_cons_state errors to EPROTONOSUPPORT to indicate - * other versions of NFS can be tried. */ int nfs4_check_client_ready(struct nfs_client *clp) { - if (!nfs4_has_session(clp)) - return 0; - if (clp->cl_cons_state < NFS_CS_READY) - return -EPROTONOSUPPORT; + if (clp->cl_cons_state < 0) + return clp->cl_cons_state; return 0; } diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index be6544a..09f709a 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -1458,6 +1458,12 @@ static int nfs4_recover_expired_lease(struct nfs_server *server) if (!test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) && !test_bit(NFS4CLNT_CHECK_LEASE,&clp->cl_state)) break; + if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) && + clp->cl_lease_time) { + /* fetch the lease reclaim error */ + ret = (int)clp->cl_lease_time; + break; + } nfs4_schedule_state_recovery(clp); ret = -EIO; } diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 65ca8c1..b5c71dc 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c @@ -1220,6 +1220,7 @@ static void nfs4_set_lease_expired(struct nfs_client *clp, int status) return; } } + clp->cl_lease_time = status; set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state); } @@ -1231,6 +1232,7 @@ static void nfs4_state_manager(struct nfs_client *clp) for(;;) { if (test_and_clear_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) { /* We're going to have to re-establish a clientid */ + clp->cl_lease_time = 0; status = nfs4_reclaim_lease(clp); if (status) { nfs4_set_lease_expired(clp, status); -- 1.6.4 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 1/1 v2] nfs41: pass state recovery error back to caller 2009-09-02 7:48 [PATCH 1/1 v2] nfs41: pass state recovery error back to caller Benny Halevy @ 2009-09-02 17:52 ` Trond Myklebust [not found] ` <1251913960.26601.41.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org> 0 siblings, 1 reply; 13+ messages in thread From: Trond Myklebust @ 2009-09-02 17:52 UTC (permalink / raw) To: Benny Halevy; +Cc: pnfs, linux-nfs On Wed, 2009-09-02 at 10:48 +0300, Benny Halevy wrote: > Currently the error returned from create_session > is ignored by nfs4_check_client_ready and mis-translated to > -EPROTONOSUPPORT if the client has a session. > Record the error returned from create_session to the state manager > in cl_cons_state via nfs_mark_client_ready and pass it upstream > in nfs4_recover_expired_lease. > > Signed-off-by: Benny Halevy <bhalevy@panasas.com> > --- Firstly, if you're out to save 4 bytes by sharing storage with an object of an entirely different type, then please use an explicit union. Then use a special state NFS4CLNT_LEASE_RECLAIM_FAILED in order to clearly label what is being stored in that union. Secondly, I'd say that it is more natural to share storage with the client id, cl_ex_clid, rather than using the lease time. The latter is read via an entirely separate RPC call _after_ you are done establishing the lease and the first session. -- Trond Myklebust Linux NFS client maintainer NetApp Trond.Myklebust@netapp.com www.netapp.com ^ permalink raw reply [flat|nested] 13+ messages in thread
[parent not found: <1251913960.26601.41.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org>]
* Re: [PATCH 1/1 v2] nfs41: pass state recovery error back to caller [not found] ` <1251913960.26601.41.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org> @ 2009-09-02 18:06 ` Benny Halevy 2009-09-02 19:09 ` Trond Myklebust 0 siblings, 1 reply; 13+ messages in thread From: Benny Halevy @ 2009-09-02 18:06 UTC (permalink / raw) To: Trond Myklebust; +Cc: pnfs, linux-nfs On Sep. 02, 2009, 20:52 +0300, Trond Myklebust <Trond.Myklebust@netapp.com> wrote: > On Wed, 2009-09-02 at 10:48 +0300, Benny Halevy wrote: >> Currently the error returned from create_session >> is ignored by nfs4_check_client_ready and mis-translated to >> -EPROTONOSUPPORT if the client has a session. >> Record the error returned from create_session to the state manager >> in cl_cons_state via nfs_mark_client_ready and pass it upstream >> in nfs4_recover_expired_lease. >> >> Signed-off-by: Benny Halevy <bhalevy@panasas.com> >> --- > > Firstly, if you're out to save 4 bytes by sharing storage with an object > of an entirely different type, then please use an explicit union. Then > use a special state NFS4CLNT_LEASE_RECLAIM_FAILED in order to clearly > label what is being stored in that union. > OK. Just to make sure, will it be acceptable by you to add a field to struct nfs_client to explicitly keep this status or would you prefer to save these 4 bytes using the union and extra state? > Secondly, I'd say that it is more natural to share storage with the > client id, cl_ex_clid, rather than using the lease time. The latter is > read via an entirely separate RPC call _after_ you are done establishing > the lease and the first session. > I (ab?)used cl_lease_time for this reason as nobody cares about its value at the session establishment phase. (cl_ex_clid is defined under #ifdef CONFIG_NFS_V4_1 so using it for this purpose will be cumbersome...) Benny ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 1/1 v2] nfs41: pass state recovery error back to caller 2009-09-02 18:06 ` Benny Halevy @ 2009-09-02 19:09 ` Trond Myklebust [not found] ` <1251918574.26601.48.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org> 0 siblings, 1 reply; 13+ messages in thread From: Trond Myklebust @ 2009-09-02 19:09 UTC (permalink / raw) To: Benny Halevy; +Cc: pnfs, linux-nfs On Wed, 2009-09-02 at 21:06 +0300, Benny Halevy wrote: > On Sep. 02, 2009, 20:52 +0300, Trond Myklebust <Trond.Myklebust@netapp.com> wrote: > > On Wed, 2009-09-02 at 10:48 +0300, Benny Halevy wrote: > >> Currently the error returned from create_session > >> is ignored by nfs4_check_client_ready and mis-translated to > >> -EPROTONOSUPPORT if the client has a session. > >> Record the error returned from create_session to the state manager > >> in cl_cons_state via nfs_mark_client_ready and pass it upstream > >> in nfs4_recover_expired_lease. > >> > >> Signed-off-by: Benny Halevy <bhalevy@panasas.com> > >> --- > > > > Firstly, if you're out to save 4 bytes by sharing storage with an object > > of an entirely different type, then please use an explicit union. Then > > use a special state NFS4CLNT_LEASE_RECLAIM_FAILED in order to clearly > > label what is being stored in that union. > > > > OK. Just to make sure, will it be acceptable by you to add a field > to struct nfs_client to explicitly keep this status or would you prefer to > save these 4 bytes using the union and extra state? For one thing, I'd like to know why we need to pass these errors up the stack. Normally, the state manager is supposed to be able to handle all recovery issues. > > Secondly, I'd say that it is more natural to share storage with the > > client id, cl_ex_clid, rather than using the lease time. The latter is > > read via an entirely separate RPC call _after_ you are done establishing > > the lease and the first session. > > > > I (ab?)used cl_lease_time for this reason as nobody cares about its > value at the session establishment phase. Are you able to guarantee that no other threads can race with the lease time RPC call? -- Trond Myklebust Linux NFS client maintainer NetApp Trond.Myklebust@netapp.com www.netapp.com ^ permalink raw reply [flat|nested] 13+ messages in thread
[parent not found: <1251918574.26601.48.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org>]
* Re: [PATCH 1/1 v2] nfs41: pass state recovery error back to caller [not found] ` <1251918574.26601.48.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org> @ 2009-09-02 21:04 ` Benny Halevy 2009-09-03 15:15 ` [RFC 1/1] nfs4: optionally return status from state_manager Benny Halevy 0 siblings, 1 reply; 13+ messages in thread From: Benny Halevy @ 2009-09-02 21:04 UTC (permalink / raw) To: Trond Myklebust; +Cc: pnfs, linux-nfs On Sep. 02, 2009, 22:09 +0300, Trond Myklebust <Trond.Myklebust@netapp.com> wrote: > On Wed, 2009-09-02 at 21:06 +0300, Benny Halevy wrote: >> On Sep. 02, 2009, 20:52 +0300, Trond Myklebust <Trond.Myklebust@netapp.com> wrote: >>> On Wed, 2009-09-02 at 10:48 +0300, Benny Halevy wrote: >>>> Currently the error returned from create_session >>>> is ignored by nfs4_check_client_ready and mis-translated to >>>> -EPROTONOSUPPORT if the client has a session. >>>> Record the error returned from create_session to the state manager >>>> in cl_cons_state via nfs_mark_client_ready and pass it upstream >>>> in nfs4_recover_expired_lease. >>>> >>>> Signed-off-by: Benny Halevy <bhalevy@panasas.com> >>>> --- >>> Firstly, if you're out to save 4 bytes by sharing storage with an object >>> of an entirely different type, then please use an explicit union. Then >>> use a special state NFS4CLNT_LEASE_RECLAIM_FAILED in order to clearly >>> label what is being stored in that union. >>> >> OK. Just to make sure, will it be acceptable by you to add a field >> to struct nfs_client to explicitly keep this status or would you prefer to >> save these 4 bytes using the union and extra state? > > For one thing, I'd like to know why we need to pass these errors up the > stack. Normally, the state manager is supposed to be able to handle all > recovery issues. > The error case I'd like to fix is that of the server returning an error on OP_PUROOTFH. In the nfsv4 case we get the error correctly on this path: nfs4_create_server nfs4_path_walk nfs4_get_root: getroot error = 2 The error in this case is returned via the regular rpc path and the state engine is not really involved. However, in the nfsv4.1 case, the failure is different: nfs4_create_server() nfs4_init_session() nfs4_recover_expired_lease() nfs4_schedule_state_recovery() # and the failure happens within the state engine nfs4_proc_create_session() nfs4_proc_get_lease_time() return -2 So, the reason I wanted to pass the status out of the state engine is to return it from nfs4_recover_expired_lease to nfs4_init_session and back to nfs4_create_server. It might be possible to avoid this if we separate out the lease time initialization >>> Secondly, I'd say that it is more natural to share storage with the >>> client id, cl_ex_clid, rather than using the lease time. The latter is >>> read via an entirely separate RPC call _after_ you are done establishing >>> the lease and the first session. >>> >> I (ab?)used cl_lease_time for this reason as nobody cares about its >> value at the session establishment phase. > > Are you able to guarantee that no other threads can race with the lease > time RPC call? > Hmm, good point. If another thread runs the state manager on the same struct nfs_client it might clear clp->cl_lease_time, but it does that after atomically clearing NFS4CLNT_LEASE_EXPIRED in clp->cl_state. Reversing the order and checking for a negative cl_lease_time would have done a safer job (though not absolutely thread safe and presuming cl_lease_time cannot normally be negative)... ret = clp->cl_lease_time; if (ret < 0 && test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) break; Benny ^ permalink raw reply [flat|nested] 13+ messages in thread
* [RFC 1/1] nfs4: optionally return status from state_manager 2009-09-02 21:04 ` Benny Halevy @ 2009-09-03 15:15 ` Benny Halevy 2009-09-25 4:30 ` Ping: [pnfs] " Benny Halevy 0 siblings, 1 reply; 13+ messages in thread From: Benny Halevy @ 2009-09-03 15:15 UTC (permalink / raw) To: Trond Myklebust; +Cc: linux-nfs, pnfs Add an optional pointer to integer parameter to nfs4_schedule_state_manager and store the state_manager status in it, if not NULL. Use it also if the state manager could not be scheduled for kthread_run's error. Signed-off-by: Benny Halevy <bhalevy@panasas.com> --- Trond, Here's an alternative approach to returning the state_manager status to whomever scheduled state recovery, requiring no additrional fields in struct nfs_client and returning the status atomically with the state_manager. Benny fs/nfs/client.c | 6 ++---- fs/nfs/delegation.c | 2 +- fs/nfs/nfs4_fs.h | 4 ++-- fs/nfs/nfs4proc.c | 26 +++++++++++++++++--------- fs/nfs/nfs4state.c | 44 ++++++++++++++++++++++++++++++++------------ 5 files changed, 54 insertions(+), 28 deletions(-) diff --git a/fs/nfs/client.c b/fs/nfs/client.c index d36925f..07ce3ae 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c @@ -541,10 +541,8 @@ void nfs_mark_client_ready(struct nfs_client *clp, int state) */ int nfs4_check_client_ready(struct nfs_client *clp) { - if (!nfs4_has_session(clp)) - return 0; - if (clp->cl_cons_state < NFS_CS_READY) - return -EPROTONOSUPPORT; + if (clp->cl_cons_state < 0) + return clp->cl_cons_state; return 0; } diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index 6dd48a4..af2c3f0 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c @@ -386,7 +386,7 @@ static void nfs_client_mark_return_all_delegations(struct nfs_client *clp) static void nfs_delegation_run_state_manager(struct nfs_client *clp) { if (test_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state)) - nfs4_schedule_state_manager(clp); + nfs4_schedule_state_manager(clp, NULL); } void nfs_expire_all_delegations(struct nfs_client *clp) diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index 6ea07a3..c2ec9bc 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h @@ -264,8 +264,8 @@ extern void nfs4_put_open_state(struct nfs4_state *); extern void nfs4_close_state(struct path *, struct nfs4_state *, fmode_t); extern void nfs4_close_sync(struct path *, struct nfs4_state *, fmode_t); extern void nfs4_state_set_mode_locked(struct nfs4_state *, fmode_t); -extern void nfs4_schedule_state_recovery(struct nfs_client *); -extern void nfs4_schedule_state_manager(struct nfs_client *); +extern void nfs4_schedule_state_recovery(struct nfs_client *, int *statusp); +extern void nfs4_schedule_state_manager(struct nfs_client *, int *statusp); extern int nfs4_state_mark_reclaim_nograce(struct nfs_client *clp, struct nfs4_state *state); extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp); extern int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl); diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 80635eb..d6dc30d 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -247,7 +247,7 @@ static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, case -NFS4ERR_STALE_CLIENTID: case -NFS4ERR_STALE_STATEID: case -NFS4ERR_EXPIRED: - nfs4_schedule_state_recovery(clp); + nfs4_schedule_state_recovery(clp, NULL); ret = nfs4_wait_clnt_recover(clp); if (ret == 0) exception->retry = 1; @@ -429,15 +429,18 @@ static int nfs4_recover_session(struct nfs4_session *session) { struct nfs_client *clp = session->clp; unsigned int loop; - int ret; + int ret, status = 0; for (loop = NFS4_MAX_LOOP_ON_RECOVER; loop != 0; loop--) { ret = nfs4_wait_clnt_recover(clp); if (ret != 0) break; + ret = status; + if (ret != 0) + break; if (!test_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state)) break; - nfs4_schedule_state_manager(clp); + nfs4_schedule_state_manager(clp, &status); ret = -EIO; } return ret; @@ -1183,7 +1186,8 @@ int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state case -NFS4ERR_STALE_STATEID: case -NFS4ERR_EXPIRED: /* Don't recall a delegation if it was lost */ - nfs4_schedule_state_recovery(server->nfs_client); + nfs4_schedule_state_recovery(server->nfs_client, + NULL); goto out; case -ERESTARTSYS: /* @@ -1448,16 +1452,19 @@ static int _nfs4_proc_open(struct nfs4_opendata *data) static int nfs4_recover_expired_lease(struct nfs_client *clp) { unsigned int loop; - int ret; + int ret, status = 0; for (loop = NFS4_MAX_LOOP_ON_RECOVER; loop != 0; loop--) { ret = nfs4_wait_clnt_recover(clp); if (ret != 0) break; + ret = status; + if (ret != 0) + break; if (!test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) && !test_bit(NFS4CLNT_CHECK_LEASE,&clp->cl_state)) break; - nfs4_schedule_state_recovery(clp); + nfs4_schedule_state_recovery(clp, &status); ret = -EIO; } return ret; @@ -3053,7 +3060,7 @@ static void nfs4_renew_done(struct rpc_task *task, void *data) if (task->tk_status < 0) { /* Unless we're shutting down, schedule state recovery! */ if (test_bit(NFS_CS_RENEWD, &clp->cl_res_state) != 0) - nfs4_schedule_state_recovery(clp); + nfs4_schedule_state_recovery(clp, NULL); return; } spin_lock(&clp->cl_lock); @@ -3333,7 +3340,7 @@ _nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server, case -NFS4ERR_STALE_STATEID: case -NFS4ERR_EXPIRED: rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL); - nfs4_schedule_state_recovery(clp); + nfs4_schedule_state_recovery(clp, NULL); if (test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) == 0) rpc_wake_up_queued_task(&clp->cl_rpcwaitq, task); task->tk_status = 0; @@ -4170,7 +4177,8 @@ int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl) case -NFS4ERR_EXPIRED: case -NFS4ERR_STALE_CLIENTID: case -NFS4ERR_STALE_STATEID: - nfs4_schedule_state_recovery(server->nfs_client); + nfs4_schedule_state_recovery(server->nfs_client, + NULL); goto out; case -ERESTARTSYS: /* diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 65ca8c1..f99278a 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c @@ -779,10 +779,20 @@ unlock: return status; } +struct nfs_state_manager_args { + struct nfs_client *clp; + int *statusp; +}; + static int nfs4_run_state_manager(void *); -static void nfs4_clear_state_manager_bit(struct nfs_client *clp) +static void nfs4_clear_state_manager_bit(struct nfs_state_manager_args *args, + int status) { + struct nfs_client *clp = args->clp; + if (args->statusp) + *args->statusp = status; + kfree(args); smp_mb__before_clear_bit(); clear_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state); smp_mb__after_clear_bit(); @@ -793,20 +803,28 @@ static void nfs4_clear_state_manager_bit(struct nfs_client *clp) /* * Schedule the nfs_client asynchronous state management routine */ -void nfs4_schedule_state_manager(struct nfs_client *clp) +void nfs4_schedule_state_manager(struct nfs_client *clp, int *statusp) { struct task_struct *task; + struct nfs_state_manager_args *args; + args = kmalloc(sizeof(*args), GFP_KERNEL); + if (!args) + return; + args->clp = clp; + args->statusp = statusp; if (test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) != 0) return; + if (statusp) + *statusp = 0; __module_get(THIS_MODULE); atomic_inc(&clp->cl_count); - task = kthread_run(nfs4_run_state_manager, clp, "%s-manager", + task = kthread_run(nfs4_run_state_manager, args, "%s-manager", rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_ADDR)); if (!IS_ERR(task)) return; - nfs4_clear_state_manager_bit(clp); + nfs4_clear_state_manager_bit(args, PTR_ERR(task)); nfs_put_client(clp); module_put(THIS_MODULE); } @@ -814,13 +832,13 @@ void nfs4_schedule_state_manager(struct nfs_client *clp) /* * Schedule a state recovery attempt */ -void nfs4_schedule_state_recovery(struct nfs_client *clp) +void nfs4_schedule_state_recovery(struct nfs_client *clp, int *statusp) { if (!clp) return; if (!test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) set_bit(NFS4CLNT_CHECK_LEASE, &clp->cl_state); - nfs4_schedule_state_manager(clp); + nfs4_schedule_state_manager(clp, statusp); } static int nfs4_state_mark_reclaim_reboot(struct nfs_client *clp, struct nfs4_state *state) @@ -1223,9 +1241,10 @@ static void nfs4_set_lease_expired(struct nfs_client *clp, int status) set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state); } -static void nfs4_state_manager(struct nfs_client *clp) +static void nfs4_state_manager(struct nfs_state_manager_args *args) { int status = 0; + struct nfs_client *clp = args->clp; /* Ensure exclusive access to NFSv4 state */ for(;;) { @@ -1298,7 +1317,7 @@ static void nfs4_state_manager(struct nfs_client *clp) continue; } - nfs4_clear_state_manager_bit(clp); + nfs4_clear_state_manager_bit(args, 0); /* Did we race with an attempt to give us more work? */ if (clp->cl_state == 0) break; @@ -1311,16 +1330,17 @@ out_error: " with error %d\n", clp->cl_hostname, -status); if (test_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state)) nfs4_state_end_reclaim_reboot(clp); - nfs4_clear_state_manager_bit(clp); + nfs4_clear_state_manager_bit(args, status); } static int nfs4_run_state_manager(void *ptr) { - struct nfs_client *clp = ptr; + struct nfs_state_manager_args *args = ptr; allow_signal(SIGKILL); - nfs4_state_manager(clp); - nfs_put_client(clp); + nfs4_state_manager(args); + nfs_put_client(args->clp); + kfree(args); module_put_and_exit(0); return 0; } -- 1.6.4 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Ping: [pnfs] [RFC 1/1] nfs4: optionally return status from state_manager 2009-09-03 15:15 ` [RFC 1/1] nfs4: optionally return status from state_manager Benny Halevy @ 2009-09-25 4:30 ` Benny Halevy 2009-09-25 13:29 ` Trond Myklebust 0 siblings, 1 reply; 13+ messages in thread From: Benny Halevy @ 2009-09-25 4:30 UTC (permalink / raw) To: Trond Myklebust; +Cc: linux-nfs, pnfs Trond, Is the patch below acceptable? Benny On Sep. 03, 2009, 18:15 +0300, Benny Halevy <bhalevy@panasas.com> wrote: > Add an optional pointer to integer parameter to > nfs4_schedule_state_manager and store the state_manager > status in it, if not NULL. Use it also if the state manager > could not be scheduled for kthread_run's error. > > Signed-off-by: Benny Halevy <bhalevy@panasas.com> > --- > > Trond, > > Here's an alternative approach to returning the state_manager > status to whomever scheduled state recovery, requiring no > additrional fields in struct nfs_client and returning > the status atomically with the state_manager. > > Benny > > fs/nfs/client.c | 6 ++---- > fs/nfs/delegation.c | 2 +- > fs/nfs/nfs4_fs.h | 4 ++-- > fs/nfs/nfs4proc.c | 26 +++++++++++++++++--------- > fs/nfs/nfs4state.c | 44 ++++++++++++++++++++++++++++++++------------ > 5 files changed, 54 insertions(+), 28 deletions(-) > > diff --git a/fs/nfs/client.c b/fs/nfs/client.c > index d36925f..07ce3ae 100644 > --- a/fs/nfs/client.c > +++ b/fs/nfs/client.c > @@ -541,10 +541,8 @@ void nfs_mark_client_ready(struct nfs_client *clp, int state) > */ > int nfs4_check_client_ready(struct nfs_client *clp) > { > - if (!nfs4_has_session(clp)) > - return 0; > - if (clp->cl_cons_state < NFS_CS_READY) > - return -EPROTONOSUPPORT; > + if (clp->cl_cons_state < 0) > + return clp->cl_cons_state; > return 0; > } > > diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c > index 6dd48a4..af2c3f0 100644 > --- a/fs/nfs/delegation.c > +++ b/fs/nfs/delegation.c > @@ -386,7 +386,7 @@ static void nfs_client_mark_return_all_delegations(struct nfs_client *clp) > static void nfs_delegation_run_state_manager(struct nfs_client *clp) > { > if (test_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state)) > - nfs4_schedule_state_manager(clp); > + nfs4_schedule_state_manager(clp, NULL); > } > > void nfs_expire_all_delegations(struct nfs_client *clp) > diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h > index 6ea07a3..c2ec9bc 100644 > --- a/fs/nfs/nfs4_fs.h > +++ b/fs/nfs/nfs4_fs.h > @@ -264,8 +264,8 @@ extern void nfs4_put_open_state(struct nfs4_state *); > extern void nfs4_close_state(struct path *, struct nfs4_state *, fmode_t); > extern void nfs4_close_sync(struct path *, struct nfs4_state *, fmode_t); > extern void nfs4_state_set_mode_locked(struct nfs4_state *, fmode_t); > -extern void nfs4_schedule_state_recovery(struct nfs_client *); > -extern void nfs4_schedule_state_manager(struct nfs_client *); > +extern void nfs4_schedule_state_recovery(struct nfs_client *, int *statusp); > +extern void nfs4_schedule_state_manager(struct nfs_client *, int *statusp); > extern int nfs4_state_mark_reclaim_nograce(struct nfs_client *clp, struct nfs4_state *state); > extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp); > extern int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl); > diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c > index 80635eb..d6dc30d 100644 > --- a/fs/nfs/nfs4proc.c > +++ b/fs/nfs/nfs4proc.c > @@ -247,7 +247,7 @@ static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, > case -NFS4ERR_STALE_CLIENTID: > case -NFS4ERR_STALE_STATEID: > case -NFS4ERR_EXPIRED: > - nfs4_schedule_state_recovery(clp); > + nfs4_schedule_state_recovery(clp, NULL); > ret = nfs4_wait_clnt_recover(clp); > if (ret == 0) > exception->retry = 1; > @@ -429,15 +429,18 @@ static int nfs4_recover_session(struct nfs4_session *session) > { > struct nfs_client *clp = session->clp; > unsigned int loop; > - int ret; > + int ret, status = 0; > > for (loop = NFS4_MAX_LOOP_ON_RECOVER; loop != 0; loop--) { > ret = nfs4_wait_clnt_recover(clp); > if (ret != 0) > break; > + ret = status; > + if (ret != 0) > + break; > if (!test_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state)) > break; > - nfs4_schedule_state_manager(clp); > + nfs4_schedule_state_manager(clp, &status); > ret = -EIO; > } > return ret; > @@ -1183,7 +1186,8 @@ int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state > case -NFS4ERR_STALE_STATEID: > case -NFS4ERR_EXPIRED: > /* Don't recall a delegation if it was lost */ > - nfs4_schedule_state_recovery(server->nfs_client); > + nfs4_schedule_state_recovery(server->nfs_client, > + NULL); > goto out; > case -ERESTARTSYS: > /* > @@ -1448,16 +1452,19 @@ static int _nfs4_proc_open(struct nfs4_opendata *data) > static int nfs4_recover_expired_lease(struct nfs_client *clp) > { > unsigned int loop; > - int ret; > + int ret, status = 0; > > for (loop = NFS4_MAX_LOOP_ON_RECOVER; loop != 0; loop--) { > ret = nfs4_wait_clnt_recover(clp); > if (ret != 0) > break; > + ret = status; > + if (ret != 0) > + break; > if (!test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) && > !test_bit(NFS4CLNT_CHECK_LEASE,&clp->cl_state)) > break; > - nfs4_schedule_state_recovery(clp); > + nfs4_schedule_state_recovery(clp, &status); > ret = -EIO; > } > return ret; > @@ -3053,7 +3060,7 @@ static void nfs4_renew_done(struct rpc_task *task, void *data) > if (task->tk_status < 0) { > /* Unless we're shutting down, schedule state recovery! */ > if (test_bit(NFS_CS_RENEWD, &clp->cl_res_state) != 0) > - nfs4_schedule_state_recovery(clp); > + nfs4_schedule_state_recovery(clp, NULL); > return; > } > spin_lock(&clp->cl_lock); > @@ -3333,7 +3340,7 @@ _nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server, > case -NFS4ERR_STALE_STATEID: > case -NFS4ERR_EXPIRED: > rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL); > - nfs4_schedule_state_recovery(clp); > + nfs4_schedule_state_recovery(clp, NULL); > if (test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) == 0) > rpc_wake_up_queued_task(&clp->cl_rpcwaitq, task); > task->tk_status = 0; > @@ -4170,7 +4177,8 @@ int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl) > case -NFS4ERR_EXPIRED: > case -NFS4ERR_STALE_CLIENTID: > case -NFS4ERR_STALE_STATEID: > - nfs4_schedule_state_recovery(server->nfs_client); > + nfs4_schedule_state_recovery(server->nfs_client, > + NULL); > goto out; > case -ERESTARTSYS: > /* > diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c > index 65ca8c1..f99278a 100644 > --- a/fs/nfs/nfs4state.c > +++ b/fs/nfs/nfs4state.c > @@ -779,10 +779,20 @@ unlock: > return status; > } > > +struct nfs_state_manager_args { > + struct nfs_client *clp; > + int *statusp; > +}; > + > static int nfs4_run_state_manager(void *); > > -static void nfs4_clear_state_manager_bit(struct nfs_client *clp) > +static void nfs4_clear_state_manager_bit(struct nfs_state_manager_args *args, > + int status) > { > + struct nfs_client *clp = args->clp; > + if (args->statusp) > + *args->statusp = status; > + kfree(args); > smp_mb__before_clear_bit(); > clear_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state); > smp_mb__after_clear_bit(); > @@ -793,20 +803,28 @@ static void nfs4_clear_state_manager_bit(struct nfs_client *clp) > /* > * Schedule the nfs_client asynchronous state management routine > */ > -void nfs4_schedule_state_manager(struct nfs_client *clp) > +void nfs4_schedule_state_manager(struct nfs_client *clp, int *statusp) > { > struct task_struct *task; > + struct nfs_state_manager_args *args; > > + args = kmalloc(sizeof(*args), GFP_KERNEL); > + if (!args) > + return; > + args->clp = clp; > + args->statusp = statusp; > if (test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) != 0) > return; > + if (statusp) > + *statusp = 0; > __module_get(THIS_MODULE); > atomic_inc(&clp->cl_count); > - task = kthread_run(nfs4_run_state_manager, clp, "%s-manager", > + task = kthread_run(nfs4_run_state_manager, args, "%s-manager", > rpc_peeraddr2str(clp->cl_rpcclient, > RPC_DISPLAY_ADDR)); > if (!IS_ERR(task)) > return; > - nfs4_clear_state_manager_bit(clp); > + nfs4_clear_state_manager_bit(args, PTR_ERR(task)); > nfs_put_client(clp); > module_put(THIS_MODULE); > } > @@ -814,13 +832,13 @@ void nfs4_schedule_state_manager(struct nfs_client *clp) > /* > * Schedule a state recovery attempt > */ > -void nfs4_schedule_state_recovery(struct nfs_client *clp) > +void nfs4_schedule_state_recovery(struct nfs_client *clp, int *statusp) > { > if (!clp) > return; > if (!test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) > set_bit(NFS4CLNT_CHECK_LEASE, &clp->cl_state); > - nfs4_schedule_state_manager(clp); > + nfs4_schedule_state_manager(clp, statusp); > } > > static int nfs4_state_mark_reclaim_reboot(struct nfs_client *clp, struct nfs4_state *state) > @@ -1223,9 +1241,10 @@ static void nfs4_set_lease_expired(struct nfs_client *clp, int status) > set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state); > } > > -static void nfs4_state_manager(struct nfs_client *clp) > +static void nfs4_state_manager(struct nfs_state_manager_args *args) > { > int status = 0; > + struct nfs_client *clp = args->clp; > > /* Ensure exclusive access to NFSv4 state */ > for(;;) { > @@ -1298,7 +1317,7 @@ static void nfs4_state_manager(struct nfs_client *clp) > continue; > } > > - nfs4_clear_state_manager_bit(clp); > + nfs4_clear_state_manager_bit(args, 0); > /* Did we race with an attempt to give us more work? */ > if (clp->cl_state == 0) > break; > @@ -1311,16 +1330,17 @@ out_error: > " with error %d\n", clp->cl_hostname, -status); > if (test_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state)) > nfs4_state_end_reclaim_reboot(clp); > - nfs4_clear_state_manager_bit(clp); > + nfs4_clear_state_manager_bit(args, status); > } > > static int nfs4_run_state_manager(void *ptr) > { > - struct nfs_client *clp = ptr; > + struct nfs_state_manager_args *args = ptr; > > allow_signal(SIGKILL); > - nfs4_state_manager(clp); > - nfs_put_client(clp); > + nfs4_state_manager(args); > + nfs_put_client(args->clp); > + kfree(args); > module_put_and_exit(0); > return 0; > } ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Ping: [pnfs] [RFC 1/1] nfs4: optionally return status from state_manager 2009-09-25 4:30 ` Ping: [pnfs] " Benny Halevy @ 2009-09-25 13:29 ` Trond Myklebust [not found] ` <1253885382.31072.14.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org> 0 siblings, 1 reply; 13+ messages in thread From: Trond Myklebust @ 2009-09-25 13:29 UTC (permalink / raw) To: Benny Halevy; +Cc: linux-nfs, pnfs On Fri, 2009-09-25 at 07:30 +0300, Benny Halevy wrote: > Trond, > > Is the patch below acceptable? > > Benny I'm still not entirely happy with the idea that the state manager can get into situations where it needs outside help, and you haven't really explained to me the root cause of the scenario. You said something about nfs4_create_server() nfs4_init_session() nfs4_recover_expired_lease() nfs4_schedule_state_recovery() # and the failure happens within the state engine nfs4_proc_create_session() nfs4_proc_get_lease_time() return -2 Where does that ENOENT come from? You said something about it being an error in OP_PUTROOTFH, but as far as I can see, the only permitted errors for putrootfh are either session related errors (which should be handled by the state machine), NFS4ERR_DELAY (which should be handled by the state machine) and NFS4ERR_WRONGSEC. So which error is generating your ENOENT? -- Trond Myklebust Linux NFS client maintainer NetApp Trond.Myklebust@netapp.com www.netapp.com ^ permalink raw reply [flat|nested] 13+ messages in thread
[parent not found: <1253885382.31072.14.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org>]
* Re: Ping: [pnfs] [RFC 1/1] nfs4: optionally return status from state_manager [not found] ` <1253885382.31072.14.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org> @ 2009-09-25 13:53 ` Benny Halevy 2009-09-25 14:10 ` J. Bruce Fields 2009-09-25 14:13 ` Trond Myklebust 0 siblings, 2 replies; 13+ messages in thread From: Benny Halevy @ 2009-09-25 13:53 UTC (permalink / raw) To: Trond Myklebust, J. Bruce Fields; +Cc: linux-nfs, pnfs On 2009-09-25 16:29, Trond Myklebust wrote: > On Fri, 2009-09-25 at 07:30 +0300, Benny Halevy wrote: >> Trond, >> >> Is the patch below acceptable? >> >> Benny > > I'm still not entirely happy with the idea that the state manager can > get into situations where it needs outside help, and you haven't really > explained to me the root cause of the scenario. > You said something about > > nfs4_create_server() > nfs4_init_session() > nfs4_recover_expired_lease() > nfs4_schedule_state_recovery() > # and the failure happens within the state engine > nfs4_proc_create_session() > nfs4_proc_get_lease_time() return -2 > > Where does that ENOENT come from? > > You said something about it being an error in OP_PUTROOTFH, but as far > as I can see, the only permitted errors for putrootfh are either session > related errors (which should be handled by the state machine), > NFS4ERR_DELAY (which should be handled by the state machine) and > NFS4ERR_WRONGSEC. So which error is generating your ENOENT? > That scenario is caused when the server's /etc/exports is badly configured, where the export entry for nfsv4 (fsid=0) exports a non-existing path. I agree that the server should not return ENOENT for PUTROOTFH as it contradicts the spec. NFS4ERR_SERVERFAULT seems more appropriate. The main reason for getting the failure from the state engine in nfsv4.1 is that we need to create a session before nfs4_path_walk in nfs4_create_server and we do that using the state manager. In the nfsv4.0 case we create no state at this point. Benny ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Ping: [pnfs] [RFC 1/1] nfs4: optionally return status from state_manager 2009-09-25 13:53 ` Benny Halevy @ 2009-09-25 14:10 ` J. Bruce Fields 2009-09-25 14:17 ` Benny Halevy 2009-09-25 14:13 ` Trond Myklebust 1 sibling, 1 reply; 13+ messages in thread From: J. Bruce Fields @ 2009-09-25 14:10 UTC (permalink / raw) To: Benny Halevy; +Cc: Trond Myklebust, linux-nfs, pnfs On Fri, Sep 25, 2009 at 04:53:17PM +0300, Benny Halevy wrote: > On 2009-09-25 16:29, Trond Myklebust wrote: > > On Fri, 2009-09-25 at 07:30 +0300, Benny Halevy wrote: > >> Trond, > >> > >> Is the patch below acceptable? > >> > >> Benny > > > > I'm still not entirely happy with the idea that the state manager can > > get into situations where it needs outside help, and you haven't really > > explained to me the root cause of the scenario. > > You said something about > > > > nfs4_create_server() > > nfs4_init_session() > > nfs4_recover_expired_lease() > > nfs4_schedule_state_recovery() > > # and the failure happens within the state engine > > nfs4_proc_create_session() > > nfs4_proc_get_lease_time() return -2 > > > > Where does that ENOENT come from? > > > > You said something about it being an error in OP_PUTROOTFH, but as far > > as I can see, the only permitted errors for putrootfh are either session > > related errors (which should be handled by the state machine), > > NFS4ERR_DELAY (which should be handled by the state machine) and > > NFS4ERR_WRONGSEC. So which error is generating your ENOENT? > > > > That scenario is caused when the server's /etc/exports > is badly configured, where the export entry for nfsv4 > (fsid=0) exports a non-existing path. > > I agree that the server should not return ENOENT > for PUTROOTFH as it contradicts the spec. > NFS4ERR_SERVERFAULT seems more appropriate. > > The main reason for getting the failure from > the state engine in nfsv4.1 is that we need to > create a session before nfs4_path_walk in nfs4_create_server > and we do that using the state manager. > In the nfsv4.0 case we create no state at this point. So is there any actual client-side bug here? --b. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Ping: [pnfs] [RFC 1/1] nfs4: optionally return status from state_manager 2009-09-25 14:10 ` J. Bruce Fields @ 2009-09-25 14:17 ` Benny Halevy 0 siblings, 0 replies; 13+ messages in thread From: Benny Halevy @ 2009-09-25 14:17 UTC (permalink / raw) To: J. Bruce Fields; +Cc: Trond Myklebust, linux-nfs, pnfs On Sep. 25, 2009, 17:10 +0300, "J. Bruce Fields" <bfields@citi.umich.edu> wrote: > On Fri, Sep 25, 2009 at 04:53:17PM +0300, Benny Halevy wrote: >> On 2009-09-25 16:29, Trond Myklebust wrote: >>> On Fri, 2009-09-25 at 07:30 +0300, Benny Halevy wrote: >>>> Trond, >>>> >>>> Is the patch below acceptable? >>>> >>>> Benny >>> I'm still not entirely happy with the idea that the state manager can >>> get into situations where it needs outside help, and you haven't really >>> explained to me the root cause of the scenario. >>> You said something about >>> >>> nfs4_create_server() >>> nfs4_init_session() >>> nfs4_recover_expired_lease() >>> nfs4_schedule_state_recovery() >>> # and the failure happens within the state engine >>> nfs4_proc_create_session() >>> nfs4_proc_get_lease_time() return -2 >>> >>> Where does that ENOENT come from? >>> >>> You said something about it being an error in OP_PUTROOTFH, but as far >>> as I can see, the only permitted errors for putrootfh are either session >>> related errors (which should be handled by the state machine), >>> NFS4ERR_DELAY (which should be handled by the state machine) and >>> NFS4ERR_WRONGSEC. So which error is generating your ENOENT? >>> >> That scenario is caused when the server's /etc/exports >> is badly configured, where the export entry for nfsv4 >> (fsid=0) exports a non-existing path. >> >> I agree that the server should not return ENOENT >> for PUTROOTFH as it contradicts the spec. >> NFS4ERR_SERVERFAULT seems more appropriate. >> >> The main reason for getting the failure from >> the state engine in nfsv4.1 is that we need to >> create a session before nfs4_path_walk in nfs4_create_server >> and we do that using the state manager. >> In the nfsv4.0 case we create no state at this point. > > So is there any actual client-side bug here? The client side bug is returning an irrelevant and confusing error status back to the application (mount.nfs4). Benny > > --b. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Ping: [pnfs] [RFC 1/1] nfs4: optionally return status from state_manager 2009-09-25 13:53 ` Benny Halevy 2009-09-25 14:10 ` J. Bruce Fields @ 2009-09-25 14:13 ` Trond Myklebust [not found] ` <1253888019.31072.31.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org> 1 sibling, 1 reply; 13+ messages in thread From: Trond Myklebust @ 2009-09-25 14:13 UTC (permalink / raw) To: Benny Halevy; +Cc: J. Bruce Fields, linux-nfs, pnfs On Fri, 2009-09-25 at 16:53 +0300, Benny Halevy wrote: > That scenario is caused when the server's /etc/exports > is badly configured, where the export entry for nfsv4 > (fsid=0) exports a non-existing path. > > I agree that the server should not return ENOENT > for PUTROOTFH as it contradicts the spec. > NFS4ERR_SERVERFAULT seems more appropriate. Indeed. > The main reason for getting the failure from > the state engine in nfsv4.1 is that we need to > create a session before nfs4_path_walk in nfs4_create_server > and we do that using the state manager. > In the nfsv4.0 case we create no state at this point. OK, so this particular case, there is no state recovery possible at all. If so, why not just label the cl_cons_state as NFS_CS_IRRECOVERABLE (or possibly NFS_CS_SERVERFAULT) instead of trying to overload it with an error value that nobody can do anything about? I'd say that if you want to pass the error value to the administrator, then the right way to do that would be via a printk. Something along the lines of printk("NFSv4: Server %s returned an illegal error %d when getting the root filehandle\n"); However, I'm not really convinced that is necessary... -- Trond Myklebust Linux NFS client maintainer NetApp Trond.Myklebust@netapp.com www.netapp.com ^ permalink raw reply [flat|nested] 13+ messages in thread
[parent not found: <1253888019.31072.31.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org>]
* Re: Ping: [pnfs] [RFC 1/1] nfs4: optionally return status from state_manager [not found] ` <1253888019.31072.31.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org> @ 2009-09-25 14:19 ` Benny Halevy 0 siblings, 0 replies; 13+ messages in thread From: Benny Halevy @ 2009-09-25 14:19 UTC (permalink / raw) To: Trond Myklebust; +Cc: J. Bruce Fields, linux-nfs, pnfs On Sep. 25, 2009, 17:13 +0300, Trond Myklebust <Trond.Myklebust@netapp.com> wrote: > On Fri, 2009-09-25 at 16:53 +0300, Benny Halevy wrote: >> That scenario is caused when the server's /etc/exports >> is badly configured, where the export entry for nfsv4 >> (fsid=0) exports a non-existing path. >> >> I agree that the server should not return ENOENT >> for PUTROOTFH as it contradicts the spec. >> NFS4ERR_SERVERFAULT seems more appropriate. > > Indeed. > >> The main reason for getting the failure from >> the state engine in nfsv4.1 is that we need to >> create a session before nfs4_path_walk in nfs4_create_server >> and we do that using the state manager. >> In the nfsv4.0 case we create no state at this point. > > OK, so this particular case, there is no state recovery possible at all. > If so, why not just label the cl_cons_state as NFS_CS_IRRECOVERABLE (or > possibly NFS_CS_SERVERFAULT) instead of trying to overload it with an > error value that nobody can do anything about? OK. I'll try this approach then. Thanks! Benny > > I'd say that if you want to pass the error value to the administrator, > then the right way to do that would be via a printk. Something along the > lines of > > printk("NFSv4: Server %s returned an illegal error %d when getting the > root filehandle\n"); > > However, I'm not really convinced that is necessary... > ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2009-09-25 14:19 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-09-02 7:48 [PATCH 1/1 v2] nfs41: pass state recovery error back to caller Benny Halevy
2009-09-02 17:52 ` Trond Myklebust
[not found] ` <1251913960.26601.41.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org>
2009-09-02 18:06 ` Benny Halevy
2009-09-02 19:09 ` Trond Myklebust
[not found] ` <1251918574.26601.48.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org>
2009-09-02 21:04 ` Benny Halevy
2009-09-03 15:15 ` [RFC 1/1] nfs4: optionally return status from state_manager Benny Halevy
2009-09-25 4:30 ` Ping: [pnfs] " Benny Halevy
2009-09-25 13:29 ` Trond Myklebust
[not found] ` <1253885382.31072.14.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org>
2009-09-25 13:53 ` Benny Halevy
2009-09-25 14:10 ` J. Bruce Fields
2009-09-25 14:17 ` Benny Halevy
2009-09-25 14:13 ` Trond Myklebust
[not found] ` <1253888019.31072.31.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org>
2009-09-25 14:19 ` Benny Halevy
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox