diff --git a/pkgs/os-specific/linux/spl/default.nix b/pkgs/os-specific/linux/spl/default.nix index 0549232fcd5b..29d56a60e95c 100644 --- a/pkgs/os-specific/linux/spl/default.nix +++ b/pkgs/os-specific/linux/spl/default.nix @@ -7,7 +7,7 @@ stdenv.mkDerivation { sha256 = "166853pqa294f78mn4j4x9pri79lyv3j2h8m9fzhfy7d7gxfqljk"; }; - patches = [ ./install_prefix.patch ./install_prefix_2.patch ./module_prefix.patch ./linux-3.6.patch ]; + patches = [ ./install_prefix.patch ./install_prefix_2.patch ./module_prefix.patch ]; buildInputs = [ perl kernel autoconf automake libtool ]; diff --git a/pkgs/os-specific/linux/spl/linux-3.6.patch b/pkgs/os-specific/linux/spl/linux-3.6.patch deleted file mode 100644 index 6b92cdd61ac9..000000000000 --- a/pkgs/os-specific/linux/spl/linux-3.6.patch +++ /dev/null @@ -1,251 +0,0 @@ -commit bcb15891ab394e11615eee08bba1fd85ac32e158 -Author: Yuxuan Shui -Date: Thu Oct 11 22:41:33 2012 +0800 - - Linux 3.6 compat, kern_path_locked() added - - The kern_path_parent() function was removed from Linux 3.6 because - it was observed that all the callers just want the parent dentry. - The simpler kern_path_locked() function replaces kern_path_parent() - and does the lookup while holding the ->i_mutex lock. - - This is good news for the vn implementation because it removes the - need for us to handle the locking. However, it makes it harder to - implement a single readable vn_remove()/vn_rename() function which - is usually what we prefer. - - Therefore, we implement a new version of vn_remove()/vn_rename() - for Linux 3.6 and newer kernels. This allows us to leave the - existing working implementation untouched, and to add a simpler - version for newer kernels. - - Long term I would very much like to see all of the vn code removed - since what this code enabled is generally frowned upon in the kernel. - But that can't happen util we either abondon the zpool.cache file - or implement alternate infrastructure to update is correctly in - user space. - - Signed-off-by: Yuxuan Shui - Signed-off-by: Richard Yao - Signed-off-by: Brian Behlendorf - Closes #154 - -diff --git a/config/spl-build.m4 b/config/spl-build.m4 -index 0c7a03c..eb644a1 100644 ---- a/config/spl-build.m4 -+++ b/config/spl-build.m4 -@@ -86,6 +86,7 @@ AC_DEFUN([SPL_AC_CONFIG_KERNEL], [ - SPL_AC_SHRINK_ICACHE_MEMORY - SPL_AC_KERN_PATH_PARENT_HEADER - SPL_AC_KERN_PATH_PARENT_SYMBOL -+ SPL_AC_KERN_PATH_LOCKED - SPL_AC_2ARGS_ZLIB_DEFLATE_WORKSPACESIZE - SPL_AC_SHRINK_CONTROL_STRUCT - SPL_AC_RWSEM_SPINLOCK_IS_RAW -@@ -2188,6 +2189,21 @@ AC_DEFUN([SPL_AC_KERN_PATH_PARENT_SYMBOL], - ]) - - dnl # -+dnl # 3.6 API compat, -+dnl # The kern_path_parent() function was replaced by the kern_path_locked() -+dnl # function to eliminate all struct nameidata usage outside fs/namei.c. -+dnl # -+AC_DEFUN([SPL_AC_KERN_PATH_LOCKED], [ -+ SPL_CHECK_SYMBOL_HEADER( -+ [kern_path_locked], -+ [struct dentry \*kern_path_locked(const char \*, struct path \*)], -+ [include/linux/namei.h], -+ [AC_DEFINE(HAVE_KERN_PATH_LOCKED, 1, -+ [kern_path_locked() is available])], -+ []) -+]) -+ -+dnl # - dnl # 2.6.39 API compat, - dnl # The function zlib_deflate_workspacesize() now take 2 arguments. - dnl # This was done to avoid always having to allocate the maximum size -diff --git a/include/linux/file_compat.h b/include/linux/file_compat.h -index 2b5b7d2..27819d5 100644 ---- a/include/linux/file_compat.h -+++ b/include/linux/file_compat.h -@@ -83,6 +83,12 @@ extern kern_path_parent_t kern_path_parent_fn; - # define spl_kern_path_parent(path, nd) path_lookup(path, LOOKUP_PARENT, nd) - #endif /* HAVE_KERN_PATH_PARENT_HEADER */ - -+#ifdef HAVE_KERN_PATH_LOCKED -+typedef struct dentry * (*kern_path_locked_t)(const char *, struct path *); -+extern kern_path_locked_t kern_path_locked_fn; -+# define spl_kern_path_locked(name, path) kern_path_locked_fn(name, path) -+#endif /* HAVE_KERN_PATH_LOCKED */ -+ - #ifndef HAVE_CLEAR_CLOSE_ON_EXEC - #define __clear_close_on_exec(fd, fdt) FD_CLR(fd, fdt->close_on_exec) - #endif -diff --git a/module/spl/spl-vnode.c b/module/spl/spl-vnode.c -index f5fc65d..a0fed32 100644 ---- a/module/spl/spl-vnode.c -+++ b/module/spl/spl-vnode.c -@@ -50,6 +50,10 @@ EXPORT_SYMBOL(kern_path_parent_fn); - #endif /* HAVE_KERN_PATH_PARENT_SYMBOL */ - #endif /* HAVE_KERN_PATH_PARENT_HEADER */ - -+#ifdef HAVE_KERN_PATH_LOCKED -+kern_path_locked_t kern_path_locked_fn = SYMBOL_POISON; -+#endif /* HAVE_KERN_PATH_LOCKED */ -+ - vtype_t - vn_mode_to_vtype(mode_t mode) - { -@@ -298,6 +302,128 @@ vn_seek(vnode_t *vp, offset_t ooff, offset_t *noffp, void *ct) - } - EXPORT_SYMBOL(vn_seek); - -+#ifdef HAVE_KERN_PATH_LOCKED -+/* Based on do_unlinkat() from linux/fs/namei.c */ -+int -+vn_remove(const char *path, uio_seg_t seg, int flags) -+{ -+ struct dentry *dentry; -+ struct path parent; -+ struct inode *inode = NULL; -+ int rc = 0; -+ SENTRY; -+ -+ ASSERT(seg == UIO_SYSSPACE); -+ ASSERT(flags == RMFILE); -+ -+ dentry = spl_kern_path_locked(path, &parent); -+ rc = PTR_ERR(dentry); -+ if (!IS_ERR(dentry)) { -+ if (parent.dentry->d_name.name[parent.dentry->d_name.len]) -+ SGOTO(slashes, rc = 0); -+ -+ inode = dentry->d_inode; -+ if (!inode) -+ SGOTO(slashes, rc = 0); -+ -+ if (inode) -+ ihold(inode); -+ -+ rc = vfs_unlink(parent.dentry->d_inode, dentry); -+exit1: -+ dput(dentry); -+ } -+ -+ spl_inode_unlock(parent.dentry->d_inode); -+ if (inode) -+ iput(inode); /* truncate the inode here */ -+ -+ path_put(&parent); -+ SRETURN(-rc); -+ -+slashes: -+ rc = !dentry->d_inode ? -ENOENT : -+ S_ISDIR(dentry->d_inode->i_mode) ? -EISDIR : -ENOTDIR; -+ SGOTO(exit1, rc); -+} /* vn_remove() */ -+EXPORT_SYMBOL(vn_remove); -+ -+/* Based on do_rename() from linux/fs/namei.c */ -+int -+vn_rename(const char *oldname, const char *newname, int x1) -+{ -+ struct dentry *old_dir, *new_dir; -+ struct dentry *old_dentry, *new_dentry; -+ struct dentry *trap; -+ struct path old_parent, new_parent; -+ int rc = 0; -+ SENTRY; -+ -+ old_dentry = spl_kern_path_locked(oldname, &old_parent); -+ if (IS_ERR(old_dentry)) -+ SGOTO(exit, rc = PTR_ERR(old_dentry)); -+ -+ spl_inode_unlock(old_parent.dentry->d_inode); -+ -+ new_dentry = spl_kern_path_locked(newname, &new_parent); -+ if (IS_ERR(new_dentry)) -+ SGOTO(exit2, rc = PTR_ERR(new_dentry)); -+ -+ spl_inode_unlock(new_parent.dentry->d_inode); -+ -+ rc = -EXDEV; -+ if (old_parent.mnt != new_parent.mnt) -+ SGOTO(exit3, rc); -+ -+ old_dir = old_parent.dentry; -+ new_dir = new_parent.dentry; -+ trap = lock_rename(new_dir, old_dir); -+ -+ /* source should not be ancestor of target */ -+ rc = -EINVAL; -+ if (old_dentry == trap) -+ SGOTO(exit4, rc); -+ -+ /* target should not be an ancestor of source */ -+ rc = -ENOTEMPTY; -+ if (new_dentry == trap) -+ SGOTO(exit4, rc); -+ -+ /* source must exist */ -+ rc = -ENOENT; -+ if (!old_dentry->d_inode) -+ SGOTO(exit4, rc); -+ -+ /* unless the source is a directory trailing slashes give -ENOTDIR */ -+ if (!S_ISDIR(old_dentry->d_inode->i_mode)) { -+ rc = -ENOTDIR; -+ if (old_dentry->d_name.name[old_dentry->d_name.len]) -+ SGOTO(exit4, rc); -+ if (new_dentry->d_name.name[new_dentry->d_name.len]) -+ SGOTO(exit4, rc); -+ } -+ -+#ifdef HAVE_4ARGS_VFS_RENAME -+ rc = vfs_rename(old_dir->d_inode, old_dentry, -+ new_dir->d_inode, new_dentry); -+#else -+ rc = vfs_rename(old_dir->d_inode, old_dentry, oldnd.nd_mnt, -+ new_dir->d_inode, new_dentry, newnd.nd_mnt); -+#endif /* HAVE_4ARGS_VFS_RENAME */ -+exit4: -+ unlock_rename(new_dir, old_dir); -+exit3: -+ dput(new_dentry); -+ path_put(&new_parent); -+exit2: -+ dput(old_dentry); -+ path_put(&old_parent); -+exit: -+ SRETURN(-rc); -+} -+EXPORT_SYMBOL(vn_rename); -+ -+#else - static struct dentry * - vn_lookup_hash(struct nameidata *nd) - { -@@ -458,6 +584,7 @@ exit: - SRETURN(-rc); - } - EXPORT_SYMBOL(vn_rename); -+#endif /* HAVE_KERN_PATH_LOCKED */ - - int - vn_getattr(vnode_t *vp, vattr_t *vap, int flags, void *x3, void *x4) -@@ -862,6 +989,15 @@ int spl_vn_init_kallsyms_lookup(void) - #endif /* HAVE_KERN_PATH_PARENT_SYMBOL */ - #endif /* HAVE_KERN_PATH_PARENT_HEADER */ - -+#ifdef HAVE_KERN_PATH_LOCKED -+ kern_path_locked_fn = (kern_path_locked_t) -+ spl_kallsyms_lookup_name("kern_path_locked"); -+ if (!kern_path_locked_fn) { -+ printk(KERN_ERR "Error: Unknown symbol kern_path_locked\n"); -+ return -EFAULT; -+ } -+#endif -+ - return (0); - } -