]> git.proxmox.com Git - mirror_zfs.git/commitdiff
Add d_clear_d_op() compatibility
authorBrian Behlendorf <behlendorf1@llnl.gov>
Wed, 23 Jan 2013 00:14:43 +0000 (16:14 -0800)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Thu, 24 Jan 2013 00:33:29 +0000 (16:33 -0800)
Added d_clear_d_op() helper function which clears some flags and the
registered dentry->d_op table.  This is required because d_set_d_op()
issues a warning when the dentry operations table is already set.
For the .zfs control directory to work properly we must be able to
override the default operations table and register custom .d_automount
and .d_revalidate callbacks.

Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Ned Bass <bass6@llnl.gov>
Closes #1230

include/linux/dcache_compat.h
module/zfs/zpl_ctldir.c

index 271a0cbef76adfd8bdb72f07363aa0549f7bb3c8..2b9e5c1c405095cd7b11e4ae8a0a953d58557846 100644 (file)
@@ -60,4 +60,24 @@ d_set_d_op(struct dentry *dentry, dentry_operations_t *op)
 }
 #endif /* HAVE_D_SET_D_OP */
 
+/*
+ * 2.6.38 API addition,
+ * Added d_clear_d_op() helper function which clears some flags and the
+ * registered dentry->d_op table.  This is required because d_set_d_op()
+ * issues a warning when the dentry operations table is already set.
+ * For the .zfs control directory to work properly we must be able to
+ * override the default operations table and register custom .d_automount
+ * and .d_revalidate callbacks.
+ */
+static inline void
+d_clear_d_op(struct dentry *dentry)
+{
+#ifdef HAVE_D_SET_D_OP
+       dentry->d_op = NULL;
+       dentry->d_flags &=
+           ~(DCACHE_OP_HASH | DCACHE_OP_COMPARE |
+             DCACHE_OP_REVALIDATE | DCACHE_OP_DELETE);
+#endif /* HAVE_D_SET_D_OP */
+}
+
 #endif /* _ZFS_DCACHE_H */
index 54bdbe409482218752c2ad55ae6573b617002551..08970170760c7f895e835e4009ed0fb721b6c9f7 100644 (file)
@@ -267,6 +267,7 @@ zpl_snapdir_lookup(struct inode *dip, struct dentry *dentry,
                return ERR_PTR(error);
 
        ASSERT(error == 0 || ip == NULL);
+       d_clear_d_op(dentry);
        d_set_d_op(dentry, &zpl_dops_snapdirs);
 
        return d_splice_alias(ip, dentry);
@@ -370,6 +371,7 @@ zpl_snapdir_mkdir(struct inode *dip, struct dentry *dentry, zpl_umode_t mode)
 
        error = -zfsctl_snapdir_mkdir(dip, dname(dentry), vap, &ip, cr, 0);
        if (error == 0) {
+               d_clear_d_op(dentry);
                d_set_d_op(dentry, &zpl_dops_snapdirs);
                d_instantiate(dentry, ip);
        }