mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 02:27:36 +03:00
Partially revert 5a6ac4c
Reinstate the zpl_revalidate() functionality to resolve a regression where dentries for open files during a rollback are not invalidated. The unrelated functionality for automatically unmounting .zfs/snapshots was not reverted. Nor was the addition of shrink_dcache_sb() to the zfs_resume_fs() function. This issue was not immediately caught by the CI because the test case intended to catch it was included in the list of ZTS tests which may occasionally fail for unrelated reasons. Remove all of the rollback tests from this list to help identify the frequency of any spurious failures. The rollback_003_pos.ksh test case exposes a real issue with the long standing code which needs to be investigated. Regardless, it has been enable with a small workaround in the test case itself. Reviewed-by: Matt Ahrens <matt@delphix.com> Reviewed-by: Pavel Snajdr <snajpa@snajpa.net> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes #9587 Closes #9592
This commit is contained in:
@@ -1926,6 +1926,7 @@ 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;
|
||||
sb->s_d_op = &zpl_dentry_operations;
|
||||
|
||||
/* Set features for file system. */
|
||||
zfs_set_fuid_feature(zfsvfs);
|
||||
|
||||
@@ -602,6 +602,46 @@ out:
|
||||
return (error);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
/*
|
||||
* 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,
|
||||
@@ -690,3 +730,7 @@ const struct inode_operations zpl_special_inode_operations = {
|
||||
.get_acl = zpl_get_acl,
|
||||
#endif /* CONFIG_FS_POSIX_ACL */
|
||||
};
|
||||
|
||||
dentry_operations_t zpl_dentry_operations = {
|
||||
.d_revalidate = zpl_revalidate,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user