From 10087fe1fa3e4aa4b6722a1d27a47853ebdf47c8 Mon Sep 17 00:00:00 2001 From: Richard Yao Date: Sun, 3 Mar 2013 23:42:32 -0500 Subject: [PATCH 1/6] Linux 3.9 compat: Include linux/sched/rt.h Linux 3.9 reorganized sched.h, splitting it into numerous files. torvalds/linux@8bd75c77b7c6a3954140dd2e20346aef3efe4a35 moved MAX_PRIO and MAX_RT_PRIO to linux/sched/rt.h. Signed-off-by: Richard Yao Signed-off-by: Brian Behlendorf --- config/spl-build.m4 | 20 ++++++++++++++++++++ include/sys/sysmacros.h | 5 +++++ 2 files changed, 25 insertions(+) diff --git a/config/spl-build.m4 b/config/spl-build.m4 index 3dcc05e65da1..eef3a76aeaa7 100644 --- a/config/spl-build.m4 +++ b/config/spl-build.m4 @@ -88,6 +88,7 @@ AC_DEFUN([SPL_AC_CONFIG_KERNEL], [ SPL_AC_2ARGS_ZLIB_DEFLATE_WORKSPACESIZE SPL_AC_SHRINK_CONTROL_STRUCT SPL_AC_RWSEM_SPINLOCK_IS_RAW + SPL_AC_SCHED_RT_HEADER ]) AC_DEFUN([SPL_AC_MODULE_SYMVERS], [ @@ -2217,3 +2218,22 @@ AC_DEFUN([SPL_AC_RWSEM_SPINLOCK_IS_RAW], [ ]) EXTRA_KCFLAGS="$tmp_flags" ]) + +dnl # +dnl # 3.9 API change, +dnl # Moved things from linux/sched.h to linux/sched/rt.h +dnl # +AC_DEFUN([SPL_AC_SCHED_RT_HEADER], + [AC_MSG_CHECKING([whether header linux/sched/rt.h exists]) + SPL_LINUX_TRY_COMPILE([ + #include + #include + ],[ + return 0; + ],[ + AC_DEFINE(HAVE_SCHED_RT_HEADER, 1, [linux/sched/rt.h exists]) + AC_MSG_RESULT(yes) + ],[ + AC_MSG_RESULT(no) + ]) +]) diff --git a/include/sys/sysmacros.h b/include/sys/sysmacros.h index 7c4da67fc9ca..b4778b70e83f 100644 --- a/include/sys/sysmacros.h +++ b/include/sys/sysmacros.h @@ -26,12 +26,17 @@ #define _SPL_SYSMACROS_H #include +#include #include #include #include #include #include +#ifdef HAVE_SCHED_RT_HEADER +#include +#endif + #ifndef _KERNEL #define _KERNEL __KERNEL__ #endif From bc90df66887af63bd67223616f9084c4e9567056 Mon Sep 17 00:00:00 2001 From: Richard Yao Date: Sun, 3 Mar 2013 23:45:33 -0500 Subject: [PATCH 2/6] Linux 3.9 compat: Do not depend on f_vfsmnt torvalds/linux@182be684784334598eee1d90274e7f7aa0063616 removed the preprocessor definition for f_vfsmnt. The ability to access the mountpoint via ->f_path.mnt has been stable for a long time, so we switch to that. Signed-off-by: Richard Yao Signed-off-by: Brian Behlendorf --- module/spl/spl-vnode.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/module/spl/spl-vnode.c b/module/spl/spl-vnode.c index 4d571c6c44bb..fb8f1fc7e489 100644 --- a/module/spl/spl-vnode.c +++ b/module/spl/spl-vnode.c @@ -175,7 +175,7 @@ vn_open(const char *path, uio_seg_t seg, int flags, int mode, if (IS_ERR(fp)) SRETURN(-PTR_ERR(fp)); - rc = vfs_getattr(fp->f_vfsmnt, fp->f_dentry, &stat); + rc = vfs_getattr(fp->f_path.mnt, fp->f_dentry, &stat); if (rc) { filp_close(fp, 0); SRETURN(-rc); @@ -602,7 +602,7 @@ vn_getattr(vnode_t *vp, vattr_t *vap, int flags, void *x3, void *x4) fp = vp->v_file; - rc = vfs_getattr(fp->f_vfsmnt, fp->f_dentry, &stat); + rc = vfs_getattr(fp->f_path.mnt, fp->f_dentry, &stat); if (rc) SRETURN(-rc); @@ -754,7 +754,7 @@ vn_getf(int fd) if (vp == NULL) SGOTO(out_fget, rc); - if (vfs_getattr(lfp->f_vfsmnt, lfp->f_dentry, &stat)) + if (vfs_getattr(lfp->f_path.mnt, lfp->f_dentry, &stat)) SGOTO(out_vnode, rc); mutex_enter(&vp->v_lock); From 2a305c34c8876c06f55475e5ff5163923baa5491 Mon Sep 17 00:00:00 2001 From: Richard Yao Date: Mon, 4 Mar 2013 00:02:43 -0500 Subject: [PATCH 3/6] Linux 3.9 compat: vfs_getattr takes two arguments The function prototype of vfs_getattr previoulsy took struct vfsmount * and struct dentry * as arguments. These would always be defined together in a struct path *. torvalds/linux@3dadecce20603aa380023c65e6f55f108fd5e952 modified vfs_getattr to take struct path * is taken as an argument instead. Signed-off-by: Richard Yao Signed-off-by: Brian Behlendorf --- config/spl-build.m4 | 32 ++++++++++++++++++++++++++++++++ module/spl/spl-vnode.c | 17 +++++++++++++++-- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/config/spl-build.m4 b/config/spl-build.m4 index eef3a76aeaa7..83cefabd422f 100644 --- a/config/spl-build.m4 +++ b/config/spl-build.m4 @@ -89,6 +89,7 @@ AC_DEFUN([SPL_AC_CONFIG_KERNEL], [ SPL_AC_SHRINK_CONTROL_STRUCT SPL_AC_RWSEM_SPINLOCK_IS_RAW SPL_AC_SCHED_RT_HEADER + SPL_AC_2ARGS_VFS_GETATTR ]) AC_DEFUN([SPL_AC_MODULE_SYMVERS], [ @@ -2237,3 +2238,34 @@ AC_DEFUN([SPL_AC_SCHED_RT_HEADER], AC_MSG_RESULT(no) ]) ]) + +dnl # +dnl # 3.9 API change, +dnl # vfs_getattr() uses 2 args +dnl # It takes struct path * instead of struct vfsmount * and struct dentry * +dnl # +AC_DEFUN([SPL_AC_2ARGS_VFS_GETATTR], [ + AC_MSG_CHECKING([whether vfs_getattr() wants]) + SPL_LINUX_TRY_COMPILE([ + #include + ],[ + vfs_getattr((struct path *) NULL, + (struct kstat *)NULL); + ],[ + AC_MSG_RESULT(2 args) + AC_DEFINE(HAVE_2ARGS_VFS_GETATTR, 1, + [vfs_getattr wants 2 args]) + ],[ + SPL_LINUX_TRY_COMPILE([ + #include + ],[ + vfs_getattr((struct vfsmount *)NULL, + (struct dentry *)NULL, + (struct kstat *)NULL); + ],[ + AC_MSG_RESULT(3 args) + ],[ + AC_MSG_ERROR(unknown) + ]) + ]) +]) diff --git a/module/spl/spl-vnode.c b/module/spl/spl-vnode.c index fb8f1fc7e489..e264fba050e9 100644 --- a/module/spl/spl-vnode.c +++ b/module/spl/spl-vnode.c @@ -175,7 +175,11 @@ vn_open(const char *path, uio_seg_t seg, int flags, int mode, if (IS_ERR(fp)) SRETURN(-PTR_ERR(fp)); +#ifdef HAVE_2ARGS_VFS_GETATTR + rc = vfs_getattr(&fp->f_path, &stat); +#else rc = vfs_getattr(fp->f_path.mnt, fp->f_dentry, &stat); +#endif if (rc) { filp_close(fp, 0); SRETURN(-rc); @@ -602,7 +606,11 @@ vn_getattr(vnode_t *vp, vattr_t *vap, int flags, void *x3, void *x4) fp = vp->v_file; - rc = vfs_getattr(fp->f_path.mnt, fp->f_dentry, &stat); +#ifdef HAVE_2ARGS_VFS_GETATTR + rc = vfs_getattr(&fp->f_path, &stat); +#else + rc = vfs_getattr(fp->f_path.mnt, fp->f_dentry, &stat); +#endif if (rc) SRETURN(-rc); @@ -754,7 +762,12 @@ vn_getf(int fd) if (vp == NULL) SGOTO(out_fget, rc); - if (vfs_getattr(lfp->f_path.mnt, lfp->f_dentry, &stat)) +#ifdef HAVE_2ARGS_VFS_GETATTR + rc = vfs_getattr(&lfp->f_path, &stat); +#else + rc = vfs_getattr(lfp->f_path.mnt, lfp->f_dentry, &stat); +#endif + if (rc) SGOTO(out_vnode, rc); mutex_enter(&vp->v_lock); From a54718cfe0d8e8a4b124f176f0d5c94141f9aea0 Mon Sep 17 00:00:00 2001 From: Richard Yao Date: Mon, 4 Mar 2013 00:24:04 -0500 Subject: [PATCH 4/6] Linux 3.9 compat: set_fs_root takes const struct path * torvalds/linux@dcf787f39162ce32ca325b3e784aba2d2444619a enforces const-correctness in passing struct path *. Signed-off-by: Richard Yao Signed-off-by: Brian Behlendorf --- config/spl-build.m4 | 44 ++++++++++++++++++++++++++++++++++++++++++ module/spl/spl-vnode.c | 4 ++++ 2 files changed, 48 insertions(+) diff --git a/config/spl-build.m4 b/config/spl-build.m4 index 83cefabd422f..6a8e658a2006 100644 --- a/config/spl-build.m4 +++ b/config/spl-build.m4 @@ -64,6 +64,7 @@ AC_DEFUN([SPL_AC_CONFIG_KERNEL], [ SPL_AC_USER_PATH_DIR SPL_AC_SET_FS_PWD SPL_AC_2ARGS_SET_FS_PWD + SPL_AC_SET_FS_PWD_WITH_CONST SPL_AC_2ARGS_VFS_UNLINK SPL_AC_4ARGS_VFS_RENAME SPL_AC_VFS_FSYNC @@ -1686,11 +1687,54 @@ AC_DEFUN([SPL_AC_2ARGS_SET_FS_PWD], AC_MSG_RESULT(yes) AC_DEFINE(HAVE_2ARGS_SET_FS_PWD, 1, [set_fs_pwd() wants 2 args]) + HAVE_2ARGS_SET_FS_PWD=yes ],[ AC_MSG_RESULT(no) ]) ]) +dnl # +dnl # 3.9 API change +dnl # set_fs_pwd takes const struct path * +dnl # +AC_DEFUN([SPL_AC_SET_FS_PWD_WITH_CONST], +if test "x$HAVE_2ARGS_SET_FS_PWD" = xyes; then + tmp_flags="$EXTRA_KCFLAGS" + EXTRA_KCFLAGS="-Werror" + [AC_MSG_CHECKING([whether set_fs_pwd() requires const struct path *]) + SPL_LINUX_TRY_COMPILE([ + #include + #include + #include + void (*const set_fs_pwd_func) + (struct fs_struct *, const struct path *) + = set_fs_pwd; + ],[ + return 0; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_SET_FS_PWD_WITH_CONST, 1, + [set_fs_pwd() needs const path *]) + ],[ + SPL_LINUX_TRY_COMPILE([ + #include + #include + #include + void (*const set_fs_pwd_func) + (struct fs_struct *, struct path *) + = set_fs_pwd; + ],[ + return 0; + ],[ + AC_MSG_RESULT(no) + ],[ + AC_MSG_ERROR(unknown) + ]) + ]) + EXTRA_KCFLAGS="$tmp_flags" +fi +]) + dnl # dnl # SLES API change, never adopted in mainline, dnl # Third 'struct vfsmount *' argument removed. diff --git a/module/spl/spl-vnode.c b/module/spl/spl-vnode.c index e264fba050e9..dac452c10ec4 100644 --- a/module/spl/spl-vnode.c +++ b/module/spl/spl-vnode.c @@ -840,7 +840,11 @@ EXPORT_SYMBOL(releasef); # ifdef HAVE_2ARGS_SET_FS_PWD /* Used from 2.6.25 - 2.6.31+ */ void +# ifdef HAVE_SET_FS_PWD_WITH_CONST +set_fs_pwd(struct fs_struct *fs, const struct path *path) +# else set_fs_pwd(struct fs_struct *fs, struct path *path) +# endif { struct path old_pwd; From 8274ed598801255626b8c1648c3a4cdfea07b738 Mon Sep 17 00:00:00 2001 From: Richard Yao Date: Mon, 11 Mar 2013 22:02:45 -0400 Subject: [PATCH 5/6] Drop support for 3 argument version of set_fs_pwd This was a suggestion that Brian Behlendorf made when reviewing an early pull request for Linux 3.9 support. This commit was made intentionally easy to revert should we ever have a reason to reintroduce support for older kernels. Signed-off-by: Richard Yao Signed-off-by: Brian Behlendorf --- config/spl-build.m4 | 24 ----------------------- module/spl/spl-vnode.c | 43 ++---------------------------------------- 2 files changed, 2 insertions(+), 65 deletions(-) diff --git a/config/spl-build.m4 b/config/spl-build.m4 index 6a8e658a2006..14a7d974095e 100644 --- a/config/spl-build.m4 +++ b/config/spl-build.m4 @@ -63,7 +63,6 @@ AC_DEFUN([SPL_AC_CONFIG_KERNEL], [ SPL_AC_GET_ZONE_COUNTS SPL_AC_USER_PATH_DIR SPL_AC_SET_FS_PWD - SPL_AC_2ARGS_SET_FS_PWD SPL_AC_SET_FS_PWD_WITH_CONST SPL_AC_2ARGS_VFS_UNLINK SPL_AC_4ARGS_VFS_RENAME @@ -1672,33 +1671,11 @@ AC_DEFUN([SPL_AC_SET_FS_PWD], ]) ]) -dnl # -dnl # 2.6.25 API change, -dnl # Simplied API by replacing mnt+dentry args with a single path arg. -dnl # -AC_DEFUN([SPL_AC_2ARGS_SET_FS_PWD], - [AC_MSG_CHECKING([whether set_fs_pwd() wants 2 args]) - SPL_LINUX_TRY_COMPILE([ - #include - #include - ],[ - set_fs_pwd(NULL, NULL); - ],[ - AC_MSG_RESULT(yes) - AC_DEFINE(HAVE_2ARGS_SET_FS_PWD, 1, - [set_fs_pwd() wants 2 args]) - HAVE_2ARGS_SET_FS_PWD=yes - ],[ - AC_MSG_RESULT(no) - ]) -]) - dnl # dnl # 3.9 API change dnl # set_fs_pwd takes const struct path * dnl # AC_DEFUN([SPL_AC_SET_FS_PWD_WITH_CONST], -if test "x$HAVE_2ARGS_SET_FS_PWD" = xyes; then tmp_flags="$EXTRA_KCFLAGS" EXTRA_KCFLAGS="-Werror" [AC_MSG_CHECKING([whether set_fs_pwd() requires const struct path *]) @@ -1732,7 +1709,6 @@ if test "x$HAVE_2ARGS_SET_FS_PWD" = xyes; then ]) ]) EXTRA_KCFLAGS="$tmp_flags" -fi ]) dnl # diff --git a/module/spl/spl-vnode.c b/module/spl/spl-vnode.c index dac452c10ec4..4f56f1039ae1 100644 --- a/module/spl/spl-vnode.c +++ b/module/spl/spl-vnode.c @@ -837,8 +837,6 @@ vn_releasef(int fd) EXPORT_SYMBOL(releasef); #ifndef HAVE_SET_FS_PWD -# ifdef HAVE_2ARGS_SET_FS_PWD -/* Used from 2.6.25 - 2.6.31+ */ void # ifdef HAVE_SET_FS_PWD_WITH_CONST set_fs_pwd(struct fs_struct *fs, const struct path *path) @@ -865,37 +863,16 @@ set_fs_pwd(struct fs_struct *fs, struct path *path) if (old_pwd.dentry) path_put(&old_pwd); } -# else -/* Used from 2.6.11 - 2.6.24 */ -void -set_fs_pwd(struct fs_struct *fs, struct vfsmount *mnt, struct dentry *dentry) -{ - struct dentry *old_pwd; - struct vfsmount *old_pwdmnt; - - write_lock(&fs->lock); - old_pwd = fs->pwd; - old_pwdmnt = fs->pwdmnt; - fs->pwdmnt = mntget(mnt); - fs->pwd = dget(dentry); - write_unlock(&fs->lock); - - if (old_pwd) { - dput(old_pwd); - mntput(old_pwdmnt); - } -} -# endif /* HAVE_2ARGS_SET_FS_PWD */ #endif /* HAVE_SET_FS_PWD */ int vn_set_pwd(const char *filename) { -#if defined(HAVE_2ARGS_SET_FS_PWD) && defined(HAVE_USER_PATH_DIR) +#ifdef HAVE_USER_PATH_DIR struct path path; #else struct nameidata nd; -#endif /* HAVE_2ARGS_SET_FS_PWD */ +#endif /* HAVE_USER_PATH_DIR */ mm_segment_t saved_fs; int rc; SENTRY; @@ -908,7 +885,6 @@ vn_set_pwd(const char *filename) saved_fs = get_fs(); set_fs(get_ds()); -#ifdef HAVE_2ARGS_SET_FS_PWD # ifdef HAVE_USER_PATH_DIR rc = user_path_dir(filename, &path); if (rc) @@ -937,21 +913,6 @@ vn_set_pwd(const char *filename) dput_and_out: path_put(&nd.path); # endif /* HAVE_USER_PATH_DIR */ -#else - rc = __user_walk(filename, - LOOKUP_FOLLOW|LOOKUP_DIRECTORY|LOOKUP_CHDIR, &nd); - if (rc) - SGOTO(out, rc); - - rc = vfs_permission(&nd, MAY_EXEC); - if (rc) - SGOTO(dput_and_out, rc); - - set_fs_pwd(current->fs, nd.nd_mnt, nd.nd_dentry); - -dput_and_out: - vn_path_release(&nd); -#endif /* HAVE_2ARGS_SET_FS_PWD */ out: set_fs(saved_fs); From 4a31e5aa9be561a450a2741f5305932e0b9df241 Mon Sep 17 00:00:00 2001 From: Richard Yao Date: Mon, 4 Mar 2013 15:17:03 -0500 Subject: [PATCH 6/6] Linux 3.9 compat: Switch to hlist_for_each{,_rcu} torvalds/linux@b67bfe0d42cac56c512dd5da4b1b347a23f4b70a changed hlist_for_each_entry{,_rcu} to take 3 arguments instead of 4. We handle this by switching to hlist_for_each{,_rcu}, which works across all supported kernels. Signed-off-by: Richard Yao Signed-off-by: Brian Behlendorf --- module/spl/spl-kmem.c | 3 ++- module/spl/spl-tsd.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/module/spl/spl-kmem.c b/module/spl/spl-kmem.c index e3538b5ff48c..f9c111491811 100644 --- a/module/spl/spl-kmem.c +++ b/module/spl/spl-kmem.c @@ -404,7 +404,8 @@ kmem_del_init(spinlock_t *lock, struct hlist_head *table, int bits, const void * spin_lock_irqsave(lock, flags); head = &table[hash_ptr(addr, bits)]; - hlist_for_each_entry_rcu(p, node, head, kd_hlist) { + hlist_for_each_rcu(node, head) { + p = list_entry_rcu(node, struct kmem_debug, kd_hlist); if (p->kd_addr == addr) { hlist_del_init(&p->kd_hlist); list_del_init(&p->kd_list); diff --git a/module/spl/spl-tsd.c b/module/spl/spl-tsd.c index d7749cf7b878..6e5605b9d7a8 100644 --- a/module/spl/spl-tsd.c +++ b/module/spl/spl-tsd.c @@ -113,7 +113,8 @@ tsd_hash_search(tsd_hash_table_t *table, uint_t key, pid_t pid) hash = hash_long((ulong_t)key * (ulong_t)pid, table->ht_bits); bin = &table->ht_bins[hash]; spin_lock(&bin->hb_lock); - hlist_for_each_entry(entry, node, &bin->hb_head, he_list) { + hlist_for_each(node, &bin->hb_head) { + entry = list_entry(node, tsd_hash_entry_t, he_list); if ((entry->he_key == key) && (entry->he_pid == pid)) { spin_unlock(&bin->hb_lock); SRETURN(entry);