]> git.proxmox.com Git - mirror_spl-debian.git/commitdiff
Linux 2.6.36 compat, fs_struct->lock type change
authorBrian Behlendorf <behlendorf1@llnl.gov>
Tue, 9 Nov 2010 19:15:32 +0000 (11:15 -0800)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Tue, 9 Nov 2010 21:29:47 +0000 (13:29 -0800)
In the linux-2.6.36 kernel the fs_struct lock was changed from a
rwlock_t to a spinlock_t.  If the kernel would export the set_fs_pwd()
symbol by default this would not have caused us any issues, but they
don't.  So we're forced to add a new autoconf check which sets the
HAVE_FS_STRUCT_SPINLOCK define when a spinlock_t is used.  We can
then correctly use either spin_lock or write_lock in our custom
set_fs_pwd() implementation.

config/spl-build.m4
configure
module/spl/spl-vnode.c
spl_config.h.in

index ec7bda7765c17d1f0f0f6e2a91bcee223c6c0ff8..c18db70df2bcc4c17e5e91856ddec52d60dddf9d 100644 (file)
@@ -66,6 +66,7 @@ AC_DEFUN([SPL_AC_CONFIG_KERNEL], [
        SPL_AC_2ARGS_SET_FS_PWD
        SPL_AC_2ARGS_VFS_UNLINK
        SPL_AC_4ARGS_VFS_RENAME
+       SPL_AC_FS_STRUCT_SPINLOCK
        SPL_AC_CRED_STRUCT
        SPL_AC_GROUPS_SEARCH
        SPL_AC_PUT_TASK_STRUCT
@@ -1547,6 +1548,28 @@ AC_DEFUN([SPL_AC_4ARGS_VFS_RENAME],
        ])
 ])
 
+dnl #
+dnl # 2.6.36 API change,
+dnl # The 'struct fs_struct->lock' was changed from a rwlock_t to
+dnl # a spinlock_t to improve the fastpath performance.
+dnl #
+AC_DEFUN([SPL_AC_FS_STRUCT_SPINLOCK], [
+       AC_MSG_CHECKING([whether struct fs_struct uses spinlock_t])
+       SPL_LINUX_TRY_COMPILE([
+               #include <linux/sched.h>
+               #include <linux/fs_struct.h>
+       ],[
+               struct fs_struct fs;
+               spin_lock_init(&fs.lock);
+       ],[
+               AC_MSG_RESULT(yes)
+               AC_DEFINE(HAVE_FS_STRUCT_SPINLOCK, 1,
+                         [struct fs_struct uses spinlock_t])
+       ],[
+               AC_MSG_RESULT(no)
+       ])
+])
+
 dnl #
 dnl # 2.6.29 API change,
 dnl # check whether 'struct cred' exists
index 1a3b376886e70f4c577e6cf5b3f591e96f5d51fb..189f0f9dc6ba75710e903696e1049760458a374a 100755 (executable)
--- a/configure
+++ b/configure
 
 
 
+       { $as_echo "$as_me:$LINENO: checking whether struct fs_struct uses spinlock_t" >&5
+$as_echo_n "checking whether struct fs_struct uses spinlock_t... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+               #include <linux/sched.h>
+               #include <linux/fs_struct.h>
+
+int
+main (void)
+{
+
+               struct fs_struct fs;
+               spin_lock_init(&fs.lock);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+       rm -Rf build && mkdir -p build
+       echo "obj-m := conftest.o" >build/Makefile
+       if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+               { $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_FS_STRUCT_SPINLOCK 1
+_ACEOF
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+               { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+
+       rm -Rf build
+
+
+
+
        { $as_echo "$as_me:$LINENO: checking whether struct cred exists" >&5
 $as_echo_n "checking whether struct cred exists... " >&6; }
 
 
 
 
+       { $as_echo "$as_me:$LINENO: checking whether struct fs_struct uses spinlock_t" >&5
+$as_echo_n "checking whether struct fs_struct uses spinlock_t... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+               #include <linux/sched.h>
+               #include <linux/fs_struct.h>
+
+int
+main (void)
+{
+
+               struct fs_struct fs;
+               spin_lock_init(&fs.lock);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+       rm -Rf build && mkdir -p build
+       echo "obj-m := conftest.o" >build/Makefile
+       if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+               { $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_FS_STRUCT_SPINLOCK 1
+_ACEOF
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+               { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+
+       rm -Rf build
+
+
+
+
        { $as_echo "$as_me:$LINENO: checking whether struct cred exists" >&5
 $as_echo_n "checking whether struct cred exists... " >&6; }
 
index 29028c3c0d41ec504114a927c3d59db44771878e..5c64f05fb0f106db46e6a2280275a3bb79a98ca2 100644 (file)
@@ -617,16 +617,24 @@ EXPORT_SYMBOL(releasef);
 void
 set_fs_pwd(struct fs_struct *fs, struct path *path)
 {
-        struct path old_pwd;
-
-        write_lock(&fs->lock);
-        old_pwd = fs->pwd;
-        fs->pwd = *path;
-        path_get(path);
-        write_unlock(&fs->lock);
-
-        if (old_pwd.dentry)
-                path_put(&old_pwd);
+       struct path old_pwd;
+
+#  ifdef HAVE_FS_STRUCT_SPINLOCK
+       spin_lock(&fs->lock);
+       old_pwd = fs->pwd;
+       fs->pwd = *path;
+       path_get(path);
+       spin_unlock(&fs->lock);
+#  else
+       write_lock(&fs->lock);
+       old_pwd = fs->pwd;
+       fs->pwd = *path;
+       path_get(path);
+       write_unlock(&fs->lock);
+#  endif /* HAVE_FS_STRUCT_SPINLOCK */
+
+       if (old_pwd.dentry)
+               path_put(&old_pwd);
 }
 # else
 /* Used from 2.6.11 - 2.6.24 */
index 2a08694c907a17a88abf42311c29864828947fbb..7863f7b3c51e176ae15ffd244c3e6fc70e72d2e2 100644 (file)
@@ -78,6 +78,9 @@
 /* fls64() is available */
 #undef HAVE_FLS64
 
+/* struct fs_struct uses spinlock_t */
+#undef HAVE_FS_STRUCT_SPINLOCK
+
 /* get_vmalloc_info() is available */
 #undef HAVE_GET_VMALLOC_INFO