mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-01-25 10:12:13 +03:00
Linux 6.17: d_set_d_op() is no longer available
We only have extremely narrow uses, so move it all into a single function that does only what we need, with and without d_set_d_op(). Sponsored-by: https://despairlabs.com/sponsor/ Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed-by: Tony Hutter <hutter2@llnl.gov> Signed-off-by: Rob Norris <robn@despairlabs.com> Closes #17621
This commit is contained in:
parent
f3421697d0
commit
7d7ae8979a
@ -24,6 +24,9 @@ dnl #
|
|||||||
dnl # 2.6.38 API change
|
dnl # 2.6.38 API change
|
||||||
dnl # Added d_set_d_op() helper function.
|
dnl # Added d_set_d_op() helper function.
|
||||||
dnl #
|
dnl #
|
||||||
|
dnl # 6.17 API change
|
||||||
|
dnl # d_set_d_op() removed. No direct replacement.
|
||||||
|
dnl #
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_D_SET_D_OP], [
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_D_SET_D_OP], [
|
||||||
ZFS_LINUX_TEST_SRC([d_set_d_op], [
|
ZFS_LINUX_TEST_SRC([d_set_d_op], [
|
||||||
#include <linux/dcache.h>
|
#include <linux/dcache.h>
|
||||||
@ -34,11 +37,12 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_D_SET_D_OP], [
|
|||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_D_SET_D_OP], [
|
AC_DEFUN([ZFS_AC_KERNEL_D_SET_D_OP], [
|
||||||
AC_MSG_CHECKING([whether d_set_d_op() is available])
|
AC_MSG_CHECKING([whether d_set_d_op() is available])
|
||||||
ZFS_LINUX_TEST_RESULT_SYMBOL([d_set_d_op],
|
ZFS_LINUX_TEST_RESULT([d_set_d_op], [
|
||||||
[d_set_d_op], [fs/dcache.c], [
|
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_D_SET_D_OP, 1,
|
||||||
|
[Define if d_set_d_op() is available])
|
||||||
], [
|
], [
|
||||||
ZFS_LINUX_TEST_ERROR([d_set_d_op])
|
AC_MSG_RESULT(no)
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|||||||
@ -59,32 +59,6 @@
|
|||||||
} while (0)
|
} while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
|
||||||
* 2.6.30 API change,
|
|
||||||
* The const keyword was added to the 'struct dentry_operations' in
|
|
||||||
* the dentry structure. To handle this we define an appropriate
|
|
||||||
* dentry_operations_t typedef which can be used.
|
|
||||||
*/
|
|
||||||
typedef const struct dentry_operations dentry_operations_t;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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)
|
|
||||||
{
|
|
||||||
dentry->d_op = NULL;
|
|
||||||
dentry->d_flags &= ~(
|
|
||||||
DCACHE_OP_HASH | DCACHE_OP_COMPARE |
|
|
||||||
DCACHE_OP_REVALIDATE | DCACHE_OP_DELETE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Walk and invalidate all dentry aliases of an inode
|
* Walk and invalidate all dentry aliases of an inode
|
||||||
* unless it's a mountpoint
|
* unless it's a mountpoint
|
||||||
|
|||||||
@ -197,7 +197,7 @@ zpl_snapdir_revalidate(struct dentry *dentry, unsigned int flags)
|
|||||||
return (!!dentry->d_inode);
|
return (!!dentry->d_inode);
|
||||||
}
|
}
|
||||||
|
|
||||||
static dentry_operations_t zpl_dops_snapdirs = {
|
static const struct dentry_operations zpl_dops_snapdirs = {
|
||||||
/*
|
/*
|
||||||
* Auto mounting of snapshots is only supported for 2.6.37 and
|
* Auto mounting of snapshots is only supported for 2.6.37 and
|
||||||
* newer kernels. Prior to this kernel the ops->follow_link()
|
* newer kernels. Prior to this kernel the ops->follow_link()
|
||||||
@ -210,6 +210,51 @@ static dentry_operations_t zpl_dops_snapdirs = {
|
|||||||
.d_revalidate = zpl_snapdir_revalidate,
|
.d_revalidate = zpl_snapdir_revalidate,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 void
|
||||||
|
set_snapdir_dentry_ops(struct dentry *dentry, unsigned int extraflags) {
|
||||||
|
static const unsigned int op_flags =
|
||||||
|
DCACHE_OP_HASH | DCACHE_OP_COMPARE |
|
||||||
|
DCACHE_OP_REVALIDATE | DCACHE_OP_DELETE |
|
||||||
|
DCACHE_OP_PRUNE | DCACHE_OP_WEAK_REVALIDATE | DCACHE_OP_REAL;
|
||||||
|
|
||||||
|
#ifdef HAVE_D_SET_D_OP
|
||||||
|
/*
|
||||||
|
* d_set_d_op() will set the DCACHE_OP_ flags according to what it
|
||||||
|
* finds in the passed dentry_operations, so we don't have to.
|
||||||
|
*
|
||||||
|
* We clear the flags and the old op table before calling d_set_d_op()
|
||||||
|
* because issues a warning when the dentry operations table is already
|
||||||
|
* set.
|
||||||
|
*/
|
||||||
|
dentry->d_op = NULL;
|
||||||
|
dentry->d_flags &= ~op_flags;
|
||||||
|
d_set_d_op(dentry, &zpl_dops_snapdirs);
|
||||||
|
dentry->d_flags |= extraflags;
|
||||||
|
#else
|
||||||
|
/*
|
||||||
|
* Since 6.17 there's no exported way to modify dentry ops, so we have
|
||||||
|
* to reach in and do it ourselves. This should be safe for our very
|
||||||
|
* narrow use case, which is to create or splice in an entry to give
|
||||||
|
* access to a snapshot.
|
||||||
|
*
|
||||||
|
* We need to set the op flags directly. We hardcode
|
||||||
|
* DCACHE_OP_REVALIDATE because that's the only operation we have; if
|
||||||
|
* we ever extend zpl_dops_snapdirs we will need to update the op flags
|
||||||
|
* to match.
|
||||||
|
*/
|
||||||
|
spin_lock(&dentry->d_lock);
|
||||||
|
dentry->d_op = &zpl_dops_snapdirs;
|
||||||
|
dentry->d_flags &= ~op_flags;
|
||||||
|
dentry->d_flags |= DCACHE_OP_REVALIDATE | extraflags;
|
||||||
|
spin_unlock(&dentry->d_lock);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static struct dentry *
|
static struct dentry *
|
||||||
zpl_snapdir_lookup(struct inode *dip, struct dentry *dentry,
|
zpl_snapdir_lookup(struct inode *dip, struct dentry *dentry,
|
||||||
unsigned int flags)
|
unsigned int flags)
|
||||||
@ -231,10 +276,7 @@ zpl_snapdir_lookup(struct inode *dip, struct dentry *dentry,
|
|||||||
return (ERR_PTR(error));
|
return (ERR_PTR(error));
|
||||||
|
|
||||||
ASSERT(error == 0 || ip == NULL);
|
ASSERT(error == 0 || ip == NULL);
|
||||||
d_clear_d_op(dentry);
|
set_snapdir_dentry_ops(dentry, DCACHE_NEED_AUTOMOUNT);
|
||||||
d_set_d_op(dentry, &zpl_dops_snapdirs);
|
|
||||||
dentry->d_flags |= DCACHE_NEED_AUTOMOUNT;
|
|
||||||
|
|
||||||
return (d_splice_alias(ip, dentry));
|
return (d_splice_alias(ip, dentry));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -368,8 +410,7 @@ zpl_snapdir_mkdir(struct inode *dip, struct dentry *dentry, umode_t mode)
|
|||||||
|
|
||||||
error = -zfsctl_snapdir_mkdir(dip, dname(dentry), vap, &ip, cr, 0);
|
error = -zfsctl_snapdir_mkdir(dip, dname(dentry), vap, &ip, cr, 0);
|
||||||
if (error == 0) {
|
if (error == 0) {
|
||||||
d_clear_d_op(dentry);
|
set_snapdir_dentry_ops(dentry, 0);
|
||||||
d_set_d_op(dentry, &zpl_dops_snapdirs);
|
|
||||||
d_instantiate(dentry, ip);
|
d_instantiate(dentry, ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user