Changeset View
Changeset View
Standalone View
Standalone View
head/sys/fs/nfsclient/nfs_clvnops.c
Show First 20 Lines • Show All 94 Lines • ▼ Show 20 Lines | dtrace_nfsclient_accesscache_load_probe_func_t | ||||
dtrace_nfscl_accesscache_load_done_probe; | dtrace_nfscl_accesscache_load_done_probe; | ||||
uint32_t nfscl_accesscache_load_done_id; | uint32_t nfscl_accesscache_load_done_id; | ||||
#endif /* !KDTRACE_HOOKS */ | #endif /* !KDTRACE_HOOKS */ | ||||
/* Defs */ | /* Defs */ | ||||
#define TRUE 1 | #define TRUE 1 | ||||
#define FALSE 0 | #define FALSE 0 | ||||
extern struct nfsstats newnfsstats; | extern struct nfsstatsv1 nfsstatsv1; | ||||
extern int nfsrv_useacl; | extern int nfsrv_useacl; | ||||
extern int nfscl_debuglevel; | extern int nfscl_debuglevel; | ||||
MALLOC_DECLARE(M_NEWNFSREQ); | MALLOC_DECLARE(M_NEWNFSREQ); | ||||
/* | /* | ||||
* Ifdef for FreeBSD-current merged buffer cache. It is unfortunate that these | * Ifdef for FreeBSD-current merged buffer cache. It is unfortunate that these | ||||
* calls are not in getblk() and brelse() so that they would not be necessary | * calls are not in getblk() and brelse() so that they would not be necessary | ||||
* here. | * here. | ||||
▲ Show 20 Lines • Show All 141 Lines • ▼ Show 20 Lines | |||||
* required can disable this knob. The process that opened the file O_DIRECT | * required can disable this knob. The process that opened the file O_DIRECT | ||||
* cannot mmap() the file, because mmap'ed IO on an O_DIRECT open() is not | * cannot mmap() the file, because mmap'ed IO on an O_DIRECT open() is not | ||||
* meaningful. | * meaningful. | ||||
*/ | */ | ||||
int newnfs_directio_allow_mmap = 1; | int newnfs_directio_allow_mmap = 1; | ||||
SYSCTL_INT(_vfs_nfs, OID_AUTO, nfs_directio_allow_mmap, CTLFLAG_RW, | SYSCTL_INT(_vfs_nfs, OID_AUTO, nfs_directio_allow_mmap, CTLFLAG_RW, | ||||
&newnfs_directio_allow_mmap, 0, "Enable mmaped IO on file with O_DIRECT opens"); | &newnfs_directio_allow_mmap, 0, "Enable mmaped IO on file with O_DIRECT opens"); | ||||
#if 0 | |||||
SYSCTL_INT(_vfs_nfs, OID_AUTO, access_cache_hits, CTLFLAG_RD, | |||||
&newnfsstats.accesscache_hits, 0, "NFS ACCESS cache hit count"); | |||||
SYSCTL_INT(_vfs_nfs, OID_AUTO, access_cache_misses, CTLFLAG_RD, | |||||
&newnfsstats.accesscache_misses, 0, "NFS ACCESS cache miss count"); | |||||
#endif | |||||
#define NFSACCESS_ALL (NFSACCESS_READ | NFSACCESS_MODIFY \ | #define NFSACCESS_ALL (NFSACCESS_READ | NFSACCESS_MODIFY \ | ||||
| NFSACCESS_EXTEND | NFSACCESS_EXECUTE \ | | NFSACCESS_EXTEND | NFSACCESS_EXECUTE \ | ||||
| NFSACCESS_DELETE | NFSACCESS_LOOKUP) | | NFSACCESS_DELETE | NFSACCESS_LOOKUP) | ||||
/* | /* | ||||
* SMP Locking Note : | * SMP Locking Note : | ||||
* The list of locks after the description of the lock is the ordering | * The list of locks after the description of the lock is the ordering | ||||
* of other locks acquired with the lock held. | * of other locks acquired with the lock held. | ||||
▲ Show 20 Lines • Show All 136 Lines • ▼ Show 20 Lines | if (v34) { | ||||
*/ | */ | ||||
gotahit = 0; | gotahit = 0; | ||||
mtx_lock(&np->n_mtx); | mtx_lock(&np->n_mtx); | ||||
for (i = 0; i < NFS_ACCESSCACHESIZE; i++) { | for (i = 0; i < NFS_ACCESSCACHESIZE; i++) { | ||||
if (ap->a_cred->cr_uid == np->n_accesscache[i].uid) { | if (ap->a_cred->cr_uid == np->n_accesscache[i].uid) { | ||||
if (time_second < (np->n_accesscache[i].stamp | if (time_second < (np->n_accesscache[i].stamp | ||||
+ nfsaccess_cache_timeout) && | + nfsaccess_cache_timeout) && | ||||
(np->n_accesscache[i].mode & mode) == mode) { | (np->n_accesscache[i].mode & mode) == mode) { | ||||
NFSINCRGLOBAL(newnfsstats.accesscache_hits); | NFSINCRGLOBAL(nfsstatsv1.accesscache_hits); | ||||
gotahit = 1; | gotahit = 1; | ||||
} | } | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
mtx_unlock(&np->n_mtx); | mtx_unlock(&np->n_mtx); | ||||
#ifdef KDTRACE_HOOKS | #ifdef KDTRACE_HOOKS | ||||
if (gotahit != 0) | if (gotahit != 0) | ||||
KDTRACE_NFS_ACCESSCACHE_GET_HIT(vp, | KDTRACE_NFS_ACCESSCACHE_GET_HIT(vp, | ||||
ap->a_cred->cr_uid, mode); | ap->a_cred->cr_uid, mode); | ||||
else | else | ||||
KDTRACE_NFS_ACCESSCACHE_GET_MISS(vp, | KDTRACE_NFS_ACCESSCACHE_GET_MISS(vp, | ||||
ap->a_cred->cr_uid, mode); | ap->a_cred->cr_uid, mode); | ||||
#endif | #endif | ||||
if (gotahit == 0) { | if (gotahit == 0) { | ||||
/* | /* | ||||
* Either a no, or a don't know. Go to the wire. | * Either a no, or a don't know. Go to the wire. | ||||
*/ | */ | ||||
NFSINCRGLOBAL(newnfsstats.accesscache_misses); | NFSINCRGLOBAL(nfsstatsv1.accesscache_misses); | ||||
error = nfs34_access_otw(vp, wmode, ap->a_td, | error = nfs34_access_otw(vp, wmode, ap->a_td, | ||||
ap->a_cred, &rmode); | ap->a_cred, &rmode); | ||||
if (!error && | if (!error && | ||||
(rmode & mode) != mode) | (rmode & mode) != mode) | ||||
error = EACCES; | error = EACCES; | ||||
} | } | ||||
return (error); | return (error); | ||||
} else { | } else { | ||||
▲ Show 20 Lines • Show All 403 Lines • ▼ Show 20 Lines | if (ncl_getattrcache(vp, &vattr) == 0) { | ||||
* delegation. | * delegation. | ||||
*/ | */ | ||||
nfscl_deleggetmodtime(vp, &vap->va_mtime); | nfscl_deleggetmodtime(vp, &vap->va_mtime); | ||||
return (0); | return (0); | ||||
} | } | ||||
if (NFS_ISV34(vp) && nfs_prime_access_cache && | if (NFS_ISV34(vp) && nfs_prime_access_cache && | ||||
nfsaccess_cache_timeout > 0) { | nfsaccess_cache_timeout > 0) { | ||||
NFSINCRGLOBAL(newnfsstats.accesscache_misses); | NFSINCRGLOBAL(nfsstatsv1.accesscache_misses); | ||||
nfs34_access_otw(vp, NFSACCESS_ALL, td, ap->a_cred, NULL); | nfs34_access_otw(vp, NFSACCESS_ALL, td, ap->a_cred, NULL); | ||||
if (ncl_getattrcache(vp, ap->a_vap) == 0) { | if (ncl_getattrcache(vp, ap->a_vap) == 0) { | ||||
nfscl_deleggetmodtime(vp, &ap->a_vap->va_mtime); | nfscl_deleggetmodtime(vp, &ap->a_vap->va_mtime); | ||||
return (0); | return (0); | ||||
} | } | ||||
} | } | ||||
error = nfsrpc_getattr(vp, ap->a_cred, td, &nfsva, NULL); | error = nfsrpc_getattr(vp, ap->a_cred, td, &nfsva, NULL); | ||||
if (!error) | if (!error) | ||||
▲ Show 20 Lines • Show All 240 Lines • ▼ Show 20 Lines | if (!(nmp->nm_flag & NFSMNT_NOCTO) && | ||||
newnp->n_attrstamp = 0; | newnp->n_attrstamp = 0; | ||||
KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(newvp); | KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(newvp); | ||||
mtx_unlock(&newnp->n_mtx); | mtx_unlock(&newnp->n_mtx); | ||||
} | } | ||||
if (nfscl_nodeleg(newvp, 0) == 0 || | if (nfscl_nodeleg(newvp, 0) == 0 || | ||||
((u_int)(ticks - ncticks) < (nmp->nm_nametimeo * hz) && | ((u_int)(ticks - ncticks) < (nmp->nm_nametimeo * hz) && | ||||
VOP_GETATTR(newvp, &vattr, cnp->cn_cred) == 0 && | VOP_GETATTR(newvp, &vattr, cnp->cn_cred) == 0 && | ||||
timespeccmp(&vattr.va_ctime, &nctime, ==))) { | timespeccmp(&vattr.va_ctime, &nctime, ==))) { | ||||
NFSINCRGLOBAL(newnfsstats.lookupcache_hits); | NFSINCRGLOBAL(nfsstatsv1.lookupcache_hits); | ||||
if (cnp->cn_nameiop != LOOKUP && | if (cnp->cn_nameiop != LOOKUP && | ||||
(flags & ISLASTCN)) | (flags & ISLASTCN)) | ||||
cnp->cn_flags |= SAVENAME; | cnp->cn_flags |= SAVENAME; | ||||
return (0); | return (0); | ||||
} | } | ||||
cache_purge(newvp); | cache_purge(newvp); | ||||
if (dvp != newvp) | if (dvp != newvp) | ||||
vput(newvp); | vput(newvp); | ||||
Show All 10 Lines | if (error == -1) { | ||||
* Otherwise, we discard all of the negative cache | * Otherwise, we discard all of the negative cache | ||||
* entries for this directory. We also only trust | * entries for this directory. We also only trust | ||||
* negative cache entries for up to nm_negnametimeo | * negative cache entries for up to nm_negnametimeo | ||||
* seconds. | * seconds. | ||||
*/ | */ | ||||
if ((u_int)(ticks - ncticks) < (nmp->nm_negnametimeo * hz) && | if ((u_int)(ticks - ncticks) < (nmp->nm_negnametimeo * hz) && | ||||
VOP_GETATTR(dvp, &vattr, cnp->cn_cred) == 0 && | VOP_GETATTR(dvp, &vattr, cnp->cn_cred) == 0 && | ||||
timespeccmp(&vattr.va_mtime, &nctime, ==)) { | timespeccmp(&vattr.va_mtime, &nctime, ==)) { | ||||
NFSINCRGLOBAL(newnfsstats.lookupcache_hits); | NFSINCRGLOBAL(nfsstatsv1.lookupcache_hits); | ||||
return (ENOENT); | return (ENOENT); | ||||
} | } | ||||
cache_purge_negative(dvp); | cache_purge_negative(dvp); | ||||
} | } | ||||
error = 0; | error = 0; | ||||
newvp = NULLVP; | newvp = NULLVP; | ||||
NFSINCRGLOBAL(newnfsstats.lookupcache_misses); | NFSINCRGLOBAL(nfsstatsv1.lookupcache_misses); | ||||
error = nfsrpc_lookup(dvp, cnp->cn_nameptr, cnp->cn_namelen, | error = nfsrpc_lookup(dvp, cnp->cn_nameptr, cnp->cn_namelen, | ||||
cnp->cn_cred, td, &dnfsva, &nfsva, &nfhp, &attrflag, &dattrflag, | cnp->cn_cred, td, &dnfsva, &nfsva, &nfhp, &attrflag, &dattrflag, | ||||
NULL); | NULL); | ||||
if (dattrflag) | if (dattrflag) | ||||
(void) nfscl_loadattrcache(&dvp, &dnfsva, NULL, NULL, 0, 1); | (void) nfscl_loadattrcache(&dvp, &dnfsva, NULL, NULL, 0, 1); | ||||
if (error) { | if (error) { | ||||
if (newvp != NULLVP) { | if (newvp != NULLVP) { | ||||
vput(newvp); | vput(newvp); | ||||
▲ Show 20 Lines • Show All 1,061 Lines • ▼ Show 20 Lines | nfs_readdir(struct vop_readdir_args *ap) | ||||
*/ | */ | ||||
if (np->n_direofoffset > 0 && uio->uio_offset >= np->n_direofoffset && | if (np->n_direofoffset > 0 && uio->uio_offset >= np->n_direofoffset && | ||||
(np->n_flag & NMODIFIED) == 0) { | (np->n_flag & NMODIFIED) == 0) { | ||||
if (VOP_GETATTR(vp, &vattr, ap->a_cred) == 0) { | if (VOP_GETATTR(vp, &vattr, ap->a_cred) == 0) { | ||||
mtx_lock(&np->n_mtx); | mtx_lock(&np->n_mtx); | ||||
if ((NFS_ISV4(vp) && np->n_change == vattr.va_filerev) || | if ((NFS_ISV4(vp) && np->n_change == vattr.va_filerev) || | ||||
!NFS_TIMESPEC_COMPARE(&np->n_mtime, &vattr.va_mtime)) { | !NFS_TIMESPEC_COMPARE(&np->n_mtime, &vattr.va_mtime)) { | ||||
mtx_unlock(&np->n_mtx); | mtx_unlock(&np->n_mtx); | ||||
NFSINCRGLOBAL(newnfsstats.direofcache_hits); | NFSINCRGLOBAL(nfsstatsv1.direofcache_hits); | ||||
if (ap->a_eofflag != NULL) | if (ap->a_eofflag != NULL) | ||||
*ap->a_eofflag = 1; | *ap->a_eofflag = 1; | ||||
return (0); | return (0); | ||||
} else | } else | ||||
mtx_unlock(&np->n_mtx); | mtx_unlock(&np->n_mtx); | ||||
} | } | ||||
} | } | ||||
Show All 10 Lines | nfs_readdir(struct vop_readdir_args *ap) | ||||
/* | /* | ||||
* Call ncl_bioread() to do the real work. | * Call ncl_bioread() to do the real work. | ||||
*/ | */ | ||||
tresid = uio->uio_resid; | tresid = uio->uio_resid; | ||||
error = ncl_bioread(vp, uio, 0, ap->a_cred); | error = ncl_bioread(vp, uio, 0, ap->a_cred); | ||||
if (!error && uio->uio_resid == tresid) { | if (!error && uio->uio_resid == tresid) { | ||||
NFSINCRGLOBAL(newnfsstats.direofcache_misses); | NFSINCRGLOBAL(nfsstatsv1.direofcache_misses); | ||||
if (ap->a_eofflag != NULL) | if (ap->a_eofflag != NULL) | ||||
*ap->a_eofflag = 1; | *ap->a_eofflag = 1; | ||||
} | } | ||||
/* Add the partial DIRBLKSIZ (left) back in. */ | /* Add the partial DIRBLKSIZ (left) back in. */ | ||||
uio->uio_resid += left; | uio->uio_resid += left; | ||||
return (error); | return (error); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 1,243 Lines • Show Last 20 Lines |