diff options
-rw-r--r-- | include/linux/dcache_compat.h | 20 | ||||
-rw-r--r-- | module/zfs/zpl_ctldir.c | 2 |
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); } |