diff --git a/kmod/src/dir.c b/kmod/src/dir.c index 18164384..12cd42ab 100644 --- a/kmod/src/dir.c +++ b/kmod/src/dir.c @@ -642,7 +642,7 @@ static struct inode *lock_hold_create(struct inode *dir, struct dentry *dentry, if (ret) return ERR_PTR(ret); - ret = scoutfs_alloc_ino(dir, &ino); + ret = scoutfs_alloc_ino(sb, S_ISDIR(mode), &ino); if (ret) return ERR_PTR(ret); diff --git a/kmod/src/inode.c b/kmod/src/inode.c index 124d9375..efab16fd 100644 --- a/kmod/src/inode.c +++ b/kmod/src/inode.c @@ -47,9 +47,17 @@ * - describe data locking size problems */ +struct inode_allocator { + spinlock_t lock; + u64 ino; + u64 nr; +}; + struct inode_sb_info { spinlock_t writeback_lock; struct rb_root writeback_inodes; + struct inode_allocator dir_ino_alloc; + struct inode_allocator ino_alloc; }; #define DECLARE_INODE_SB_INFO(sb, name) \ @@ -74,7 +82,6 @@ static void scoutfs_inode_ctor(void *obj) init_waitqueue_head(&ci->data_waitq.waitq); init_rwsem(&ci->xattr_rwsem); RB_CLEAR_NODE(&ci->writeback_node); - spin_lock_init(&ci->ino_alloc.lock); inode_init_once(&ci->inode); } @@ -682,8 +689,6 @@ struct inode *scoutfs_iget(struct super_block *sb, u64 ino) /* XXX ensure refresh, instead clear in drop_inode? */ si = SCOUTFS_I(inode); atomic64_set(&si->last_refreshed, 0); - si->ino_alloc.ino = 0; - si->ino_alloc.nr = 0; ret = scoutfs_inode_refresh(inode, lock, 0); if (ret) { @@ -1322,14 +1327,16 @@ u64 scoutfs_last_ino(struct super_block *sb) * minimize that loss while still being large enough for typical * directory file counts. */ -int scoutfs_alloc_ino(struct inode *parent, u64 *ino_ret) +int scoutfs_alloc_ino(struct super_block *sb, bool is_dir, u64 *ino_ret) { - struct scoutfs_inode_allocator *ia = &SCOUTFS_I(parent)->ino_alloc; - struct super_block *sb = parent->i_sb; + DECLARE_INODE_SB_INFO(sb, inf); + struct inode_allocator *ia; u64 ino; u64 nr; int ret; + ia = is_dir ? &inf->dir_ino_alloc : &inf->ino_alloc; + spin_lock(&ia->lock); if (ia->nr == 0) { @@ -1385,8 +1392,6 @@ struct inode *scoutfs_new_inode(struct super_block *sb, struct inode *dir, ci->have_item = false; atomic64_set(&ci->last_refreshed, lock->refresh_gen); ci->flags = 0; - ci->ino_alloc.ino = 0; - ci->ino_alloc.nr = 0; scoutfs_inode_set_meta_seq(inode); scoutfs_inode_set_data_seq(inode); @@ -1725,6 +1730,8 @@ int scoutfs_inode_setup(struct super_block *sb) spin_lock_init(&inf->writeback_lock); inf->writeback_inodes = RB_ROOT; + spin_lock_init(&inf->dir_ino_alloc.lock); + spin_lock_init(&inf->ino_alloc.lock); sbi->inode_sb_info = inf; diff --git a/kmod/src/inode.h b/kmod/src/inode.h index 719fb391..9034aef4 100644 --- a/kmod/src/inode.h +++ b/kmod/src/inode.h @@ -10,12 +10,6 @@ struct scoutfs_lock; -struct scoutfs_inode_allocator { - spinlock_t lock; - u64 ino; - u64 nr; -}; - struct scoutfs_inode_info { /* read or initialized for each inode instance */ u64 ino; @@ -42,9 +36,6 @@ struct scoutfs_inode_info { /* updated at on each new lock acquisition */ atomic64_t last_refreshed; - /* reset for every new inode instance */ - struct scoutfs_inode_allocator ino_alloc; - /* initialized once for slab object */ seqcount_t seqcount; bool staging; /* holder of i_mutex is staging */ @@ -95,7 +86,7 @@ int scoutfs_dirty_inode_item(struct inode *inode, struct scoutfs_lock *lock); void scoutfs_update_inode_item(struct inode *inode, struct scoutfs_lock *lock, struct list_head *ind_locks); -int scoutfs_alloc_ino(struct inode *parent, u64 *ino); +int scoutfs_alloc_ino(struct super_block *sb, bool is_dir, u64 *ino_ret); struct inode *scoutfs_new_inode(struct super_block *sb, struct inode *dir, umode_t mode, dev_t rdev, u64 ino, struct scoutfs_lock *lock);