Dynamically create loop devices

Several of the in-tree regression tests depend on the availability
of loop devices.  If for some reason no loop devices are available
the tests will fail.

Normally this isn't an issue because most Linux distributions create
8 loop devices by default.  This is enough for our purposes.  However,
recent Fedora releases have only been creating a single loop device
and this leads to failures.  Alternately, if something else of the
system is using the loop devices we may see failures.

The fix for this is to update the support scripts to dynamically
create loop devices as needed.  The scripts need only create a node
under /dev/ and the loop driver with create the minor.  This behavior
has been supported by the loop driver for ages.

Additionally this patch updates cleanup_loop_devices() to cleanup
loop devices which have already had their file store deleted.  This
helps prevent stale loop devices from accumulating on the system due
to test failures.

Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Prakash Surya <surya1@llnl.gov>
Closes #2249
Set errno for mkdirp() called with NULL path ptr

If mkdirp() is called with a NULL ptr for the path arg, it will return
-1 with errno unchanged.  This is unexpected since on error it should
return -1 and set errno to one of the error values listed for mkdir(2).

This commit sets errno = ENOENT for this NULL ptr case.  This is in
accordance with the errors specified by mkdir(2):

  ENOENT
  A component of the path prefix does not exist or is a null pathname.

Signed-off-by: Chris Dunlap <cdunlap@llnl.gov>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Issue #2248
Replace zed_file_create_dirs() with mkdirp()

When processing directory components starting from the root dir,
zed_file_create_dirs() contained a bug in checking the return value of
mkdir().  A typo was made, and the test for (mkdir_errno != EEXIST) was
erroneously written as (mkdir_errno == EEXIST).  If some of the leading
directory components already existed, this bug would cause the routine
to exit before creating the remaining directory components.

Instead of fixing the above mkdir_errno test, this commit replaces
zed_file_create_dirs() with mkdirp().  This cleanup was already
planned, and zed_file_create_dirs() only existed because I didn't
realize mkdirp() was already in tree at the time.

Signed-off-by: Chris Dunlap <cdunlap@llnl.gov>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #2248
Improve zfs.sh error messages

Ensure an error message is logged when the 'zfs.sh' script fails
to either load a module or if udev fails to create the /dev/zfs
device.  Error messages for missing KERNEL_MODULES are suppressed
because that functionality may just be built-in to the kernel.

Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Linux 3.14 compat: posix_acl_{create,chmod}

posix_acl_{create,chmod} is changed to __posix_acl_{create_chmod}

Signed-off-by: Chunwei Chen <tuxoko@gmail.com>
Signed-off-by: Richard Yao <ryao@gentoo.org>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Issue #2124
Linux 3.14 compat: Immutable biovec changes in vdev_disk.c

bi_sector, bi_size and bi_idx are moved from bio to bio->bi_iter.
This patch creates BIO_BI_*(bio) macros to hide the differences.

Signed-off-by: Chunwei Chen <tuxoko@gmail.com>
Signed-off-by: Richard Yao <ryao@gentoo.org>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Issue #2124
Refactor dmu_req_copy for immutable biovec changes

Originally, dmu_req_copy modifies bv_len and bv_offset in bio_vec so that it
can continue in subsequent passes. However, after the immutable biovec changes
in Linux 3.14, this is not allowed. So instead, we just tell dmu_req_copy how
many bytes are already copied and it will skip to the right spot accordingly.

Signed-off-by: Chunwei Chen <tuxoko@gmail.com>
Signed-off-by: Richard Yao <ryao@gentoo.org>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Issue #2124
Revert "Fix zvol+btrfs hang"

After the dmu_req_copy change, bi_io_vecs are not touched, so this is no
longer needed.

This reverts commit e26ade5101ba1d8e8350ff1270bfca4258e1ffe3.

Signed-off-by: Chunwei Chen <tuxoko@gmail.com>
Signed-off-by: Richard Yao <ryao@gentoo.org>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Issue #2124
Linux 3.14 compat: rq_for_each_segment in dmu_req_copy

rq_for_each_segment changed from taking bio_vec * to taking bio_vec.
We provide rq_for_each_segment4 which takes both.

Signed-off-by: Chunwei Chen <tuxoko@gmail.com>
Signed-off-by: Richard Yao <ryao@gentoo.org>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Issue #2124
Make zimport.sh bash dependency explicit

Unfortunately, the zimport.sh test script really does depend on
bash.  Moving to /bin/sh should be possible once the shared
infrastructure scripts it depends on is made portable.

Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Use ddi_time_after and friends to compare time

Also, make sure we use clock_t for ddi_get_lbolt to prevent type conversion
from screwing things.

Signed-off-by: Chunwei Chen <tuxoko@gmail.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #2142
Uninitialized variable spa_autoreplace used

Caught by ztest and valgrind.

Signed-off-by: DHE <git@dehacked.net>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #2259
Report atime and relatime as the property's actual value.

Neither atime nor relatime should be considered to be "temporary mount
point properties".  Their semantics are enforced completely within ZFS
and also they're (correctly) not documented as being temporary mount
point properties.

Signed-off-by: Tim Chase <tim@chase2k.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #2257
Various zimport.sh fixes

1) $SPLSRC and $SRCDIR should be changed to $SRC_DIR.  These are
   vestiges of an earlier version of the script and were missed when
   it was updated.  Additionally ensure the directory is created.

2) The 'fail' function should take an integer argument for the
   error code to return.  Otherwise 0 (success) will be mistakenly
   returned and errors will we incorrectly suppressed.  The error
   code should be meaningful enough to determine where the script
   failed.

Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Fix zfsdev_ioctl() kmem leak warning

Due to an asymmetry in the kmem accounting a memory leak was being
reported when it was only an accounting issue.  All memory allocated
with kmem_alloc() must be released with kmem_free() or it will not
be properly accounted for.

In this case the code used strfree() to release the memory allocated
by kmem_alloc().  Presumably this was done because the size of the
memory region wasn't available when the memory needed to be freed.

To resolve this issue the code has been updated to use strdup() instead
of kmem_alloc() to allocate the memory.  Like strfree(), strdup() is
not integrated with the memory accounting.  This means we can use
strfree() to release it like Illumos.

  SPL: kmem leaked 10/4368729 bytes
  address          size  data             func:line
  ffff880067e9aa40 10    ZZZZZZZZZZ       zfsdev_ioctl:5655

Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Tim Chase <tim@chase2k.com>
Signed-off-by: Chunwei Chen <tuxoko@gmail.com>
Closes #2262
Fix LZ4 endianness autodetection

Endianness detection in LZ4 is broken in user-space builds.  This
bug corrupts compressed data and manifests itself in several ztest
failures.  When LZ4 was originally ported to Illumos ZFS, the proper
checks for Linux were stripped out. The Linux port then inherited
the remaining detection code that works on Illumos but not on Linux.

The current LZ4 endianness check misuses the condition
defined(__BIG_ENDIAN) to indicate a big-endian system.  On Linux
__BIG_ENDIAN is defined uncondtionally in the user-space header
/usr/include/endian.h, regardless of the endianness of the system.
The kernel does not use this header, so only user-space builds are
affected.

While we could fix this by restoring the upstream LZ4 endianness
detection code, reliable checks already exist in
libspl/include/sys/isa_defs.h. This change uses the libspl results
to replace the word-size and endianness checks in LZ4, simplifying
the code and reducing duplication.

Signed-off-by: Ned Bass <bass6@llnl.gov>
Signed-off-by: Chunwei Chen <tuxoko@gmail.com>
Signed-off-by: DHE <git@dehacked.net>
Signed-off-by: Prakash Surya <surya1@llnl.gov>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Fixes #1963
Fixes #1964
Fixes #1965
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>