Index: fs/nfsserver/nfs_nfsdstate.c =================================================================== --- fs/nfsserver/nfs_nfsdstate.c +++ fs/nfsserver/nfs_nfsdstate.c @@ -95,6 +95,7 @@ static int nfsrv_returnoldstateid = 0, nfsrv_clients = 0; static int nfsrv_clienthighwater = NFSRV_CLIENTHIGHWATER; static int nfsrv_nogsscallback = 0; +static volatile int nfsrv_writedelegcnt = 0; /* local functions */ static void nfsrv_dumpaclient(struct nfsclient *clp, @@ -1263,6 +1264,8 @@ LIST_REMOVE(stp, ls_hash); LIST_REMOVE(stp, ls_list); LIST_REMOVE(stp, ls_file); + if ((stp->ls_flags & NFSLCK_DELEGWRITE) != 0) + atomic_add_int(&nfsrv_writedelegcnt, -1); lfp = stp->ls_lfp; if (LIST_EMPTY(&lfp->lf_open) && LIST_EMPTY(&lfp->lf_lock) && LIST_EMPTY(&lfp->lf_deleg) && @@ -2907,6 +2910,7 @@ new_deleg->ls_flags = (NFSLCK_DELEGWRITE | NFSLCK_READACCESS | NFSLCK_WRITEACCESS); *rflagsp |= NFSV4OPEN_WRITEDELEGATE; + atomic_add_int(&nfsrv_writedelegcnt, 1); } else { new_deleg->ls_flags = (NFSLCK_DELEGREAD | NFSLCK_READACCESS); @@ -3037,6 +3041,7 @@ new_deleg->ls_clp = clp; new_deleg->ls_filerev = filerev; new_deleg->ls_compref = nd->nd_compref; + atomic_add_int(&nfsrv_writedelegcnt, 1); LIST_INSERT_HEAD(&lfp->lf_deleg, new_deleg, ls_file); LIST_INSERT_HEAD(NFSSTATEHASH(clp, new_deleg->ls_stateid), new_deleg, ls_hash); @@ -3094,6 +3099,7 @@ new_deleg->ls_flags = (NFSLCK_DELEGWRITE | NFSLCK_READACCESS | NFSLCK_WRITEACCESS); *rflagsp |= NFSV4OPEN_WRITEDELEGATE; + atomic_add_int(&nfsrv_writedelegcnt, 1); } else { new_deleg->ls_flags = (NFSLCK_DELEGREAD | NFSLCK_READACCESS); @@ -3170,6 +3176,7 @@ NFSLCK_READACCESS | NFSLCK_WRITEACCESS); *rflagsp |= NFSV4OPEN_WRITEDELEGATE; + atomic_add_int(&nfsrv_writedelegcnt, 1); } else { new_deleg->ls_flags = (NFSLCK_DELEGREAD | @@ -5293,13 +5300,16 @@ struct nfsclient *clp; struct nfsvattr nva; fhandle_t nfh; - int error = 0; + int error = 0, wdelegcnt; nfsattrbit_t cbbits; u_quad_t delegfilerev; NFSCBGETATTR_ATTRBIT(attrbitp, &cbbits); if (!NFSNONZERO_ATTRBIT(&cbbits)) goto out; + wdelegcnt = atomic_load_acq_int(&nfsrv_writedelegcnt); + if (wdelegcnt == 0) + goto out; /* * Get the lock file structure.