diff options
| author | perrin <none@none> | 2005-11-09 08:53:35 -0800 |
|---|---|---|
| committer | perrin <none@none> | 2005-11-09 08:53:35 -0800 |
| commit | 7f6e3e7d4ebf3d6d45073854bef004ca26f8e918 (patch) | |
| tree | 159a50d276154eda494ec4a7b6f8a95f56c104f5 /usr/src | |
| parent | 9b4f025ea51100e697da5c5d6afbcb60aee41c73 (diff) | |
| download | illumos-joyent-7f6e3e7d4ebf3d6d45073854bef004ca26f8e918.tar.gz | |
6297285 znode prefetching in zfs_readdir causes 5x performance degradation for 'ls'
Diffstat (limited to 'usr/src')
| -rw-r--r-- | usr/src/uts/common/fs/zfs/sys/zfs_znode.h | 1 | ||||
| -rw-r--r-- | usr/src/uts/common/fs/zfs/zfs_dir.c | 1 | ||||
| -rw-r--r-- | usr/src/uts/common/fs/zfs/zfs_vnops.c | 21 | ||||
| -rw-r--r-- | usr/src/uts/common/fs/zfs/zfs_znode.c | 1 |
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: |
