It seems there is a bug introduced by the putback for author: Mark Maybee <Mark.Maybee at Sun.COM> date: Wed Jan 28 11:04:37 2009 -0700 (2 weeks ago) files: usr/src/uts/common/fs/zfs/arc.c usr/src/uts/common/fs/zfs/sys/zfs_znode.h usr/src/uts/common/fs/zfs/zfs_rlock.c usr/src/uts/common/fs/zfs/zfs_vnops.c usr/src/uts/common/fs/zfs/zfs_znode.c description: 6551866 deadlock between zfs_write(), zfs_freesp(), and zfs_putapage() 6504953 zfs_getpage() misunderstands VOP_GETPAGE() interface 6702206 ZFS read/writer lock contention throttles sendfile() benchmark 6780491 Zone on a ZFS filesystem has poor fork/exec performance 6747596 assertion failed: DVA_EQUAL(BP_IDENTITY(&zio->io_bp_orig), BP_IDENTITY(zio->io_bp)));
zfs_vnops, zfs_putpage() 3695 /* 3696 * Align this request to the file block size in case we kluster. 3697 * XXX - this can result in pretty aggresive locking, which can 3698 * impact simultanious read/write access. One option might be 3699 * to break up long requests (len == 0) into block-by-block 3700 * operations to get narrower locking. 3701 */ 3702 blksz = zp->z_blksz; 3703 if (ISP2(blksz)) 3704 io_off = P2ALIGN_TYPED(off, blksz, u_offset_t); 3705 else 3706 io_off = 0; 3707 if (len > 0 && ISP2(blksz)) 3708 io_len = P2ROUNDUP_TYPED(len + (io_off - off), blksz, size_t); 3709 else 3710 io_len = 0; 3711 3712 if (io_len == 0) { 3713 /* 3714 * Search the entire vp list for pages >= io_off. 3715 */ 3716 rl = zfs_range_lock(zp, io_off, UINT64_MAX, RL_WRITER); 3717 error = pvn_vplist_dirty(vp, io_off, zfs_putapage, flags, cr); 3718 goto out; 3719 } 3720 rl = zfs_range_lock(zp, io_off, io_len, RL_WRITER); Line 3708: "len + (io_off - off)" looks wrong, this should be "len + (off - io_off)". The P2ALIGN_TYPED() macro at line 3704 should round down "off", i.e. io_off <= off. Test case: /files2/media/osol-0906-106a-global-x86.iso is a file on a zfs filesystem # mount -F hsfs /files2/media/osol-0906-106a-global-x86.iso /mnt # time mkisofs -r -o /dev/null /mnt <<< very slow >>> 1.22u 5.05s 59:37.46 0.1% On snv_104 the same test completes in 21 seconds. It has become 180x slower... diff --git a/usr/src/uts/common/fs/zfs/zfs_vnops.c b/usr/src/uts/common/fs/zfs/zfs_vnops.c --- a/usr/src/uts/common/fs/zfs/zfs_vnops.c +++ b/usr/src/uts/common/fs/zfs/zfs_vnops.c @@ -3705,7 +3705,7 @@ else io_off = 0; if (len > 0 && ISP2(blksz)) - io_len = P2ROUNDUP_TYPED(len + (io_off - off), blksz, size_t); + io_len = P2ROUNDUP_TYPED(len + (off - io_off), blksz, size_t); else io_len = 0; -- This message posted from opensolaris.org