diff options
-rw-r--r-- | fs/nfsd/nfs4proc.c | 1 | ||||
-rw-r--r-- | fs/nfsd/nfs4state.c | 20 | ||||
-rw-r--r-- | fs/nfsd/state.h | 1 | ||||
-rw-r--r-- | fs/nfsd/xdr4.h | 1 |
4 files changed, 21 insertions, 2 deletions
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 5b192a2512b6..10b50d78bdc3 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -409,6 +409,7 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, */ status = nfsd4_process_open2(rqstp, &cstate->current_fh, open); out: + nfsd4_cleanup_open_state(open, status); if (open->op_openowner) cstate->replay_owner = &open->op_openowner->oo_owner; else diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 62aa91ae278b..2c9a1a20e014 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -2320,7 +2320,7 @@ alloc_init_open_stateowner(unsigned int strhashval, struct nfs4_client *clp, str return NULL; oo->oo_owner.so_is_open_owner = 1; oo->oo_owner.so_seqid = open->op_seqid; - oo->oo_flags = 0; + oo->oo_flags = NFS4_OO_NEW; oo->oo_time = 0; oo->oo_last_closed_stid = NULL; INIT_LIST_HEAD(&oo->oo_close_lru); @@ -2526,7 +2526,6 @@ nfsd4_process_open1(struct nfsd4_compound_state *cstate, open->op_openowner = NULL; goto new_owner; } - list_del_init(&oo->oo_close_lru); return nfsd4_check_seqid(cstate, &oo->oo_owner, open->op_seqid); new_owner: oo = alloc_init_open_stateowner(strhashval, clp, open); @@ -2946,6 +2945,23 @@ out: return status; } +void nfsd4_cleanup_open_state(struct nfsd4_open *open, __be32 status) +{ + if (open->op_openowner) { + struct nfs4_openowner *oo = open->op_openowner; + + if (!list_empty(&oo->oo_owner.so_stateids)) + list_del_init(&oo->oo_close_lru); + if (oo->oo_flags & NFS4_OO_NEW) { + if (status) { + release_openowner(oo); + open->op_openowner = NULL; + } else + oo->oo_flags &= ~NFS4_OO_NEW; + } + } +} + __be32 nfsd4_renew(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, clientid_t *clid) diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index 87eecfd9b968..eab9dae23c06 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -359,6 +359,7 @@ struct nfs4_openowner { time_t oo_time; /* time of placement on so_close_lru */ #define NFS4_OO_CONFIRMED 1 #define NFS4_OO_PURGE_CLOSE 2 +#define NFS4_OO_NEW 4 unsigned char oo_flags; }; diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index 4c8a7ec3f25d..32e6fd8d9768 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -554,6 +554,7 @@ extern __be32 nfsd4_process_open1(struct nfsd4_compound_state *, struct nfsd4_open *open); extern __be32 nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open); +extern void nfsd4_cleanup_open_state(struct nfsd4_open *open, __be32 status); extern __be32 nfsd4_open_confirm(struct svc_rqst *rqstp, struct nfsd4_compound_state *, struct nfsd4_open_confirm *oc); extern __be32 nfsd4_close(struct svc_rqst *rqstp, |