summaryrefslogtreecommitdiffstats
path: root/sys/fs
diff options
context:
space:
mode:
authorrmacklem <rmacklem@FreeBSD.org>2010-12-24 18:46:44 +0000
committerrmacklem <rmacklem@FreeBSD.org>2010-12-24 18:46:44 +0000
commit48c3637883bb38d7811578ecfce2bec18e9b87be (patch)
tree956872e4384318817db6f6a44fcaa16c9845f597 /sys/fs
parent1d89f14a5c73f15c775296de015f425df23c8d94 (diff)
downloadFreeBSD-src-48c3637883bb38d7811578ecfce2bec18e9b87be.zip
FreeBSD-src-48c3637883bb38d7811578ecfce2bec18e9b87be.tar.gz
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
Diffstat (limited to 'sys/fs')
-rw-r--r--sys/fs/nfsserver/nfs_nfsdport.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c
index 380aa72..36bed08 100644
--- a/sys/fs/nfsserver/nfs_nfsdport.c
+++ b/sys/fs/nfsserver/nfs_nfsdport.c
@@ -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 @@ again:
* 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 @@ again:
* 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]=='.'))))) {
OpenPOWER on IntegriCloud