@@ -2887,6 +2887,7 @@ alloc_init_open_stateowner(unsigned int strhashval, struct nfs4_client *clp, str
static void init_open_stateid(struct nfs4_ol_stateid *stp, struct nfs4_file *fp, struct nfsd4_open *open) {
struct nfs4_openowner *oo = open->op_openowner;
+ atomic_inc(&stp->st_stid.sc_count);
stp->st_stid.sc_type = NFS4_OPEN_STID;
INIT_LIST_HEAD(&stp->st_locks);
stp->st_stateowner = &oo->oo_owner;
@@ -3223,6 +3224,7 @@ nfs4_check_open(struct nfs4_file *fp, struct nfsd4_open *open, struct nfs4_ol_st
{
struct nfs4_ol_stateid *local;
struct nfs4_openowner *oo = open->op_openowner;
+ struct nfs4_ol_stateid *ret = NULL;
spin_lock(&fp->fi_lock);
list_for_each_entry(local, &fp->fi_stateids, st_perfile) {
@@ -3231,13 +3233,17 @@ nfs4_check_open(struct nfs4_file *fp, struct nfsd4_open *open, struct nfs4_ol_st
continue;
/* remember if we have seen this open owner */
if (local->st_stateowner == &oo->oo_owner)
- *stpp = local;
+ ret = local;
/* check for conflicting share reservations */
if (!test_share(local, open)) {
spin_unlock(&fp->fi_lock);
return nfserr_share_denied;
}
}
+ if (ret) {
+ atomic_inc(&ret->st_stid.sc_count);
+ *stpp = ret;
+ }
spin_unlock(&fp->fi_lock);
return nfs_ok;
}
@@ -3652,6 +3658,8 @@ out:
open->op_rflags |= NFS4_OPEN_RESULT_CONFIRM;
if (dp)
nfs4_put_delegation(dp);
+ if (stp)
+ put_generic_stateid(stp);
return status;
}