summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Behlendorf <[email protected]>2013-01-22 16:14:43 -0800
committerBrian Behlendorf <[email protected]>2013-01-23 16:33:29 -0800
commitbf01b5e6161b4aa94c69792e50de4102a033be09 (patch)
tree22e09aec7a7f4a5bdee391b4e6091334fa4116e9
parent1305d33a4b0f8b10cea61989330cc5d059cfa7cb (diff)
Add d_clear_d_op() compatibility
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 <[email protected]> Signed-off-by: Ned Bass <[email protected]> Closes #1230
-rw-r--r--include/linux/dcache_compat.h20
-rw-r--r--module/zfs/zpl_ctldir.c2
2 files changed, 22 insertions, 0 deletions
diff --git a/include/linux/dcache_compat.h b/include/linux/dcache_compat.h
index 271a0cbef..2b9e5c1c4 100644
--- a/include/linux/dcache_compat.h
+++ b/include/linux/dcache_compat.h
@@ -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 */
diff --git a/module/zfs/zpl_ctldir.c b/module/zfs/zpl_ctldir.c
index 54bdbe409..089701707 100644
--- a/module/zfs/zpl_ctldir.c
+++ b/module/zfs/zpl_ctldir.c
@@ -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);
}