Always return correct where from avl_find()

The AVL tree code expects to receive NULL only when the tree is empty,
in which case, it will return NULL. However, avl_find() will set where
to 0 when a match is found with debugging enabled and leave where
uninitialized when no match is found.

Trying to take a range lock passes the return value of where to
zfs_range_add_reader, which then passes it to avl_nearest() to try to
find the nearest reader. What happens is undefined without debugging
enabled and should trigger an assertion when debugging is enabled. Under
the right circumstances, the range lock code can trigger an assertion in
the AVL tree code:

SPLError: 31638:0:(avl.c:222:avl_nearest()) ASSERTION(tree->avl_root ==
NULL) failed

Signed-off-by: Richard Yao <ryao@gentoo.org>
Improve dirty page writeout performance

This refactors ->writepages and ->writepage to improve performance.

->writepages has been refactored to call zfs_range_lock() once per call.
Each zfs_range_lock() does its own memory allocation and various tree
operations, so making it occur only once reduces the computational
complexity of writepages, by at least a factor of log(N) where N is the
number of pages. This avoids significant virtual memory contention that
is prevalent in Linux's vmalloc(). In addition, we now pass WB_SYNC_NONE
to write_cache_pages. This moves responsibility for ensuring synchronous
semantics entirely to zil_commit(), where it should have been in the
first place. It also eliminates an opportunity for concurrent threads to
block each other on writeback.

->writepage has been refactored to permit the changes to ->writepages.
Situations where it is told to write out an invalidated page is now
properly handled by ignoring them. This avoids a theoretical NULL
pointer dereference.

These changes substantially improve 32-thread 4K randomwrite IO on a RAM
disk in filebench's randomwrite benchmark. This has been tested with the
following commands on a boot that passed ramdisk_size=8388604 to the
kernel commandline:

modprobe loop
losetup loop0 /dev/ram0
zpool create -o ashift=12 -O recordsize=4K test /dev/loop0
zpool export test
losetup -D
zpool import -d /dev test

filebench << END
load randomwrite
set \$dir=/test
set \$nthreads=32
set \$iosize=4096
run 60
END

zpool destroy test

Previous tests on Gentoo Linux using a kernel compiled from the CentOS
2.6.32-431.11.2.el6.x86_64 kernel with the default .config showed single
threaded performance at roughly 10k to 11k IOPS with 32-thread
performance at 5k-6k in this benchmark. Tests with this patch show a
performance improvement to 15k to 17k in the 32-thread case. These tests
were conducted on a single processor Xeon E5-2620 with 64GB of RAM.

Signed-off-by: Richard Yao <ryao@gentoo.org>