From da1af9b8414649047e0653b2c12dea82963e33b9 Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Wed, 24 Mar 2021 11:28:16 -0700 Subject: [PATCH] Add scoutfs inode ino lock coverage Add lock coverage which tracks if the inode has been refreshed and is covered by the inode group cluster lock. This will be used by drop_inode and evict_inode to discover that the inode is current and doesn't need to be refreshed. Signed-off-by: Zach Brown --- kmod/src/inode.c | 6 ++++++ kmod/src/inode.h | 2 ++ kmod/src/lock.c | 23 ++++++++++++++--------- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/kmod/src/inode.c b/kmod/src/inode.c index 42761a3f..e0e11e59 100644 --- a/kmod/src/inode.c +++ b/kmod/src/inode.c @@ -82,6 +82,7 @@ static void scoutfs_inode_ctor(void *obj) init_waitqueue_head(&si->data_waitq.waitq); init_rwsem(&si->xattr_rwsem); RB_CLEAR_NODE(&si->writeback_node); + scoutfs_lock_init_coverage(&si->ino_lock_cov); inode_init_once(&si->inode); } @@ -141,12 +142,15 @@ static void remove_writeback_inode(struct inode_sb_info *inf, void scoutfs_destroy_inode(struct inode *inode) { + struct scoutfs_inode_info *si = SCOUTFS_I(inode); DECLARE_INODE_SB_INFO(inode->i_sb, inf); spin_lock(&inf->writeback_lock); remove_writeback_inode(inf, SCOUTFS_I(inode)); spin_unlock(&inf->writeback_lock); + scoutfs_lock_del_coverage(inode->i_sb, &si->ino_lock_cov); + call_rcu(&inode->i_rcu, scoutfs_i_callback); } @@ -307,6 +311,7 @@ int scoutfs_inode_refresh(struct inode *inode, struct scoutfs_lock *lock, if (ret == 0) { load_inode(inode, &sinode); atomic64_set(&si->last_refreshed, refresh_gen); + scoutfs_lock_add_coverage(sb, lock, &si->ino_lock_cov); } } else { ret = 0; @@ -1384,6 +1389,7 @@ struct inode *scoutfs_new_inode(struct super_block *sb, struct inode *dir, si->next_xattr_id = 0; si->have_item = false; atomic64_set(&si->last_refreshed, lock->refresh_gen); + scoutfs_lock_add_coverage(sb, lock, &si->ino_lock_cov); si->flags = 0; scoutfs_inode_set_meta_seq(inode); diff --git a/kmod/src/inode.h b/kmod/src/inode.h index ad517752..60213d73 100644 --- a/kmod/src/inode.h +++ b/kmod/src/inode.h @@ -51,6 +51,8 @@ struct scoutfs_inode_info { struct rw_semaphore xattr_rwsem; struct rb_node writeback_node; + struct scoutfs_lock_coverage ino_lock_cov; + struct inode inode; }; diff --git a/kmod/src/lock.c b/kmod/src/lock.c index 10d95507..7bddb762 100644 --- a/kmod/src/lock.c +++ b/kmod/src/lock.c @@ -127,15 +127,19 @@ static bool lock_modes_match(int granted, int requested) */ static void invalidate_inode(struct super_block *sb, u64 ino) { + struct scoutfs_inode_info *si; struct inode *inode; inode = scoutfs_ilookup(sb, ino); if (inode) { + si = SCOUTFS_I(inode); + scoutfs_inc_counter(sb, lock_invalidate_inode); if (S_ISREG(inode->i_mode)) { truncate_inode_pages(inode->i_mapping, 0); scoutfs_data_wait_changed(inode); } + iput(inode); } } @@ -172,6 +176,16 @@ static int lock_invalidate(struct super_block *sb, struct scoutfs_lock *lock, /* have to invalidate if we're not in the only usable case */ if (!(prev == SCOUTFS_LOCK_WRITE && mode == SCOUTFS_LOCK_READ)) { retry: + /* invalidate inodes before removing coverage */ + if (lock->start.sk_zone == SCOUTFS_FS_ZONE) { + ino = le64_to_cpu(lock->start.ski_ino); + last = le64_to_cpu(lock->end.ski_ino); + while (ino <= last) { + invalidate_inode(sb, ino); + ino++; + } + } + /* remove cov items to tell users that their cache is stale */ spin_lock(&lock->cov_list_lock); list_for_each_entry_safe(cov, tmp, &lock->cov_list, head) { @@ -187,15 +201,6 @@ retry: } spin_unlock(&lock->cov_list_lock); - if (lock->start.sk_zone == SCOUTFS_FS_ZONE) { - ino = le64_to_cpu(lock->start.ski_ino); - last = le64_to_cpu(lock->end.ski_ino); - while (ino <= last) { - invalidate_inode(sb, ino); - ino++; - } - } - scoutfs_item_invalidate(sb, &lock->start, &lock->end); }