changeset 869:dc133b87dfb3

6297285 znode prefetching in zfs_readdir causes 5x performance degradation for 'ls'
author perrin
date Wed, 09 Nov 2005 08:53:35 -0800
parents 09ef7c98db8f
children 31f4460227a3
files usr/src/uts/common/fs/zfs/sys/zfs_znode.h usr/src/uts/common/fs/zfs/zfs_dir.c usr/src/uts/common/fs/zfs/zfs_vnops.c usr/src/uts/common/fs/zfs/zfs_znode.c
diffstat 4 files changed, 17 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/fs/zfs/sys/zfs_znode.h	Tue Nov 08 23:13:25 2005 -0800
+++ b/usr/src/uts/common/fs/zfs/sys/zfs_znode.h	Wed Nov 09 08:53:35 2005 -0800
@@ -148,6 +148,7 @@
 	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 */
--- a/usr/src/uts/common/fs/zfs/zfs_dir.c	Tue Nov 08 23:13:25 2005 -0800
+++ b/usr/src/uts/common/fs/zfs/zfs_dir.c	Wed Nov 09 08:53:35 2005 -0800
@@ -246,6 +246,7 @@
 		if (error == 0) {
 			*vpp = ZTOV(zp);
 			zfs_dirent_unlock(dl);
+			dzp->z_zn_prefetch = B_TRUE; /* enable prefetching */
 		}
 	}
 
--- a/usr/src/uts/common/fs/zfs/zfs_vnops.c	Tue Nov 08 23:13:25 2005 -0800
+++ b/usr/src/uts/common/fs/zfs/zfs_vnops.c	Wed Nov 09 08:53:35 2005 -0800
@@ -1605,6 +1605,7 @@
 	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 @@
 	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 @@
 		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 @@
 		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 @@
 		}
 		*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;
--- a/usr/src/uts/common/fs/zfs/zfs_znode.c	Tue Nov 08 23:13:25 2005 -0800
+++ b/usr/src/uts/common/fs/zfs/zfs_znode.c	Wed Nov 09 08:53:35 2005 -0800
@@ -612,6 +612,7 @@
 			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: