summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/fs/nfs/nfs4_srv.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/common/fs/nfs/nfs4_srv.c')
-rw-r--r--usr/src/uts/common/fs/nfs/nfs4_srv.c81
1 files changed, 51 insertions, 30 deletions
diff --git a/usr/src/uts/common/fs/nfs/nfs4_srv.c b/usr/src/uts/common/fs/nfs/nfs4_srv.c
index 5315f716b6..990a1d9d0a 100644
--- a/usr/src/uts/common/fs/nfs/nfs4_srv.c
+++ b/usr/src/uts/common/fs/nfs/nfs4_srv.c
@@ -6676,6 +6676,21 @@ rfs4_do_open(struct compound_state *cs, struct svc_req *req,
rfs4_recall_deleg(fp, FALSE, sp->rs_owner->ro_client);
delay(NFS4_DELEGATION_CONFLICT_DELAY);
rfs4_dbe_lock(sp->rs_dbe);
+
+ /* if state closed while lock was dropped */
+ if (sp->rs_closed) {
+ if (dmodes || amodes)
+ (void) rfs4_unshare(sp);
+ rfs4_dbe_unlock(sp->rs_dbe);
+ rfs4_file_rele(fp);
+ /* Not a fully formed open; "close" it */
+ if (screate == TRUE)
+ rfs4_state_close(sp, FALSE, FALSE, cs->cr);
+ rfs4_state_rele(sp);
+ resp->status = NFS4ERR_OLD_STATEID;
+ return;
+ }
+
rfs4_dbe_lock(fp->rf_dbe);
/* Let's see if the delegation was returned */
if (rfs4_check_recall(sp, access)) {
@@ -6743,6 +6758,7 @@ rfs4_do_open(struct compound_state *cs, struct svc_req *req,
fflags |= FWRITE;
vn_open_upgrade(cs->vp, fflags);
}
+ sp->rs_opened = TRUE;
if (dmodes & OPEN4_SHARE_DENY_READ)
fp->rf_deny_read++;
@@ -8183,35 +8199,6 @@ rfs4_release_share_lock_state(rfs4_state_t *sp, cred_t *cr,
int fflags = 0;
/*
- * Decrement the count for each access and deny bit that this
- * state has contributed to the file. If the file counts go to zero
- * clear the appropriate bit in the appropriate mask.
- */
-
- if (sp->rs_share_access & OPEN4_SHARE_ACCESS_READ) {
- fp->rf_access_read--;
- fflags |= FREAD;
- if (fp->rf_access_read == 0)
- fp->rf_share_access &= ~OPEN4_SHARE_ACCESS_READ;
- }
- if (sp->rs_share_access & OPEN4_SHARE_ACCESS_WRITE) {
- fp->rf_access_write--;
- fflags |= FWRITE;
- if (fp->rf_access_write == 0)
- fp->rf_share_access &= ~OPEN4_SHARE_ACCESS_WRITE;
- }
- if (sp->rs_share_deny & OPEN4_SHARE_DENY_READ) {
- fp->rf_deny_read--;
- if (fp->rf_deny_read == 0)
- fp->rf_share_deny &= ~OPEN4_SHARE_DENY_READ;
- }
- if (sp->rs_share_deny & OPEN4_SHARE_DENY_WRITE) {
- fp->rf_deny_write--;
- if (fp->rf_deny_write == 0)
- fp->rf_share_deny &= ~OPEN4_SHARE_DENY_WRITE;
- }
-
- /*
* If this call is part of the larger closing down of client
* state then it is just easier to release all locks
* associated with this client instead of going through each
@@ -8280,7 +8267,41 @@ rfs4_release_share_lock_state(rfs4_state_t *sp, cred_t *cr,
if (sp->rs_owner->ro_client->rc_sysidt != LM_NOSYSID)
(void) rfs4_unshare(sp);
- (void) VOP_CLOSE(fp->rf_vp, fflags, 1, (offset_t)0, cr, NULL);
+ if (sp->rs_opened) {
+ /*
+ * Decrement the count for each access and deny bit that this
+ * state has contributed to the file.
+ * If the file counts go to zero
+ * clear the appropriate bit in the appropriate mask.
+ */
+ if (sp->rs_share_access & OPEN4_SHARE_ACCESS_READ) {
+ fp->rf_access_read--;
+ fflags |= FREAD;
+ if (fp->rf_access_read == 0)
+ fp->rf_share_access &= ~OPEN4_SHARE_ACCESS_READ;
+ }
+ if (sp->rs_share_access & OPEN4_SHARE_ACCESS_WRITE) {
+ fp->rf_access_write--;
+ fflags |= FWRITE;
+ if (fp->rf_access_write == 0)
+ fp->rf_share_access &=
+ ~OPEN4_SHARE_ACCESS_WRITE;
+ }
+ if (sp->rs_share_deny & OPEN4_SHARE_DENY_READ) {
+ fp->rf_deny_read--;
+ if (fp->rf_deny_read == 0)
+ fp->rf_share_deny &= ~OPEN4_SHARE_DENY_READ;
+ }
+ if (sp->rs_share_deny & OPEN4_SHARE_DENY_WRITE) {
+ fp->rf_deny_write--;
+ if (fp->rf_deny_write == 0)
+ fp->rf_share_deny &= ~OPEN4_SHARE_DENY_WRITE;
+ }
+
+ (void) VOP_CLOSE(fp->rf_vp, fflags, 1, (offset_t)0, cr, NULL);
+
+ sp->rs_opened = FALSE;
+ }
}
/*