diff options
author | Pavel Snajdr <[email protected]> | 2019-12-05 01:52:27 +0100 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2022-10-28 09:47:19 -0700 |
commit | 86db35c447aa3f4cc848497d78d54ec9c985d1ed (patch) | |
tree | 5303b586298436d9be2d4471189096f8fdc4f196 /include | |
parent | e09fdda9775d47078a9dff9d958faf25cf8ca9e8 (diff) |
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 <[email protected]>
Reviewed-by: Alexander Motin <[email protected]>
Reviewed-by: Brian Behlendorf <[email protected]>
Signed-off-by: Pavel Snajdr <[email protected]>
Closes #9600
Closes #14070
Diffstat (limited to 'include')
-rw-r--r-- | include/os/linux/kernel/linux/dcache_compat.h | 21 | ||||
-rw-r--r-- | include/os/linux/zfs/sys/trace_acl.h | 9 | ||||
-rw-r--r-- | include/os/linux/zfs/sys/zpl.h | 3 | ||||
-rw-r--r-- | include/sys/zfs_znode.h | 1 |
4 files changed, 26 insertions, 8 deletions
diff --git a/include/os/linux/kernel/linux/dcache_compat.h b/include/os/linux/kernel/linux/dcache_compat.h index 0fbd92458..4de1118da 100644 --- a/include/os/linux/kernel/linux/dcache_compat.h +++ b/include/os/linux/kernel/linux/dcache_compat.h @@ -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 */ diff --git a/include/os/linux/zfs/sys/trace_acl.h b/include/os/linux/zfs/sys/trace_acl.h index 6a73545fe..2c7343222 100644 --- a/include/os/linux/zfs/sys/trace_acl.h +++ b/include/os/linux/zfs/sys/trace_acl.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, diff --git a/include/os/linux/zfs/sys/zpl.h b/include/os/linux/zfs/sys/zpl.h index 30d73db6b..83416d647 100644 --- a/include/os/linux/zfs/sys/zpl.h +++ b/include/os/linux/zfs/sys/zpl.h @@ -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; diff --git a/include/sys/zfs_znode.h b/include/sys/zfs_znode.h index 7c906050b..c8656b3f6 100644 --- a/include/sys/zfs_znode.h +++ b/include/sys/zfs_znode.h @@ -190,7 +190,6 @@ typedef struct znode { boolean_t z_is_sa; /* are we native sa? */ boolean_t z_is_mapped; /* are we mmap'ed */ boolean_t z_is_ctldir; /* are we .zfs entry */ - boolean_t z_is_stale; /* are we stale due to rollback? */ boolean_t z_suspended; /* extra ref from a suspend? */ uint_t z_blksz; /* block size in bytes */ uint_t z_seq; /* modification sequence number */ |