kmod: dont revalidate past fs boundary

This commit is contained in:
Miroslav Crnic
2025-10-05 19:19:05 +01:00
committed by GitHub
parent 3aff31a026
commit bad26576a8

View File

@@ -21,20 +21,30 @@ static inline int ternfs_dir_needs_reval(struct ternfs_inode* dir, struct dentry
u64 dentry_dir_mtime = dentry->d_time; u64 dentry_dir_mtime = dentry->d_time;
int ret; int ret;
u64 t = get_jiffies_64(); u64 t = get_jiffies_64();
if (dentry_dir_mtime != dir->mtime) { if (t >= dir->dir.mtime_expiry) { ret = -ECHILD; }
if (dentry->d_inode == NULL || !S_ISDIR(dentry->d_inode->i_mode)) { ret = 0; } else if (dentry_dir_mtime != dir->mtime) {
struct inode* inode;
if (in_rcu) {
inode = d_inode_rcu(dentry);
} else {
inode = dentry->d_inode;
}
// We are fine invalidating negative or dentries for non-directories
// as this is not expensive
if (inode == NULL || !S_ISDIR(inode->i_mode)) { ret = 0; }
// we want to confirm we are still valid but we need to do lookup
// so we need to drop into non-rcu mode
else if (in_rcu) { ret = -ECHILD; } else if (in_rcu) { ret = -ECHILD; }
else { else {
u64 ino, creation_time; u64 ino, creation_time;
if (ternfs_shard_lookup( if (ternfs_shard_lookup(
dir->inode.i_sb->s_fs_info, dir->inode.i_ino, inode->i_sb->s_fs_info, dir->inode.i_ino,
dentry->d_name.name, dentry->d_name.len, dentry->d_name.name, dentry->d_name.len,
&ino, &creation_time) < 0) &ino, &creation_time) < 0)
{ {
ret = 0; ret = 0;
} else { } else {
if (dentry->d_inode->i_ino != ino) { if (inode->i_ino != ino) {
ret = 0; ret = 0;
} else { } else {
dentry->d_time = dir->mtime; dentry->d_time = dir->mtime;
@@ -43,7 +53,6 @@ static inline int ternfs_dir_needs_reval(struct ternfs_inode* dir, struct dentry
} }
} }
} }
else if (t >= dir->dir.mtime_expiry) { ret = -ECHILD; }
else { ret = 1; } else { ret = 1; }
ternfs_debug( ternfs_debug(
@@ -71,6 +80,9 @@ static int ternfs_d_revalidate(struct dentry* dentry, unsigned int flags) {
parent = READ_ONCE(dentry->d_parent); parent = READ_ONCE(dentry->d_parent);
dir = d_inode_rcu(parent); dir = d_inode_rcu(parent);
if (!dir) { return -ECHILD; } if (!dir) { return -ECHILD; }
// we are either asked for validiti of our root dentry or we are bound mounted
// either way we can't return invalid
if (parent->d_sb != dentry->d_sb) { return 1; }
ret = ternfs_dir_needs_reval(TERNFS_I(dir), dentry, true); ret = ternfs_dir_needs_reval(TERNFS_I(dir), dentry, true);
if (parent != READ_ONCE(dentry->d_parent)) { return -ECHILD; } if (parent != READ_ONCE(dentry->d_parent)) { return -ECHILD; }
return ret; return ret;