ZFS might not return monotonically increasing directory offset cookies,
so turn off UFS-specific hack that assumes so in ZFS case. Before the change we can miss returning some directory entries to a NFS client. I believe that the hack should be moved to ufs_readdir(), but until we find somebody who will do it, turn it off for ZFS in NFS server code. Submitted by: rmacklem Discussed with: rmacklem, mckusick MFC after: 3 days
This commit is contained in:
parent
1dadcedcfc
commit
8449945a4d
@ -2737,7 +2737,7 @@ nfsrv_readdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
|||||||
int v3 = (nfsd->nd_flag & ND_NFSV3);
|
int v3 = (nfsd->nd_flag & ND_NFSV3);
|
||||||
u_quad_t off, toff, verf;
|
u_quad_t off, toff, verf;
|
||||||
u_long *cookies = NULL, *cookiep; /* needs to be int64_t or off_t */
|
u_long *cookies = NULL, *cookiep; /* needs to be int64_t or off_t */
|
||||||
int vfslocked;
|
int vfslocked, not_zfs;
|
||||||
|
|
||||||
nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
|
nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
|
||||||
vfslocked = 0;
|
vfslocked = 0;
|
||||||
@ -2801,6 +2801,7 @@ nfsrv_readdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
|||||||
error = 0;
|
error = 0;
|
||||||
goto nfsmout;
|
goto nfsmout;
|
||||||
}
|
}
|
||||||
|
not_zfs = strcmp(vp->v_mount->mnt_vfc->vfc_name, "zfs") != 0;
|
||||||
VOP_UNLOCK(vp, 0);
|
VOP_UNLOCK(vp, 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2887,10 +2888,12 @@ again:
|
|||||||
* skip over the records that precede the requested offset. This
|
* skip over the records that precede the requested offset. This
|
||||||
* requires the assumption that file offset cookies monotonically
|
* requires the assumption that file offset cookies monotonically
|
||||||
* increase.
|
* increase.
|
||||||
|
* Since the offset cookies don't monotonically increase for ZFS,
|
||||||
|
* this is not done when ZFS is the file system.
|
||||||
*/
|
*/
|
||||||
while (cpos < cend && ncookies > 0 &&
|
while (cpos < cend && ncookies > 0 &&
|
||||||
(dp->d_fileno == 0 || dp->d_type == DT_WHT ||
|
(dp->d_fileno == 0 || dp->d_type == DT_WHT ||
|
||||||
((u_quad_t)(*cookiep)) <= toff)) {
|
(not_zfs != 0 && ((u_quad_t)(*cookiep)) <= toff))) {
|
||||||
cpos += dp->d_reclen;
|
cpos += dp->d_reclen;
|
||||||
dp = (struct dirent *)cpos;
|
dp = (struct dirent *)cpos;
|
||||||
cookiep++;
|
cookiep++;
|
||||||
@ -3037,6 +3040,7 @@ nfsrv_readdirplus(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
|||||||
int usevget = 1, vfslocked;
|
int usevget = 1, vfslocked;
|
||||||
struct componentname cn;
|
struct componentname cn;
|
||||||
struct mount *mntp = NULL;
|
struct mount *mntp = NULL;
|
||||||
|
int not_zfs;
|
||||||
|
|
||||||
nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
|
nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
|
||||||
vfslocked = 0;
|
vfslocked = 0;
|
||||||
@ -3097,6 +3101,7 @@ nfsrv_readdirplus(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
|||||||
error = 0;
|
error = 0;
|
||||||
goto nfsmout;
|
goto nfsmout;
|
||||||
}
|
}
|
||||||
|
not_zfs = strcmp(vp->v_mount->mnt_vfc->vfc_name, "zfs") != 0;
|
||||||
VOP_UNLOCK(vp, 0);
|
VOP_UNLOCK(vp, 0);
|
||||||
vp_locked = 0;
|
vp_locked = 0;
|
||||||
rbuf = malloc(siz, M_TEMP, M_WAITOK);
|
rbuf = malloc(siz, M_TEMP, M_WAITOK);
|
||||||
@ -3176,10 +3181,12 @@ again:
|
|||||||
* skip over the records that precede the requested offset. This
|
* skip over the records that precede the requested offset. This
|
||||||
* requires the assumption that file offset cookies monotonically
|
* requires the assumption that file offset cookies monotonically
|
||||||
* increase.
|
* increase.
|
||||||
|
* Since the offset cookies don't monotonically increase for ZFS,
|
||||||
|
* this is not done when ZFS is the file system.
|
||||||
*/
|
*/
|
||||||
while (cpos < cend && ncookies > 0 &&
|
while (cpos < cend && ncookies > 0 &&
|
||||||
(dp->d_fileno == 0 || dp->d_type == DT_WHT ||
|
(dp->d_fileno == 0 || dp->d_type == DT_WHT ||
|
||||||
((u_quad_t)(*cookiep)) <= toff)) {
|
(not_zfs != 0 && ((u_quad_t)(*cookiep)) <= toff))) {
|
||||||
cpos += dp->d_reclen;
|
cpos += dp->d_reclen;
|
||||||
dp = (struct dirent *)cpos;
|
dp = (struct dirent *)cpos;
|
||||||
cookiep++;
|
cookiep++;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user