Loading fs/nfs/delegation.c +28 −14 Original line number Original line Diff line number Diff line Loading @@ -92,7 +92,7 @@ static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_ return status; return status; } } static void nfs_delegation_claim_opens(struct inode *inode, const nfs4_stateid *stateid) static int nfs_delegation_claim_opens(struct inode *inode, const nfs4_stateid *stateid) { { struct nfs_inode *nfsi = NFS_I(inode); struct nfs_inode *nfsi = NFS_I(inode); struct nfs_open_context *ctx; struct nfs_open_context *ctx; Loading @@ -116,10 +116,11 @@ static void nfs_delegation_claim_opens(struct inode *inode, const nfs4_stateid * err = nfs_delegation_claim_locks(ctx, state); err = nfs_delegation_claim_locks(ctx, state); put_nfs_open_context(ctx); put_nfs_open_context(ctx); if (err != 0) if (err != 0) return; return err; goto again; goto again; } } spin_unlock(&inode->i_lock); spin_unlock(&inode->i_lock); return 0; } } /* /* Loading Loading @@ -261,30 +262,34 @@ static void nfs_msync_inode(struct inode *inode) /* /* * Basic procedure for returning a delegation to the server * Basic procedure for returning a delegation to the server */ */ static int __nfs_inode_return_delegation(struct inode *inode, struct nfs_delegation *delegation) static int __nfs_inode_return_delegation(struct inode *inode, struct nfs_delegation *delegation, int issync) { { struct nfs_inode *nfsi = NFS_I(inode); struct nfs_inode *nfsi = NFS_I(inode); int err; nfs_msync_inode(inode); /* /* * Guard against new delegated open/lock/unlock calls and against * Guard against new delegated open/lock/unlock calls and against * state recovery * state recovery */ */ down_write(&nfsi->rwsem); down_write(&nfsi->rwsem); nfs_delegation_claim_opens(inode, &delegation->stateid); err = nfs_delegation_claim_opens(inode, &delegation->stateid); up_write(&nfsi->rwsem); up_write(&nfsi->rwsem); nfs_msync_inode(inode); if (err) goto out; return nfs_do_return_delegation(inode, delegation, 1); err = nfs_do_return_delegation(inode, delegation, issync); out: return err; } } /* /* * Return all delegations that have been marked for return * Return all delegations that have been marked for return */ */ void nfs_client_return_marked_delegations(struct nfs_client *clp) int nfs_client_return_marked_delegations(struct nfs_client *clp) { { struct nfs_delegation *delegation; struct nfs_delegation *delegation; struct inode *inode; struct inode *inode; int err = 0; restart: restart: rcu_read_lock(); rcu_read_lock(); Loading @@ -298,12 +303,18 @@ void nfs_client_return_marked_delegations(struct nfs_client *clp) delegation = nfs_detach_delegation_locked(NFS_I(inode), NULL); delegation = nfs_detach_delegation_locked(NFS_I(inode), NULL); spin_unlock(&clp->cl_lock); spin_unlock(&clp->cl_lock); rcu_read_unlock(); rcu_read_unlock(); if (delegation != NULL) if (delegation != NULL) { __nfs_inode_return_delegation(inode, delegation); filemap_flush(inode->i_mapping); err = __nfs_inode_return_delegation(inode, delegation, 0); } iput(inode); iput(inode); if (!err) goto restart; goto restart; set_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state); return err; } } rcu_read_unlock(); rcu_read_unlock(); return 0; } } /* /* Loading Loading @@ -338,8 +349,10 @@ int nfs_inode_return_delegation(struct inode *inode) spin_lock(&clp->cl_lock); spin_lock(&clp->cl_lock); delegation = nfs_detach_delegation_locked(nfsi, NULL); delegation = nfs_detach_delegation_locked(nfsi, NULL); spin_unlock(&clp->cl_lock); spin_unlock(&clp->cl_lock); if (delegation != NULL) if (delegation != NULL) { err = __nfs_inode_return_delegation(inode, delegation); nfs_msync_inode(inode); err = __nfs_inode_return_delegation(inode, delegation, 1); } } } return err; return err; } } Loading Loading @@ -368,7 +381,8 @@ void nfs_super_return_all_delegations(struct super_block *sb) spin_unlock(&delegation->lock); spin_unlock(&delegation->lock); } } rcu_read_unlock(); rcu_read_unlock(); nfs_client_return_marked_delegations(clp); if (nfs_client_return_marked_delegations(clp) != 0) nfs4_schedule_state_manager(clp); } } static void nfs_client_mark_return_all_delegations(struct nfs_client *clp) static void nfs_client_mark_return_all_delegations(struct nfs_client *clp) Loading fs/nfs/delegation.h +1 −1 Original line number Original line Diff line number Diff line Loading @@ -42,7 +42,7 @@ void nfs_super_return_all_delegations(struct super_block *sb); void nfs_expire_all_delegations(struct nfs_client *clp); void nfs_expire_all_delegations(struct nfs_client *clp); void nfs_expire_unreferenced_delegations(struct nfs_client *clp); void nfs_expire_unreferenced_delegations(struct nfs_client *clp); void nfs_handle_cb_pathdown(struct nfs_client *clp); void nfs_handle_cb_pathdown(struct nfs_client *clp); void nfs_client_return_marked_delegations(struct nfs_client *clp); int nfs_client_return_marked_delegations(struct nfs_client *clp); void nfs_delegation_mark_reclaim(struct nfs_client *clp); void nfs_delegation_mark_reclaim(struct nfs_client *clp); void nfs_delegation_reap_unclaimed(struct nfs_client *clp); void nfs_delegation_reap_unclaimed(struct nfs_client *clp); Loading fs/nfs/dns_resolve.c +2 −2 Original line number Original line Diff line number Diff line Loading @@ -146,7 +146,7 @@ static int nfs_dns_show(struct seq_file *m, struct cache_detail *cd, return 0; return 0; } } struct nfs_dns_ent *nfs_dns_lookup(struct cache_detail *cd, static struct nfs_dns_ent *nfs_dns_lookup(struct cache_detail *cd, struct nfs_dns_ent *key) struct nfs_dns_ent *key) { { struct cache_head *ch; struct cache_head *ch; Loading @@ -159,7 +159,7 @@ struct nfs_dns_ent *nfs_dns_lookup(struct cache_detail *cd, return container_of(ch, struct nfs_dns_ent, h); return container_of(ch, struct nfs_dns_ent, h); } } struct nfs_dns_ent *nfs_dns_update(struct cache_detail *cd, static struct nfs_dns_ent *nfs_dns_update(struct cache_detail *cd, struct nfs_dns_ent *new, struct nfs_dns_ent *new, struct nfs_dns_ent *key) struct nfs_dns_ent *key) { { Loading fs/nfs/nfs4proc.c +20 −8 Original line number Original line Diff line number Diff line Loading @@ -1488,7 +1488,7 @@ static int _nfs4_open_expired(struct nfs_open_context *ctx, struct nfs4_state *s return ret; return ret; } } static inline int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4_state *state) static int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4_state *state) { { struct nfs_server *server = NFS_SERVER(state->inode); struct nfs_server *server = NFS_SERVER(state->inode); struct nfs4_exception exception = { }; struct nfs4_exception exception = { }; Loading @@ -1496,10 +1496,16 @@ static inline int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4 do { do { err = _nfs4_open_expired(ctx, state); err = _nfs4_open_expired(ctx, state); if (err != -NFS4ERR_DELAY) switch (err) { break; default: goto out; case -NFS4ERR_GRACE: case -NFS4ERR_DELAY: nfs4_handle_exception(server, err, &exception); nfs4_handle_exception(server, err, &exception); err = 0; } } while (exception.retry); } while (exception.retry); out: return err; return err; } } Loading Loading @@ -1981,7 +1987,7 @@ nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, st return 0; return 0; } } void nfs4_close_context(struct nfs_open_context *ctx, int is_sync) static void nfs4_close_context(struct nfs_open_context *ctx, int is_sync) { { if (ctx->state == NULL) if (ctx->state == NULL) return; return; Loading Loading @@ -4049,10 +4055,16 @@ static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0) if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0) return 0; return 0; err = _nfs4_do_setlk(state, F_SETLK, request, 0); err = _nfs4_do_setlk(state, F_SETLK, request, 0); if (err != -NFS4ERR_DELAY) switch (err) { break; default: goto out; case -NFS4ERR_GRACE: case -NFS4ERR_DELAY: nfs4_handle_exception(server, err, &exception); nfs4_handle_exception(server, err, &exception); err = 0; } } while (exception.retry); } while (exception.retry); out: return err; return err; } } Loading fs/nfs/nfs4state.c +31 −36 Original line number Original line Diff line number Diff line Loading @@ -1046,20 +1046,19 @@ static void nfs4_state_start_reclaim_nograce(struct nfs_client *clp) nfs4_state_mark_reclaim_helper(clp, nfs4_state_mark_reclaim_nograce); nfs4_state_mark_reclaim_helper(clp, nfs4_state_mark_reclaim_nograce); } } static void nfs4_state_end_reclaim_nograce(struct nfs_client *clp) static int nfs4_recovery_handle_error(struct nfs_client *clp, int error) { clear_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state); } static void nfs4_recovery_handle_error(struct nfs_client *clp, int error) { { switch (error) { switch (error) { case -NFS4ERR_CB_PATH_DOWN: case -NFS4ERR_CB_PATH_DOWN: nfs_handle_cb_pathdown(clp); nfs_handle_cb_pathdown(clp); break; return 0; case -NFS4ERR_NO_GRACE: nfs4_state_end_reclaim_reboot(clp); return 0; case -NFS4ERR_STALE_CLIENTID: case -NFS4ERR_STALE_CLIENTID: case -NFS4ERR_LEASE_MOVED: case -NFS4ERR_LEASE_MOVED: set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state); set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state); nfs4_state_end_reclaim_reboot(clp); nfs4_state_start_reclaim_reboot(clp); nfs4_state_start_reclaim_reboot(clp); break; break; case -NFS4ERR_EXPIRED: case -NFS4ERR_EXPIRED: Loading @@ -1074,6 +1073,7 @@ static void nfs4_recovery_handle_error(struct nfs_client *clp, int error) case -NFS4ERR_SEQ_MISORDERED: case -NFS4ERR_SEQ_MISORDERED: set_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state); set_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state); } } return error; } } static int nfs4_do_reclaim(struct nfs_client *clp, const struct nfs4_state_recovery_ops *ops) static int nfs4_do_reclaim(struct nfs_client *clp, const struct nfs4_state_recovery_ops *ops) Loading @@ -1093,8 +1093,7 @@ static int nfs4_do_reclaim(struct nfs_client *clp, const struct nfs4_state_recov if (status < 0) { if (status < 0) { set_bit(ops->owner_flag_bit, &sp->so_flags); set_bit(ops->owner_flag_bit, &sp->so_flags); nfs4_put_state_owner(sp); nfs4_put_state_owner(sp); nfs4_recovery_handle_error(clp, status); return nfs4_recovery_handle_error(clp, status); return status; } } nfs4_put_state_owner(sp); nfs4_put_state_owner(sp); goto restart; goto restart; Loading Loading @@ -1124,8 +1123,7 @@ static int nfs4_check_lease(struct nfs_client *clp) status = ops->renew_lease(clp, cred); status = ops->renew_lease(clp, cred); put_rpccred(cred); put_rpccred(cred); out: out: nfs4_recovery_handle_error(clp, status); return nfs4_recovery_handle_error(clp, status); return status; } } static int nfs4_reclaim_lease(struct nfs_client *clp) static int nfs4_reclaim_lease(struct nfs_client *clp) Loading Loading @@ -1234,7 +1232,8 @@ static void nfs4_state_manager(struct nfs_client *clp) status = nfs4_reclaim_lease(clp); status = nfs4_reclaim_lease(clp); if (status) { if (status) { nfs4_set_lease_expired(clp, status); nfs4_set_lease_expired(clp, status); if (status == -EAGAIN) if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) continue; continue; if (clp->cl_cons_state == if (clp->cl_cons_state == NFS_CS_SESSION_INITING) NFS_CS_SESSION_INITING) Loading @@ -1246,9 +1245,12 @@ static void nfs4_state_manager(struct nfs_client *clp) if (test_and_clear_bit(NFS4CLNT_CHECK_LEASE, &clp->cl_state)) { if (test_and_clear_bit(NFS4CLNT_CHECK_LEASE, &clp->cl_state)) { status = nfs4_check_lease(clp); status = nfs4_check_lease(clp); if (status != 0) if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) continue; continue; if (status < 0 && status != -NFS4ERR_CB_PATH_DOWN) goto out_error; } } /* Initialize or reset the session */ /* Initialize or reset the session */ if (test_and_clear_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state) if (test_and_clear_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state) && nfs4_has_session(clp)) { && nfs4_has_session(clp)) { Loading @@ -1256,41 +1258,36 @@ static void nfs4_state_manager(struct nfs_client *clp) status = nfs4_initialize_session(clp); status = nfs4_initialize_session(clp); else else status = nfs4_reset_session(clp); status = nfs4_reset_session(clp); if (status) { if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) if (status == -NFS4ERR_STALE_CLIENTID) continue; continue; if (status < 0) goto out_error; goto out_error; } } } /* First recover reboot state... */ /* First recover reboot state... */ if (test_and_clear_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state)) { if (test_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state)) { status = nfs4_do_reclaim(clp, status = nfs4_do_reclaim(clp, nfs4_reboot_recovery_ops[clp->cl_minorversion]); nfs4_reboot_recovery_ops[clp->cl_minorversion]); if (status == -NFS4ERR_STALE_CLIENTID) if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) || continue; test_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state)) if (test_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state)) continue; continue; nfs4_state_end_reclaim_reboot(clp); nfs4_state_end_reclaim_reboot(clp); if (test_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state)) continue; continue; if (status < 0) goto out_error; } } /* Now recover expired state... */ /* Now recover expired state... */ if (test_and_clear_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state)) { if (test_and_clear_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state)) { status = nfs4_do_reclaim(clp, status = nfs4_do_reclaim(clp, nfs4_nograce_recovery_ops[clp->cl_minorversion]); nfs4_nograce_recovery_ops[clp->cl_minorversion]); if (status < 0) { if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) || set_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state); test_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state) || if (status == -NFS4ERR_STALE_CLIENTID) test_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state)) continue; if (status == -NFS4ERR_EXPIRED) continue; if (test_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state)) continue; continue; if (status < 0) goto out_error; goto out_error; } else nfs4_state_end_reclaim_nograce(clp); continue; } } if (test_and_clear_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state)) { if (test_and_clear_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state)) { Loading @@ -1309,8 +1306,6 @@ static void nfs4_state_manager(struct nfs_client *clp) out_error: out_error: printk(KERN_WARNING "Error: state manager failed on NFSv4 server %s" printk(KERN_WARNING "Error: state manager failed on NFSv4 server %s" " with error %d\n", clp->cl_hostname, -status); " 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(clp); } } Loading Loading
fs/nfs/delegation.c +28 −14 Original line number Original line Diff line number Diff line Loading @@ -92,7 +92,7 @@ static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_ return status; return status; } } static void nfs_delegation_claim_opens(struct inode *inode, const nfs4_stateid *stateid) static int nfs_delegation_claim_opens(struct inode *inode, const nfs4_stateid *stateid) { { struct nfs_inode *nfsi = NFS_I(inode); struct nfs_inode *nfsi = NFS_I(inode); struct nfs_open_context *ctx; struct nfs_open_context *ctx; Loading @@ -116,10 +116,11 @@ static void nfs_delegation_claim_opens(struct inode *inode, const nfs4_stateid * err = nfs_delegation_claim_locks(ctx, state); err = nfs_delegation_claim_locks(ctx, state); put_nfs_open_context(ctx); put_nfs_open_context(ctx); if (err != 0) if (err != 0) return; return err; goto again; goto again; } } spin_unlock(&inode->i_lock); spin_unlock(&inode->i_lock); return 0; } } /* /* Loading Loading @@ -261,30 +262,34 @@ static void nfs_msync_inode(struct inode *inode) /* /* * Basic procedure for returning a delegation to the server * Basic procedure for returning a delegation to the server */ */ static int __nfs_inode_return_delegation(struct inode *inode, struct nfs_delegation *delegation) static int __nfs_inode_return_delegation(struct inode *inode, struct nfs_delegation *delegation, int issync) { { struct nfs_inode *nfsi = NFS_I(inode); struct nfs_inode *nfsi = NFS_I(inode); int err; nfs_msync_inode(inode); /* /* * Guard against new delegated open/lock/unlock calls and against * Guard against new delegated open/lock/unlock calls and against * state recovery * state recovery */ */ down_write(&nfsi->rwsem); down_write(&nfsi->rwsem); nfs_delegation_claim_opens(inode, &delegation->stateid); err = nfs_delegation_claim_opens(inode, &delegation->stateid); up_write(&nfsi->rwsem); up_write(&nfsi->rwsem); nfs_msync_inode(inode); if (err) goto out; return nfs_do_return_delegation(inode, delegation, 1); err = nfs_do_return_delegation(inode, delegation, issync); out: return err; } } /* /* * Return all delegations that have been marked for return * Return all delegations that have been marked for return */ */ void nfs_client_return_marked_delegations(struct nfs_client *clp) int nfs_client_return_marked_delegations(struct nfs_client *clp) { { struct nfs_delegation *delegation; struct nfs_delegation *delegation; struct inode *inode; struct inode *inode; int err = 0; restart: restart: rcu_read_lock(); rcu_read_lock(); Loading @@ -298,12 +303,18 @@ void nfs_client_return_marked_delegations(struct nfs_client *clp) delegation = nfs_detach_delegation_locked(NFS_I(inode), NULL); delegation = nfs_detach_delegation_locked(NFS_I(inode), NULL); spin_unlock(&clp->cl_lock); spin_unlock(&clp->cl_lock); rcu_read_unlock(); rcu_read_unlock(); if (delegation != NULL) if (delegation != NULL) { __nfs_inode_return_delegation(inode, delegation); filemap_flush(inode->i_mapping); err = __nfs_inode_return_delegation(inode, delegation, 0); } iput(inode); iput(inode); if (!err) goto restart; goto restart; set_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state); return err; } } rcu_read_unlock(); rcu_read_unlock(); return 0; } } /* /* Loading Loading @@ -338,8 +349,10 @@ int nfs_inode_return_delegation(struct inode *inode) spin_lock(&clp->cl_lock); spin_lock(&clp->cl_lock); delegation = nfs_detach_delegation_locked(nfsi, NULL); delegation = nfs_detach_delegation_locked(nfsi, NULL); spin_unlock(&clp->cl_lock); spin_unlock(&clp->cl_lock); if (delegation != NULL) if (delegation != NULL) { err = __nfs_inode_return_delegation(inode, delegation); nfs_msync_inode(inode); err = __nfs_inode_return_delegation(inode, delegation, 1); } } } return err; return err; } } Loading Loading @@ -368,7 +381,8 @@ void nfs_super_return_all_delegations(struct super_block *sb) spin_unlock(&delegation->lock); spin_unlock(&delegation->lock); } } rcu_read_unlock(); rcu_read_unlock(); nfs_client_return_marked_delegations(clp); if (nfs_client_return_marked_delegations(clp) != 0) nfs4_schedule_state_manager(clp); } } static void nfs_client_mark_return_all_delegations(struct nfs_client *clp) static void nfs_client_mark_return_all_delegations(struct nfs_client *clp) Loading
fs/nfs/delegation.h +1 −1 Original line number Original line Diff line number Diff line Loading @@ -42,7 +42,7 @@ void nfs_super_return_all_delegations(struct super_block *sb); void nfs_expire_all_delegations(struct nfs_client *clp); void nfs_expire_all_delegations(struct nfs_client *clp); void nfs_expire_unreferenced_delegations(struct nfs_client *clp); void nfs_expire_unreferenced_delegations(struct nfs_client *clp); void nfs_handle_cb_pathdown(struct nfs_client *clp); void nfs_handle_cb_pathdown(struct nfs_client *clp); void nfs_client_return_marked_delegations(struct nfs_client *clp); int nfs_client_return_marked_delegations(struct nfs_client *clp); void nfs_delegation_mark_reclaim(struct nfs_client *clp); void nfs_delegation_mark_reclaim(struct nfs_client *clp); void nfs_delegation_reap_unclaimed(struct nfs_client *clp); void nfs_delegation_reap_unclaimed(struct nfs_client *clp); Loading
fs/nfs/dns_resolve.c +2 −2 Original line number Original line Diff line number Diff line Loading @@ -146,7 +146,7 @@ static int nfs_dns_show(struct seq_file *m, struct cache_detail *cd, return 0; return 0; } } struct nfs_dns_ent *nfs_dns_lookup(struct cache_detail *cd, static struct nfs_dns_ent *nfs_dns_lookup(struct cache_detail *cd, struct nfs_dns_ent *key) struct nfs_dns_ent *key) { { struct cache_head *ch; struct cache_head *ch; Loading @@ -159,7 +159,7 @@ struct nfs_dns_ent *nfs_dns_lookup(struct cache_detail *cd, return container_of(ch, struct nfs_dns_ent, h); return container_of(ch, struct nfs_dns_ent, h); } } struct nfs_dns_ent *nfs_dns_update(struct cache_detail *cd, static struct nfs_dns_ent *nfs_dns_update(struct cache_detail *cd, struct nfs_dns_ent *new, struct nfs_dns_ent *new, struct nfs_dns_ent *key) struct nfs_dns_ent *key) { { Loading
fs/nfs/nfs4proc.c +20 −8 Original line number Original line Diff line number Diff line Loading @@ -1488,7 +1488,7 @@ static int _nfs4_open_expired(struct nfs_open_context *ctx, struct nfs4_state *s return ret; return ret; } } static inline int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4_state *state) static int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4_state *state) { { struct nfs_server *server = NFS_SERVER(state->inode); struct nfs_server *server = NFS_SERVER(state->inode); struct nfs4_exception exception = { }; struct nfs4_exception exception = { }; Loading @@ -1496,10 +1496,16 @@ static inline int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4 do { do { err = _nfs4_open_expired(ctx, state); err = _nfs4_open_expired(ctx, state); if (err != -NFS4ERR_DELAY) switch (err) { break; default: goto out; case -NFS4ERR_GRACE: case -NFS4ERR_DELAY: nfs4_handle_exception(server, err, &exception); nfs4_handle_exception(server, err, &exception); err = 0; } } while (exception.retry); } while (exception.retry); out: return err; return err; } } Loading Loading @@ -1981,7 +1987,7 @@ nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, st return 0; return 0; } } void nfs4_close_context(struct nfs_open_context *ctx, int is_sync) static void nfs4_close_context(struct nfs_open_context *ctx, int is_sync) { { if (ctx->state == NULL) if (ctx->state == NULL) return; return; Loading Loading @@ -4049,10 +4055,16 @@ static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0) if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0) return 0; return 0; err = _nfs4_do_setlk(state, F_SETLK, request, 0); err = _nfs4_do_setlk(state, F_SETLK, request, 0); if (err != -NFS4ERR_DELAY) switch (err) { break; default: goto out; case -NFS4ERR_GRACE: case -NFS4ERR_DELAY: nfs4_handle_exception(server, err, &exception); nfs4_handle_exception(server, err, &exception); err = 0; } } while (exception.retry); } while (exception.retry); out: return err; return err; } } Loading
fs/nfs/nfs4state.c +31 −36 Original line number Original line Diff line number Diff line Loading @@ -1046,20 +1046,19 @@ static void nfs4_state_start_reclaim_nograce(struct nfs_client *clp) nfs4_state_mark_reclaim_helper(clp, nfs4_state_mark_reclaim_nograce); nfs4_state_mark_reclaim_helper(clp, nfs4_state_mark_reclaim_nograce); } } static void nfs4_state_end_reclaim_nograce(struct nfs_client *clp) static int nfs4_recovery_handle_error(struct nfs_client *clp, int error) { clear_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state); } static void nfs4_recovery_handle_error(struct nfs_client *clp, int error) { { switch (error) { switch (error) { case -NFS4ERR_CB_PATH_DOWN: case -NFS4ERR_CB_PATH_DOWN: nfs_handle_cb_pathdown(clp); nfs_handle_cb_pathdown(clp); break; return 0; case -NFS4ERR_NO_GRACE: nfs4_state_end_reclaim_reboot(clp); return 0; case -NFS4ERR_STALE_CLIENTID: case -NFS4ERR_STALE_CLIENTID: case -NFS4ERR_LEASE_MOVED: case -NFS4ERR_LEASE_MOVED: set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state); set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state); nfs4_state_end_reclaim_reboot(clp); nfs4_state_start_reclaim_reboot(clp); nfs4_state_start_reclaim_reboot(clp); break; break; case -NFS4ERR_EXPIRED: case -NFS4ERR_EXPIRED: Loading @@ -1074,6 +1073,7 @@ static void nfs4_recovery_handle_error(struct nfs_client *clp, int error) case -NFS4ERR_SEQ_MISORDERED: case -NFS4ERR_SEQ_MISORDERED: set_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state); set_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state); } } return error; } } static int nfs4_do_reclaim(struct nfs_client *clp, const struct nfs4_state_recovery_ops *ops) static int nfs4_do_reclaim(struct nfs_client *clp, const struct nfs4_state_recovery_ops *ops) Loading @@ -1093,8 +1093,7 @@ static int nfs4_do_reclaim(struct nfs_client *clp, const struct nfs4_state_recov if (status < 0) { if (status < 0) { set_bit(ops->owner_flag_bit, &sp->so_flags); set_bit(ops->owner_flag_bit, &sp->so_flags); nfs4_put_state_owner(sp); nfs4_put_state_owner(sp); nfs4_recovery_handle_error(clp, status); return nfs4_recovery_handle_error(clp, status); return status; } } nfs4_put_state_owner(sp); nfs4_put_state_owner(sp); goto restart; goto restart; Loading Loading @@ -1124,8 +1123,7 @@ static int nfs4_check_lease(struct nfs_client *clp) status = ops->renew_lease(clp, cred); status = ops->renew_lease(clp, cred); put_rpccred(cred); put_rpccred(cred); out: out: nfs4_recovery_handle_error(clp, status); return nfs4_recovery_handle_error(clp, status); return status; } } static int nfs4_reclaim_lease(struct nfs_client *clp) static int nfs4_reclaim_lease(struct nfs_client *clp) Loading Loading @@ -1234,7 +1232,8 @@ static void nfs4_state_manager(struct nfs_client *clp) status = nfs4_reclaim_lease(clp); status = nfs4_reclaim_lease(clp); if (status) { if (status) { nfs4_set_lease_expired(clp, status); nfs4_set_lease_expired(clp, status); if (status == -EAGAIN) if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) continue; continue; if (clp->cl_cons_state == if (clp->cl_cons_state == NFS_CS_SESSION_INITING) NFS_CS_SESSION_INITING) Loading @@ -1246,9 +1245,12 @@ static void nfs4_state_manager(struct nfs_client *clp) if (test_and_clear_bit(NFS4CLNT_CHECK_LEASE, &clp->cl_state)) { if (test_and_clear_bit(NFS4CLNT_CHECK_LEASE, &clp->cl_state)) { status = nfs4_check_lease(clp); status = nfs4_check_lease(clp); if (status != 0) if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) continue; continue; if (status < 0 && status != -NFS4ERR_CB_PATH_DOWN) goto out_error; } } /* Initialize or reset the session */ /* Initialize or reset the session */ if (test_and_clear_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state) if (test_and_clear_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state) && nfs4_has_session(clp)) { && nfs4_has_session(clp)) { Loading @@ -1256,41 +1258,36 @@ static void nfs4_state_manager(struct nfs_client *clp) status = nfs4_initialize_session(clp); status = nfs4_initialize_session(clp); else else status = nfs4_reset_session(clp); status = nfs4_reset_session(clp); if (status) { if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) if (status == -NFS4ERR_STALE_CLIENTID) continue; continue; if (status < 0) goto out_error; goto out_error; } } } /* First recover reboot state... */ /* First recover reboot state... */ if (test_and_clear_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state)) { if (test_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state)) { status = nfs4_do_reclaim(clp, status = nfs4_do_reclaim(clp, nfs4_reboot_recovery_ops[clp->cl_minorversion]); nfs4_reboot_recovery_ops[clp->cl_minorversion]); if (status == -NFS4ERR_STALE_CLIENTID) if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) || continue; test_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state)) if (test_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state)) continue; continue; nfs4_state_end_reclaim_reboot(clp); nfs4_state_end_reclaim_reboot(clp); if (test_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state)) continue; continue; if (status < 0) goto out_error; } } /* Now recover expired state... */ /* Now recover expired state... */ if (test_and_clear_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state)) { if (test_and_clear_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state)) { status = nfs4_do_reclaim(clp, status = nfs4_do_reclaim(clp, nfs4_nograce_recovery_ops[clp->cl_minorversion]); nfs4_nograce_recovery_ops[clp->cl_minorversion]); if (status < 0) { if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) || set_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state); test_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state) || if (status == -NFS4ERR_STALE_CLIENTID) test_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state)) continue; if (status == -NFS4ERR_EXPIRED) continue; if (test_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state)) continue; continue; if (status < 0) goto out_error; goto out_error; } else nfs4_state_end_reclaim_nograce(clp); continue; } } if (test_and_clear_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state)) { if (test_and_clear_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state)) { Loading @@ -1309,8 +1306,6 @@ static void nfs4_state_manager(struct nfs_client *clp) out_error: out_error: printk(KERN_WARNING "Error: state manager failed on NFSv4 server %s" printk(KERN_WARNING "Error: state manager failed on NFSv4 server %s" " with error %d\n", clp->cl_hostname, -status); " 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(clp); } } Loading