Since VOP_READDIR() for ZFS does not return monotonically

increasing directory offset cookies, disable the UFS related
loop that skips over directory entries at the beginning of
the block for the experimental NFS server. This loop is
required for UFS since it always returns directory entries
starting at the beginning of the block that
the requested directory offset is in. In discussion with pjd@
and mckusick@ it seems that this behaviour of UFS should maybe
change, with this fix being an interim patch until then.
This patch only fixes the experimental server, since pjd@ is
working on a patch for the regular server.

Discussed with:	pjd, mckusick
MFC after:	5 days
This commit is contained in:
Rick Macklem 2010-12-24 18:46:44 +00:00
parent e29ba4c2db
commit 63e1cb4308
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=216691

View file

@ -1432,6 +1432,7 @@ nfsrvd_readdir(struct nfsrv_descript *nd, int isdgram,
u_long *cookies = NULL, *cookiep;
struct uio io;
struct iovec iv;
int not_zfs;
if (nd->nd_repstat) {
nfsrv_postopattr(nd, getret, &at);
@ -1484,6 +1485,7 @@ nfsrvd_readdir(struct nfsrv_descript *nd, int isdgram,
nfsrv_postopattr(nd, getret, &at);
return (0);
}
not_zfs = strcmp(vp->v_mount->mnt_vfc->vfc_name, "zfs");
NFSVOPUNLOCK(vp, 0, p);
MALLOC(rbuf, caddr_t, siz, M_TEMP, M_WAITOK);
again:
@ -1566,10 +1568,12 @@ nfsrvd_readdir(struct nfsrv_descript *nd, int isdgram,
* skip over the records that precede the requested offset. This
* requires the assumption that file offset cookies monotonically
* 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 &&
(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;
dp = (struct dirent *)cpos;
cookiep++;
@ -1678,6 +1682,7 @@ nfsrvd_readdirplus(struct nfsrv_descript *nd, int isdgram,
struct uio io;
struct iovec iv;
struct componentname cn;
int not_zfs;
if (nd->nd_repstat) {
nfsrv_postopattr(nd, getret, &at);
@ -1755,6 +1760,7 @@ nfsrvd_readdirplus(struct nfsrv_descript *nd, int isdgram,
nfsrv_postopattr(nd, getret, &at);
return (0);
}
not_zfs = strcmp(vp->v_mount->mnt_vfc->vfc_name, "zfs");
MALLOC(rbuf, caddr_t, siz, M_TEMP, M_WAITOK);
again:
@ -1827,10 +1833,12 @@ nfsrvd_readdirplus(struct nfsrv_descript *nd, int isdgram,
* skip over the records that precede the requested offset. This
* requires the assumption that file offset cookies monotonically
* 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 &&
(dp->d_fileno == 0 || dp->d_type == DT_WHT ||
((u_quad_t)(*cookiep)) <= toff ||
(not_zfs != 0 && ((u_quad_t)(*cookiep)) <= toff) ||
((nd->nd_flag & ND_NFSV4) &&
((dp->d_namlen == 1 && dp->d_name[0] == '.') ||
(dp->d_namlen==2 && dp->d_name[0]=='.' && dp->d_name[1]=='.'))))) {