Changeset View
Changeset View
Standalone View
Standalone View
sys/fs/nfsclient/nfs_clport.c
Show First 20 Lines • Show All 240 Lines • ▼ Show 20 Lines | nfscl_nget(struct mount *mntp, struct vnode *dvp, struct nfsfh *nfhp, | ||||
* are correct | * are correct | ||||
*/ | */ | ||||
if ((nfhp->nfh_len == nmp->nm_fhsize) && | if ((nfhp->nfh_len == nmp->nm_fhsize) && | ||||
!bcmp(nfhp->nfh_fh, nmp->nm_fh, nfhp->nfh_len)) { | !bcmp(nfhp->nfh_fh, nmp->nm_fh, nfhp->nfh_len)) { | ||||
if (vp->v_type == VNON) | if (vp->v_type == VNON) | ||||
vp->v_type = VDIR; | vp->v_type = VDIR; | ||||
vp->v_vflag |= VV_ROOT; | vp->v_vflag |= VV_ROOT; | ||||
} | } | ||||
vp->v_vflag |= VV_VMSIZEVNLOCK; | |||||
np->n_fhp = nfhp; | np->n_fhp = nfhp; | ||||
/* | /* | ||||
* For NFSv4, we have to attach the directory file handle and | * For NFSv4, we have to attach the directory file handle and | ||||
* file name, so that Open Ops can be done later. | * file name, so that Open Ops can be done later. | ||||
*/ | */ | ||||
if (nmp->nm_flag & NFSMNT_NFSV4) { | if (nmp->nm_flag & NFSMNT_NFSV4) { | ||||
np->n_v4 = malloc(sizeof (struct nfsv4node) | np->n_v4 = malloc(sizeof (struct nfsv4node) | ||||
+ dnp->n_fhp->nfh_len + cnp->cn_namelen - 1, M_NFSV4NODE, | + dnp->n_fhp->nfh_len + cnp->cn_namelen - 1, M_NFSV4NODE, | ||||
▲ Show 20 Lines • Show All 151 Lines • ▼ Show 20 Lines | |||||
nfscl_loadattrcache(struct vnode **vpp, struct nfsvattr *nap, void *nvaper, | nfscl_loadattrcache(struct vnode **vpp, struct nfsvattr *nap, void *nvaper, | ||||
void *stuff, int writeattr, int dontshrink) | void *stuff, int writeattr, int dontshrink) | ||||
{ | { | ||||
struct vnode *vp = *vpp; | struct vnode *vp = *vpp; | ||||
struct vattr *vap, *nvap = &nap->na_vattr, *vaper = nvaper; | struct vattr *vap, *nvap = &nap->na_vattr, *vaper = nvaper; | ||||
struct nfsnode *np; | struct nfsnode *np; | ||||
struct nfsmount *nmp; | struct nfsmount *nmp; | ||||
struct timespec mtime_save; | struct timespec mtime_save; | ||||
vm_object_t object; | |||||
u_quad_t nsize; | |||||
int error, force_fid_err; | int error, force_fid_err; | ||||
bool setnsize; | |||||
error = 0; | error = 0; | ||||
/* | /* | ||||
* If v_type == VNON it is a new node, so fill in the v_type, | * If v_type == VNON it is a new node, so fill in the v_type, | ||||
* n_mtime fields. Check to see if it represents a special | * n_mtime fields. Check to see if it represents a special | ||||
* device, and if so, check for a possible alias. Once the | * device, and if so, check for a possible alias. Once the | ||||
* correct vnode has been obtained, fill in the rest of the | * correct vnode has been obtained, fill in the rest of the | ||||
▲ Show 20 Lines • Show All 131 Lines • ▼ Show 20 Lines | if (vaper != NULL) { | ||||
} | } | ||||
} | } | ||||
out: | out: | ||||
#ifdef KDTRACE_HOOKS | #ifdef KDTRACE_HOOKS | ||||
if (np->n_attrstamp != 0) | if (np->n_attrstamp != 0) | ||||
KDTRACE_NFS_ATTRCACHE_LOAD_DONE(vp, vap, error); | KDTRACE_NFS_ATTRCACHE_LOAD_DONE(vp, vap, error); | ||||
#endif | #endif | ||||
(void)ncl_pager_setsize(vp, NULL); | |||||
return (error); | |||||
} | |||||
rmacklem: It might be nice to have a comment here noting that the function
unlocks the NFS node, but only… | |||||
/* | |||||
* Call vnode_pager_setsize() if the size of the node changed, as | |||||
* recorded in nfsnode vs. v_object, or delay the call if notifying | |||||
* the pager is not possible at the moment. | |||||
* | |||||
* If nsizep is non-NULL, the call is delayed and the new node size is | |||||
* provided. Caller should itself call vnode_pager_setsize() if | |||||
* function returned true. If nsizep is NULL, function tries to call | |||||
* vnode_pager_setsize() itself if needed and possible, and the nfs | |||||
* node is unlocked unconditionally, the return value is not useful. | |||||
*/ | |||||
bool | |||||
ncl_pager_setsize(struct vnode *vp, u_quad_t *nsizep) | |||||
{ | |||||
struct nfsnode *np; | |||||
vm_object_t object; | |||||
struct vattr *vap; | |||||
u_quad_t nsize; | |||||
bool setnsize; | |||||
np = VTONFS(vp); | |||||
NFSASSERTNODE(np); | |||||
vap = &np->n_vattr.na_vattr; | |||||
nsize = vap->va_size; | nsize = vap->va_size; | ||||
object = vp->v_object; | object = vp->v_object; | ||||
setnsize = false; | setnsize = false; | ||||
if (object != NULL) { | |||||
if (OFF_TO_IDX(nsize + PAGE_MASK) < object->size) { | if (object != NULL && nsize != object->un_pager.vnp.vnp_size) { | ||||
/* | if (VOP_ISLOCKED(vp) == LK_EXCLUSIVE) | ||||
* When shrinking the size, the call to | |||||
* vnode_pager_setsize() cannot be done with | |||||
* the mutex held, because we might need to | |||||
* wait for a busy page. Delay it until after | |||||
* the node is unlocked. | |||||
*/ | |||||
setnsize = true; | setnsize = true; | ||||
} else { | else | ||||
vnode_pager_setsize(vp, nsize); | np->n_flag |= NVNSETSZSKIP; | ||||
} | } | ||||
} | if (nsizep == NULL) { | ||||
NFSUNLOCKNODE(np); | NFSUNLOCKNODE(np); | ||||
if (setnsize) | if (setnsize) | ||||
vnode_pager_setsize(vp, nsize); | vnode_pager_setsize(vp, nsize); | ||||
return (error); | setnsize = false; | ||||
} else { | |||||
*nsizep = nsize; | |||||
} | |||||
return (setnsize); | |||||
} | } | ||||
/* | /* | ||||
* Fill in the client id name. For these bytes: | * Fill in the client id name. For these bytes: | ||||
* 1 - they must be unique | * 1 - they must be unique | ||||
* 2 - they should be persistent across client reboots | * 2 - they should be persistent across client reboots | ||||
* 1 is more critical than 2 | * 1 is more critical than 2 | ||||
* Use the mount point's unique id plus either the uuid or, if that | * Use the mount point's unique id plus either the uuid or, if that | ||||
▲ Show 20 Lines • Show All 794 Lines • Show Last 20 Lines |
It might be nice to have a comment here noting that the function
unlocks the NFS node, but only when nsizep == NULL.
(I find I have to look at the function closely to notice this.)
But it is just a suggestion.