--- fs/nfsserver/nfs_nfsdstate.c.sav 2011-07-16 09:21:13.000000000 -0400 +++ fs/nfsserver/nfs_nfsdstate.c 2011-07-19 16:24:43.000000000 -0400 @@ -41,6 +41,7 @@ extern struct nfsstats newnfsstats; extern int nfsrv_lease; extern struct timeval nfsboottime; extern u_int32_t newnfs_true, newnfs_false; +extern int nfsrc_floodlevel, nfsrc_tcpsavedreplies; NFSV4ROOTLOCKMUTEX; NFSSTATESPINLOCK; @@ -854,7 +855,7 @@ nfsrv_servertimer(void) { struct nfsclient *clp, *nclp; struct nfsstate *stp, *nstp; - int got_ref, i; + int got_ref, i, tcpreplycnt; /* * Make sure nfsboottime is set. This is used by V3 as well @@ -894,6 +895,8 @@ nfsrv_servertimer(void) return; } + /* Calculate 10% above nfsrc_tcpsavedreplies. */ + tcpreplycnt = nfsrc_tcpsavedreplies + nfsrc_tcpsavedreplies / 10; /* * For each client... */ @@ -947,7 +950,8 @@ nfsrv_servertimer(void) stp->ls_noopens++; if (stp->ls_noopens > NFSNOOPEN || (nfsrv_openpluslock * 2) > - NFSRV_V4STATELIMIT) + NFSRV_V4STATELIMIT || + tcpreplycnt >= nfsrc_floodlevel) nfsrv_stablefirst.nsf_flags |= NFSNSF_NOOPENS; } else { @@ -4882,8 +4886,10 @@ nfsrv_throwawayopens(NFSPROC_T *p) { struct nfsclient *clp, *nclp; struct nfsstate *stp, *nstp; - int i; + int i, tcpreplycnt; + /* Calculate 10% above nfsrc_tcpsavedreplies. */ + tcpreplycnt = nfsrc_tcpsavedreplies + nfsrc_tcpsavedreplies / 10; NFSLOCKSTATE(); nfsrv_stablefirst.nsf_flags &= ~NFSNSF_NOOPENS; /* @@ -4894,8 +4900,8 @@ nfsrv_throwawayopens(NFSPROC_T *p) LIST_FOREACH_SAFE(stp, &clp->lc_open, ls_list, nstp) { if (LIST_EMPTY(&stp->ls_open) && (stp->ls_noopens > NFSNOOPEN || - (nfsrv_openpluslock * 2) > - NFSRV_V4STATELIMIT)) + (nfsrv_openpluslock * 2) > NFSRV_V4STATELIMIT || + tcpreplycnt >= nfsrc_floodlevel)) nfsrv_freeopenowner(stp, 0, p); } }