Changeset View
Changeset View
Standalone View
Standalone View
head/sys/fs/nfsserver/nfs_nfsdport.c
Show First 20 Lines • Show All 2,410 Lines • ▼ Show 20 Lines | if (dp->d_fileno != 0 && dp->d_type != DT_WHT && | ||||
r = VFS_ROOT(new_mp, | r = VFS_ROOT(new_mp, | ||||
LK_SHARED, &nvp); | LK_SHARED, &nvp); | ||||
needs_unbusy = 1; | needs_unbusy = 1; | ||||
if (r == 0) | if (r == 0) | ||||
at_root = 1; | at_root = 1; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
if (!r) { | |||||
/* | |||||
* If we failed to look up the entry, then it | |||||
* has become invalid, most likely removed. | |||||
*/ | |||||
if (r != 0) { | |||||
if (needs_unbusy) | |||||
vfs_unbusy(new_mp); | |||||
goto invalid; | |||||
} | |||||
KASSERT(refp != NULL || nvp != NULL, | |||||
("%s: undetected lookup error", __func__)); | |||||
if (refp == NULL && | if (refp == NULL && | ||||
((nd->nd_flag & ND_NFSV3) || | ((nd->nd_flag & ND_NFSV3) || | ||||
NFSNONZERO_ATTRBIT(&attrbits))) { | NFSNONZERO_ATTRBIT(&attrbits))) { | ||||
r = nfsvno_getfh(nvp, &nfh, p); | r = nfsvno_getfh(nvp, &nfh, p); | ||||
if (!r) | if (!r) | ||||
r = nfsvno_getattr(nvp, nvap, nd, p, | r = nfsvno_getattr(nvp, nvap, nd, p, | ||||
1, &attrbits); | 1, &attrbits); | ||||
if (r == 0 && is_zfs == 1 && | if (r == 0 && is_zfs == 1 && | ||||
nfsrv_enable_crossmntpt != 0 && | nfsrv_enable_crossmntpt != 0 && | ||||
(nd->nd_flag & ND_NFSV4) != 0 && | (nd->nd_flag & ND_NFSV4) != 0 && | ||||
nvp->v_type == VDIR && | nvp->v_type == VDIR && | ||||
vp->v_mount != nvp->v_mount) { | vp->v_mount != nvp->v_mount) { | ||||
/* | /* | ||||
* For a ZFS snapshot, there is a | * For a ZFS snapshot, there is a | ||||
* pseudo mount that does not set | * pseudo mount that does not set | ||||
* v_mountedhere, so it needs to | * v_mountedhere, so it needs to | ||||
* be detected via a different | * be detected via a different | ||||
* mount structure. | * mount structure. | ||||
*/ | */ | ||||
at_root = 1; | at_root = 1; | ||||
if (new_mp == mp) | if (new_mp == mp) | ||||
new_mp = nvp->v_mount; | new_mp = nvp->v_mount; | ||||
} | } | ||||
} | } | ||||
} else { | |||||
nvp = NULL; | /* | ||||
} | * If we failed to get attributes of the entry, | ||||
if (r) { | * then just skip it for NFSv3 (the traditional | ||||
* behavior in the old NFS server). | |||||
* For NFSv4 the behavior is controlled by | |||||
* RDATTRERROR: we either ignore the error or | |||||
* fail the request. | |||||
* Note that RDATTRERROR is never set for NFSv3. | |||||
*/ | |||||
if (r != 0) { | |||||
if (!NFSISSET_ATTRBIT(&attrbits, | if (!NFSISSET_ATTRBIT(&attrbits, | ||||
NFSATTRBIT_RDATTRERROR)) { | NFSATTRBIT_RDATTRERROR)) { | ||||
if (nvp != NULL) | |||||
vput(nvp); | vput(nvp); | ||||
if (needs_unbusy != 0) | if (needs_unbusy != 0) | ||||
vfs_unbusy(new_mp); | vfs_unbusy(new_mp); | ||||
if ((nd->nd_flag & ND_NFSV3)) | |||||
goto invalid; | |||||
nd->nd_repstat = r; | nd->nd_repstat = r; | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
/* | /* | ||||
* Build the directory record xdr | * Build the directory record xdr | ||||
▲ Show 20 Lines • Show All 52 Lines • ▼ Show 20 Lines | if (dp->d_fileno != 0 && dp->d_type != DT_WHT && | ||||
vrele(nvp); | vrele(nvp); | ||||
dirlen += (3 * NFSX_UNSIGNED); | dirlen += (3 * NFSX_UNSIGNED); | ||||
} | } | ||||
if (needs_unbusy != 0) | if (needs_unbusy != 0) | ||||
vfs_unbusy(new_mp); | vfs_unbusy(new_mp); | ||||
if (dirlen <= cnt) | if (dirlen <= cnt) | ||||
entrycnt++; | entrycnt++; | ||||
} | } | ||||
invalid: | |||||
cpos += dp->d_reclen; | cpos += dp->d_reclen; | ||||
dp = (struct dirent *)cpos; | dp = (struct dirent *)cpos; | ||||
cookiep++; | cookiep++; | ||||
ncookies--; | ncookies--; | ||||
} | } | ||||
vrele(vp); | vrele(vp); | ||||
vfs_unbusy(mp); | vfs_unbusy(mp); | ||||
▲ Show 20 Lines • Show All 3,282 Lines • Show Last 20 Lines |