mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 02:27:36 +03:00
Remove zpl_revalidate: fix snapshot rollback
Open files, which aren't present in the snapshot, which is being roll-backed to, need to disappear from the visible VFS image of the dataset. Kernel provides d_drop function to drop invalid entry from the dcache, but inode can be referenced by dentry multiple dentries. The introduced zpl_d_drop_aliases function walks and invalidates all aliases of an inode. Reviewed-by: Ryan Moeller <ryan@iXsystems.com> Reviewed-by: Alexander Motin <mav@FreeBSD.org> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Pavel Snajdr <snajpa@snajpa.net> Closes #9600 Closes #14070
This commit is contained in:
committed by
Brian Behlendorf
parent
e09fdda977
commit
86db35c447
@@ -61,4 +61,25 @@ d_clear_d_op(struct dentry *dentry)
|
||||
DCACHE_OP_REVALIDATE | DCACHE_OP_DELETE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Walk and invalidate all dentry aliases of an inode
|
||||
* unless it's a mountpoint
|
||||
*/
|
||||
static inline void
|
||||
zpl_d_drop_aliases(struct inode *inode)
|
||||
{
|
||||
struct dentry *dentry;
|
||||
spin_lock(&inode->i_lock);
|
||||
#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
|
||||
if (!IS_ROOT(dentry) && !d_mountpoint(dentry) &&
|
||||
(dentry->d_inode == inode)) {
|
||||
d_drop(dentry);
|
||||
}
|
||||
}
|
||||
spin_unlock(&inode->i_lock);
|
||||
}
|
||||
#endif /* _ZFS_DCACHE_H */
|
||||
|
||||
@@ -64,7 +64,6 @@ DECLARE_EVENT_CLASS(zfs_ace_class,
|
||||
__field(boolean_t, z_is_sa)
|
||||
__field(boolean_t, z_is_mapped)
|
||||
__field(boolean_t, z_is_ctldir)
|
||||
__field(boolean_t, z_is_stale)
|
||||
|
||||
__field(uint32_t, i_uid)
|
||||
__field(uint32_t, i_gid)
|
||||
@@ -99,7 +98,6 @@ DECLARE_EVENT_CLASS(zfs_ace_class,
|
||||
__entry->z_is_sa = zn->z_is_sa;
|
||||
__entry->z_is_mapped = zn->z_is_mapped;
|
||||
__entry->z_is_ctldir = zn->z_is_ctldir;
|
||||
__entry->z_is_stale = zn->z_is_stale;
|
||||
|
||||
__entry->i_uid = KUID_TO_SUID(ZTOI(zn)->i_uid);
|
||||
__entry->i_gid = KGID_TO_SGID(ZTOI(zn)->i_gid);
|
||||
@@ -121,9 +119,8 @@ DECLARE_EVENT_CLASS(zfs_ace_class,
|
||||
"zn_prefetch %u blksz %u seq %u "
|
||||
"mapcnt %llu size %llu pflags %llu "
|
||||
"sync_cnt %u sync_writes_cnt %u async_writes_cnt %u "
|
||||
"mode 0x%x is_sa %d is_mapped %d "
|
||||
"is_ctldir %d is_stale %d inode { "
|
||||
"uid %u gid %u ino %lu nlink %u size %lli "
|
||||
"mode 0x%x is_sa %d is_mapped %d is_ctldir %d "
|
||||
"inode { uid %u gid %u ino %lu nlink %u size %lli "
|
||||
"blkbits %u bytes %u mode 0x%x generation %x } } "
|
||||
"ace { type %u flags %u access_mask %u } mask_matched %u",
|
||||
__entry->z_id, __entry->z_unlinked, __entry->z_atime_dirty,
|
||||
@@ -132,7 +129,7 @@ DECLARE_EVENT_CLASS(zfs_ace_class,
|
||||
__entry->z_pflags, __entry->z_sync_cnt,
|
||||
__entry->z_sync_writes_cnt, __entry->z_async_writes_cnt,
|
||||
__entry->z_mode, __entry->z_is_sa, __entry->z_is_mapped,
|
||||
__entry->z_is_ctldir, __entry->z_is_stale, __entry->i_uid,
|
||||
__entry->z_is_ctldir, __entry->i_uid,
|
||||
__entry->i_gid, __entry->i_ino, __entry->i_nlink,
|
||||
__entry->i_size, __entry->i_blkbits,
|
||||
__entry->i_bytes, __entry->i_mode, __entry->i_generation,
|
||||
|
||||
@@ -45,7 +45,8 @@ 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 const struct address_space_operations zpl_address_space_operations;
|
||||
extern const struct file_operations zpl_file_operations;
|
||||
extern const struct file_operations zpl_dir_file_operations;
|
||||
|
||||
Reference in New Issue
Block a user