Changeset View
Changeset View
Standalone View
Standalone View
sys/fs/nfsserver/nfs_nfsdstate.c
Show All 29 Lines | |||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include "opt_inet.h" | #include "opt_inet.h" | ||||
#include "opt_inet6.h" | #include "opt_inet6.h" | ||||
#include <sys/extattr.h> | #include <sys/extattr.h> | ||||
#include <fs/nfs/nfsport.h> | #include <fs/nfs/nfsport.h> | ||||
struct nfsrv_stablefirst nfsrv_stablefirst; | |||||
int nfsrv_issuedelegs = 0; | int nfsrv_issuedelegs = 0; | ||||
int nfsrv_dolocallocks = 0; | int nfsrv_dolocallocks = 0; | ||||
struct nfsv4lock nfsv4rootfs_lock; | struct nfsv4lock nfsv4rootfs_lock; | ||||
time_t nfsdev_time = 0; | time_t nfsdev_time = 0; | ||||
int nfsrv_layouthashsize; | int nfsrv_layouthashsize; | ||||
volatile int nfsrv_layoutcnt = 0; | volatile int nfsrv_layoutcnt = 0; | ||||
extern uint32_t nfs_srvmaxio; | |||||
extern int newnfs_numnfsd; | VNET_DEFINE(struct nfsrv_stablefirst, nfsrv_stablefirst); | ||||
VNET_DECLARE(int, nfsrv_numnfsd); | |||||
VNET_DECLARE(struct nfsdontlisthead, nfsrv_dontlisthead); | |||||
extern uint32_t nfs_srvmaxio; | |||||
extern struct nfsstatsv1 nfsstatsv1; | extern struct nfsstatsv1 nfsstatsv1; | ||||
extern int nfsrv_lease; | extern int nfsrv_lease; | ||||
extern struct timeval nfsboottime; | extern struct timeval nfsboottime; | ||||
extern u_int32_t newnfs_true, newnfs_false; | extern u_int32_t newnfs_true, newnfs_false; | ||||
extern struct mtx nfsrv_dslock_mtx; | extern struct mtx nfsrv_dslock_mtx; | ||||
extern struct mtx nfsrv_recalllock_mtx; | extern struct mtx nfsrv_recalllock_mtx; | ||||
extern struct mtx nfsrv_dontlistlock_mtx; | extern struct mtx nfsrv_dontlistlock_mtx; | ||||
extern int nfsd_debuglevel; | extern int nfsd_debuglevel; | ||||
extern u_int nfsrv_dsdirsize; | extern u_int nfsrv_dsdirsize; | ||||
extern struct nfsdevicehead nfsrv_devidhead; | extern struct nfsdevicehead nfsrv_devidhead; | ||||
extern int nfsrv_doflexfile; | extern int nfsrv_doflexfile; | ||||
extern int nfsrv_maxpnfsmirror; | extern int nfsrv_maxpnfsmirror; | ||||
NFSV4ROOTLOCKMUTEX; | NFSV4ROOTLOCKMUTEX; | ||||
NFSSTATESPINLOCK; | NFSSTATESPINLOCK; | ||||
extern struct nfsdontlisthead nfsrv_dontlisthead; | |||||
extern volatile int nfsrv_devidcnt; | extern volatile int nfsrv_devidcnt; | ||||
extern struct nfslayouthead nfsrv_recalllisthead; | extern struct nfslayouthead nfsrv_recalllisthead; | ||||
extern char *nfsrv_zeropnfsdat; | extern char *nfsrv_zeropnfsdat; | ||||
SYSCTL_DECL(_vfs_nfsd); | SYSCTL_DECL(_vfs_nfsd); | ||||
int nfsrv_statehashsize = NFSSTATEHASHSIZE; | int nfsrv_statehashsize = NFSSTATEHASHSIZE; | ||||
SYSCTL_INT(_vfs_nfsd, OID_AUTO, statehashsize, CTLFLAG_RDTUN, | SYSCTL_INT(_vfs_nfsd, OID_AUTO, statehashsize, CTLFLAG_RDTUN, | ||||
&nfsrv_statehashsize, 0, | &nfsrv_statehashsize, 0, | ||||
▲ Show 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | |||||
int nfsrv_flexlinuxhack = 0; | int nfsrv_flexlinuxhack = 0; | ||||
SYSCTL_INT(_vfs_nfsd, OID_AUTO, flexlinuxhack, CTLFLAG_RW, | SYSCTL_INT(_vfs_nfsd, OID_AUTO, flexlinuxhack, CTLFLAG_RW, | ||||
&nfsrv_flexlinuxhack, 0, | &nfsrv_flexlinuxhack, 0, | ||||
"For Linux clients, hack around Flex File Layout bug"); | "For Linux clients, hack around Flex File Layout bug"); | ||||
/* | /* | ||||
* Hash lists for nfs V4. | * Hash lists for nfs V4. | ||||
*/ | */ | ||||
struct nfsclienthashhead *nfsclienthash; | VNET_DEFINE(struct nfsclienthashhead *, nfsclienthash); | ||||
struct nfslockhashhead *nfslockhash; | VNET_DEFINE(struct nfslockhashhead *, nfslockhash); | ||||
struct nfssessionhash *nfssessionhash; | VNET_DEFINE(struct nfssessionhash *, nfssessionhash); | ||||
VNET_DEFINE(volatile int, nfsrv_dontlistlen) = 0; | |||||
struct nfslayouthash *nfslayouthash; | struct nfslayouthash *nfslayouthash; | ||||
volatile int nfsrv_dontlistlen = 0; | |||||
static u_int32_t nfsrv_openpluslock = 0, nfsrv_delegatecnt = 0; | static u_int32_t nfsrv_openpluslock = 0, nfsrv_delegatecnt = 0; | ||||
static time_t nfsrvboottime; | static time_t nfsrvboottime; | ||||
static int nfsrv_returnoldstateid = 0, nfsrv_clients = 0; | static int nfsrv_returnoldstateid = 0, nfsrv_clients = 0; | ||||
static int nfsrv_clienthighwater = NFSRV_CLIENTHIGHWATER; | static int nfsrv_clienthighwater = NFSRV_CLIENTHIGHWATER; | ||||
static int nfsrv_nogsscallback = 0; | static int nfsrv_nogsscallback = 0; | ||||
static volatile int nfsrv_writedelegcnt = 0; | static volatile int nfsrv_writedelegcnt = 0; | ||||
static int nfsrv_faildscnt; | static int nfsrv_faildscnt; | ||||
▲ Show 20 Lines • Show All 159 Lines • ▼ Show 20 Lines | #endif | ||||
} while (!igotlock); | } while (!igotlock); | ||||
NFSUNLOCKV4ROOTMUTEX(); | NFSUNLOCKV4ROOTMUTEX(); | ||||
/* | /* | ||||
* Search for a match in the client list. | * Search for a match in the client list. | ||||
*/ | */ | ||||
gotit = i = 0; | gotit = i = 0; | ||||
while (i < nfsrv_clienthashsize && !gotit) { | while (i < nfsrv_clienthashsize && !gotit) { | ||||
LIST_FOREACH(clp, &nfsclienthash[i], lc_hash) { | LIST_FOREACH(clp, &VNET(nfsclienthash)[i], lc_hash) { | ||||
if (new_clp->lc_idlen == clp->lc_idlen && | if (new_clp->lc_idlen == clp->lc_idlen && | ||||
!NFSBCMP(new_clp->lc_id, clp->lc_id, clp->lc_idlen)) { | !NFSBCMP(new_clp->lc_id, clp->lc_id, clp->lc_idlen)) { | ||||
gotit = 1; | gotit = 1; | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
if (gotit == 0) | if (gotit == 0) | ||||
i++; | i++; | ||||
▲ Show 20 Lines • Show All 597 Lines • ▼ Show 20 Lines | nfsrv_adminrevoke(struct nfsd_clid *revokep, NFSPROC_T *p) | ||||
} while (!igotlock); | } while (!igotlock); | ||||
NFSUNLOCKV4ROOTMUTEX(); | NFSUNLOCKV4ROOTMUTEX(); | ||||
/* | /* | ||||
* Search for a match in the client list. | * Search for a match in the client list. | ||||
*/ | */ | ||||
gotit = i = 0; | gotit = i = 0; | ||||
while (i < nfsrv_clienthashsize && !gotit) { | while (i < nfsrv_clienthashsize && !gotit) { | ||||
LIST_FOREACH(clp, &nfsclienthash[i], lc_hash) { | LIST_FOREACH(clp, &VNET(nfsclienthash)[i], lc_hash) { | ||||
if (revokep->nclid_idlen == clp->lc_idlen && | if (revokep->nclid_idlen == clp->lc_idlen && | ||||
!NFSBCMP(revokep->nclid_id, clp->lc_id, clp->lc_idlen)) { | !NFSBCMP(revokep->nclid_id, clp->lc_id, clp->lc_idlen)) { | ||||
gotit = 1; | gotit = 1; | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
i++; | i++; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | nfsrv_dumpclients(struct nfsd_dumpclients *dumpp, int maxcnt) | ||||
NFSLOCKV4ROOTMUTEX(); | NFSLOCKV4ROOTMUTEX(); | ||||
nfsv4_getref(&nfsv4rootfs_lock, NULL, NFSV4ROOTLOCKMUTEXPTR, NULL); | nfsv4_getref(&nfsv4rootfs_lock, NULL, NFSV4ROOTLOCKMUTEXPTR, NULL); | ||||
NFSUNLOCKV4ROOTMUTEX(); | NFSUNLOCKV4ROOTMUTEX(); | ||||
NFSLOCKSTATE(); | NFSLOCKSTATE(); | ||||
/* | /* | ||||
* Rattle through the client lists until done. | * Rattle through the client lists until done. | ||||
*/ | */ | ||||
while (i < nfsrv_clienthashsize && cnt < maxcnt) { | while (i < nfsrv_clienthashsize && cnt < maxcnt) { | ||||
clp = LIST_FIRST(&nfsclienthash[i]); | clp = LIST_FIRST(&VNET(nfsclienthash)[i]); | ||||
while (clp != LIST_END(&nfsclienthash[i]) && cnt < maxcnt) { | while (clp != LIST_END(&VNET(nfsclienthash)[i]) && cnt < maxcnt) { | ||||
nfsrv_dumpaclient(clp, &dumpp[cnt]); | nfsrv_dumpaclient(clp, &dumpp[cnt]); | ||||
cnt++; | cnt++; | ||||
clp = LIST_NEXT(clp, lc_hash); | clp = LIST_NEXT(clp, lc_hash); | ||||
} | } | ||||
i++; | i++; | ||||
} | } | ||||
if (cnt < maxcnt) | if (cnt < maxcnt) | ||||
dumpp[cnt].ndcl_clid.nclid_idlen = 0; | dumpp[cnt].ndcl_clid.nclid_idlen = 0; | ||||
▲ Show 20 Lines • Show All 259 Lines • ▼ Show 20 Lines | nfsrv_servertimer(void) | ||||
*/ | */ | ||||
if (nfsboottime.tv_sec == 0) | if (nfsboottime.tv_sec == 0) | ||||
NFSSETBOOTTIME(nfsboottime); | NFSSETBOOTTIME(nfsboottime); | ||||
/* | /* | ||||
* If server hasn't started yet, just return. | * If server hasn't started yet, just return. | ||||
*/ | */ | ||||
NFSLOCKSTATE(); | NFSLOCKSTATE(); | ||||
if (nfsrv_stablefirst.nsf_eograce == 0) { | if (VNET(nfsrv_stablefirst).nsf_eograce == 0) { | ||||
NFSUNLOCKSTATE(); | NFSUNLOCKSTATE(); | ||||
return; | return; | ||||
} | } | ||||
if (!(nfsrv_stablefirst.nsf_flags & NFSNSF_UPDATEDONE)) { | if (!(VNET(nfsrv_stablefirst).nsf_flags & NFSNSF_UPDATEDONE)) { | ||||
if (!(nfsrv_stablefirst.nsf_flags & NFSNSF_GRACEOVER) && | if (!(VNET(nfsrv_stablefirst).nsf_flags & NFSNSF_GRACEOVER) && | ||||
NFSD_MONOSEC > nfsrv_stablefirst.nsf_eograce) | NFSD_MONOSEC > VNET(nfsrv_stablefirst).nsf_eograce) | ||||
nfsrv_stablefirst.nsf_flags |= | VNET(nfsrv_stablefirst).nsf_flags |= | ||||
(NFSNSF_GRACEOVER | NFSNSF_NEEDLOCK); | (NFSNSF_GRACEOVER | NFSNSF_NEEDLOCK); | ||||
NFSUNLOCKSTATE(); | NFSUNLOCKSTATE(); | ||||
return; | return; | ||||
} | } | ||||
/* | /* | ||||
* Try and get a reference count on the nfsv4rootfs_lock so that | * Try and get a reference count on the nfsv4rootfs_lock so that | ||||
* no nfsd thread can acquire an exclusive lock on it before this | * no nfsd thread can acquire an exclusive lock on it before this | ||||
* call is done. If it is already exclusively locked, just return. | * call is done. If it is already exclusively locked, just return. | ||||
*/ | */ | ||||
NFSLOCKV4ROOTMUTEX(); | NFSLOCKV4ROOTMUTEX(); | ||||
got_ref = nfsv4_getref_nonblock(&nfsv4rootfs_lock); | got_ref = nfsv4_getref_nonblock(&nfsv4rootfs_lock); | ||||
NFSUNLOCKV4ROOTMUTEX(); | NFSUNLOCKV4ROOTMUTEX(); | ||||
if (got_ref == 0) { | if (got_ref == 0) { | ||||
NFSUNLOCKSTATE(); | NFSUNLOCKSTATE(); | ||||
return; | return; | ||||
} | } | ||||
/* | /* | ||||
* For each client... | * For each client... | ||||
*/ | */ | ||||
for (i = 0; i < nfsrv_clienthashsize; i++) { | for (i = 0; i < nfsrv_clienthashsize; i++) { | ||||
clp = LIST_FIRST(&nfsclienthash[i]); | clp = LIST_FIRST(&VNET(nfsclienthash)[i]); | ||||
while (clp != LIST_END(&nfsclienthash[i])) { | while (clp != LIST_END(&VNET(nfsclienthash)[i])) { | ||||
nclp = LIST_NEXT(clp, lc_hash); | nclp = LIST_NEXT(clp, lc_hash); | ||||
if (!(clp->lc_flags & LCL_EXPIREIT)) { | if (!(clp->lc_flags & LCL_EXPIREIT)) { | ||||
if (((clp->lc_expiry + NFSRV_STALELEASE) < NFSD_MONOSEC | if (((clp->lc_expiry + NFSRV_STALELEASE) < NFSD_MONOSEC | ||||
&& ((LIST_EMPTY(&clp->lc_deleg) | && ((LIST_EMPTY(&clp->lc_deleg) | ||||
&& LIST_EMPTY(&clp->lc_open)) || | && LIST_EMPTY(&clp->lc_open)) || | ||||
nfsrv_clients > nfsrv_clienthighwater)) || | nfsrv_clients > nfsrv_clienthighwater)) || | ||||
(clp->lc_expiry + NFSRV_MOULDYLEASE) < NFSD_MONOSEC || | (clp->lc_expiry + NFSRV_MOULDYLEASE) < NFSD_MONOSEC || | ||||
(clp->lc_expiry < NFSD_MONOSEC && | (clp->lc_expiry < NFSD_MONOSEC && | ||||
Show All 14 Lines | if (!(clp->lc_flags & LCL_EXPIREIT)) { | ||||
* OR | * OR | ||||
* Lease has expired PLUS the number of opens + locks | * Lease has expired PLUS the number of opens + locks | ||||
* has exceeded 90% of capacity | * has exceeded 90% of capacity | ||||
* | * | ||||
* --> Mark for expiry. The actual expiry will be done | * --> Mark for expiry. The actual expiry will be done | ||||
* by an nfsd sometime soon. | * by an nfsd sometime soon. | ||||
*/ | */ | ||||
clp->lc_flags |= LCL_EXPIREIT; | clp->lc_flags |= LCL_EXPIREIT; | ||||
nfsrv_stablefirst.nsf_flags |= | VNET(nfsrv_stablefirst).nsf_flags |= | ||||
(NFSNSF_NEEDLOCK | NFSNSF_EXPIREDCLIENT); | (NFSNSF_NEEDLOCK | NFSNSF_EXPIREDCLIENT); | ||||
} else { | } else { | ||||
/* | /* | ||||
* If there are no opens, increment no open tick cnt | * If there are no opens, increment no open tick cnt | ||||
* If time exceeds NFSNOOPEN, mark it to be thrown away | * If time exceeds NFSNOOPEN, mark it to be thrown away | ||||
* otherwise, if there is an open, reset no open time | * otherwise, if there is an open, reset no open time | ||||
* Hopefully, this will avoid excessive re-creation | * Hopefully, this will avoid excessive re-creation | ||||
* of open owners and subsequent open confirms. | * of open owners and subsequent open confirms. | ||||
*/ | */ | ||||
stp = LIST_FIRST(&clp->lc_open); | stp = LIST_FIRST(&clp->lc_open); | ||||
while (stp != LIST_END(&clp->lc_open)) { | while (stp != LIST_END(&clp->lc_open)) { | ||||
nstp = LIST_NEXT(stp, ls_list); | nstp = LIST_NEXT(stp, ls_list); | ||||
if (LIST_EMPTY(&stp->ls_open)) { | if (LIST_EMPTY(&stp->ls_open)) { | ||||
stp->ls_noopens++; | stp->ls_noopens++; | ||||
if (stp->ls_noopens > NFSNOOPEN || | if (stp->ls_noopens > NFSNOOPEN || | ||||
(nfsrv_openpluslock * 2) > | (nfsrv_openpluslock * 2) > | ||||
nfsrv_v4statelimit) | nfsrv_v4statelimit) | ||||
nfsrv_stablefirst.nsf_flags |= | VNET(nfsrv_stablefirst).nsf_flags |= | ||||
NFSNSF_NOOPENS; | NFSNSF_NOOPENS; | ||||
} else { | } else { | ||||
stp->ls_noopens = 0; | stp->ls_noopens = 0; | ||||
} | } | ||||
stp = nstp; | stp = nstp; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 3,046 Lines • ▼ Show 20 Lines | |||||
*/ | */ | ||||
static int | static int | ||||
nfsrv_checkgrace(struct nfsrv_descript *nd, struct nfsclient *clp, | nfsrv_checkgrace(struct nfsrv_descript *nd, struct nfsclient *clp, | ||||
u_int32_t flags) | u_int32_t flags) | ||||
{ | { | ||||
int error = 0, notreclaimed; | int error = 0, notreclaimed; | ||||
struct nfsrv_stable *sp; | struct nfsrv_stable *sp; | ||||
if ((nfsrv_stablefirst.nsf_flags & (NFSNSF_UPDATEDONE | | if ((VNET(nfsrv_stablefirst).nsf_flags & (NFSNSF_UPDATEDONE | | ||||
NFSNSF_GRACEOVER)) == 0) { | NFSNSF_GRACEOVER)) == 0) { | ||||
/* | /* | ||||
* First, check to see if all of the clients have done a | * First, check to see if all of the clients have done a | ||||
* ReclaimComplete. If so, grace can end now. | * ReclaimComplete. If so, grace can end now. | ||||
*/ | */ | ||||
notreclaimed = 0; | notreclaimed = 0; | ||||
LIST_FOREACH(sp, &nfsrv_stablefirst.nsf_head, nst_list) { | LIST_FOREACH(sp, &VNET(nfsrv_stablefirst).nsf_head, nst_list) { | ||||
if ((sp->nst_flag & NFSNST_RECLAIMED) == 0) { | if ((sp->nst_flag & NFSNST_RECLAIMED) == 0) { | ||||
notreclaimed = 1; | notreclaimed = 1; | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
if (notreclaimed == 0) | if (notreclaimed == 0) | ||||
nfsrv_stablefirst.nsf_flags |= (NFSNSF_GRACEOVER | | VNET(nfsrv_stablefirst).nsf_flags |= (NFSNSF_GRACEOVER | | ||||
NFSNSF_NEEDLOCK); | NFSNSF_NEEDLOCK); | ||||
} | } | ||||
if ((nfsrv_stablefirst.nsf_flags & NFSNSF_GRACEOVER) != 0) { | if ((VNET(nfsrv_stablefirst).nsf_flags & NFSNSF_GRACEOVER) != 0) { | ||||
if (flags & NFSLCK_RECLAIM) { | if (flags & NFSLCK_RECLAIM) { | ||||
error = NFSERR_NOGRACE; | error = NFSERR_NOGRACE; | ||||
goto out; | goto out; | ||||
} | } | ||||
} else { | } else { | ||||
if (!(flags & NFSLCK_RECLAIM)) { | if (!(flags & NFSLCK_RECLAIM)) { | ||||
error = NFSERR_GRACE; | error = NFSERR_GRACE; | ||||
goto out; | goto out; | ||||
} | } | ||||
if (nd != NULL && clp != NULL && | if (nd != NULL && clp != NULL && | ||||
(nd->nd_flag & ND_NFSV41) != 0 && | (nd->nd_flag & ND_NFSV41) != 0 && | ||||
(clp->lc_flags & LCL_RECLAIMCOMPLETE) != 0) { | (clp->lc_flags & LCL_RECLAIMCOMPLETE) != 0) { | ||||
error = NFSERR_NOGRACE; | error = NFSERR_NOGRACE; | ||||
goto out; | goto out; | ||||
} | } | ||||
/* | /* | ||||
* If grace is almost over and we are still getting Reclaims, | * If grace is almost over and we are still getting Reclaims, | ||||
* extend grace a bit. | * extend grace a bit. | ||||
*/ | */ | ||||
if ((NFSD_MONOSEC + NFSRV_LEASEDELTA) > | if ((NFSD_MONOSEC + NFSRV_LEASEDELTA) > | ||||
nfsrv_stablefirst.nsf_eograce) | VNET(nfsrv_stablefirst).nsf_eograce) | ||||
nfsrv_stablefirst.nsf_eograce = NFSD_MONOSEC + | VNET(nfsrv_stablefirst).nsf_eograce = NFSD_MONOSEC + | ||||
NFSRV_LEASEDELTA; | NFSRV_LEASEDELTA; | ||||
} | } | ||||
out: | out: | ||||
NFSEXITCODE(error); | NFSEXITCODE(error); | ||||
return (error); | return (error); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 418 Lines • ▼ Show 20 Lines | |||||
/* | /* | ||||
* Read in the stable storage file. Called by nfssvc() before the nfsd | * Read in the stable storage file. Called by nfssvc() before the nfsd | ||||
* processes start servicing requests. | * processes start servicing requests. | ||||
*/ | */ | ||||
void | void | ||||
nfsrv_setupstable(NFSPROC_T *p) | nfsrv_setupstable(NFSPROC_T *p) | ||||
{ | { | ||||
struct nfsrv_stablefirst *sf = &nfsrv_stablefirst; | struct nfsrv_stablefirst *sf = &VNET(nfsrv_stablefirst); | ||||
struct nfsrv_stable *sp, *nsp; | struct nfsrv_stable *sp, *nsp; | ||||
struct nfst_rec *tsp; | struct nfst_rec *tsp; | ||||
int error, i, tryagain; | int error, i, tryagain; | ||||
off_t off = 0; | off_t off = 0; | ||||
ssize_t aresid, len; | ssize_t aresid, len; | ||||
/* | /* | ||||
* If NFSNSF_UPDATEDONE is set, this is a restart of the nfsds without | * If NFSNSF_UPDATEDONE is set, this is a restart of the nfsds without | ||||
▲ Show 20 Lines • Show All 118 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
/* | /* | ||||
* Update the stable storage file, now that the grace period is over. | * Update the stable storage file, now that the grace period is over. | ||||
*/ | */ | ||||
void | void | ||||
nfsrv_updatestable(NFSPROC_T *p) | nfsrv_updatestable(NFSPROC_T *p) | ||||
{ | { | ||||
struct nfsrv_stablefirst *sf = &nfsrv_stablefirst; | struct nfsrv_stablefirst *sf = &VNET(nfsrv_stablefirst); | ||||
struct nfsrv_stable *sp, *nsp; | struct nfsrv_stable *sp, *nsp; | ||||
int i; | int i; | ||||
struct nfsvattr nva; | struct nfsvattr nva; | ||||
vnode_t vp; | vnode_t vp; | ||||
#if defined(__FreeBSD_version) && (__FreeBSD_version >= 500000) | #if defined(__FreeBSD_version) && (__FreeBSD_version >= 500000) | ||||
mount_t mp = NULL; | mount_t mp = NULL; | ||||
#endif | #endif | ||||
int error; | int error; | ||||
▲ Show 20 Lines • Show All 66 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
/* | /* | ||||
* Append a record to the stable storage file. | * Append a record to the stable storage file. | ||||
*/ | */ | ||||
void | void | ||||
nfsrv_writestable(u_char *client, int len, int flag, NFSPROC_T *p) | nfsrv_writestable(u_char *client, int len, int flag, NFSPROC_T *p) | ||||
{ | { | ||||
struct nfsrv_stablefirst *sf = &nfsrv_stablefirst; | struct nfsrv_stablefirst *sf = &VNET(nfsrv_stablefirst); | ||||
struct nfst_rec *sp; | struct nfst_rec *sp; | ||||
int error; | int error; | ||||
if (!(sf->nsf_flags & NFSNSF_OK) || sf->nsf_fp == NULL) | if (!(sf->nsf_flags & NFSNSF_OK) || sf->nsf_fp == NULL) | ||||
return; | return; | ||||
sp = (struct nfst_rec *)malloc(sizeof (struct nfst_rec) + | sp = (struct nfst_rec *)malloc(sizeof (struct nfst_rec) + | ||||
len - 1, M_TEMP, M_WAITOK); | len - 1, M_TEMP, M_WAITOK); | ||||
sp->len = len; | sp->len = len; | ||||
Show All 16 Lines | |||||
static void | static void | ||||
nfsrv_markstable(struct nfsclient *clp) | nfsrv_markstable(struct nfsclient *clp) | ||||
{ | { | ||||
struct nfsrv_stable *sp; | struct nfsrv_stable *sp; | ||||
/* | /* | ||||
* First find the client structure. | * First find the client structure. | ||||
*/ | */ | ||||
LIST_FOREACH(sp, &nfsrv_stablefirst.nsf_head, nst_list) { | LIST_FOREACH(sp, &VNET(nfsrv_stablefirst).nsf_head, nst_list) { | ||||
if (sp->nst_len == clp->lc_idlen && | if (sp->nst_len == clp->lc_idlen && | ||||
!NFSBCMP(sp->nst_client, clp->lc_id, sp->nst_len)) | !NFSBCMP(sp->nst_client, clp->lc_id, sp->nst_len)) | ||||
break; | break; | ||||
} | } | ||||
if (sp == LIST_END(&nfsrv_stablefirst.nsf_head)) | if (sp == LIST_END(&VNET(nfsrv_stablefirst).nsf_head)) | ||||
return; | return; | ||||
/* | /* | ||||
* Now, just mark it and set the nfsclient back pointer. | * Now, just mark it and set the nfsclient back pointer. | ||||
*/ | */ | ||||
sp->nst_flag |= NFSNST_GOTSTATE; | sp->nst_flag |= NFSNST_GOTSTATE; | ||||
sp->nst_clp = clp; | sp->nst_clp = clp; | ||||
} | } | ||||
/* | /* | ||||
* This function is called when a NFSv4.1 client does a ReclaimComplete. | * This function is called when a NFSv4.1 client does a ReclaimComplete. | ||||
* Very similar to nfsrv_markstable(), except for the flag being set. | * Very similar to nfsrv_markstable(), except for the flag being set. | ||||
*/ | */ | ||||
static void | static void | ||||
nfsrv_markreclaim(struct nfsclient *clp) | nfsrv_markreclaim(struct nfsclient *clp) | ||||
{ | { | ||||
struct nfsrv_stable *sp; | struct nfsrv_stable *sp; | ||||
/* | /* | ||||
* First find the client structure. | * First find the client structure. | ||||
*/ | */ | ||||
LIST_FOREACH(sp, &nfsrv_stablefirst.nsf_head, nst_list) { | LIST_FOREACH(sp, &VNET(nfsrv_stablefirst).nsf_head, nst_list) { | ||||
if (sp->nst_len == clp->lc_idlen && | if (sp->nst_len == clp->lc_idlen && | ||||
!NFSBCMP(sp->nst_client, clp->lc_id, sp->nst_len)) | !NFSBCMP(sp->nst_client, clp->lc_id, sp->nst_len)) | ||||
break; | break; | ||||
} | } | ||||
if (sp == LIST_END(&nfsrv_stablefirst.nsf_head)) | if (sp == LIST_END(&VNET(nfsrv_stablefirst).nsf_head)) | ||||
return; | return; | ||||
/* | /* | ||||
* Now, just set the flag. | * Now, just set the flag. | ||||
*/ | */ | ||||
sp->nst_flag |= NFSNST_RECLAIMED; | sp->nst_flag |= NFSNST_RECLAIMED; | ||||
} | } | ||||
/* | /* | ||||
* This function is called for a reclaim, to see if it gets grace. | * This function is called for a reclaim, to see if it gets grace. | ||||
* It returns 0 if a reclaim is allowed, 1 otherwise. | * It returns 0 if a reclaim is allowed, 1 otherwise. | ||||
*/ | */ | ||||
static int | static int | ||||
nfsrv_checkstable(struct nfsclient *clp) | nfsrv_checkstable(struct nfsclient *clp) | ||||
{ | { | ||||
struct nfsrv_stable *sp; | struct nfsrv_stable *sp; | ||||
/* | /* | ||||
* First, find the entry for the client. | * First, find the entry for the client. | ||||
*/ | */ | ||||
LIST_FOREACH(sp, &nfsrv_stablefirst.nsf_head, nst_list) { | LIST_FOREACH(sp, &VNET(nfsrv_stablefirst).nsf_head, nst_list) { | ||||
if (sp->nst_len == clp->lc_idlen && | if (sp->nst_len == clp->lc_idlen && | ||||
!NFSBCMP(sp->nst_client, clp->lc_id, sp->nst_len)) | !NFSBCMP(sp->nst_client, clp->lc_id, sp->nst_len)) | ||||
break; | break; | ||||
} | } | ||||
/* | /* | ||||
* If not in the list, state was revoked or no state was issued | * If not in the list, state was revoked or no state was issued | ||||
* since the previous reboot, a reclaim is denied. | * since the previous reboot, a reclaim is denied. | ||||
*/ | */ | ||||
if (sp == LIST_END(&nfsrv_stablefirst.nsf_head) || | if (sp == LIST_END(&VNET(nfsrv_stablefirst).nsf_head) || | ||||
(sp->nst_flag & NFSNST_REVOKE) || | (sp->nst_flag & NFSNST_REVOKE) || | ||||
!(nfsrv_stablefirst.nsf_flags & NFSNSF_OK)) | !(VNET(nfsrv_stablefirst).nsf_flags & NFSNSF_OK)) | ||||
return (1); | return (1); | ||||
return (0); | return (0); | ||||
} | } | ||||
/* | /* | ||||
* Test for and try to clear out a conflicting client. This is called by | * Test for and try to clear out a conflicting client. This is called by | ||||
* nfsrv_lockctrl() and nfsrv_openctrl() when conflicts with other clients | * nfsrv_lockctrl() and nfsrv_openctrl() when conflicts with other clients | ||||
* a found. | * a found. | ||||
Show All 11 Lines | nfsrv_clientconflict(struct nfsclient *clp, int *haslockp, vnode_t vp, | ||||
NFSPROC_T *p) | NFSPROC_T *p) | ||||
{ | { | ||||
int gotlock, lktype = 0; | int gotlock, lktype = 0; | ||||
/* | /* | ||||
* If lease hasn't expired, we can't fix it. | * If lease hasn't expired, we can't fix it. | ||||
*/ | */ | ||||
if (clp->lc_expiry >= NFSD_MONOSEC || | if (clp->lc_expiry >= NFSD_MONOSEC || | ||||
!(nfsrv_stablefirst.nsf_flags & NFSNSF_UPDATEDONE)) | !(VNET(nfsrv_stablefirst).nsf_flags & NFSNSF_UPDATEDONE)) | ||||
return (0); | return (0); | ||||
if (*haslockp == 0) { | if (*haslockp == 0) { | ||||
NFSUNLOCKSTATE(); | NFSUNLOCKSTATE(); | ||||
if (vp != NULL) { | if (vp != NULL) { | ||||
lktype = NFSVOPISLOCKED(vp); | lktype = NFSVOPISLOCKED(vp); | ||||
NFSVOPUNLOCK(vp); | NFSVOPUNLOCK(vp); | ||||
} | } | ||||
NFSLOCKV4ROOTMUTEX(); | NFSLOCKV4ROOTMUTEX(); | ||||
▲ Show 20 Lines • Show All 382 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
time_t starttime; | time_t starttime; | ||||
int error; | int error; | ||||
/* | /* | ||||
* First, check to see if the server is currently running and it has | * First, check to see if the server is currently running and it has | ||||
* been called for a regular file when issuing delegations. | * been called for a regular file when issuing delegations. | ||||
*/ | */ | ||||
if (newnfs_numnfsd == 0 || vp->v_type != VREG || | if (VNET(nfsrv_numnfsd) == 0 || vp->v_type != VREG || | ||||
nfsrv_issuedelegs == 0) | nfsrv_issuedelegs == 0) | ||||
return; | return; | ||||
KASSERT((NFSVOPISLOCKED(vp) != LK_EXCLUSIVE), ("vp %p is locked", vp)); | KASSERT((NFSVOPISLOCKED(vp) != LK_EXCLUSIVE), ("vp %p is locked", vp)); | ||||
/* | /* | ||||
* First, get a reference on the nfsv4rootfs_lock so that an | * First, get a reference on the nfsv4rootfs_lock so that an | ||||
* exclusive lock cannot be acquired by another thread. | * exclusive lock cannot be acquired by another thread. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 217 Lines • ▼ Show 20 Lines | |||||
void | void | ||||
nfsrv_throwawayopens(NFSPROC_T *p) | nfsrv_throwawayopens(NFSPROC_T *p) | ||||
{ | { | ||||
struct nfsclient *clp, *nclp; | struct nfsclient *clp, *nclp; | ||||
struct nfsstate *stp, *nstp; | struct nfsstate *stp, *nstp; | ||||
int i; | int i; | ||||
NFSLOCKSTATE(); | NFSLOCKSTATE(); | ||||
nfsrv_stablefirst.nsf_flags &= ~NFSNSF_NOOPENS; | VNET(nfsrv_stablefirst).nsf_flags &= ~NFSNSF_NOOPENS; | ||||
/* | /* | ||||
* For each client... | * For each client... | ||||
*/ | */ | ||||
for (i = 0; i < nfsrv_clienthashsize; i++) { | for (i = 0; i < nfsrv_clienthashsize; i++) { | ||||
LIST_FOREACH_SAFE(clp, &nfsclienthash[i], lc_hash, nclp) { | LIST_FOREACH_SAFE(clp, &VNET(nfsclienthash)[i], lc_hash, nclp) { | ||||
LIST_FOREACH_SAFE(stp, &clp->lc_open, ls_list, nstp) { | LIST_FOREACH_SAFE(stp, &clp->lc_open, ls_list, nstp) { | ||||
if (LIST_EMPTY(&stp->ls_open) && | if (LIST_EMPTY(&stp->ls_open) && | ||||
(stp->ls_noopens > NFSNOOPEN || | (stp->ls_noopens > NFSNOOPEN || | ||||
(nfsrv_openpluslock * 2) > | (nfsrv_openpluslock * 2) > | ||||
nfsrv_v4statelimit)) | nfsrv_v4statelimit)) | ||||
nfsrv_freeopenowner(stp, 0, p); | nfsrv_freeopenowner(stp, 0, p); | ||||
} | } | ||||
} | } | ||||
Show All 39 Lines | |||||
/* | /* | ||||
* Calculate the lease expiry time. | * Calculate the lease expiry time. | ||||
*/ | */ | ||||
static time_t | static time_t | ||||
nfsrv_leaseexpiry(void) | nfsrv_leaseexpiry(void) | ||||
{ | { | ||||
if (nfsrv_stablefirst.nsf_eograce > NFSD_MONOSEC) | if (VNET(nfsrv_stablefirst).nsf_eograce > NFSD_MONOSEC) | ||||
return (NFSD_MONOSEC + 2 * (nfsrv_lease + NFSRV_LEASEDELTA)); | return (NFSD_MONOSEC + 2 * (nfsrv_lease + NFSRV_LEASEDELTA)); | ||||
return (NFSD_MONOSEC + nfsrv_lease + NFSRV_LEASEDELTA); | return (NFSD_MONOSEC + nfsrv_lease + NFSRV_LEASEDELTA); | ||||
} | } | ||||
/* | /* | ||||
* Delay the delegation timeout as far as ls_delegtimelimit, as required. | * Delay the delegation timeout as far as ls_delegtimelimit, as required. | ||||
*/ | */ | ||||
static void | static void | ||||
▲ Show 20 Lines • Show All 304 Lines • ▼ Show 20 Lines | nfsrv_throwawayallstate(NFSPROC_T *p) | ||||
struct nfsclient *clp, *nclp; | struct nfsclient *clp, *nclp; | ||||
struct nfslockfile *lfp, *nlfp; | struct nfslockfile *lfp, *nlfp; | ||||
int i; | int i; | ||||
/* | /* | ||||
* For each client, clean out the state and then free the structure. | * For each client, clean out the state and then free the structure. | ||||
*/ | */ | ||||
for (i = 0; i < nfsrv_clienthashsize; i++) { | for (i = 0; i < nfsrv_clienthashsize; i++) { | ||||
LIST_FOREACH_SAFE(clp, &nfsclienthash[i], lc_hash, nclp) { | LIST_FOREACH_SAFE(clp, &VNET(nfsclienthash)[i], lc_hash, nclp) { | ||||
nfsrv_cleanclient(clp, p); | nfsrv_cleanclient(clp, p); | ||||
nfsrv_freedeleglist(&clp->lc_deleg); | nfsrv_freedeleglist(&clp->lc_deleg); | ||||
nfsrv_freedeleglist(&clp->lc_olddeleg); | nfsrv_freedeleglist(&clp->lc_olddeleg); | ||||
free(clp->lc_stateid, M_NFSDCLIENT); | free(clp->lc_stateid, M_NFSDCLIENT); | ||||
free(clp, M_NFSDCLIENT); | free(clp, M_NFSDCLIENT); | ||||
} | } | ||||
} | } | ||||
/* | /* | ||||
* Also, free up any remaining lock file structures. | * Also, free up any remaining lock file structures. | ||||
*/ | */ | ||||
for (i = 0; i < nfsrv_lockhashsize; i++) { | for (i = 0; i < nfsrv_lockhashsize; i++) { | ||||
LIST_FOREACH_SAFE(lfp, &nfslockhash[i], lf_hash, nlfp) { | LIST_FOREACH_SAFE(lfp, &VNET(nfslockhash)[i], lf_hash, nlfp) { | ||||
printf("nfsd unload: fnd a lock file struct\n"); | printf("nfsd unload: fnd a lock file struct\n"); | ||||
nfsrv_freenfslockfile(lfp); | nfsrv_freenfslockfile(lfp); | ||||
} | } | ||||
} | } | ||||
/* And get rid of the deviceid structures and layouts. */ | /* And get rid of the deviceid structures and layouts. */ | ||||
nfsrv_freealllayoutsanddevids(); | nfsrv_freealllayoutsanddevids(); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 101 Lines • ▼ Show 20 Lines | #ifdef INET6 | ||||
struct sockaddr_in6 *sin6; | struct sockaddr_in6 *sin6; | ||||
#endif | #endif | ||||
shp = NFSSESSIONHASH(nd->nd_sessionid); | shp = NFSSESSIONHASH(nd->nd_sessionid); | ||||
NFSLOCKSESSION(shp); | NFSLOCKSESSION(shp); | ||||
sep = nfsrv_findsession(nd->nd_sessionid); | sep = nfsrv_findsession(nd->nd_sessionid); | ||||
if (sep == NULL) { | if (sep == NULL) { | ||||
NFSUNLOCKSESSION(shp); | NFSUNLOCKSESSION(shp); | ||||
if ((nfsrv_stablefirst.nsf_flags & NFSNSF_GRACEOVER) != 0) { | if ((VNET(nfsrv_stablefirst).nsf_flags & NFSNSF_GRACEOVER) != 0) { | ||||
buf = malloc(INET6_ADDRSTRLEN, M_TEMP, M_WAITOK); | buf = malloc(INET6_ADDRSTRLEN, M_TEMP, M_WAITOK); | ||||
switch (nd->nd_nam->sa_family) { | switch (nd->nd_nam->sa_family) { | ||||
#ifdef INET | #ifdef INET | ||||
case AF_INET: | case AF_INET: | ||||
sin = (struct sockaddr_in *)nd->nd_nam; | sin = (struct sockaddr_in *)nd->nd_nam; | ||||
cp = inet_ntop(sin->sin_family, | cp = inet_ntop(sin->sin_family, | ||||
&sin->sin_addr.s_addr, buf, | &sin->sin_addr.s_addr, buf, | ||||
INET6_ADDRSTRLEN); | INET6_ADDRSTRLEN); | ||||
▲ Show 20 Lines • Show All 345 Lines • ▼ Show 20 Lines | |||||
nfsrv_freeallbackchannel_xprts(void) | nfsrv_freeallbackchannel_xprts(void) | ||||
{ | { | ||||
struct nfsdsession *sep; | struct nfsdsession *sep; | ||||
struct nfsclient *clp; | struct nfsclient *clp; | ||||
SVCXPRT *xprt; | SVCXPRT *xprt; | ||||
int i; | int i; | ||||
for (i = 0; i < nfsrv_clienthashsize; i++) { | for (i = 0; i < nfsrv_clienthashsize; i++) { | ||||
LIST_FOREACH(clp, &nfsclienthash[i], lc_hash) { | LIST_FOREACH(clp, &VNET(nfsclienthash)[i], lc_hash) { | ||||
LIST_FOREACH(sep, &clp->lc_session, sess_list) { | LIST_FOREACH(sep, &clp->lc_session, sess_list) { | ||||
xprt = sep->sess_cbsess.nfsess_xprt; | xprt = sep->sess_cbsess.nfsess_xprt; | ||||
sep->sess_cbsess.nfsess_xprt = NULL; | sep->sess_cbsess.nfsess_xprt = NULL; | ||||
if (xprt != NULL) | if (xprt != NULL) | ||||
SVC_RELEASE(xprt); | SVC_RELEASE(xprt); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 847 Lines • ▼ Show 20 Lines | nfsrv_freealllayoutsanddevids(void) | ||||
nfsrv_freealldevids(); | nfsrv_freealldevids(); | ||||
TAILQ_INIT(&nfsrv_devidhead); | TAILQ_INIT(&nfsrv_devidhead); | ||||
nfsrv_devidcnt = 0; | nfsrv_devidcnt = 0; | ||||
/* Get rid of all layouts. */ | /* Get rid of all layouts. */ | ||||
nfsrv_freealllayouts(); | nfsrv_freealllayouts(); | ||||
/* Get rid of any nfsdontlist entries. */ | /* Get rid of any nfsdontlist entries. */ | ||||
LIST_FOREACH_SAFE(mrp, &nfsrv_dontlisthead, nfsmr_list, nmrp) | LIST_FOREACH_SAFE(mrp, &VNET(nfsrv_dontlisthead), nfsmr_list, nmrp) | ||||
free(mrp, M_NFSDSTATE); | free(mrp, M_NFSDSTATE); | ||||
LIST_INIT(&nfsrv_dontlisthead); | LIST_INIT(&VNET(nfsrv_dontlisthead)); | ||||
nfsrv_dontlistlen = 0; | VNET(nfsrv_dontlistlen) = 0; | ||||
/* Free layouts in the recall list. */ | /* Free layouts in the recall list. */ | ||||
TAILQ_FOREACH_SAFE(lyp, &nfsrv_recalllisthead, lay_list, nlyp) | TAILQ_FOREACH_SAFE(lyp, &nfsrv_recalllisthead, lay_list, nlyp) | ||||
nfsrv_freelayout(&nfsrv_recalllisthead, lyp); | nfsrv_freelayout(&nfsrv_recalllisthead, lyp); | ||||
TAILQ_INIT(&nfsrv_recalllisthead); | TAILQ_INIT(&nfsrv_recalllisthead); | ||||
} | } | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 623 Lines • ▼ Show 20 Lines | |||||
* Return 1 if issuing an rw layout isn't allowed, 0 otherwise. | * Return 1 if issuing an rw layout isn't allowed, 0 otherwise. | ||||
*/ | */ | ||||
static int | static int | ||||
nfsrv_dontlayout(fhandle_t *fhp) | nfsrv_dontlayout(fhandle_t *fhp) | ||||
{ | { | ||||
struct nfsdontlist *mrp; | struct nfsdontlist *mrp; | ||||
int ret; | int ret; | ||||
if (nfsrv_dontlistlen == 0) | if (VNET(nfsrv_dontlistlen) == 0) | ||||
return (0); | return (0); | ||||
ret = 0; | ret = 0; | ||||
NFSDDONTLISTLOCK(); | NFSDDONTLISTLOCK(); | ||||
LIST_FOREACH(mrp, &nfsrv_dontlisthead, nfsmr_list) { | LIST_FOREACH(mrp, &VNET(nfsrv_dontlisthead), nfsmr_list) { | ||||
if (NFSBCMP(fhp, &mrp->nfsmr_fh, sizeof(*fhp)) == 0 && | if (NFSBCMP(fhp, &mrp->nfsmr_fh, sizeof(*fhp)) == 0 && | ||||
(mrp->nfsmr_flags & NFSMR_DONTLAYOUT) != 0) { | (mrp->nfsmr_flags & NFSMR_DONTLAYOUT) != 0) { | ||||
ret = 1; | ret = 1; | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
NFSDDONTLISTUNLOCK(); | NFSDDONTLISTUNLOCK(); | ||||
return (ret); | return (ret); | ||||
▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | nfsrv_copymr(vnode_t vp, vnode_t fvp, vnode_t dvp, struct nfsdevice *ds, | ||||
if (ret != 0) { | if (ret != 0) { | ||||
NFSD_DEBUG(4, "nfsrv_copymr: getfh=%d\n", ret); | NFSD_DEBUG(4, "nfsrv_copymr: getfh=%d\n", ret); | ||||
return (ret); | return (ret); | ||||
} | } | ||||
nmrp = malloc(sizeof(*nmrp), M_NFSDSTATE, M_WAITOK); | nmrp = malloc(sizeof(*nmrp), M_NFSDSTATE, M_WAITOK); | ||||
nmrp->nfsmr_flags = NFSMR_DONTLAYOUT; | nmrp->nfsmr_flags = NFSMR_DONTLAYOUT; | ||||
NFSBCOPY(&fh, &nmrp->nfsmr_fh, sizeof(fh)); | NFSBCOPY(&fh, &nmrp->nfsmr_fh, sizeof(fh)); | ||||
NFSDDONTLISTLOCK(); | NFSDDONTLISTLOCK(); | ||||
LIST_FOREACH(mrp, &nfsrv_dontlisthead, nfsmr_list) { | LIST_FOREACH(mrp, &VNET(nfsrv_dontlisthead), nfsmr_list) { | ||||
if (NFSBCMP(&fh, &mrp->nfsmr_fh, sizeof(fh)) == 0) | if (NFSBCMP(&fh, &mrp->nfsmr_fh, sizeof(fh)) == 0) | ||||
break; | break; | ||||
} | } | ||||
if (mrp == NULL) { | if (mrp == NULL) { | ||||
LIST_INSERT_HEAD(&nfsrv_dontlisthead, nmrp, nfsmr_list); | LIST_INSERT_HEAD(&VNET(nfsrv_dontlisthead), nmrp, nfsmr_list); | ||||
mrp = nmrp; | mrp = nmrp; | ||||
nmrp = NULL; | nmrp = NULL; | ||||
nfsrv_dontlistlen++; | VNET(nfsrv_dontlistlen)++; | ||||
NFSD_DEBUG(4, "nfsrv_copymr: in dontlist\n"); | NFSD_DEBUG(4, "nfsrv_copymr: in dontlist\n"); | ||||
} else { | } else { | ||||
NFSDDONTLISTUNLOCK(); | NFSDDONTLISTUNLOCK(); | ||||
free(nmrp, M_NFSDSTATE); | free(nmrp, M_NFSDSTATE); | ||||
NFSD_DEBUG(4, "nfsrv_copymr: dup dontlist\n"); | NFSD_DEBUG(4, "nfsrv_copymr: dup dontlist\n"); | ||||
return (ENXIO); | return (ENXIO); | ||||
} | } | ||||
NFSDDONTLISTUNLOCK(); | NFSDDONTLISTUNLOCK(); | ||||
▲ Show 20 Lines • Show All 538 Lines • Show Last 20 Lines |