From a0ffc0bf6e299809a09fe39414a8a359be1b67ac Mon Sep 17 00:00:00 2001 From: Pavel Snajdr Date: Tue, 24 Sep 2019 03:39:48 +0200 Subject: [PATCH] Remove zpl_revalidate Fixes zfsonlinux/zfs#8774 --- include/os/linux/zfs/sys/zfs_vfsops.h | 1 + include/os/linux/zfs/sys/zpl.h | 1 - include/sys/zfs_znode.h | 17 +++++++- module/os/linux/zfs/zfs_vfsops.c | 16 +++++-- module/os/linux/zfs/zpl_inode.c | 60 --------------------------- 5 files changed, 30 insertions(+), 65 deletions(-) diff --git a/include/os/linux/zfs/sys/zfs_vfsops.h b/include/os/linux/zfs/sys/zfs_vfsops.h index c288a2dce999..25b275a0bc57 100644 --- a/include/os/linux/zfs/sys/zfs_vfsops.h +++ b/include/os/linux/zfs/sys/zfs_vfsops.h @@ -219,6 +219,7 @@ extern int zfsvfs_create(const char *name, boolean_t readony, zfsvfs_t **zfvp); extern int zfsvfs_create_impl(zfsvfs_t **zfvp, zfsvfs_t *zfsvfs, objset_t *os); extern void zfsvfs_free(zfsvfs_t *zfsvfs); extern int zfs_check_global_label(const char *dsname, const char *hexsl); +extern void zfs_defer_snap_umount(zfsvfs_t *zfsvfs); extern boolean_t zfs_is_readonly(zfsvfs_t *zfsvfs); extern int zfs_domount(struct super_block *sb, zfs_mnt_t *zm, int silent); diff --git a/include/os/linux/zfs/sys/zpl.h b/include/os/linux/zfs/sys/zpl.h index 2766269f31c8..01f0f6f38c6e 100644 --- a/include/os/linux/zfs/sys/zpl.h +++ b/include/os/linux/zfs/sys/zpl.h @@ -45,7 +45,6 @@ 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; -extern dentry_operations_t zpl_dentry_operations; /* zpl_file.c */ extern ssize_t zpl_read_common(struct inode *ip, const char *buf, diff --git a/include/sys/zfs_znode.h b/include/sys/zfs_znode.h index acaaf28845e6..d748d43367a6 100644 --- a/include/sys/zfs_znode.h +++ b/include/sys/zfs_znode.h @@ -272,11 +272,26 @@ do { \ #define ZFS_ENTER(zfsvfs) ZFS_ENTER_ERROR(zfsvfs, EIO) #define ZPL_ENTER(zfsvfs) ZFS_ENTER_ERROR(zfsvfs, -EIO) -/* Must be called before exiting the operation. */ +/* Must be called before exiting the vop + * + */ +#ifdef __linux_ +/* + * Automounted snapshots rely on periodic revalidation + * to defer snapshots from being automatically unmounted. + */ +#define ZFS_EXIT(zfsvfs) \ +do { \ + if (unlikely(zfsvfs->z_issnap)) \ + zfs_defer_snap_umount(zfsvfs); \ + rrm_exit(&(zfsvfs)->z_teardown_lock, FTAG); \ +} while (0) +#else #define ZFS_EXIT(zfsvfs) \ do { \ rrm_exit(&(zfsvfs)->z_teardown_lock, FTAG); \ } while (0) +#endif #define ZPL_EXIT(zfsvfs) ZFS_EXIT(zfsvfs) /* Verifies the znode is valid. */ diff --git a/module/os/linux/zfs/zfs_vfsops.c b/module/os/linux/zfs/zfs_vfsops.c index 9d846f474b48..5af5a9329b61 100644 --- a/module/os/linux/zfs/zfs_vfsops.c +++ b/module/os/linux/zfs/zfs_vfsops.c @@ -1813,6 +1813,18 @@ zfsvfs_teardown(zfsvfs_t *zfsvfs, boolean_t unmounting) atomic_long_t zfs_bdi_seq = ATOMIC_LONG_INIT(0); #endif +void +zfs_defer_snap_umount(zfsvfs_t *zfsvfs) +{ + if (time_after(jiffies, zfsvfs->z_snap_defer_time + + MAX(zfs_expire_snapshot * HZ / 2, HZ))) { + zfsvfs->z_snap_defer_time = jiffies; + zfsctl_snapshot_unmount_delay(zfsvfs->z_os->os_spa, + dmu_objset_id(zfsvfs->z_os), + zfs_expire_snapshot); + } +} + int zfs_domount(struct super_block *sb, zfs_mnt_t *zm, int silent) { @@ -1862,9 +1874,6 @@ 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; -#ifdef HAVE_S_D_OP - sb->s_d_op = &zpl_dentry_operations; -#endif /* HAVE_S_D_OP */ /* Set features for file system. */ zfs_set_fuid_feature(zfsvfs); @@ -2234,6 +2243,7 @@ zfs_resume_fs(zfsvfs_t *zfsvfs, dsl_dataset_t *ds) zfs_unlinked_drain(zfsvfs); } + shrink_dcache_sb(zfsvfs->z_parent->z_sb); bail: if (err != 0) zfsvfs->z_unmounted = B_TRUE; diff --git a/module/os/linux/zfs/zpl_inode.c b/module/os/linux/zfs/zpl_inode.c index 3f3b2e2dc53c..4c628f60898c 100644 --- a/module/os/linux/zfs/zpl_inode.c +++ b/module/os/linux/zfs/zpl_inode.c @@ -70,9 +70,6 @@ zpl_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) spin_lock(&dentry->d_lock); dentry->d_time = jiffies; -#ifndef HAVE_S_D_OP - d_set_d_op(dentry, &zpl_dentry_operations); -#endif /* HAVE_S_D_OP */ spin_unlock(&dentry->d_lock); if (error) { @@ -655,59 +652,6 @@ zpl_fallocate(struct inode *ip, int mode, loff_t offset, loff_t len) } #endif /* HAVE_INODE_FALLOCATE */ -static int -#ifdef HAVE_D_REVALIDATE_NAMEIDATA -zpl_revalidate(struct dentry *dentry, struct nameidata *nd) -{ - unsigned int flags = (nd ? nd->flags : 0); -#else -zpl_revalidate(struct dentry *dentry, unsigned int flags) -{ -#endif /* HAVE_D_REVALIDATE_NAMEIDATA */ - /* CSTYLED */ - zfsvfs_t *zfsvfs = dentry->d_sb->s_fs_info; - int error; - - if (flags & LOOKUP_RCU) - return (-ECHILD); - - /* - * Automounted snapshots rely on periodic dentry revalidation - * to defer snapshots from being automatically unmounted. - */ - if (zfsvfs->z_issnap) { - if (time_after(jiffies, zfsvfs->z_snap_defer_time + - MAX(zfs_expire_snapshot * HZ / 2, HZ))) { - zfsvfs->z_snap_defer_time = jiffies; - zfsctl_snapshot_unmount_delay(zfsvfs->z_os->os_spa, - dmu_objset_id(zfsvfs->z_os), zfs_expire_snapshot); - } - } - - /* - * After a rollback negative dentries created before the rollback - * time must be invalidated. Otherwise they can obscure files which - * are only present in the rolled back dataset. - */ - if (dentry->d_inode == NULL) { - spin_lock(&dentry->d_lock); - error = time_before(dentry->d_time, zfsvfs->z_rollback_time); - spin_unlock(&dentry->d_lock); - - if (error) - return (0); - } - - /* - * The dentry may reference a stale inode if a mounted file system - * was rolled back to a point in time where the object didn't exist. - */ - if (dentry->d_inode && ITOZ(dentry->d_inode)->z_is_stale) - return (0); - - return (1); -} - const struct inode_operations zpl_inode_operations = { .setattr = zpl_setattr, .getattr = zpl_getattr, @@ -820,7 +764,3 @@ const struct inode_operations zpl_special_inode_operations = { #endif /* HAVE_GET_ACL | HAVE_CHECK_ACL | HAVE_PERMISSION */ #endif /* CONFIG_FS_POSIX_ACL */ }; - -dentry_operations_t zpl_dentry_operations = { - .d_revalidate = zpl_revalidate, -};