summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorperrin <none@none>2005-11-09 08:53:35 -0800
committerperrin <none@none>2005-11-09 08:53:35 -0800
commit7f6e3e7d4ebf3d6d45073854bef004ca26f8e918 (patch)
tree159a50d276154eda494ec4a7b6f8a95f56c104f5
parent9b4f025ea51100e697da5c5d6afbcb60aee41c73 (diff)
downloadillumos-joyent-7f6e3e7d4ebf3d6d45073854bef004ca26f8e918.tar.gz
6297285 znode prefetching in zfs_readdir causes 5x performance degradation for 'ls'
-rw-r--r--usr/src/uts/common/fs/zfs/sys/zfs_znode.h1
-rw-r--r--usr/src/uts/common/fs/zfs/zfs_dir.c1
-rw-r--r--usr/src/uts/common/fs/zfs/zfs_vnops.c21
-rw-r--r--usr/src/uts/common/fs/zfs/zfs_znode.c1
4 files changed, 17 insertions, 7 deletions
diff --git a/usr/src/uts/common/fs/zfs/sys/zfs_znode.h b/usr/src/uts/common/fs/zfs/sys/zfs_znode.h
index d3f28df4cd..77c4a5fb16 100644
--- a/usr/src/uts/common/fs/zfs/sys/zfs_znode.h
+++ b/usr/src/uts/common/fs/zfs/sys/zfs_znode.h
@@ -148,6 +148,7 @@ typedef struct znode {
uint8_t z_reap; /* reap file at last reference */
uint8_t z_atime_dirty; /* atime needs to be synced */
uint8_t z_dbuf_held; /* Is z_dbuf already held? */
+ uint8_t z_zn_prefetch; /* Prefetch znodes? */
uint_t z_mapcnt; /* number of memory maps to file */
uint_t z_blksz; /* block size in bytes */
uint_t z_seq; /* modification sequence number */
diff --git a/usr/src/uts/common/fs/zfs/zfs_dir.c b/usr/src/uts/common/fs/zfs/zfs_dir.c
index 6df89ad0c4..cc87a3b3fa 100644
--- a/usr/src/uts/common/fs/zfs/zfs_dir.c
+++ b/usr/src/uts/common/fs/zfs/zfs_dir.c
@@ -246,6 +246,7 @@ zfs_dirlook(znode_t *dzp, char *name, vnode_t **vpp)
if (error == 0) {
*vpp = ZTOV(zp);
zfs_dirent_unlock(dl);
+ dzp->z_zn_prefetch = B_TRUE; /* enable prefetching */
}
}
diff --git a/usr/src/uts/common/fs/zfs/zfs_vnops.c b/usr/src/uts/common/fs/zfs/zfs_vnops.c
index eb9964aa20..15c535a38e 100644
--- a/usr/src/uts/common/fs/zfs/zfs_vnops.c
+++ b/usr/src/uts/common/fs/zfs/zfs_vnops.c
@@ -1605,6 +1605,7 @@ zfs_readdir(vnode_t *vp, uio_t *uio, cred_t *cr, int *eofp)
iovec_t *iovp;
dirent64_t *odp;
zfsvfs_t *zfsvfs = zp->z_zfsvfs;
+ objset_t *os;
caddr_t outbuf;
size_t bufsize;
zap_cursor_t zc;
@@ -1614,8 +1615,9 @@ zfs_readdir(vnode_t *vp, uio_t *uio, cred_t *cr, int *eofp)
uint64_t offset; /* must be unsigned; checks for < 1 */
off64_t *next;
int local_eof;
- int outcount = 0;
- int error = 0;
+ int outcount;
+ int error;
+ uint8_t prefetch;
ZFS_ENTER(zfsvfs);
@@ -1642,21 +1644,24 @@ zfs_readdir(vnode_t *vp, uio_t *uio, cred_t *cr, int *eofp)
return (0);
}
+ error = 0;
+ os = zfsvfs->z_os;
+ offset = uio->uio_loffset;
+ prefetch = zp->z_zn_prefetch;
+
/*
* Initialize the iterator cursor.
*/
- offset = uio->uio_loffset;
if (offset <= 3) {
/*
* Start iteration from the beginning of the directory.
*/
- zap_cursor_init(&zc, zfsvfs->z_os, zp->z_id);
+ zap_cursor_init(&zc, os, zp->z_id);
} else {
/*
* The offset is a serialized cursor.
*/
- zap_cursor_init_serialized(&zc, zfsvfs->z_os, zp->z_id,
- offset);
+ zap_cursor_init_serialized(&zc, os, zp->z_id, offset);
}
/*
@@ -1745,7 +1750,8 @@ zfs_readdir(vnode_t *vp, uio_t *uio, cred_t *cr, int *eofp)
ASSERT(outcount <= bufsize);
/* Prefetch znode */
- dmu_prefetch(zfsvfs->z_os, zap.za_first_integer, 0, 0);
+ if (prefetch)
+ dmu_prefetch(os, zap.za_first_integer, 0, 0);
/*
* Move to the next entry, fill in the previous offset.
@@ -1758,6 +1764,7 @@ zfs_readdir(vnode_t *vp, uio_t *uio, cred_t *cr, int *eofp)
}
*next = offset;
}
+ zp->z_zn_prefetch = B_FALSE; /* a lookup will re-enable pre-fetching */
if (uio->uio_segflg == UIO_SYSSPACE && uio->uio_iovcnt == 1) {
iovp->iov_base += outcount;
diff --git a/usr/src/uts/common/fs/zfs/zfs_znode.c b/usr/src/uts/common/fs/zfs/zfs_znode.c
index 1ff11e29b8..9d52c5d11d 100644
--- a/usr/src/uts/common/fs/zfs/zfs_znode.c
+++ b/usr/src/uts/common/fs/zfs/zfs_znode.c
@@ -612,6 +612,7 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, uint64_t obj_num, int blksz)
vp->v_flag |= V_XATTRDIR;
} else
vn_setops(vp, zfs_dvnodeops);
+ zp->z_zn_prefetch = B_TRUE; /* z_prefetch default is enabled */
break;
case VBLK:
case VCHR: