diff --git a/config/kernel-vfs-rw-iterate.m4 b/config/kernel-vfs-rw-iterate.m4 index f8dc42229686..af44beb7bcfc 100644 --- a/config/kernel-vfs-rw-iterate.m4 +++ b/config/kernel-vfs-rw-iterate.m4 @@ -1,27 +1,48 @@ dnl # dnl # Linux 4.1.x API dnl # AC_DEFUN([ZFS_AC_KERNEL_VFS_RW_ITERATE], [AC_MSG_CHECKING([whether fops->read/write_iter() are available]) ZFS_LINUX_TRY_COMPILE([ #include ssize_t test_read(struct kiocb *kiocb, struct iov_iter *to) { return 0; } ssize_t test_write(struct kiocb *kiocb, struct iov_iter *from) { return 0; } static const struct file_operations fops __attribute__ ((unused)) = { .read_iter = test_read, .write_iter = test_write, }; ],[ ],[ AC_MSG_RESULT(yes) AC_DEFINE(HAVE_VFS_RW_ITERATE, 1, [fops->read/write_iter() are available]) ],[ AC_MSG_RESULT(no) ]) ]) + +dnl # +dnl # Linux 4.1.x API +dnl # +AC_DEFUN([ZFS_AC_KERNEL_GENERIC_WRITE_CHECKS], + [AC_MSG_CHECKING([whether generic_write_checks() takes kiocb]) + ZFS_LINUX_TRY_COMPILE([ + #include + + ],[ + struct kiocb *iocb = NULL; + struct iov_iter *iov = NULL; + generic_write_checks(iocb, iov); + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_GENERIC_WRITE_CHECKS_KIOCB, 1, + [generic_write_checks() takes kiocb]) + ],[ + AC_MSG_RESULT(no) + ]) +]) diff --git a/config/kernel.m4 b/config/kernel.m4 index 980d2801f6df..afb0cc7faad6 100644 --- a/config/kernel.m4 +++ b/config/kernel.m4 @@ -1,721 +1,722 @@ dnl # dnl # Default ZFS kernel configuration dnl # AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [ ZFS_AC_KERNEL ZFS_AC_SPL ZFS_AC_TEST_MODULE ZFS_AC_KERNEL_CONFIG ZFS_AC_KERNEL_DECLARE_EVENT_CLASS ZFS_AC_KERNEL_CURRENT_BIO_TAIL ZFS_AC_KERNEL_SUPER_USER_NS ZFS_AC_KERNEL_SUBMIT_BIO ZFS_AC_KERNEL_BDEV_BLOCK_DEVICE_OPERATIONS ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID ZFS_AC_KERNEL_TYPE_FMODE_T ZFS_AC_KERNEL_3ARG_BLKDEV_GET ZFS_AC_KERNEL_BLKDEV_GET_BY_PATH ZFS_AC_KERNEL_OPEN_BDEV_EXCLUSIVE ZFS_AC_KERNEL_LOOKUP_BDEV ZFS_AC_KERNEL_INVALIDATE_BDEV_ARGS ZFS_AC_KERNEL_BDEV_LOGICAL_BLOCK_SIZE ZFS_AC_KERNEL_BDEV_PHYSICAL_BLOCK_SIZE ZFS_AC_KERNEL_BIO_BVEC_ITER ZFS_AC_KERNEL_BIO_FAILFAST_DTD ZFS_AC_KERNEL_REQ_FAILFAST_MASK ZFS_AC_KERNEL_REQ_OP_DISCARD ZFS_AC_KERNEL_REQ_OP_SECURE_ERASE ZFS_AC_KERNEL_REQ_OP_FLUSH ZFS_AC_KERNEL_BIO_BI_OPF ZFS_AC_KERNEL_BIO_END_IO_T_ARGS ZFS_AC_KERNEL_BIO_RW_BARRIER ZFS_AC_KERNEL_BIO_RW_DISCARD ZFS_AC_KERNEL_BLK_QUEUE_FLUSH ZFS_AC_KERNEL_BLK_QUEUE_MAX_HW_SECTORS ZFS_AC_KERNEL_BLK_QUEUE_MAX_SEGMENTS ZFS_AC_KERNEL_BLK_QUEUE_HAVE_BIO_RW_UNPLUG ZFS_AC_KERNEL_BLK_QUEUE_HAVE_BLK_PLUG ZFS_AC_KERNEL_GET_DISK_RO ZFS_AC_KERNEL_GET_GENDISK ZFS_AC_KERNEL_HAVE_BIO_SET_OP_ATTRS ZFS_AC_KERNEL_GENERIC_READLINK_GLOBAL ZFS_AC_KERNEL_DISCARD_GRANULARITY ZFS_AC_KERNEL_CONST_XATTR_HANDLER ZFS_AC_KERNEL_XATTR_HANDLER_NAME ZFS_AC_KERNEL_XATTR_HANDLER_GET ZFS_AC_KERNEL_XATTR_HANDLER_SET ZFS_AC_KERNEL_XATTR_HANDLER_LIST ZFS_AC_KERNEL_INODE_OWNER_OR_CAPABLE ZFS_AC_KERNEL_POSIX_ACL_FROM_XATTR_USERNS ZFS_AC_KERNEL_POSIX_ACL_RELEASE ZFS_AC_KERNEL_SET_CACHED_ACL_USABLE ZFS_AC_KERNEL_POSIX_ACL_CHMOD ZFS_AC_KERNEL_POSIX_ACL_EQUIV_MODE_WANTS_UMODE_T ZFS_AC_KERNEL_POSIX_ACL_VALID_WITH_NS ZFS_AC_KERNEL_INODE_OPERATIONS_PERMISSION ZFS_AC_KERNEL_INODE_OPERATIONS_PERMISSION_WITH_NAMEIDATA ZFS_AC_KERNEL_INODE_OPERATIONS_CHECK_ACL ZFS_AC_KERNEL_INODE_OPERATIONS_CHECK_ACL_WITH_FLAGS ZFS_AC_KERNEL_INODE_OPERATIONS_GET_ACL ZFS_AC_KERNEL_INODE_OPERATIONS_SET_ACL ZFS_AC_KERNEL_INODE_SET_FLAGS ZFS_AC_KERNEL_GET_ACL_HANDLE_CACHE ZFS_AC_KERNEL_SHOW_OPTIONS ZFS_AC_KERNEL_FILE_INODE ZFS_AC_KERNEL_FILE_DENTRY ZFS_AC_KERNEL_FSYNC ZFS_AC_KERNEL_EVICT_INODE ZFS_AC_KERNEL_DIRTY_INODE_WITH_FLAGS ZFS_AC_KERNEL_NR_CACHED_OBJECTS ZFS_AC_KERNEL_FREE_CACHED_OBJECTS ZFS_AC_KERNEL_FALLOCATE ZFS_AC_KERNEL_AIO_FSYNC ZFS_AC_KERNEL_MKDIR_UMODE_T ZFS_AC_KERNEL_LOOKUP_NAMEIDATA ZFS_AC_KERNEL_CREATE_NAMEIDATA ZFS_AC_KERNEL_GET_LINK ZFS_AC_KERNEL_PUT_LINK ZFS_AC_KERNEL_TMPFILE ZFS_AC_KERNEL_TRUNCATE_RANGE ZFS_AC_KERNEL_AUTOMOUNT ZFS_AC_KERNEL_ENCODE_FH_WITH_INODE ZFS_AC_KERNEL_COMMIT_METADATA ZFS_AC_KERNEL_CLEAR_INODE ZFS_AC_KERNEL_SETATTR_PREPARE ZFS_AC_KERNEL_INSERT_INODE_LOCKED ZFS_AC_KERNEL_D_MAKE_ROOT ZFS_AC_KERNEL_D_OBTAIN_ALIAS ZFS_AC_KERNEL_D_PRUNE_ALIASES ZFS_AC_KERNEL_D_SET_D_OP ZFS_AC_KERNEL_D_REVALIDATE_NAMEIDATA ZFS_AC_KERNEL_CONST_DENTRY_OPERATIONS ZFS_AC_KERNEL_TRUNCATE_SETSIZE ZFS_AC_KERNEL_6ARGS_SECURITY_INODE_INIT_SECURITY ZFS_AC_KERNEL_CALLBACK_SECURITY_INODE_INIT_SECURITY ZFS_AC_KERNEL_MOUNT_NODEV ZFS_AC_KERNEL_SHRINK ZFS_AC_KERNEL_SHRINK_CONTROL_HAS_NID ZFS_AC_KERNEL_S_INSTANCES_LIST_HEAD ZFS_AC_KERNEL_S_D_OP ZFS_AC_KERNEL_BDI_SETUP_AND_REGISTER ZFS_AC_KERNEL_SET_NLINK ZFS_AC_KERNEL_ELEVATOR_CHANGE ZFS_AC_KERNEL_5ARG_SGET ZFS_AC_KERNEL_LSEEK_EXECUTE ZFS_AC_KERNEL_VFS_ITERATE ZFS_AC_KERNEL_VFS_RW_ITERATE + ZFS_AC_KERNEL_GENERIC_WRITE_CHECKS ZFS_AC_KERNEL_KMAP_ATOMIC_ARGS ZFS_AC_KERNEL_FOLLOW_DOWN_ONE ZFS_AC_KERNEL_MAKE_REQUEST_FN ZFS_AC_KERNEL_GENERIC_IO_ACCT ZFS_AC_KERNEL_FPU ZFS_AC_KERNEL_KUID_HELPERS ZFS_AC_KERNEL_MODULE_PARAM_CALL_CONST ZFS_AC_KERNEL_RENAME_WANTS_FLAGS ZFS_AC_KERNEL_HAVE_GENERIC_SETXATTR AS_IF([test "$LINUX_OBJ" != "$LINUX"], [ KERNELMAKE_PARAMS="$KERNELMAKE_PARAMS O=$LINUX_OBJ" ]) AC_SUBST(KERNELMAKE_PARAMS) dnl # -Wall -fno-strict-aliasing -Wstrict-prototypes and other dnl # compiler options are added by the kernel build system. KERNELCPPFLAGS="$KERNELCPPFLAGS $NO_UNUSED_BUT_SET_VARIABLE" KERNELCPPFLAGS="$KERNELCPPFLAGS $NO_BOOL_COMPARE" KERNELCPPFLAGS="$KERNELCPPFLAGS -DHAVE_SPL -D_KERNEL" KERNELCPPFLAGS="$KERNELCPPFLAGS -DTEXT_DOMAIN=\\\"zfs-linux-kernel\\\"" AC_SUBST(KERNELCPPFLAGS) ]) dnl # dnl # Detect name used for Module.symvers file in kernel dnl # AC_DEFUN([ZFS_AC_MODULE_SYMVERS], [ modpost=$LINUX/scripts/Makefile.modpost AC_MSG_CHECKING([kernel file name for module symbols]) AS_IF([test "x$enable_linux_builtin" != xyes -a -f "$modpost"], [ AS_IF([grep -q Modules.symvers $modpost], [ LINUX_SYMBOLS=Modules.symvers ], [ LINUX_SYMBOLS=Module.symvers ]) AS_IF([test ! -f "$LINUX_OBJ/$LINUX_SYMBOLS"], [ AC_MSG_ERROR([ *** Please make sure the kernel devel package for your distribution *** is installed. If you are building with a custom kernel, make sure the *** kernel is configured, built, and the '--with-linux=PATH' configure *** option refers to the location of the kernel source.]) ]) ], [ LINUX_SYMBOLS=NONE ]) AC_MSG_RESULT($LINUX_SYMBOLS) AC_SUBST(LINUX_SYMBOLS) ]) dnl # dnl # Detect the kernel to be built against dnl # AC_DEFUN([ZFS_AC_KERNEL], [ AC_ARG_WITH([linux], AS_HELP_STRING([--with-linux=PATH], [Path to kernel source]), [kernelsrc="$withval"]) AC_ARG_WITH(linux-obj, AS_HELP_STRING([--with-linux-obj=PATH], [Path to kernel build objects]), [kernelbuild="$withval"]) AC_MSG_CHECKING([kernel source directory]) AS_IF([test -z "$kernelsrc"], [ AS_IF([test -e "/lib/modules/$(uname -r)/source"], [ headersdir="/lib/modules/$(uname -r)/source" sourcelink=$(readlink -f "$headersdir") ], [test -e "/lib/modules/$(uname -r)/build"], [ headersdir="/lib/modules/$(uname -r)/build" sourcelink=$(readlink -f "$headersdir") ], [ sourcelink=$(ls -1d /usr/src/kernels/* \ /usr/src/linux-* \ 2>/dev/null | grep -v obj | tail -1) ]) AS_IF([test -n "$sourcelink" && test -e ${sourcelink}], [ kernelsrc=`readlink -f ${sourcelink}` ], [ kernelsrc="[Not found]" ]) ], [ AS_IF([test "$kernelsrc" = "NONE"], [ kernsrcver=NONE ]) ]) AC_MSG_RESULT([$kernelsrc]) AS_IF([test ! -d "$kernelsrc"], [ AC_MSG_ERROR([ *** Please make sure the kernel devel package for your distribution *** is installed and then try again. If that fails, you can specify the *** location of the kernel source with the '--with-linux=PATH' option.]) ]) AC_MSG_CHECKING([kernel build directory]) AS_IF([test -z "$kernelbuild"], [ AS_IF([test -e "/lib/modules/$(uname -r)/build"], [ kernelbuild=`readlink -f /lib/modules/$(uname -r)/build` ], [test -d ${kernelsrc}-obj/${target_cpu}/${target_cpu}], [ kernelbuild=${kernelsrc}-obj/${target_cpu}/${target_cpu} ], [test -d ${kernelsrc}-obj/${target_cpu}/default], [ kernelbuild=${kernelsrc}-obj/${target_cpu}/default ], [test -d `dirname ${kernelsrc}`/build-${target_cpu}], [ kernelbuild=`dirname ${kernelsrc}`/build-${target_cpu} ], [ kernelbuild=${kernelsrc} ]) ]) AC_MSG_RESULT([$kernelbuild]) AC_MSG_CHECKING([kernel source version]) utsrelease1=$kernelbuild/include/linux/version.h utsrelease2=$kernelbuild/include/linux/utsrelease.h utsrelease3=$kernelbuild/include/generated/utsrelease.h AS_IF([test -r $utsrelease1 && fgrep -q UTS_RELEASE $utsrelease1], [ utsrelease=linux/version.h ], [test -r $utsrelease2 && fgrep -q UTS_RELEASE $utsrelease2], [ utsrelease=linux/utsrelease.h ], [test -r $utsrelease3 && fgrep -q UTS_RELEASE $utsrelease3], [ utsrelease=generated/utsrelease.h ]) AS_IF([test "$utsrelease"], [ kernsrcver=`(echo "#include <$utsrelease>"; echo "kernsrcver=UTS_RELEASE") | cpp -I $kernelbuild/include | grep "^kernsrcver=" | cut -d \" -f 2` AS_IF([test -z "$kernsrcver"], [ AC_MSG_RESULT([Not found]) AC_MSG_ERROR([*** Cannot determine kernel version.]) ]) ], [ AC_MSG_RESULT([Not found]) if test "x$enable_linux_builtin" != xyes; then AC_MSG_ERROR([*** Cannot find UTS_RELEASE definition.]) else AC_MSG_ERROR([ *** Cannot find UTS_RELEASE definition. *** Please run 'make prepare' inside the kernel source tree.]) fi ]) AC_MSG_RESULT([$kernsrcver]) LINUX=${kernelsrc} LINUX_OBJ=${kernelbuild} LINUX_VERSION=${kernsrcver} AC_SUBST(LINUX) AC_SUBST(LINUX_OBJ) AC_SUBST(LINUX_VERSION) ZFS_AC_MODULE_SYMVERS ]) dnl # dnl # Detect the SPL module to be built against dnl # AC_DEFUN([ZFS_AC_SPL], [ AC_ARG_WITH([spl], AS_HELP_STRING([--with-spl=PATH], [Path to spl source]), AS_IF([test "$withval" = "yes"], AC_MSG_ERROR([--with-spl=PATH requires a PATH]), [splsrc="$withval"])) AC_ARG_WITH([spl-obj], AS_HELP_STRING([--with-spl-obj=PATH], [Path to spl build objects]), [splbuild="$withval"]) AC_ARG_WITH([spl-timeout], AS_HELP_STRING([--with-spl-timeout=SECS], [Wait SECS for SPL header and symver file @<:@default=0@:>@]), [timeout="$withval"], [timeout=0]) dnl # dnl # The existence of spl.release.in is used to identify a valid dnl # source directory. In order of preference: dnl # splsrc0="/var/lib/dkms/spl/${VERSION}/build" splsrc1="/usr/local/src/spl-${VERSION}/${LINUX_VERSION}" splsrc2="/usr/local/src/spl-${VERSION}" splsrc3="/usr/src/spl-${VERSION}/${LINUX_VERSION}" splsrc4="/usr/src/spl-${VERSION}" splsrc5="../spl/" splsrc6="$LINUX" AC_MSG_CHECKING([spl source directory]) AS_IF([test -z "${splsrc}"], [ [all_spl_sources=" ${splsrc0} ${splsrc1} ${splsrc2} ${splsrc3} ${splsrc4} ${splsrc5} ${splsrc6}"], AS_IF([ test -e "${splsrc0}/spl.release.in"], [ splsrc=${splsrc0} ], [ test -e "${splsrc1}/spl.release.in"], [ splsrc=${splsrc1} ], [ test -e "${splsrc2}/spl.release.in"], [ splsrc=${splsrc2} ], [ test -e "${splsrc3}/spl.release.in"], [ splsrc=$(readlink -f "${splsrc3}") ], [ test -e "${splsrc4}/spl.release.in" ], [ splsrc=${splsrc4} ], [ test -e "${splsrc5}/spl.release.in"], [ splsrc=$(readlink -f "${splsrc5}") ], [ test -e "${splsrc6}/spl.release.in" ], [ splsrc=${splsrc6} ], [ splsrc="[Not found]" ]) ], [ [all_spl_sources="$withval"], AS_IF([test "$splsrc" = "NONE"], [ splbuild=NONE splsrcver=NONE ]) ]) AC_MSG_RESULT([$splsrc]) AS_IF([ test ! -e "$splsrc/spl.release.in"], [ AC_MSG_ERROR([ *** Please make sure the kmod spl devel package for your distribution *** is installed then try again. If that fails you can specify the *** location of the spl source with the '--with-spl=PATH' option. *** The spl version must match the version of ZFS you are building, *** ${VERSION}. Failed to find spl.release.in in the following: $all_spl_sources]) ]) dnl # dnl # The existence of the spl_config.h is used to identify a valid dnl # spl object directory. In many cases the object and source dnl # directory are the same, however the objects may also reside dnl # is a subdirectory named after the kernel version. dnl # dnl # This file is supposed to be available after DKMS finishes dnl # building the SPL kernel module for the target kernel. The dnl # '--with-spl-timeout' option can be passed to pause here, dnl # waiting for the file to appear from a concurrently building dnl # SPL package. dnl # AC_MSG_CHECKING([spl build directory]) all_spl_config_locs="${splsrc}/${LINUX_VERSION} ${splsrc}" while true; do AS_IF([test -z "$splbuild"], [ AS_IF([ test -e "${splsrc}/${LINUX_VERSION}/spl_config.h" ], [ splbuild="${splsrc}/${LINUX_VERSION}" ], [ test -e "${splsrc}/spl_config.h" ], [ splbuild="${splsrc}" ], [ find -L "${splsrc}" -name spl_config.h 2> /dev/null | grep -wq spl_config.h ], [ splbuild=$(find -L "${splsrc}" -name spl_config.h | sed 's,/spl_config.h,,') ], [ splbuild="[Not found]" ]) ]) AS_IF([test -e "$splbuild/spl_config.h" -o $timeout -le 0], [ break; ], [ sleep 1 timeout=$((timeout-1)) ]) done AC_MSG_RESULT([$splbuild]) AS_IF([ ! test -e "$splbuild/spl_config.h"], [ AC_MSG_ERROR([ *** Please make sure the kmod spl devel package for your *** distribution is installed then try again. If that fails you *** can specify the location of the spl objects with the *** '--with-spl-obj=PATH' option. Failed to find spl_config.h in *** any of the following: $all_spl_config_locs]) ]) AC_MSG_CHECKING([spl source version]) AS_IF([test -r $splbuild/spl_config.h && fgrep -q SPL_META_VERSION $splbuild/spl_config.h], [ splsrcver=`(echo "#include "; echo "splsrcver=SPL_META_VERSION-SPL_META_RELEASE") | cpp -I $splbuild | grep "^splsrcver=" | tr -d \" | cut -d= -f2` ]) AS_IF([test -z "$splsrcver"], [ AC_MSG_RESULT([Not found]) AC_MSG_ERROR([ *** Cannot determine the version of the spl source. *** Please prepare the spl source before running this script]) ]) AC_MSG_RESULT([$splsrcver]) SPL=${splsrc} SPL_OBJ=${splbuild} SPL_VERSION=${splsrcver} AC_SUBST(SPL) AC_SUBST(SPL_OBJ) AC_SUBST(SPL_VERSION) dnl # dnl # Detect the name used for the SPL Module.symvers file. If one dnl # does not exist this is likely because the SPL has been configured dnl # but not built. The '--with-spl-timeout' option can be passed dnl # to pause here, waiting for the file to appear from a concurrently dnl # building SPL package. If the file does not appear in time, a good dnl # guess is made as to what this file will be named based on what it dnl # is named in the kernel build products. This file will first be dnl # used at link time so if the guess is wrong the build will fail dnl # then. This unfortunately means the ZFS package does not contain a dnl # reliable mechanism to detect symbols exported by the SPL at dnl # configure time. dnl # AC_MSG_CHECKING([spl file name for module symbols]) SPL_SYMBOLS=NONE while true; do AS_IF([test -r $SPL_OBJ/Module.symvers], [ SPL_SYMBOLS=Module.symvers ], [test -r $SPL_OBJ/Modules.symvers], [ SPL_SYMBOLS=Modules.symvers ], [test -r $SPL_OBJ/module/Module.symvers], [ SPL_SYMBOLS=Module.symvers ], [test -r $SPL_OBJ/module/Modules.symvers], [ SPL_SYMBOLS=Modules.symvers ]) AS_IF([test $SPL_SYMBOLS != NONE -o $timeout -le 0], [ break; ], [ sleep 1 timeout=$((timeout-1)) ]) done AS_IF([test "$SPL_SYMBOLS" = NONE], [ SPL_SYMBOLS=$LINUX_SYMBOLS ]) AC_MSG_RESULT([$SPL_SYMBOLS]) AC_SUBST(SPL_SYMBOLS) ]) dnl # dnl # Basic toolchain sanity check. dnl # AC_DEFUN([ZFS_AC_TEST_MODULE], [ AC_MSG_CHECKING([whether modules can be built]) ZFS_LINUX_TRY_COMPILE([],[],[ AC_MSG_RESULT([yes]) ],[ AC_MSG_RESULT([no]) if test "x$enable_linux_builtin" != xyes; then AC_MSG_ERROR([*** Unable to build an empty module.]) else AC_MSG_ERROR([ *** Unable to build an empty module. *** Please run 'make scripts' inside the kernel source tree.]) fi ]) ]) dnl # dnl # Certain kernel build options are not supported. These must be dnl # detected at configure time and cause a build failure. Otherwise dnl # modules may be successfully built that behave incorrectly. dnl # AC_DEFUN([ZFS_AC_KERNEL_CONFIG], [ AS_IF([test "x$cross_compiling" != xyes], [ AC_RUN_IFELSE([ AC_LANG_PROGRAM([ #include "$LINUX/include/linux/license.h" ], [ return !license_is_gpl_compatible("$ZFS_META_LICENSE"); ]) ], [ AC_DEFINE([ZFS_IS_GPL_COMPATIBLE], [1], [Define to 1 if GPL-only symbols can be used]) ], [ ]) ]) ZFS_AC_KERNEL_CONFIG_THREAD_SIZE ZFS_AC_KERNEL_CONFIG_DEBUG_LOCK_ALLOC ]) dnl # dnl # Check configured THREAD_SIZE dnl # dnl # The stack size will vary by architecture, but as of Linux 3.15 on x86_64 dnl # the default thread stack size was increased to 16K from 8K. Therefore, dnl # on newer kernels and some architectures stack usage optimizations can be dnl # conditionally applied to improve performance without negatively impacting dnl # stability. dnl # AC_DEFUN([ZFS_AC_KERNEL_CONFIG_THREAD_SIZE], [ AC_MSG_CHECKING([whether kernel was built with 16K or larger stacks]) ZFS_LINUX_TRY_COMPILE([ #include ],[ #if (THREAD_SIZE < 16384) #error "THREAD_SIZE is less than 16K" #endif ],[ AC_MSG_RESULT([yes]) AC_DEFINE(HAVE_LARGE_STACKS, 1, [kernel has large stacks]) ],[ AC_MSG_RESULT([no]) ]) ]) dnl # dnl # Check CONFIG_DEBUG_LOCK_ALLOC dnl # dnl # This is typically only set for debug kernels because it comes with dnl # a performance penalty. However, when it is set it maps the non-GPL dnl # symbol mutex_lock() to the GPL-only mutex_lock_nested() symbol. dnl # This will cause a failure at link time which we'd rather know about dnl # at compile time. dnl # dnl # Since we plan to pursue making mutex_lock_nested() a non-GPL symbol dnl # with the upstream community we add a check to detect this case. dnl # AC_DEFUN([ZFS_AC_KERNEL_CONFIG_DEBUG_LOCK_ALLOC], [ ZFS_LINUX_CONFIG([DEBUG_LOCK_ALLOC], [ AC_MSG_CHECKING([whether mutex_lock() is GPL-only]) tmp_flags="$EXTRA_KCFLAGS" ZFS_LINUX_TRY_COMPILE([ #include #include MODULE_LICENSE("$ZFS_META_LICENSE"); ],[ struct mutex lock; mutex_init(&lock); mutex_lock(&lock); mutex_unlock(&lock); ],[ AC_MSG_RESULT(no) ],[ AC_MSG_RESULT(yes) AC_MSG_ERROR([ *** Kernel built with CONFIG_DEBUG_LOCK_ALLOC which is incompatible *** with the CDDL license and will prevent the module linking stage *** from succeeding. You must rebuild your kernel without this *** option enabled.]) ]) EXTRA_KCFLAGS="$tmp_flags" ], []) ]) dnl # dnl # ZFS_LINUX_CONFTEST_H dnl # AC_DEFUN([ZFS_LINUX_CONFTEST_H], [ cat - <<_ACEOF >conftest.h $1 _ACEOF ]) dnl # dnl # ZFS_LINUX_CONFTEST_C dnl # AC_DEFUN([ZFS_LINUX_CONFTEST_C], [ cat confdefs.h - <<_ACEOF >conftest.c $1 _ACEOF ]) dnl # dnl # ZFS_LANG_PROGRAM(C)([PROLOGUE], [BODY]) dnl # m4_define([ZFS_LANG_PROGRAM], [ $1 int main (void) { dnl Do *not* indent the following line: there may be CPP directives. dnl Don't move the `;' right after for the same reason. $2 ; return 0; } ]) dnl # dnl # ZFS_LINUX_COMPILE_IFELSE / like AC_COMPILE_IFELSE dnl # AC_DEFUN([ZFS_LINUX_COMPILE_IFELSE], [ m4_ifvaln([$1], [ZFS_LINUX_CONFTEST_C([$1])]) m4_ifvaln([$6], [ZFS_LINUX_CONFTEST_H([$6])], [ZFS_LINUX_CONFTEST_H([])]) rm -Rf build && mkdir -p build && touch build/conftest.mod.c echo "obj-m := conftest.o" >build/Makefile modpost_flag='' test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage AS_IF( [AC_TRY_COMMAND(cp conftest.c conftest.h build && make [$2] -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag) >/dev/null && AC_TRY_COMMAND([$3])], [$4], [_AC_MSG_LOG_CONFTEST m4_ifvaln([$5],[$5])] ) rm -Rf build ]) dnl # dnl # ZFS_LINUX_TRY_COMPILE like AC_TRY_COMPILE dnl # AC_DEFUN([ZFS_LINUX_TRY_COMPILE], [ZFS_LINUX_COMPILE_IFELSE( [AC_LANG_SOURCE([ZFS_LANG_PROGRAM([[$1]], [[$2]])])], [modules], [test -s build/conftest.o], [$3], [$4]) ]) dnl # dnl # ZFS_LINUX_CONFIG dnl # AC_DEFUN([ZFS_LINUX_CONFIG], [AC_MSG_CHECKING([whether kernel was built with CONFIG_$1]) ZFS_LINUX_TRY_COMPILE([ #include ],[ #ifndef CONFIG_$1 #error CONFIG_$1 not #defined #endif ],[ AC_MSG_RESULT([yes]) $2 ],[ AC_MSG_RESULT([no]) $3 ]) ]) dnl # dnl # ZFS_CHECK_SYMBOL_EXPORT dnl # check symbol exported or not dnl # AC_DEFUN([ZFS_CHECK_SYMBOL_EXPORT], [ grep -q -E '[[[:space:]]]$1[[[:space:]]]' \ $LINUX_OBJ/$LINUX_SYMBOLS 2>/dev/null rc=$? if test $rc -ne 0; then export=0 for file in $2; do grep -q -E "EXPORT_SYMBOL.*($1)" \ "$LINUX/$file" 2>/dev/null rc=$? if test $rc -eq 0; then export=1 break; fi done if test $export -eq 0; then : $4 else : $3 fi else : $3 fi ]) dnl # dnl # ZFS_LINUX_TRY_COMPILE_SYMBOL dnl # like ZFS_LINUX_TRY_COMPILE, except ZFS_CHECK_SYMBOL_EXPORT dnl # is called if not compiling for builtin dnl # AC_DEFUN([ZFS_LINUX_TRY_COMPILE_SYMBOL], [ ZFS_LINUX_TRY_COMPILE([$1], [$2], [rc=0], [rc=1]) if test $rc -ne 0; then : $6 else if test "x$enable_linux_builtin" != xyes; then ZFS_CHECK_SYMBOL_EXPORT([$3], [$4], [rc=0], [rc=1]) fi if test $rc -ne 0; then : $6 else : $5 fi fi ]) dnl # dnl # ZFS_LINUX_TRY_COMPILE_HEADER dnl # like ZFS_LINUX_TRY_COMPILE, except the contents conftest.h are dnl # provided via the fifth parameter dnl # AC_DEFUN([ZFS_LINUX_TRY_COMPILE_HEADER], [ZFS_LINUX_COMPILE_IFELSE( [AC_LANG_SOURCE([ZFS_LANG_PROGRAM([[$1]], [[$2]])])], [modules], [test -s build/conftest.o], [$3], [$4], [$5]) ]) diff --git a/module/zfs/zpl_file.c b/module/zfs/zpl_file.c index 356fa78f83af..75a3b55d1f89 100644 --- a/module/zfs/zpl_file.c +++ b/module/zfs/zpl_file.c @@ -1,876 +1,892 @@ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright (c) 2011, Lawrence Livermore National Security, LLC. * Copyright (c) 2015 by Chunwei Chen. All rights reserved. */ #ifdef CONFIG_COMPAT #include #endif #include #include #include #include #include static int zpl_open(struct inode *ip, struct file *filp) { cred_t *cr = CRED(); int error; fstrans_cookie_t cookie; error = generic_file_open(ip, filp); if (error) return (error); crhold(cr); cookie = spl_fstrans_mark(); error = -zfs_open(ip, filp->f_mode, filp->f_flags, cr); spl_fstrans_unmark(cookie); crfree(cr); ASSERT3S(error, <=, 0); return (error); } static int zpl_release(struct inode *ip, struct file *filp) { cred_t *cr = CRED(); int error; fstrans_cookie_t cookie; cookie = spl_fstrans_mark(); if (ITOZ(ip)->z_atime_dirty) zfs_mark_inode_dirty(ip); crhold(cr); error = -zfs_close(ip, filp->f_flags, cr); spl_fstrans_unmark(cookie); crfree(cr); ASSERT3S(error, <=, 0); return (error); } static int zpl_iterate(struct file *filp, struct dir_context *ctx) { cred_t *cr = CRED(); int error; fstrans_cookie_t cookie; crhold(cr); cookie = spl_fstrans_mark(); error = -zfs_readdir(file_inode(filp), ctx, cr); spl_fstrans_unmark(cookie); crfree(cr); ASSERT3S(error, <=, 0); return (error); } #if !defined(HAVE_VFS_ITERATE) && !defined(HAVE_VFS_ITERATE_SHARED) static int zpl_readdir(struct file *filp, void *dirent, filldir_t filldir) { struct dir_context ctx = DIR_CONTEXT_INIT(dirent, filldir, filp->f_pos); int error; error = zpl_iterate(filp, &ctx); filp->f_pos = ctx.pos; return (error); } #endif /* HAVE_VFS_ITERATE */ #if defined(HAVE_FSYNC_WITH_DENTRY) /* * Linux 2.6.x - 2.6.34 API, * Through 2.6.34 the nfsd kernel server would pass a NULL 'file struct *' * to the fops->fsync() hook. For this reason, we must be careful not to * use filp unconditionally. */ static int zpl_fsync(struct file *filp, struct dentry *dentry, int datasync) { cred_t *cr = CRED(); int error; fstrans_cookie_t cookie; crhold(cr); cookie = spl_fstrans_mark(); error = -zfs_fsync(dentry->d_inode, datasync, cr); spl_fstrans_unmark(cookie); crfree(cr); ASSERT3S(error, <=, 0); return (error); } #ifdef HAVE_FILE_AIO_FSYNC static int zpl_aio_fsync(struct kiocb *kiocb, int datasync) { struct file *filp = kiocb->ki_filp; return (zpl_fsync(filp, file_dentry(filp), datasync)); } #endif #elif defined(HAVE_FSYNC_WITHOUT_DENTRY) /* * Linux 2.6.35 - 3.0 API, * As of 2.6.35 the dentry argument to the fops->fsync() hook was deemed * redundant. The dentry is still accessible via filp->f_path.dentry, * and we are guaranteed that filp will never be NULL. */ static int zpl_fsync(struct file *filp, int datasync) { struct inode *inode = filp->f_mapping->host; cred_t *cr = CRED(); int error; fstrans_cookie_t cookie; crhold(cr); cookie = spl_fstrans_mark(); error = -zfs_fsync(inode, datasync, cr); spl_fstrans_unmark(cookie); crfree(cr); ASSERT3S(error, <=, 0); return (error); } #ifdef HAVE_FILE_AIO_FSYNC static int zpl_aio_fsync(struct kiocb *kiocb, int datasync) { return (zpl_fsync(kiocb->ki_filp, datasync)); } #endif #elif defined(HAVE_FSYNC_RANGE) /* * Linux 3.1 - 3.x API, * As of 3.1 the responsibility to call filemap_write_and_wait_range() has * been pushed down in to the .fsync() vfs hook. Additionally, the i_mutex * lock is no longer held by the caller, for zfs we don't require the lock * to be held so we don't acquire it. */ static int zpl_fsync(struct file *filp, loff_t start, loff_t end, int datasync) { struct inode *inode = filp->f_mapping->host; cred_t *cr = CRED(); int error; fstrans_cookie_t cookie; error = filemap_write_and_wait_range(inode->i_mapping, start, end); if (error) return (error); crhold(cr); cookie = spl_fstrans_mark(); error = -zfs_fsync(inode, datasync, cr); spl_fstrans_unmark(cookie); crfree(cr); ASSERT3S(error, <=, 0); return (error); } #ifdef HAVE_FILE_AIO_FSYNC static int zpl_aio_fsync(struct kiocb *kiocb, int datasync) { return (zpl_fsync(kiocb->ki_filp, kiocb->ki_pos, -1, datasync)); } #endif #else #error "Unsupported fops->fsync() implementation" #endif static ssize_t zpl_read_common_iovec(struct inode *ip, const struct iovec *iovp, size_t count, unsigned long nr_segs, loff_t *ppos, uio_seg_t segment, int flags, cred_t *cr, size_t skip) { ssize_t read; uio_t uio; int error; fstrans_cookie_t cookie; uio.uio_iov = iovp; uio.uio_skip = skip; uio.uio_resid = count; uio.uio_iovcnt = nr_segs; uio.uio_loffset = *ppos; uio.uio_limit = MAXOFFSET_T; uio.uio_segflg = segment; cookie = spl_fstrans_mark(); error = -zfs_read(ip, &uio, flags, cr); spl_fstrans_unmark(cookie); if (error < 0) return (error); read = count - uio.uio_resid; *ppos += read; task_io_account_read(read); return (read); } inline ssize_t zpl_read_common(struct inode *ip, const char *buf, size_t len, loff_t *ppos, uio_seg_t segment, int flags, cred_t *cr) { struct iovec iov; iov.iov_base = (void *)buf; iov.iov_len = len; return (zpl_read_common_iovec(ip, &iov, len, 1, ppos, segment, flags, cr, 0)); } -static ssize_t -zpl_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos) -{ - cred_t *cr = CRED(); - ssize_t read; - - crhold(cr); - read = zpl_read_common(filp->f_mapping->host, buf, len, ppos, - UIO_USERSPACE, filp->f_flags, cr); - crfree(cr); - - file_accessed(filp); - return (read); -} - static ssize_t zpl_iter_read_common(struct kiocb *kiocb, const struct iovec *iovp, unsigned long nr_segs, size_t count, uio_seg_t seg, size_t skip) { cred_t *cr = CRED(); struct file *filp = kiocb->ki_filp; ssize_t read; crhold(cr); read = zpl_read_common_iovec(filp->f_mapping->host, iovp, count, nr_segs, &kiocb->ki_pos, seg, filp->f_flags, cr, skip); crfree(cr); file_accessed(filp); return (read); } #if defined(HAVE_VFS_RW_ITERATE) static ssize_t zpl_iter_read(struct kiocb *kiocb, struct iov_iter *to) { ssize_t ret; uio_seg_t seg = UIO_USERSPACE; if (to->type & ITER_KVEC) seg = UIO_SYSSPACE; if (to->type & ITER_BVEC) seg = UIO_BVEC; ret = zpl_iter_read_common(kiocb, to->iov, to->nr_segs, iov_iter_count(to), seg, to->iov_offset); if (ret > 0) iov_iter_advance(to, ret); return (ret); } #else static ssize_t zpl_aio_read(struct kiocb *kiocb, const struct iovec *iovp, unsigned long nr_segs, loff_t pos) { - return (zpl_iter_read_common(kiocb, iovp, nr_segs, kiocb->ki_nbytes, + ssize_t ret; + size_t count; + + ret = generic_segment_checks(iovp, &nr_segs, &count, VERIFY_WRITE); + if (ret) + return (ret); + + return (zpl_iter_read_common(kiocb, iovp, nr_segs, count, UIO_USERSPACE, 0)); } #endif /* HAVE_VFS_RW_ITERATE */ static ssize_t zpl_write_common_iovec(struct inode *ip, const struct iovec *iovp, size_t count, unsigned long nr_segs, loff_t *ppos, uio_seg_t segment, int flags, cred_t *cr, size_t skip) { ssize_t wrote; uio_t uio; int error; fstrans_cookie_t cookie; if (flags & O_APPEND) *ppos = i_size_read(ip); uio.uio_iov = iovp; uio.uio_skip = skip; uio.uio_resid = count; uio.uio_iovcnt = nr_segs; uio.uio_loffset = *ppos; uio.uio_limit = MAXOFFSET_T; uio.uio_segflg = segment; cookie = spl_fstrans_mark(); error = -zfs_write(ip, &uio, flags, cr); spl_fstrans_unmark(cookie); if (error < 0) return (error); wrote = count - uio.uio_resid; *ppos += wrote; task_io_account_write(wrote); return (wrote); } + inline ssize_t zpl_write_common(struct inode *ip, const char *buf, size_t len, loff_t *ppos, uio_seg_t segment, int flags, cred_t *cr) { struct iovec iov; iov.iov_base = (void *)buf; iov.iov_len = len; return (zpl_write_common_iovec(ip, &iov, len, 1, ppos, segment, flags, cr, 0)); } -static ssize_t -zpl_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos) -{ - cred_t *cr = CRED(); - ssize_t wrote; - - crhold(cr); - wrote = zpl_write_common(filp->f_mapping->host, buf, len, ppos, - UIO_USERSPACE, filp->f_flags, cr); - crfree(cr); - - return (wrote); -} - static ssize_t zpl_iter_write_common(struct kiocb *kiocb, const struct iovec *iovp, unsigned long nr_segs, size_t count, uio_seg_t seg, size_t skip) { cred_t *cr = CRED(); struct file *filp = kiocb->ki_filp; ssize_t wrote; crhold(cr); wrote = zpl_write_common_iovec(filp->f_mapping->host, iovp, count, nr_segs, &kiocb->ki_pos, seg, filp->f_flags, cr, skip); crfree(cr); return (wrote); } #if defined(HAVE_VFS_RW_ITERATE) static ssize_t zpl_iter_write(struct kiocb *kiocb, struct iov_iter *from) { + size_t count; ssize_t ret; uio_seg_t seg = UIO_USERSPACE; + +#ifndef HAVE_GENERIC_WRITE_CHECKS_KIOCB + struct file *file = kiocb->ki_filp; + struct address_space *mapping = file->f_mapping; + struct inode *ip = mapping->host; + int isblk = S_ISBLK(ip->i_mode); + + count = iov_iter_count(from); + ret = generic_write_checks(file, &kiocb->ki_pos, &count, isblk); +#else + /* + * XXX - ideally this check should be in the same lock region with + * write operations, so that there's no TOCTTOU race when doing + * append and someone else grow the file. + */ + ret = generic_write_checks(kiocb, from); + count = ret; +#endif + if (ret <= 0) + return (ret); + if (from->type & ITER_KVEC) seg = UIO_SYSSPACE; if (from->type & ITER_BVEC) seg = UIO_BVEC; + ret = zpl_iter_write_common(kiocb, from->iov, from->nr_segs, - iov_iter_count(from), seg, from->iov_offset); + count, seg, from->iov_offset); if (ret > 0) iov_iter_advance(from, ret); + return (ret); } #else static ssize_t zpl_aio_write(struct kiocb *kiocb, const struct iovec *iovp, unsigned long nr_segs, loff_t pos) { - return (zpl_iter_write_common(kiocb, iovp, nr_segs, kiocb->ki_nbytes, + struct file *file = kiocb->ki_filp; + struct address_space *mapping = file->f_mapping; + struct inode *ip = mapping->host; + int isblk = S_ISBLK(ip->i_mode); + size_t count; + ssize_t ret; + + ret = generic_segment_checks(iovp, &nr_segs, &count, VERIFY_READ); + if (ret) + return (ret); + + ret = generic_write_checks(file, &pos, &count, isblk); + if (ret) + return (ret); + + return (zpl_iter_write_common(kiocb, iovp, nr_segs, count, UIO_USERSPACE, 0)); } #endif /* HAVE_VFS_RW_ITERATE */ static loff_t zpl_llseek(struct file *filp, loff_t offset, int whence) { #if defined(SEEK_HOLE) && defined(SEEK_DATA) fstrans_cookie_t cookie; if (whence == SEEK_DATA || whence == SEEK_HOLE) { struct inode *ip = filp->f_mapping->host; loff_t maxbytes = ip->i_sb->s_maxbytes; loff_t error; spl_inode_lock_shared(ip); cookie = spl_fstrans_mark(); error = -zfs_holey(ip, whence, &offset); spl_fstrans_unmark(cookie); if (error == 0) error = lseek_execute(filp, ip, offset, maxbytes); spl_inode_unlock_shared(ip); return (error); } #endif /* SEEK_HOLE && SEEK_DATA */ return (generic_file_llseek(filp, offset, whence)); } /* * It's worth taking a moment to describe how mmap is implemented * for zfs because it differs considerably from other Linux filesystems. * However, this issue is handled the same way under OpenSolaris. * * The issue is that by design zfs bypasses the Linux page cache and * leaves all caching up to the ARC. This has been shown to work * well for the common read(2)/write(2) case. However, mmap(2) * is problem because it relies on being tightly integrated with the * page cache. To handle this we cache mmap'ed files twice, once in * the ARC and a second time in the page cache. The code is careful * to keep both copies synchronized. * * When a file with an mmap'ed region is written to using write(2) * both the data in the ARC and existing pages in the page cache * are updated. For a read(2) data will be read first from the page * cache then the ARC if needed. Neither a write(2) or read(2) will * will ever result in new pages being added to the page cache. * * New pages are added to the page cache only via .readpage() which * is called when the vfs needs to read a page off disk to back the * virtual memory region. These pages may be modified without * notifying the ARC and will be written out periodically via * .writepage(). This will occur due to either a sync or the usual * page aging behavior. Note because a read(2) of a mmap'ed file * will always check the page cache first even when the ARC is out * of date correct data will still be returned. * * While this implementation ensures correct behavior it does have * have some drawbacks. The most obvious of which is that it * increases the required memory footprint when access mmap'ed * files. It also adds additional complexity to the code keeping * both caches synchronized. * * Longer term it may be possible to cleanly resolve this wart by * mapping page cache pages directly on to the ARC buffers. The * Linux address space operations are flexible enough to allow * selection of which pages back a particular index. The trick * would be working out the details of which subsystem is in * charge, the ARC, the page cache, or both. It may also prove * helpful to move the ARC buffers to a scatter-gather lists * rather than a vmalloc'ed region. */ static int zpl_mmap(struct file *filp, struct vm_area_struct *vma) { struct inode *ip = filp->f_mapping->host; znode_t *zp = ITOZ(ip); int error; fstrans_cookie_t cookie; cookie = spl_fstrans_mark(); error = -zfs_map(ip, vma->vm_pgoff, (caddr_t *)vma->vm_start, (size_t)(vma->vm_end - vma->vm_start), vma->vm_flags); spl_fstrans_unmark(cookie); if (error) return (error); error = generic_file_mmap(filp, vma); if (error) return (error); mutex_enter(&zp->z_lock); zp->z_is_mapped = 1; mutex_exit(&zp->z_lock); return (error); } /* * Populate a page with data for the Linux page cache. This function is * only used to support mmap(2). There will be an identical copy of the * data in the ARC which is kept up to date via .write() and .writepage(). * * Current this function relies on zpl_read_common() and the O_DIRECT * flag to read in a page. This works but the more correct way is to * update zfs_fillpage() to be Linux friendly and use that interface. */ static int zpl_readpage(struct file *filp, struct page *pp) { struct inode *ip; struct page *pl[1]; int error = 0; fstrans_cookie_t cookie; ASSERT(PageLocked(pp)); ip = pp->mapping->host; pl[0] = pp; cookie = spl_fstrans_mark(); error = -zfs_getpage(ip, pl, 1); spl_fstrans_unmark(cookie); if (error) { SetPageError(pp); ClearPageUptodate(pp); } else { ClearPageError(pp); SetPageUptodate(pp); flush_dcache_page(pp); } unlock_page(pp); return (error); } /* * Populate a set of pages with data for the Linux page cache. This * function will only be called for read ahead and never for demand * paging. For simplicity, the code relies on read_cache_pages() to * correctly lock each page for IO and call zpl_readpage(). */ static int zpl_readpages(struct file *filp, struct address_space *mapping, struct list_head *pages, unsigned nr_pages) { return (read_cache_pages(mapping, pages, (filler_t *)zpl_readpage, filp)); } int zpl_putpage(struct page *pp, struct writeback_control *wbc, void *data) { struct address_space *mapping = data; fstrans_cookie_t cookie; ASSERT(PageLocked(pp)); ASSERT(!PageWriteback(pp)); cookie = spl_fstrans_mark(); (void) zfs_putpage(mapping->host, pp, wbc); spl_fstrans_unmark(cookie); return (0); } static int zpl_writepages(struct address_space *mapping, struct writeback_control *wbc) { znode_t *zp = ITOZ(mapping->host); zfs_sb_t *zsb = ITOZSB(mapping->host); enum writeback_sync_modes sync_mode; int result; ZFS_ENTER(zsb); if (zsb->z_os->os_sync == ZFS_SYNC_ALWAYS) wbc->sync_mode = WB_SYNC_ALL; ZFS_EXIT(zsb); sync_mode = wbc->sync_mode; /* * We don't want to run write_cache_pages() in SYNC mode here, because * that would make putpage() wait for a single page to be committed to * disk every single time, resulting in atrocious performance. Instead * we run it once in non-SYNC mode so that the ZIL gets all the data, * and then we commit it all in one go. */ wbc->sync_mode = WB_SYNC_NONE; result = write_cache_pages(mapping, wbc, zpl_putpage, mapping); if (sync_mode != wbc->sync_mode) { ZFS_ENTER(zsb); ZFS_VERIFY_ZP(zp); if (zsb->z_log != NULL) zil_commit(zsb->z_log, zp->z_id); ZFS_EXIT(zsb); /* * We need to call write_cache_pages() again (we can't just * return after the commit) because the previous call in * non-SYNC mode does not guarantee that we got all the dirty * pages (see the implementation of write_cache_pages() for * details). That being said, this is a no-op in most cases. */ wbc->sync_mode = sync_mode; result = write_cache_pages(mapping, wbc, zpl_putpage, mapping); } return (result); } /* * Write out dirty pages to the ARC, this function is only required to * support mmap(2). Mapped pages may be dirtied by memory operations * which never call .write(). These dirty pages are kept in sync with * the ARC buffers via this hook. */ static int zpl_writepage(struct page *pp, struct writeback_control *wbc) { if (ITOZSB(pp->mapping->host)->z_os->os_sync == ZFS_SYNC_ALWAYS) wbc->sync_mode = WB_SYNC_ALL; return (zpl_putpage(pp, wbc, pp->mapping)); } /* * The only flag combination which matches the behavior of zfs_space() * is FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE. The FALLOC_FL_PUNCH_HOLE * flag was introduced in the 2.6.38 kernel. */ #if defined(HAVE_FILE_FALLOCATE) || defined(HAVE_INODE_FALLOCATE) long zpl_fallocate_common(struct inode *ip, int mode, loff_t offset, loff_t len) { int error = -EOPNOTSUPP; #if defined(FALLOC_FL_PUNCH_HOLE) && defined(FALLOC_FL_KEEP_SIZE) cred_t *cr = CRED(); flock64_t bf; loff_t olen; fstrans_cookie_t cookie; if (mode != (FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE)) return (error); if (offset < 0 || len <= 0) return (-EINVAL); spl_inode_lock(ip); olen = i_size_read(ip); if (offset > olen) { spl_inode_unlock(ip); return (0); } if (offset + len > olen) len = olen - offset; bf.l_type = F_WRLCK; bf.l_whence = 0; bf.l_start = offset; bf.l_len = len; bf.l_pid = 0; crhold(cr); cookie = spl_fstrans_mark(); error = -zfs_space(ip, F_FREESP, &bf, FWRITE, offset, cr); spl_fstrans_unmark(cookie); spl_inode_unlock(ip); crfree(cr); #endif /* defined(FALLOC_FL_PUNCH_HOLE) && defined(FALLOC_FL_KEEP_SIZE) */ ASSERT3S(error, <=, 0); return (error); } #endif /* defined(HAVE_FILE_FALLOCATE) || defined(HAVE_INODE_FALLOCATE) */ #ifdef HAVE_FILE_FALLOCATE static long zpl_fallocate(struct file *filp, int mode, loff_t offset, loff_t len) { return zpl_fallocate_common(file_inode(filp), mode, offset, len); } #endif /* HAVE_FILE_FALLOCATE */ /* * Map zfs file z_pflags (xvattr_t) to linux file attributes. Only file * attributes common to both Linux and Solaris are mapped. */ static int zpl_ioctl_getflags(struct file *filp, void __user *arg) { struct inode *ip = file_inode(filp); unsigned int ioctl_flags = 0; uint64_t zfs_flags = ITOZ(ip)->z_pflags; int error; if (zfs_flags & ZFS_IMMUTABLE) ioctl_flags |= FS_IMMUTABLE_FL; if (zfs_flags & ZFS_APPENDONLY) ioctl_flags |= FS_APPEND_FL; if (zfs_flags & ZFS_NODUMP) ioctl_flags |= FS_NODUMP_FL; ioctl_flags &= FS_FL_USER_VISIBLE; error = copy_to_user(arg, &ioctl_flags, sizeof (ioctl_flags)); return (error); } /* * fchange() is a helper macro to detect if we have been asked to change a * flag. This is ugly, but the requirement that we do this is a consequence of * how the Linux file attribute interface was designed. Another consequence is * that concurrent modification of files suffers from a TOCTOU race. Neither * are things we can fix without modifying the kernel-userland interface, which * is outside of our jurisdiction. */ #define fchange(f0, f1, b0, b1) (!((f0) & (b0)) != !((f1) & (b1))) static int zpl_ioctl_setflags(struct file *filp, void __user *arg) { struct inode *ip = file_inode(filp); uint64_t zfs_flags = ITOZ(ip)->z_pflags; unsigned int ioctl_flags; cred_t *cr = CRED(); xvattr_t xva; xoptattr_t *xoap; int error; fstrans_cookie_t cookie; if (copy_from_user(&ioctl_flags, arg, sizeof (ioctl_flags))) return (-EFAULT); if ((ioctl_flags & ~(FS_IMMUTABLE_FL | FS_APPEND_FL | FS_NODUMP_FL))) return (-EOPNOTSUPP); if ((ioctl_flags & ~(FS_FL_USER_MODIFIABLE))) return (-EACCES); if ((fchange(ioctl_flags, zfs_flags, FS_IMMUTABLE_FL, ZFS_IMMUTABLE) || fchange(ioctl_flags, zfs_flags, FS_APPEND_FL, ZFS_APPENDONLY)) && !capable(CAP_LINUX_IMMUTABLE)) return (-EACCES); if (!zpl_inode_owner_or_capable(ip)) return (-EACCES); xva_init(&xva); xoap = xva_getxoptattr(&xva); XVA_SET_REQ(&xva, XAT_IMMUTABLE); if (ioctl_flags & FS_IMMUTABLE_FL) xoap->xoa_immutable = B_TRUE; XVA_SET_REQ(&xva, XAT_APPENDONLY); if (ioctl_flags & FS_APPEND_FL) xoap->xoa_appendonly = B_TRUE; XVA_SET_REQ(&xva, XAT_NODUMP); if (ioctl_flags & FS_NODUMP_FL) xoap->xoa_nodump = B_TRUE; crhold(cr); cookie = spl_fstrans_mark(); error = -zfs_setattr(ip, (vattr_t *)&xva, 0, cr); spl_fstrans_unmark(cookie); crfree(cr); return (error); } static long zpl_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { switch (cmd) { case FS_IOC_GETFLAGS: return (zpl_ioctl_getflags(filp, (void *)arg)); case FS_IOC_SETFLAGS: return (zpl_ioctl_setflags(filp, (void *)arg)); default: return (-ENOTTY); } } #ifdef CONFIG_COMPAT static long zpl_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { switch (cmd) { case FS_IOC32_GETFLAGS: cmd = FS_IOC_GETFLAGS; break; case FS_IOC32_SETFLAGS: cmd = FS_IOC_SETFLAGS; break; default: return (-ENOTTY); } return (zpl_ioctl(filp, cmd, (unsigned long)compat_ptr(arg))); } #endif /* CONFIG_COMPAT */ const struct address_space_operations zpl_address_space_operations = { .readpages = zpl_readpages, .readpage = zpl_readpage, .writepage = zpl_writepage, .writepages = zpl_writepages, }; const struct file_operations zpl_file_operations = { .open = zpl_open, .release = zpl_release, .llseek = zpl_llseek, - .read = zpl_read, - .write = zpl_write, #ifdef HAVE_VFS_RW_ITERATE .read_iter = zpl_iter_read, .write_iter = zpl_iter_write, #else .aio_read = zpl_aio_read, .aio_write = zpl_aio_write, #endif .mmap = zpl_mmap, .fsync = zpl_fsync, #ifdef HAVE_FILE_AIO_FSYNC .aio_fsync = zpl_aio_fsync, #endif #ifdef HAVE_FILE_FALLOCATE .fallocate = zpl_fallocate, #endif /* HAVE_FILE_FALLOCATE */ .unlocked_ioctl = zpl_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = zpl_compat_ioctl, #endif }; const struct file_operations zpl_dir_file_operations = { .llseek = generic_file_llseek, .read = generic_read_dir, #ifdef HAVE_VFS_ITERATE_SHARED .iterate_shared = zpl_iterate, #elif defined(HAVE_VFS_ITERATE) .iterate = zpl_iterate, #else .readdir = zpl_readdir, #endif .fsync = zpl_fsync, .unlocked_ioctl = zpl_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = zpl_compat_ioctl, #endif }; diff --git a/tests/runfiles/linux.run b/tests/runfiles/linux.run index f09001d24ed4..0a8198236fbf 100644 --- a/tests/runfiles/linux.run +++ b/tests/runfiles/linux.run @@ -1,668 +1,669 @@ # # This file and its contents are supplied under the terms of the # Common Development and Distribution License ("CDDL"), version 1.0. # You may only use this file in accordance with the terms of version # 1.0 of the CDDL. # # A full copy of the text of the CDDL should have accompanied this # source. A copy of the CDDL is also available via the Internet at # http://www.illumos.org/license/CDDL. # [DEFAULT] pre = setup quiet = False pre_user = root user = root timeout = 600 post_user = root post = cleanup outputdir = /var/tmp/test_results # DISABLED: update to use ZFS_ACL_* variables and user_run helper. # posix_001_pos # posix_002_pos [tests/functional/acl/posix] tests = ['posix_003_pos'] [tests/functional/atime] tests = ['atime_001_pos', 'atime_002_neg', 'atime_003_pos'] # DISABLED: # bootfs_006_pos - needs investigation # bootfs_008_neg - needs investigation [tests/functional/bootfs] tests = ['bootfs_001_pos', 'bootfs_002_neg', 'bootfs_003_pos', 'bootfs_004_neg', 'bootfs_005_neg', 'bootfs_007_neg'] # DISABLED: # cache_001_pos - needs investigation # cache_010_neg - needs investigation [tests/functional/cache] tests = ['cache_002_pos', 'cache_003_pos', 'cache_004_neg', 'cache_005_neg', 'cache_006_pos', 'cache_007_neg', 'cache_008_neg', 'cache_009_pos', 'cache_011_pos'] # DISABLED: needs investigation #[tests/functional/cachefile] #tests = ['cachefile_001_pos', 'cachefile_002_pos', 'cachefile_003_pos', # 'cachefile_004_pos'] #pre = #post = # DISABLED: needs investigation # 'sensitive_none_lookup', 'sensitive_none_delete', # 'sensitive_formd_lookup', 'sensitive_formd_delete', # 'insensitive_none_lookup', 'insensitive_none_delete', # 'insensitive_formd_lookup', 'insensitive_formd_delete', # 'mixed_none_lookup', 'mixed_none_lookup_ci', 'mixed_none_delete', # 'mixed_formd_lookup', 'mixed_formd_lookup_ci', 'mixed_formd_delete'] [tests/functional/casenorm] tests = ['case_all_values', 'norm_all_values'] [tests/functional/chattr] tests = ['chattr_001_pos', 'chattr_002_neg'] [tests/functional/checksum] tests = ['run_edonr_test', 'run_sha2_test', 'run_skein_test', 'filetest_001_pos'] [tests/functional/clean_mirror] tests = [ 'clean_mirror_001_pos', 'clean_mirror_002_pos', 'clean_mirror_003_pos', 'clean_mirror_004_pos'] [tests/functional/cli_root/zdb] tests = ['zdb_001_neg', 'zdb_002_pos'] pre = post = [tests/functional/cli_root/zfs] tests = ['zfs_001_neg', 'zfs_002_pos', 'zfs_003_neg'] # DISABLED: # zfs_clone_005_pos - busy unmount [tests/functional/cli_root/zfs_clone] tests = ['zfs_clone_001_neg', 'zfs_clone_002_pos', 'zfs_clone_003_pos', 'zfs_clone_004_pos', 'zfs_clone_006_pos', 'zfs_clone_007_pos', 'zfs_clone_008_neg', 'zfs_clone_009_neg', 'zfs_clone_010_pos'] # DISABLED: # zfs_copies_003_pos - https://github.com/zfsonlinux/zfs/issues/3484 # zfs_copies_005_neg - https://github.com/zfsonlinux/zfs/issues/3484 [tests/functional/cli_root/zfs_copies] tests = ['zfs_copies_001_pos', 'zfs_copies_002_pos', 'zfs_copies_004_neg', 'zfs_copies_006_pos'] [tests/functional/cli_root/zfs_create] tests = ['zfs_create_001_pos', 'zfs_create_002_pos', 'zfs_create_003_pos', 'zfs_create_004_pos', 'zfs_create_005_pos', 'zfs_create_006_pos', 'zfs_create_007_pos', 'zfs_create_008_neg', 'zfs_create_009_neg', 'zfs_create_010_neg', 'zfs_create_011_pos', 'zfs_create_012_pos', 'zfs_create_013_pos', 'zfs_create_014_pos'] # DISABLED: # zfs_destroy_005_neg - busy mountpoint behavior # zfs_destroy_001_pos - https://github.com/zfsonlinux/zfs/issues/5635 [tests/functional/cli_root/zfs_destroy] tests = ['zfs_destroy_002_pos', 'zfs_destroy_003_pos', 'zfs_destroy_004_pos','zfs_destroy_006_neg', 'zfs_destroy_007_neg', 'zfs_destroy_008_pos','zfs_destroy_009_pos', 'zfs_destroy_010_pos', 'zfs_destroy_011_pos','zfs_destroy_012_pos', 'zfs_destroy_013_neg', 'zfs_destroy_014_pos','zfs_destroy_015_pos', 'zfs_destroy_016_pos'] # DISABLED: # zfs_get_004_pos - https://github.com/zfsonlinux/zfs/issues/3484 # zfs_get_006_neg - needs investigation [tests/functional/cli_root/zfs_get] tests = ['zfs_get_001_pos', 'zfs_get_002_pos', 'zfs_get_003_pos', 'zfs_get_005_neg', 'zfs_get_007_neg', 'zfs_get_008_pos', 'zfs_get_009_pos', 'zfs_get_010_neg'] # DISABLED: # zfs_inherit_003_pos - https://github.com/zfsonlinux/zfs/issues/5669 [tests/functional/cli_root/zfs_inherit] tests = ['zfs_inherit_001_neg', 'zfs_inherit_002_neg'] # DISABLED: # zfs_mount_006_pos - https://github.com/zfsonlinux/zfs/issues/4990 # zfs_mount_007_pos - needs investigation # zfs_mount_009_neg - needs investigation # zfs_mount_all_001_pos - needs investigation [tests/functional/cli_root/zfs_mount] tests = ['zfs_mount_001_pos', 'zfs_mount_002_pos', 'zfs_mount_003_pos', 'zfs_mount_004_pos', 'zfs_mount_005_pos', 'zfs_mount_008_pos', 'zfs_mount_010_neg', 'zfs_mount_011_neg', 'zfs_mount_012_neg'] [tests/functional/cli_root/zfs_promote] tests = ['zfs_promote_001_pos', 'zfs_promote_002_pos', 'zfs_promote_003_pos', 'zfs_promote_004_pos', 'zfs_promote_005_pos', 'zfs_promote_006_neg', 'zfs_promote_007_neg', 'zfs_promote_008_pos'] # DISABLED: # zfs_written_property_001_pos - https://github.com/zfsonlinux/zfs/issues/2441 [tests/functional/cli_root/zfs_property] tests = [] # DISABLED: # zfs_receive_004_neg - Fails for OpenZFS on illumos [tests/functional/cli_root/zfs_receive] tests = ['zfs_receive_001_pos', 'zfs_receive_002_pos', 'zfs_receive_003_pos', 'zfs_receive_005_neg', 'zfs_receive_006_pos', 'zfs_receive_007_neg', 'zfs_receive_008_pos', 'zfs_receive_009_neg', 'zfs_receive_010_pos', 'zfs_receive_011_pos', 'zfs_receive_012_pos', 'zfs_receive_013_pos', 'zfs_receive_014_pos'] # DISABLED: # zfs_rename_006_pos - https://github.com/zfsonlinux/zfs/issues/5647 # zfs_rename_009_neg - https://github.com/zfsonlinux/zfs/issues/5648 [tests/functional/cli_root/zfs_rename] tests = ['zfs_rename_001_pos', 'zfs_rename_002_pos', 'zfs_rename_003_pos', 'zfs_rename_004_neg', 'zfs_rename_005_neg', 'zfs_rename_007_pos', 'zfs_rename_008_pos', 'zfs_rename_010_neg', 'zfs_rename_011_pos', 'zfs_rename_012_neg', 'zfs_rename_013_pos'] [tests/functional/cli_root/zfs_reservation] tests = ['zfs_reservation_001_pos', 'zfs_reservation_002_pos'] # DISABLED: # zfs_rollback_001_pos - busy mountpoint behavior # zfs_rollback_002_pos - busy mountpoint behavior [tests/functional/cli_root/zfs_rollback] tests = ['zfs_rollback_003_neg', 'zfs_rollback_004_neg'] [tests/functional/cli_root/zfs_send] tests = ['zfs_send_001_pos', 'zfs_send_002_pos', 'zfs_send_003_pos', 'zfs_send_004_neg', 'zfs_send_005_pos', 'zfs_send_006_pos', 'zfs_send_007_pos'] # DISABLED: # ro_props_001_pos - https://github.com/zfsonlinux/zfs/issues/5511 [tests/functional/cli_root/zfs_set] tests = ['cache_001_pos', 'cache_002_neg', 'canmount_001_pos', 'canmount_002_pos', 'canmount_003_pos', 'canmount_004_pos', 'checksum_001_pos', 'compression_001_pos', 'mountpoint_001_pos', 'mountpoint_002_pos', 'reservation_001_neg', 'user_property_002_pos', 'share_mount_001_neg', 'snapdir_001_pos', 'onoffs_001_pos', 'user_property_001_pos', 'user_property_003_neg', 'readonly_001_pos', 'user_property_004_pos', 'version_001_neg', 'zfs_set_001_neg', 'zfs_set_002_neg', 'zfs_set_003_neg', 'property_alias_001_pos', 'mountpoint_003_pos'] # DISABLED: # zfs_share_005_pos - needs investigation, probably unsupported NFS share format [tests/functional/cli_root/zfs_share] tests = ['zfs_share_001_pos', 'zfs_share_002_pos', 'zfs_share_003_pos', 'zfs_share_004_pos', 'zfs_share_006_pos', 'zfs_share_007_neg', 'zfs_share_008_neg', 'zfs_share_009_neg', 'zfs_share_010_neg', 'zfs_share_011_pos'] [tests/functional/cli_root/zfs_snapshot] tests = ['zfs_snapshot_001_neg', 'zfs_snapshot_002_neg', 'zfs_snapshot_003_neg', 'zfs_snapshot_004_neg', 'zfs_snapshot_005_neg', 'zfs_snapshot_006_pos', 'zfs_snapshot_007_neg', 'zfs_snapshot_008_neg', 'zfs_snapshot_009_pos'] # DISABLED: # zfs_unmount_005_pos - needs investigation # zfs_unmount_009_pos - needs investigation # zfs_unmount_all_001_pos - needs investigation [tests/functional/cli_root/zfs_unmount] tests = ['zfs_unmount_001_pos', 'zfs_unmount_002_pos', 'zfs_unmount_003_pos', 'zfs_unmount_004_pos', 'zfs_unmount_006_pos', 'zfs_unmount_007_neg', 'zfs_unmount_008_neg'] # DISABLED: # zfs_unshare_002_pos - zfs set sharenfs=off won't unshare if it was already off # zfs_unshare_006_pos - some distros come with Samba "user shares" disabled [tests/functional/cli_root/zfs_unshare] tests = ['zfs_unshare_001_pos', 'zfs_unshare_003_pos', 'zfs_unshare_004_neg', 'zfs_unshare_005_neg'] [tests/functional/cli_root/zfs_upgrade] tests = ['zfs_upgrade_001_pos', 'zfs_upgrade_002_pos', 'zfs_upgrade_003_pos', 'zfs_upgrade_004_pos', 'zfs_upgrade_005_pos', 'zfs_upgrade_006_neg', 'zfs_upgrade_007_neg'] [tests/functional/cli_root/zpool] tests = ['zpool_001_neg', 'zpool_002_pos', 'zpool_003_pos'] # DISABLED: # zpool_add_004_pos - https://github.com/zfsonlinux/zfs/issues/3484 # zpool_add_005_pos - no 'dumpadm' command. # zpool_add_006_pos - https://github.com/zfsonlinux/zfs/issues/3484 [tests/functional/cli_root/zpool_add] tests = ['zpool_add_001_pos', 'zpool_add_002_pos', 'zpool_add_003_pos', 'zpool_add_007_neg', 'zpool_add_008_neg', 'zpool_add_009_neg'] [tests/functional/cli_root/zpool_attach] tests = ['zpool_attach_001_neg'] # DISABLED: # zpool_clear_001_pos - https://github.com/zfsonlinux/zfs/issues/5634 [tests/functional/cli_root/zpool_clear] tests = ['zpool_clear_002_neg', 'zpool_clear_003_neg'] # DISABLED: # zpool_create_001_pos - needs investigation # zpool_create_002_pos - needs investigation # zpool_create_004_pos - needs investigation # zpool_create_006_pos - https://github.com/zfsonlinux/zfs/issues/3484 # zpool_create_008_pos - uses VTOC labels (?) and 'overlapping slices' # zpool_create_011_neg - tries to access /etc/vfstab etc # zpool_create_012_neg - swap devices # zpool_create_014_neg - swap devices # zpool_create_015_neg - swap devices # zpool_create_016_pos - no dumadm command. # zpool_create_020_pos - needs investigation [tests/functional/cli_root/zpool_create] tests = [ 'zpool_create_003_pos', 'zpool_create_005_pos', 'zpool_create_007_neg', 'zpool_create_009_neg', 'zpool_create_010_neg', 'zpool_create_017_neg', 'zpool_create_018_pos', 'zpool_create_019_pos', 'zpool_create_021_pos', 'zpool_create_022_pos', 'zpool_create_023_neg', 'zpool_create_024_pos', 'zpool_create_features_001_pos', 'zpool_create_features_002_pos', 'zpool_create_features_003_pos', 'zpool_create_features_004_neg', 'zpool_create_features_005_pos'] # DISABLED: # zpool_destroy_001_pos - needs investigation # zpool_destroy_002_pos - busy mountpoint behavior [tests/functional/cli_root/zpool_destroy] tests = [ 'zpool_destroy_003_neg'] pre = post = [tests/functional/cli_root/zpool_detach] tests = ['zpool_detach_001_neg'] # DISABLED: Requires full FMA support in ZED # zpool_expand_* - https://github.com/zfsonlinux/zfs/issues/2437 #[tests/functional/cli_root/zpool_expand] #tests = ['zpool_expand_001_pos', 'zpool_expand_002_pos', # 'zpool_expand_003_neg'] # DISABLED: # zpool_export_004_pos - https://github.com/zfsonlinux/zfs/issues/3484 [tests/functional/cli_root/zpool_export] tests = ['zpool_export_001_pos', 'zpool_export_002_pos', 'zpool_export_003_neg'] [tests/functional/cli_root/zpool_get] tests = ['zpool_get_001_pos', 'zpool_get_002_pos', 'zpool_get_003_pos', 'zpool_get_004_neg'] [tests/functional/cli_root/zpool_history] tests = ['zpool_history_001_neg', 'zpool_history_002_pos'] # DISABLED: # zpool_import_002_pos - https://github.com/zfsonlinux/zfs/issues/5202 # zpool_import_012_pos - sharenfs issue # zpool_import_all_001_pos - partition issue [tests/functional/cli_root/zpool_import] tests = ['zpool_import_001_pos', 'zpool_import_003_pos', 'zpool_import_004_pos', 'zpool_import_005_pos', 'zpool_import_006_pos', 'zpool_import_007_pos', 'zpool_import_008_pos', 'zpool_import_009_neg', 'zpool_import_010_pos', 'zpool_import_011_neg', 'zpool_import_013_neg', 'zpool_import_014_pos', 'zpool_import_features_001_pos', 'zpool_import_features_002_neg', 'zpool_import_features_003_pos','zpool_import_missing_001_pos', 'zpool_import_missing_002_pos', 'zpool_import_missing_003_pos', 'zpool_import_rename_001_pos'] [tests/functional/cli_root/zpool_offline] tests = ['zpool_offline_001_pos', 'zpool_offline_002_neg'] [tests/functional/cli_root/zpool_online] tests = ['zpool_online_001_pos', 'zpool_online_002_neg'] # DISABLED: # zpool_remove_003_pos - needs investigation [tests/functional/cli_root/zpool_remove] tests = ['zpool_remove_001_neg', 'zpool_remove_002_pos'] [tests/functional/cli_root/zpool_replace] tests = ['zpool_replace_001_neg'] [tests/functional/cli_root/zpool_scrub] tests = ['zpool_scrub_001_neg', 'zpool_scrub_002_pos', 'zpool_scrub_003_pos', 'zpool_scrub_004_pos', 'zpool_scrub_005_pos'] [tests/functional/cli_root/zpool_set] tests = ['zpool_set_001_pos', 'zpool_set_002_neg', 'zpool_set_003_neg'] pre = post = [tests/functional/cli_root/zpool_status] tests = ['zpool_status_001_pos', 'zpool_status_002_pos'] # DISABLED: # zpool_upgrade_002_pos - https://github.com/zfsonlinux/zfs/issues/4034 # zpool_upgrade_004_pos - https://github.com/zfsonlinux/zfs/issues/4034 # zpool_upgrade_007_pos - needs investigation [tests/functional/cli_root/zpool_upgrade] tests = ['zpool_upgrade_001_pos', 'zpool_upgrade_003_pos', 'zpool_upgrade_005_neg', 'zpool_upgrade_006_neg', 'zpool_upgrade_008_pos', 'zpool_upgrade_009_neg'] # DISABLED: # zfs_share_001_neg - requires additional dependencies # zfs_unshare_001_neg - requires additional dependencies [tests/functional/cli_user/misc] tests = ['zdb_001_neg', 'zfs_001_neg', 'zfs_allow_001_neg', 'zfs_clone_001_neg', 'zfs_create_001_neg', 'zfs_destroy_001_neg', 'zfs_get_001_neg', 'zfs_inherit_001_neg', 'zfs_mount_001_neg', 'zfs_promote_001_neg', 'zfs_receive_001_neg', 'zfs_rename_001_neg', 'zfs_rollback_001_neg', 'zfs_send_001_neg', 'zfs_set_001_neg', 'zfs_snapshot_001_neg', 'zfs_unallow_001_neg', 'zfs_unmount_001_neg', 'zfs_upgrade_001_neg', 'zpool_001_neg', 'zpool_add_001_neg', 'zpool_attach_001_neg', 'zpool_clear_001_neg', 'zpool_create_001_neg', 'zpool_destroy_001_neg', 'zpool_detach_001_neg', 'zpool_export_001_neg', 'zpool_get_001_neg', 'zpool_history_001_neg', 'zpool_import_001_neg', 'zpool_import_002_neg', 'zpool_offline_001_neg', 'zpool_online_001_neg', 'zpool_remove_001_neg', 'zpool_replace_001_neg', 'zpool_scrub_001_neg', 'zpool_set_001_neg', 'zpool_status_001_neg', 'zpool_upgrade_001_neg', 'arcstat_001_pos', 'arc_summary_001_pos', 'dbufstat_001_pos'] user = [tests/functional/cli_user/zfs_list] tests = ['zfs_list_001_pos', 'zfs_list_002_pos', 'zfs_list_003_pos', 'zfs_list_004_neg', 'zfs_list_007_pos', 'zfs_list_008_neg'] user = [tests/functional/cli_user/zpool_iostat] tests = ['zpool_iostat_001_neg', 'zpool_iostat_002_pos', 'zpool_iostat_003_neg', 'zpool_iostat_004_pos', 'zpool_iostat_005_pos'] user = [tests/functional/cli_user/zpool_list] tests = ['zpool_list_001_pos', 'zpool_list_002_neg'] user = [tests/functional/compression] tests = ['compress_001_pos', 'compress_002_pos', 'compress_003_pos', 'compress_004_pos'] [tests/functional/ctime] tests = ['ctime_001_pos' ] # DISABLED: # zfs_allow_010_pos - https://github.com/zfsonlinux/zfs/issues/5646 [tests/functional/delegate] tests = ['zfs_allow_001_pos', 'zfs_allow_002_pos', 'zfs_allow_004_pos', 'zfs_allow_005_pos', 'zfs_allow_006_pos', 'zfs_allow_007_pos', 'zfs_allow_008_pos', 'zfs_allow_009_neg', 'zfs_allow_011_neg', 'zfs_allow_012_neg', 'zfs_unallow_001_pos', 'zfs_unallow_002_pos', 'zfs_unallow_003_pos', 'zfs_unallow_004_pos', 'zfs_unallow_005_pos', 'zfs_unallow_006_pos', 'zfs_unallow_007_neg', 'zfs_unallow_008_neg'] # DISABLED: # devices_001_pos - needs investigation # devices_002_neg - needs investigation [tests/functional/devices] tests = ['devices_003_pos'] # DISABLED: # exec_002_neg - needs investigation [tests/functional/exec] tests = ['exec_001_pos'] [tests/functional/features/async_destroy] tests = ['async_destroy_001_pos'] [tests/functional/features/large_dnode] tests = ['large_dnode_001_pos', 'large_dnode_002_pos', 'large_dnode_003_pos', 'large_dnode_004_neg', 'large_dnode_005_pos', 'large_dnode_006_pos', 'large_dnode_007_neg'] # DISABLED: needs investigation #[tests/functional/grow_pool] #tests = ['grow_pool_001_pos'] #pre = #post = # DISABLED: needs investigation #[tests/functional/grow_replicas] #tests = ['grow_replicas_001_pos'] #pre = #post = # DISABLED: # history_004_pos - https://github.com/zfsonlinux/zfs/issues/5664 # history_006_neg - https://github.com/zfsonlinux/zfs/issues/5657 # history_008_pos - https://github.com/zfsonlinux/zfs/issues/5658 [tests/functional/history] tests = ['history_001_pos', 'history_002_pos', 'history_003_pos', 'history_005_neg', 'history_007_pos', 'history_009_pos', 'history_010_pos'] [tests/functional/inheritance] tests = ['inherit_001_pos'] pre = # DISABLED: # inuse_001_pos, inuse_007_pos - no dumpadm command # inuse_005_pos - partition issue # inuse_006_pos - partition issue # inuse_008_pos - partition issue # inuse_009_pos - partition issue [tests/functional/inuse] tests = ['inuse_004_pos'] post = # DISABLED: needs investigation -#[tests/functional/large_files] -#tests = ['large_files_001_pos'] +# large_files_001_pos +[tests/functional/large_files] +tests = ['large_files_002_pos'] # DISABLED: needs investigation #[tests/functional/largest_pool] #tests = ['largest_pool_001_pos'] #pre = #post = # DISABLED: needs investigation #[tests/functional/link_count] #tests = ['link_count_001'] [tests/functional/migration] tests = ['migration_001_pos', 'migration_002_pos', 'migration_003_pos', 'migration_004_pos', 'migration_005_pos', 'migration_006_pos', 'migration_007_pos', 'migration_008_pos', 'migration_009_pos', 'migration_010_pos', 'migration_011_pos', 'migration_012_pos'] # DISABLED: # mmap_write_001_pos - needs investigation [tests/functional/mmap] tests = ['mmap_read_001_pos'] # DISABLED: # umountall_001 - requires umountall command. [tests/functional/mount] tests = ['umount_001'] [tests/functional/mv_files] tests = ['mv_files_001_pos', 'mv_files_002_pos'] [tests/functional/nestedfs] tests = ['nestedfs_001_pos'] [tests/functional/no_space] tests = ['enospc_001_pos'] # DISABLED: # nopwrite_volume - https://github.com/zfsonlinux/zfs/issues/5510 # nopwrite_varying_compression - needs investigation [tests/functional/nopwrite] tests = ['nopwrite_copies', 'nopwrite_mtime', 'nopwrite_negative', 'nopwrite_promoted_clone', 'nopwrite_recsize', 'nopwrite_sync'] # DISABLED: needs investigation #[tests/functional/online_offline] #tests = ['online_offline_001_pos', 'online_offline_002_neg', # 'online_offline_003_neg'] [tests/functional/pool_names] tests = ['pool_names_001_pos', 'pool_names_002_neg'] pre = post = [tests/functional/poolversion] tests = ['poolversion_001_pos', 'poolversion_002_pos'] # DISABLED: requires pfexec command or 'RBAC profile' #[tests/functional/privilege] #tests = ['privilege_001_pos', 'privilege_002_pos'] [tests/functional/quota] tests = ['quota_001_pos', 'quota_002_pos', 'quota_003_pos', 'quota_004_pos', 'quota_005_pos', 'quota_006_neg'] [tests/functional/raidz] tests = ['raidz_001_neg', 'raidz_002_pos'] [tests/functional/redundancy] tests = ['redundancy_001_pos', 'redundancy_002_pos', 'redundancy_003_pos'] [tests/functional/refquota] tests = ['refquota_001_pos', 'refquota_002_pos', 'refquota_003_pos', 'refquota_004_pos', 'refquota_005_pos', 'refquota_006_neg'] # DISABLED: # refreserv_004_pos - needs investigation [tests/functional/refreserv] tests = ['refreserv_001_pos', 'refreserv_002_pos', 'refreserv_003_pos', 'refreserv_005_pos'] # DISABLED: #[tests/functional/rename_dirs] #tests = ['rename_dirs_001_pos'] [tests/functional/replacement] tests = ['replacement_001_pos', 'replacement_002_pos', 'replacement_003_pos'] # DISABLED: # reservation_001_pos - https://github.com/zfsonlinux/zfs/issues/4445 # reservation_013_pos - https://github.com/zfsonlinux/zfs/issues/4444 # reservation_018_pos - https://github.com/zfsonlinux/zfs/issues/5642 [tests/functional/reservation] tests = ['reservation_001_pos', 'reservation_002_pos', 'reservation_003_pos', 'reservation_004_pos', 'reservation_005_pos', 'reservation_006_pos', 'reservation_007_pos', 'reservation_008_pos', 'reservation_009_pos', 'reservation_010_pos', 'reservation_011_pos', 'reservation_012_pos', 'reservation_013_pos', 'reservation_014_pos', 'reservation_015_pos', 'reservation_016_pos', 'reservation_017_pos'] # DISABLED: Root pools must be handled differently under Linux #[tests/functional/rootpool] #tests = ['rootpool_002_neg', 'rootpool_003_neg', 'rootpool_007_neg'] # DISABLED: # rsend_008_pos - Fails for OpenZFS on illumos # rsend_009_pos - Fails for OpenZFS on illumos # rsend_020_pos - ASSERTs in dump_record() [tests/functional/rsend] tests = ['rsend_001_pos', 'rsend_002_pos', 'rsend_003_pos', 'rsend_004_pos', 'rsend_005_pos', 'rsend_006_pos', 'rsend_007_pos', 'rsend_010_pos', 'rsend_011_pos', 'rsend_012_pos', 'rsend_013_pos', 'rsend_014_pos', 'rsend_019_pos', 'rsend_021_pos', 'rsend_022_pos', 'rsend_024_pos'] [tests/functional/scrub_mirror] tests = ['scrub_mirror_001_pos', 'scrub_mirror_002_pos', 'scrub_mirror_003_pos', 'scrub_mirror_004_pos'] # DISABLED: Scripts need to be updated. # slog_012_neg - needs investigation # slog_013_pos - requires 'lofiadm' command. # slog_014_pos - needs investigation [tests/functional/slog] tests = ['slog_001_pos', 'slog_002_pos', 'slog_003_pos', 'slog_004_pos', 'slog_005_pos', 'slog_006_pos', 'slog_007_pos', 'slog_008_neg', 'slog_009_neg', 'slog_010_neg', 'slog_011_neg'] # DISABLED: # clone_001_pos - https://github.com/zfsonlinux/zfs/issues/3484 # rollback_003_pos - Hangs in unmount and spins. # snapshot_016_pos - Problem with automount [tests/functional/snapshot] tests = ['rollback_001_pos', 'rollback_002_pos', 'snapshot_001_pos', 'snapshot_002_pos', 'snapshot_003_pos', 'snapshot_004_pos', 'snapshot_005_pos', 'snapshot_006_pos', 'snapshot_007_pos', 'snapshot_008_pos', 'snapshot_009_pos', 'snapshot_010_pos', 'snapshot_011_pos', 'snapshot_012_pos', 'snapshot_013_pos', 'snapshot_014_pos', 'snapshot_015_pos', 'snapshot_017_pos'] # DISABLED: # snapused_004_pos - https://github.com/zfsonlinux/zfs/issues/5513 [tests/functional/snapused] tests = ['snapused_001_pos', 'snapused_002_pos', 'snapused_003_pos', 'snapused_005_pos'] [tests/functional/sparse] tests = ['sparse_001_pos'] # DISABLED: needs investigation #[tests/functional/threadsappend] #tests = ['threadsappend_001_pos'] [tests/functional/tmpfile] tests = ['tmpfile_001_pos', 'tmpfile_002_pos', 'tmpfile_003_pos'] [tests/functional/truncate] tests = ['truncate_001_pos', 'truncate_002_pos'] [tests/functional/upgrade] tests = [ 'upgrade_userobj_001_pos' ] [tests/functional/userquota] tests = [ 'userquota_001_pos', 'userquota_002_pos', 'userquota_003_pos', 'userquota_004_pos', 'userquota_005_neg', 'userquota_006_pos', 'userquota_007_pos', 'userquota_008_pos', 'userquota_009_pos', 'userquota_010_pos', 'userquota_011_pos', 'userquota_012_neg', 'userquota_013_pos', 'userspace_001_pos', 'userspace_002_pos', 'userspace_003_pos', 'groupspace_001_pos', 'groupspace_002_pos', 'groupspace_003_pos' ] # DISABLED: # vdev_zaps_007_pos -- fails due to a pre-existing issue with zpool split [tests/functional/vdev_zaps] tests = ['vdev_zaps_001_pos', 'vdev_zaps_002_pos', 'vdev_zaps_003_pos', 'vdev_zaps_004_pos', 'vdev_zaps_005_pos', 'vdev_zaps_006_pos'] # DISABLED: # write_dirs_002_pos - needs investigation [tests/functional/write_dirs] tests = ['write_dirs_001_pos'] # DISABLED: No 'runat' command, replace the Linux equivalent and add xattrtest #[tests/functional/xattr] #tests = ['xattr_001_pos', 'xattr_002_neg', 'xattr_003_neg', 'xattr_004_pos', # 'xattr_005_pos', 'xattr_006_pos', 'xattr_007_neg', 'xattr_008_pos', # 'xattr_009_neg', 'xattr_010_neg', 'xattr_011_pos', 'xattr_012_pos', # 'xattr_013_pos'] [tests/functional/zvol/zvol_ENOSPC] tests = ['zvol_ENOSPC_001_pos'] [tests/functional/zvol/zvol_cli] tests = ['zvol_cli_001_pos', 'zvol_cli_002_pos', 'zvol_cli_003_neg'] # DISABLED: requires dumpadm #[tests/functional/zvol/zvol_misc] #tests = ['zvol_misc_001_neg', 'zvol_misc_002_pos', 'zvol_misc_003_neg', # 'zvol_misc_004_pos', 'zvol_misc_005_neg', 'zvol_misc_006_pos'] # DISABLED: requires updated for Linux #[tests/functional/zvol/zvol_swap] #tests = ['zvol_swap_001_pos', 'zvol_swap_002_pos', 'zvol_swap_003_pos', # 'zvol_swap_004_pos', 'zvol_swap_005_pos', 'zvol_swap_006_pos'] diff --git a/tests/zfs-tests/tests/functional/large_files/Makefile.am b/tests/zfs-tests/tests/functional/large_files/Makefile.am index d78ea4722887..0e471533090c 100644 --- a/tests/zfs-tests/tests/functional/large_files/Makefile.am +++ b/tests/zfs-tests/tests/functional/large_files/Makefile.am @@ -1,5 +1,6 @@ pkgdatadir = $(datadir)/@PACKAGE@/zfs-tests/tests/functional/large_files dist_pkgdata_SCRIPTS = \ setup.ksh \ cleanup.ksh \ - large_files_001_pos.ksh + large_files_001_pos.ksh \ + large_files_002_pos.ksh diff --git a/tests/zfs-tests/tests/functional/large_files/large_files_002_pos.ksh b/tests/zfs-tests/tests/functional/large_files/large_files_002_pos.ksh new file mode 100755 index 000000000000..152fe2e08121 --- /dev/null +++ b/tests/zfs-tests/tests/functional/large_files/large_files_002_pos.ksh @@ -0,0 +1,55 @@ +#!/bin/ksh -p +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright (c) 2015 by Lawrence Livermore National Security, LLC. +# All rights reserved. +# + +. $STF_SUITE/include/libtest.shlib + +# +# DESCRIPTION: +# Verify 'ulimit -f' file size restrictions are enforced. +# +# STRATEGY: +# 1. Set ulimit file size to unlimited, verify files can be created. +# 2. Reduce ulimit file size, verify the expected error is returned. +# + +verify_runnable "both" + +log_assert "Verify 'ulimit -f' maximum file size is enforced" + +# Verify 'ulimit -f unlimited' works +log_must ulimit -f unlimited +log_must sh -c 'dd if=/dev/zero of=$TESTDIR/ulimit_write_file bs=1M count=2' +log_must sh -c '$TRUNCATE -s2M $TESTDIR/ulimit_trunc_file' +log_must $RM $TESTDIR/ulimit_write_file $TESTDIR/ulimit_trunc_file + +# Verify 'ulimit -f ' works +log_must ulimit -f 1024 +log_mustnot sh -c 'dd if=/dev/zero of=$TESTDIR/ulimit_write_file bs=1M count=2' +log_mustnot sh -c '$TRUNCATE -s2M $TESTDIR/ulimit_trunc_file' +log_must $RM $TESTDIR/ulimit_write_file $TESTDIR/ulimit_trunc_file + +log_pass "Successfully enforced 'ulimit -f' maximum file size"