mirror of
https://github.com/XTXMarkets/ternfs.git
synced 2025-12-19 09:40:05 -06:00
kmod: force update attributes before updating atime
This commit is contained in:
committed by
GitHub Enterprise
parent
575314956c
commit
4d1d24cc45
@@ -16,7 +16,7 @@ int eggsfs_dir_readdir_entry_cb(void* ptr, u64 name_hash, const char* name, int
|
||||
void eggsfs_dir_drop_cache(struct eggsfs_inode* enode);
|
||||
|
||||
static inline int eggsfs_dir_revalidate(struct eggsfs_inode* enode) {
|
||||
return eggsfs_do_getattr(enode, true);
|
||||
return eggsfs_do_getattr(enode, ATTR_CACHE_DIR_TIMEOUT);
|
||||
}
|
||||
|
||||
static inline int eggsfs_dir_needs_reval(struct eggsfs_inode* dir, struct dentry* dentry) {
|
||||
|
||||
@@ -84,7 +84,7 @@ static int file_open(struct inode* inode, struct file* filp) {
|
||||
// we might have cached data and another client updated atime.
|
||||
// eggsfs_do_getattr is orders of magnitude cheaper than eggsfs_shard_set_time,
|
||||
// so we might as well refresh and re-check
|
||||
int err = eggsfs_do_getattr(enode, false);
|
||||
int err = eggsfs_do_getattr(enode, ATTR_CACHE_NO_TIMEOUT);
|
||||
if (err) {
|
||||
inode_unlock(inode);
|
||||
return err;
|
||||
@@ -945,7 +945,7 @@ static ssize_t file_read_iter(struct kiocb* iocb, struct iov_iter* to) {
|
||||
if (unlikely(iocb->ki_flags & IOCB_DIRECT)) { return -ENOSYS; }
|
||||
|
||||
// make sure we have size information
|
||||
int err = eggsfs_do_getattr(enode, false);
|
||||
int err = eggsfs_do_getattr(enode, ATTR_CACHE_NORM_TIMEOUT);
|
||||
if (err) { return err; }
|
||||
|
||||
// Three-level loop:
|
||||
@@ -1104,7 +1104,7 @@ char* eggsfs_read_link(struct eggsfs_inode* enode) {
|
||||
BUG_ON(eggsfs_inode_type(enode->inode.i_ino) != EGGSFS_INODE_SYMLINK);
|
||||
|
||||
// make sure we have size information
|
||||
int err = eggsfs_do_getattr(enode, false);
|
||||
int err = eggsfs_do_getattr(enode, ATTR_CACHE_NORM_TIMEOUT);
|
||||
if (err) { return ERR_PTR(err); }
|
||||
|
||||
BUG_ON(enode->inode.i_size > PAGE_SIZE); // for simplicity...
|
||||
@@ -1163,7 +1163,7 @@ static loff_t file_lseek(struct file *file, loff_t offset, int whence) {
|
||||
|
||||
if (likely(smp_load_acquire(&enode->file.status) == EGGSFS_FILE_STATUS_READING)) {
|
||||
// make sure we have size information
|
||||
int err = eggsfs_do_getattr(enode, false);
|
||||
int err = eggsfs_do_getattr(enode, ATTR_CACHE_NORM_TIMEOUT);
|
||||
if (err) { return err; }
|
||||
return generic_file_llseek(file, offset, whence);
|
||||
}
|
||||
|
||||
20
kmod/inode.c
20
kmod/inode.c
@@ -214,7 +214,7 @@ static void getattr_async_complete(struct work_struct* work) {
|
||||
iput(&enode->inode);
|
||||
}
|
||||
|
||||
int eggsfs_do_getattr(struct eggsfs_inode* enode, bool for_dir_revalidation) {
|
||||
int eggsfs_do_getattr(struct eggsfs_inode* enode, int cache_timeout_type) {
|
||||
int err;
|
||||
s64 seqno;
|
||||
|
||||
@@ -229,11 +229,19 @@ int eggsfs_do_getattr(struct eggsfs_inode* enode, bool for_dir_revalidation) {
|
||||
|
||||
if (eggsfs_latch_try_acquire(&enode->getattr_update_latch, seqno)) {
|
||||
u64 ts = get_jiffies_64();
|
||||
if (for_dir_revalidation) {
|
||||
switch (cache_timeout_type) {
|
||||
case ATTR_CACHE_NORM_TIMEOUT:
|
||||
if (smp_load_acquire(&enode->getattr_expiry) > ts) { err = 0; goto out; }
|
||||
break;
|
||||
case ATTR_CACHE_DIR_TIMEOUT:
|
||||
BUG_ON(!S_ISDIR(enode->inode.i_mode));
|
||||
if (smp_load_acquire(&enode->dir.mtime_expiry) > ts) { err = 0; goto out; }
|
||||
} else {
|
||||
if (smp_load_acquire(&enode->getattr_expiry) > ts) { err = 0; goto out; }
|
||||
break;
|
||||
case ATTR_CACHE_NO_TIMEOUT:
|
||||
break;
|
||||
default:
|
||||
eggsfs_error("unknown cache timeout type %d", cache_timeout_type);
|
||||
BUG();
|
||||
}
|
||||
|
||||
u64 mtime;
|
||||
@@ -271,7 +279,7 @@ int eggsfs_do_getattr(struct eggsfs_inode* enode, bool for_dir_revalidation) {
|
||||
eggsfs_debug("updating getattr for reading file");
|
||||
u64 size;
|
||||
err = eggsfs_shard_getattr_file(
|
||||
(struct eggsfs_fs_info*)enode->inode.i_sb->s_fs_info,
|
||||
(struct eggsfs_fs_info*)enode->inode.i_sb->s_fs_info,
|
||||
enode->inode.i_ino,
|
||||
&mtime,
|
||||
&atime,
|
||||
@@ -416,7 +424,7 @@ static int eggsfs_getattr(const struct path* path, struct kstat* stat, u32 reque
|
||||
|
||||
// dentry refcount also protects the inode (e.g. d_delete will not turn used dentry into a negative one),
|
||||
// so no need to grab anything before we start waiting for stuff
|
||||
err = eggsfs_do_getattr(enode, false);
|
||||
err = eggsfs_do_getattr(enode, ATTR_CACHE_NORM_TIMEOUT);
|
||||
if (err) {
|
||||
trace_eggsfs_vfs_getattr_exit(inode, err);
|
||||
return err;
|
||||
|
||||
@@ -222,7 +222,8 @@ void eggsfs_inode_evict(struct inode* inode);
|
||||
void eggsfs_inode_free(struct inode* inode);
|
||||
|
||||
// inode ops
|
||||
int eggsfs_do_getattr(struct eggsfs_inode* enode, bool for_dir_revalidation);
|
||||
enum { ATTR_CACHE_NORM_TIMEOUT, ATTR_CACHE_DIR_TIMEOUT, ATTR_CACHE_NO_TIMEOUT };
|
||||
int eggsfs_do_getattr(struct eggsfs_inode* enode, int cache_timeout_type);
|
||||
// 0: not started
|
||||
// 1: started
|
||||
// -n: error
|
||||
|
||||
@@ -580,7 +580,7 @@ static struct dentry* eggsfs_mount(struct file_system_type* fs_type, int flags,
|
||||
|
||||
struct eggsfs_inode* root_enode = EGGSFS_I(root);
|
||||
|
||||
err = eggsfs_do_getattr(root_enode, false);
|
||||
err = eggsfs_do_getattr(root_enode, ATTR_CACHE_NORM_TIMEOUT);
|
||||
if (err) { goto out_sb; }
|
||||
|
||||
if (!root_enode->block_policy || !root_enode->span_policy || !root_enode->stripe_policy) {
|
||||
|
||||
Reference in New Issue
Block a user