]> git.proxmox.com Git - mirror_spl.git/commitdiff
Linux 4.7 compat: inode_lock() and friends
authorChunwei Chen <david.chen@osnexus.com>
Wed, 18 May 2016 18:28:46 +0000 (11:28 -0700)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Fri, 20 May 2016 18:00:14 +0000 (11:00 -0700)
Linux 4.7 changes i_mutex to i_rwsem, and we should used inode_lock and
inode_lock_shared to do exclusive and shared lock respectively.

We use spl_inode_lock{,_shared}() to hide the difference. Note that on older
kernel you'll always take an exclusive lock.

We also add all other inode_lock friends. And nested users now should
explicitly call spl_inode_lock_nested with correct subclass.

Signed-off-by: Chunwei Chen <david.chen@osnexus.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Issue zfsonlinux/zfs#4665
Closes #549

config/spl-build.m4
include/linux/file_compat.h
module/spl/spl-vnode.c

index 55453c822e7d5d6d680c87c3029839a8e1682fd0..720506959f0b2789ad4e7f2be68ce130624d8315 100644 (file)
@@ -45,6 +45,7 @@ AC_DEFUN([SPL_AC_CONFIG_KERNEL], [
        SPL_AC_KMEM_CACHE_ALLOCFLAGS
        SPL_AC_WAIT_ON_BIT
        SPL_AC_MUTEX_OWNER
+       SPL_AC_INODE_LOCK
 ])
 
 AC_DEFUN([SPL_AC_MODULE_SYMVERS], [
@@ -1476,3 +1477,27 @@ AC_DEFUN([SPL_AC_MUTEX_OWNER], [
        ])
        EXTRA_KCFLAGS="$tmp_flags"
 ])
+
+dnl #
+dnl # 4.7 API change
+dnl # i_mutex is changed to i_rwsem. Instead of directly using
+dnl # i_mutex/i_rwsem, we should use inode_lock() and inode_lock_shared()
+dnl # We test inode_lock_shared because inode_lock is introduced earlier.
+dnl #
+AC_DEFUN([SPL_AC_INODE_LOCK], [
+       AC_MSG_CHECKING([whether inode_lock_shared() exists])
+       tmp_flags="$EXTRA_KCFLAGS"
+       EXTRA_KCFLAGS="-Werror"
+       SPL_LINUX_TRY_COMPILE([
+               #include <linux/fs.h>
+       ],[
+               struct inode *inode = NULL;
+               inode_lock_shared(inode);
+       ],[
+               AC_MSG_RESULT(yes)
+               AC_DEFINE(HAVE_INODE_LOCK_SHARED, 1, [yes])
+       ],[
+               AC_MSG_RESULT(no)
+       ])
+       EXTRA_KCFLAGS="$tmp_flags"
+])
index c58bb815608bf367a56ca9b81b94669b9e28e048..916514566a23807fcd83ca4431f48ab72151259a 100644 (file)
@@ -76,8 +76,25 @@ spl_filp_fallocate(struct file *fp, int mode, loff_t offset, loff_t len)
 #define        spl_filp_fsync(fp, sync)        vfs_fsync(fp, (fp)->f_dentry, sync)
 #endif /* HAVE_2ARGS_VFS_FSYNC */
 
-#define        spl_inode_lock(ip)              mutex_lock_nested(&(ip)->i_mutex, I_MUTEX_PARENT)
+#ifdef HAVE_INODE_LOCK_SHARED
+#define        spl_inode_lock(ip)              inode_lock(ip)
+#define        spl_inode_unlock(ip)            inode_unlock(ip)
+#define        spl_inode_lock_shared(ip)       inode_lock_shared(ip)
+#define        spl_inode_unlock_shared(ip)     inode_unlock_shared(ip)
+#define        spl_inode_trylock(ip)           inode_trylock(ip)
+#define        spl_inode_trylock_shared(ip)    inode_trylock_shared(ip)
+#define        spl_inode_is_locked(ip)         inode_is_locked(ip)
+#define        spl_inode_lock_nested(ip, s)    inode_lock_nested(ip, s)
+#else
+#define        spl_inode_lock(ip)              mutex_lock(&(ip)->i_mutex)
 #define        spl_inode_unlock(ip)            mutex_unlock(&(ip)->i_mutex)
+#define        spl_inode_lock_shared(ip)       mutex_lock(&(ip)->i_mutex)
+#define        spl_inode_unlock_shared(ip)     mutex_unlock(&(ip)->i_mutex)
+#define        spl_inode_trylock(ip)           mutex_trylock(&(ip)->i_mutex)
+#define        spl_inode_trylock_shared(ip)    mutex_trylock(&(ip)->i_mutex)
+#define        spl_inode_is_locked(ip)         mutex_is_locked(&(ip)->i_mutex)
+#define        spl_inode_lock_nested(ip, s)    mutex_lock_nested(&(ip)->i_mutex, s)
+#endif
 
 #endif /* SPL_FILE_COMPAT_H */
 
index a914e046c206081bea992d382d4dfa57dba9c628..addc611554b66b1b0994cee923d4868e0de0474e 100644 (file)
@@ -352,7 +352,8 @@ spl_kern_path_locked(const char *name, struct path *path)
        if (rc)
                return (ERR_PTR(rc));
 
-       spl_inode_lock(parent.dentry->d_inode);
+       /* use I_MUTEX_PARENT because vfs_unlink needs it */
+       spl_inode_lock_nested(parent.dentry->d_inode, I_MUTEX_PARENT);
 
        dentry = lookup_one_len(basename, parent.dentry, len);
        if (IS_ERR(dentry)) {