Use sb->s_d_op default dentry operations
authorBrian Behlendorf <behlendorf1@llnl.gov>
Fri, 18 Jan 2013 22:11:40 +0000 (14:11 -0800)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Fri, 18 Jan 2013 23:04:23 +0000 (15:04 -0800)
As of Linux 2.6.37 the right way to register custom dentry
operations is to use the super block's ->s_d_op field.
For older kernels they should be registered as part of the
lookup operation.

Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #1223

config/kernel-dentry-operations.m4
config/kernel.m4
module/zfs/zfs_vfsops.c
module/zfs/zpl_inode.c

index 5685b7d..dfbea7d 100644 (file)
@@ -62,3 +62,22 @@ AC_DEFUN([ZFS_AC_KERNEL_D_SET_D_OP],
                AC_MSG_RESULT(no)
        ])
 ])
+
+dnl #
+dnl # 2.6.38 API chage
+dnl # Added sb->s_d_op default dentry_operations member
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_S_D_OP],
+       [AC_MSG_CHECKING([whether super_block has s_d_op])
+       ZFS_LINUX_TRY_COMPILE([
+               #include <linux/fs.h>
+       ],[
+               struct super_block sb __attribute__ ((unused));
+               sb.s_d_op = NULL;
+       ], [
+               AC_MSG_RESULT(yes)
+               AC_DEFINE(HAVE_S_D_OP, 1, [struct super_block has s_d_op])
+       ], [
+               AC_MSG_RESULT(no)
+       ])
+])
index 58a8080..fd6ab1f 100644 (file)
@@ -71,6 +71,7 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [
        ZFS_AC_KERNEL_CALLBACK_SECURITY_INODE_INIT_SECURITY
        ZFS_AC_KERNEL_MOUNT_NODEV
        ZFS_AC_KERNEL_SHRINK
+       ZFS_AC_KERNEL_S_D_OP
        ZFS_AC_KERNEL_BDI
        ZFS_AC_KERNEL_BDI_SETUP_AND_REGISTER
        ZFS_AC_KERNEL_SET_NLINK
index f445242..620e39b 100644 (file)
@@ -1188,6 +1188,9 @@ zfs_domount(struct super_block *sb, void *data, int silent)
        sb->s_op = &zpl_super_operations;
        sb->s_xattr = zpl_xattr_handlers;
        sb->s_export_op = &zpl_export_operations;
+#ifdef HAVE_S_D_OP
+       sb->s_d_op = &zpl_dentry_operations;
+#endif /* HAVE_S_D_OP */
 
        /* Set features for file system. */
        zfs_set_fuid_feature(zsb);
index 15ee0f6..0f6f3a4 100644 (file)
@@ -48,6 +48,9 @@ zpl_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
 
        spin_lock(&dentry->d_lock);
        dentry->d_time = jiffies;
+#ifndef HAVE_S_D_OP
+       d_set_d_op(dentry, &zpl_dentry_operations);
+#endif /* HAVE_S_D_OP */
        spin_unlock(&dentry->d_lock);
 
        if (error) {
@@ -99,7 +102,6 @@ zpl_create(struct inode *dir, struct dentry *dentry, zpl_umode_t mode,
                error = zpl_xattr_security_init(ip, dir, &dentry->d_name);
                VERIFY3S(error, ==, 0);
                d_instantiate(dentry, ip);
-               d_set_d_op(dentry, &zpl_dentry_operations);
        }
 
        kmem_free(vap, sizeof(vattr_t));
@@ -131,10 +133,8 @@ zpl_mknod(struct inode *dir, struct dentry *dentry, zpl_umode_t mode,
        vap->va_rdev = rdev;
 
        error = -zfs_create(dir, dname(dentry), vap, 0, mode, &ip, cr, 0, NULL);
-       if (error == 0) {
+       if (error == 0)
                d_instantiate(dentry, ip);
-               d_set_d_op(dentry, &zpl_dentry_operations);
-       }
 
        kmem_free(vap, sizeof(vattr_t));
        crfree(cr);
@@ -170,10 +170,8 @@ zpl_mkdir(struct inode *dir, struct dentry *dentry, zpl_umode_t mode)
        zpl_vap_init(vap, dir, mode | S_IFDIR, cr);
 
        error = -zfs_mkdir(dir, dname(dentry), vap, &ip, cr, 0, NULL);
-       if (error == 0) {
+       if (error == 0)
                d_instantiate(dentry, ip);
-               d_set_d_op(dentry, &zpl_dentry_operations);
-       }
 
        kmem_free(vap, sizeof(vattr_t));
        crfree(cr);
@@ -278,10 +276,8 @@ zpl_symlink(struct inode *dir, struct dentry *dentry, const char *name)
        zpl_vap_init(vap, dir, S_IFLNK | S_IRWXUGO, cr);
 
        error = -zfs_symlink(dir, dname(dentry), vap, (char *)name, &ip, cr, 0);
-       if (error == 0) {
+       if (error == 0)
                d_instantiate(dentry, ip);
-               d_set_d_op(dentry, &zpl_dentry_operations);
-       }
 
        kmem_free(vap, sizeof(vattr_t));
        crfree(cr);
@@ -352,7 +348,6 @@ zpl_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
        }
 
        d_instantiate(dentry, ip);
-       d_set_d_op(dentry, &zpl_dentry_operations);
 out:
        crfree(cr);
        ASSERT3S(error, <=, 0);