diff --git a/config/kernel-dentry-alias.m4 b/config/kernel-dentry-alias.m4 new file mode 100644 index 000000000000..d06511da8ce5 --- /dev/null +++ b/config/kernel-dentry-alias.m4 @@ -0,0 +1,30 @@ +dnl # +dnl # 3.18 API change +dnl # Dentry aliases are in d_u struct dentry member +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_DENTRY_ALIAS_D_U], [ + ZFS_LINUX_TEST_SRC([dentry_alias_d_u], [ + #include + #include + #include + + void testfn(void) { + hlist_for_each_entry(dentry, &inode->i_dentry, + d_u.d_alias) { + __d_drop(dentry); + } + } + ],[]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_DENTRY_ALIAS_D_U], [ + AC_MSG_CHECKING([whether dentry aliases are in d_u member]) + ZFS_LINUX_TEST_RESULT([dentry_alias_d_u], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_DENTRY_D_U_ALIASES, 1, + [dentry aliases are in d_u member]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + diff --git a/config/kernel.m4 b/config/kernel.m4 index 4309d5456e2c..ffba545896df 100644 --- a/config/kernel.m4 +++ b/config/kernel.m4 @@ -87,6 +87,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [ ZFS_AC_KERNEL_SRC_SETATTR_PREPARE ZFS_AC_KERNEL_SRC_INSERT_INODE_LOCKED ZFS_AC_KERNEL_SRC_DENTRY + ZFS_AC_KERNEL_SRC_DENTRY_ALIAS_D_U ZFS_AC_KERNEL_SRC_TRUNCATE_SETSIZE ZFS_AC_KERNEL_SRC_SECURITY_INODE ZFS_AC_KERNEL_SRC_FST_MOUNT @@ -181,6 +182,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [ ZFS_AC_KERNEL_SETATTR_PREPARE ZFS_AC_KERNEL_INSERT_INODE_LOCKED ZFS_AC_KERNEL_DENTRY + ZFS_AC_KERNEL_DENTRY_ALIAS_D_U ZFS_AC_KERNEL_TRUNCATE_SETSIZE ZFS_AC_KERNEL_SECURITY_INODE ZFS_AC_KERNEL_FST_MOUNT diff --git a/include/os/linux/spl/sys/Makefile.am b/include/os/linux/spl/sys/Makefile.am index e3df4edaeee9..94bcce0f734d 100644 --- a/include/os/linux/spl/sys/Makefile.am +++ b/include/os/linux/spl/sys/Makefile.am @@ -9,6 +9,7 @@ KERNEL_H = \ $(top_srcdir)/include/os/linux/spl/sys/console.h \ $(top_srcdir)/include/os/linux/spl/sys/cred.h \ $(top_srcdir)/include/os/linux/spl/sys/ctype.h \ + $(top_srcdir)/include/os/linux/spl/sys/dcache.h \ $(top_srcdir)/include/os/linux/spl/sys/debug.h \ $(top_srcdir)/include/os/linux/spl/sys/disp.h \ $(top_srcdir)/include/os/linux/spl/sys/dkio.h \ diff --git a/include/os/linux/spl/sys/dcache.h b/include/os/linux/spl/sys/dcache.h new file mode 100644 index 000000000000..8e0aa3fd6fa6 --- /dev/null +++ b/include/os/linux/spl/sys/dcache.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2019 OpenZFS Project + * Written by Pavel Snajdr + * + * This file is part of the SPL, Solaris Porting Layer. + * For details, see . + * + * The SPL is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * The SPL is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with the SPL. If not, see . + */ + +#ifndef _SPL_DCACHE_H +#define _SPL_DCACHE_H + +#include +#include +#include + +extern void spl_d_drop_aliases(struct inode *inode); +#endif /* SPL_DCACHE_H */ diff --git a/include/os/linux/zfs/sys/zpl.h b/include/os/linux/zfs/sys/zpl.h index 20a3dc674988..808e89a3ef0e 100644 --- a/include/os/linux/zfs/sys/zpl.h +++ b/include/os/linux/zfs/sys/zpl.h @@ -45,7 +45,9 @@ extern const struct inode_operations zpl_inode_operations; extern const struct inode_operations zpl_dir_inode_operations; extern const struct inode_operations zpl_symlink_inode_operations; extern const struct inode_operations zpl_special_inode_operations; +#if 0 extern dentry_operations_t zpl_dentry_operations; +#endif /* zpl_file.c */ extern ssize_t zpl_read_common(struct inode *ip, const char *buf, diff --git a/module/os/linux/spl/Makefile.in b/module/os/linux/spl/Makefile.in index 94804bfed4c9..410d2edf4ce1 100644 --- a/module/os/linux/spl/Makefile.in +++ b/module/os/linux/spl/Makefile.in @@ -1,6 +1,7 @@ $(MODULE)-objs += ../os/linux/spl/spl-atomic.o $(MODULE)-objs += ../os/linux/spl/spl-condvar.o $(MODULE)-objs += ../os/linux/spl/spl-cred.o +$(MODULE)-objs += ../os/linux/spl/spl-dcache.o $(MODULE)-objs += ../os/linux/spl/spl-err.o $(MODULE)-objs += ../os/linux/spl/spl-generic.o $(MODULE)-objs += ../os/linux/spl/spl-kmem.o diff --git a/module/os/linux/spl/spl-dcache.c b/module/os/linux/spl/spl-dcache.c new file mode 100644 index 000000000000..12912cb983e9 --- /dev/null +++ b/module/os/linux/spl/spl-dcache.c @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2019 OpenZFS Project + * Written by Pavel Snajdr + * + * This file is part of the SPL, Solaris Porting Layer. + * For details, see . + * + * The SPL is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * The SPL is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with the SPL. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Locklessly walk and invalidate all aliases of an inode; the lockless + * approach assumes the function is only called when z_teardown_lock is + * active or the inode in question is locked. + */ +void +spl_d_drop_aliases(struct inode *inode) +{ + struct dentry *dentry; +#ifdef HAVE_DENTRY_D_U_ALIASES + hlist_for_each_entry(dentry, &inode->i_dentry, d_u.d_alias) { +#else + hlist_for_each_entry(dentry, &inode->i_dentry, d_alias) { +#endif + __d_drop(dentry); + } +} +EXPORT_SYMBOL(spl_d_drop_aliases); diff --git a/module/os/linux/zfs/zfs_vfsops.c b/module/os/linux/zfs/zfs_vfsops.c index 154933a4cc0a..642d2e28d166 100644 --- a/module/os/linux/zfs/zfs_vfsops.c +++ b/module/os/linux/zfs/zfs_vfsops.c @@ -54,6 +54,7 @@ #include #include #include +#include #include #include #include @@ -1926,7 +1927,9 @@ zfs_domount(struct super_block *sb, zfs_mnt_t *zm, int silent) sb->s_op = &zpl_super_operations; sb->s_xattr = zpl_xattr_handlers; sb->s_export_op = &zpl_export_operations; +#if 0 sb->s_d_op = &zpl_dentry_operations; +#endif /* Set features for file system. */ zfs_set_fuid_feature(zfsvfs); @@ -2275,6 +2278,7 @@ zfs_resume_fs(zfsvfs_t *zfsvfs, dsl_dataset_t *ds) zp = list_next(&zfsvfs->z_all_znodes, zp)) { err2 = zfs_rezget(zp); if (err2) { + spl_d_drop_aliases(ZTOI(zp)); remove_inode_hash(ZTOI(zp)); zp->z_is_stale = B_TRUE; } diff --git a/module/os/linux/zfs/zpl_inode.c b/module/os/linux/zfs/zpl_inode.c index 124021166291..56e43893260d 100644 --- a/module/os/linux/zfs/zpl_inode.c +++ b/module/os/linux/zfs/zpl_inode.c @@ -602,6 +602,7 @@ zpl_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry) return (error); } +#if 0 static int #ifdef HAVE_D_REVALIDATE_NAMEIDATA zpl_revalidate(struct dentry *dentry, struct nameidata *nd) @@ -641,6 +642,7 @@ zpl_revalidate(struct dentry *dentry, unsigned int flags) return (1); } +#endif const struct inode_operations zpl_inode_operations = { .setattr = zpl_setattr, @@ -731,6 +733,8 @@ const struct inode_operations zpl_special_inode_operations = { #endif /* CONFIG_FS_POSIX_ACL */ }; +#if 0 dentry_operations_t zpl_dentry_operations = { .d_revalidate = zpl_revalidate, }; +#endif