diff --git a/kmod/src/data.c b/kmod/src/data.c index 73289828..cce006d3 100644 --- a/kmod/src/data.c +++ b/kmod/src/data.c @@ -522,7 +522,7 @@ static int set_blkno_free(struct super_block *sb, u64 blkno) } /* dirty so we can safely delete if set segno fails */ - ret = scoutfs_item_dirty(sb, &key, lock->end); + ret = scoutfs_item_dirty(sb, &key, lock); if (ret) goto out; diff --git a/kmod/src/dir.c b/kmod/src/dir.c index e7c38265..3b711372 100644 --- a/kmod/src/dir.c +++ b/kmod/src/dir.c @@ -509,9 +509,9 @@ static int del_entry_items(struct super_block *sb, u64 dir_ino, u64 pos, goto out; } - ret = scoutfs_item_dirty(sb, ent_key, dir_lock->end) ?: - scoutfs_item_dirty(sb, &rdir_key, dir_lock->end) ?: - scoutfs_item_dirty(sb, lb_key, inode_lock->end); + ret = scoutfs_item_dirty(sb, ent_key, dir_lock) ?: + scoutfs_item_dirty(sb, &rdir_key, dir_lock) ?: + scoutfs_item_dirty(sb, lb_key, inode_lock); if (ret) goto out; @@ -578,7 +578,7 @@ static struct inode *lock_hold_create(struct inode *dir, struct dentry *dentry, goto out; } - ret = scoutfs_dirty_inode_item(dir, (*dir_lock)->end); + ret = scoutfs_dirty_inode_item(dir, *dir_lock); out: if (ret) scoutfs_release_trans(sb); @@ -694,7 +694,7 @@ static int scoutfs_link(struct dentry *old_dentry, if (ret) goto out_unlock; - ret = scoutfs_dirty_inode_item(dir, dir_lock->end); + ret = scoutfs_dirty_inode_item(dir, dir_lock); if (ret) goto out; @@ -1397,12 +1397,12 @@ static int scoutfs_rename(struct inode *old_dir, struct dentry *old_dentry, new_pos = SCOUTFS_I(new_dir)->next_readdir_pos++; /* dirty the inodes so that updating doesn't fail */ - ret = scoutfs_dirty_inode_item(old_dir, old_dir_lock->end) ?: - scoutfs_dirty_inode_item(old_inode, old_inode_lock->end) ?: + ret = scoutfs_dirty_inode_item(old_dir, old_dir_lock) ?: + scoutfs_dirty_inode_item(old_inode, old_inode_lock) ?: (old_dir != new_dir ? - scoutfs_dirty_inode_item(new_dir, new_dir_lock->end) : 0) ?: + scoutfs_dirty_inode_item(new_dir, new_dir_lock) : 0) ?: (new_inode ? - scoutfs_dirty_inode_item(new_inode, new_inode_lock->end) : 0); + scoutfs_dirty_inode_item(new_inode, new_inode_lock) : 0); if (ret) goto out; diff --git a/kmod/src/inode.c b/kmod/src/inode.c index b576333a..e4149787 100644 --- a/kmod/src/inode.c +++ b/kmod/src/inode.c @@ -498,7 +498,7 @@ static void store_inode(struct scoutfs_inode *cinode, struct inode *inode) * * XXX this will have to do something about variable length inodes */ -int scoutfs_dirty_inode_item(struct inode *inode, struct scoutfs_key_buf *end) +int scoutfs_dirty_inode_item(struct inode *inode, struct scoutfs_lock *lock) { struct super_block *sb = inode->i_sb; struct scoutfs_inode_key ikey; @@ -510,7 +510,7 @@ int scoutfs_dirty_inode_item(struct inode *inode, struct scoutfs_key_buf *end) scoutfs_inode_init_key(&key, &ikey, scoutfs_ino(inode)); - ret = scoutfs_item_dirty(sb, &key, end); + ret = scoutfs_item_dirty(sb, &key, lock); if (!ret) trace_scoutfs_dirty_inode(inode); return ret; diff --git a/kmod/src/inode.h b/kmod/src/inode.h index d4f23b46..15175dd4 100644 --- a/kmod/src/inode.h +++ b/kmod/src/inode.h @@ -61,7 +61,7 @@ int scoutfs_orphan_inode(struct inode *inode); struct inode *scoutfs_iget(struct super_block *sb, u64 ino); struct inode *scoutfs_ilookup(struct super_block *sb, u64 ino); -int scoutfs_dirty_inode_item(struct inode *inode, struct scoutfs_key_buf *end); +int scoutfs_dirty_inode_item(struct inode *inode, struct scoutfs_lock *lock); void scoutfs_update_inode_item(struct inode *inode); void scoutfs_inode_fill_pool(struct super_block *sb, u64 ino, u64 nr); int scoutfs_alloc_ino(struct super_block *sb, u64 *ino); diff --git a/kmod/src/item.c b/kmod/src/item.c index 0b62b730..9e793798 100644 --- a/kmod/src/item.c +++ b/kmod/src/item.c @@ -1329,7 +1329,7 @@ void scoutfs_item_free_batch(struct super_block *sb, struct list_head *list) * if it wasn't cached. -ENOENT is returned if the item doesn't exist. */ int scoutfs_item_dirty(struct super_block *sb, struct scoutfs_key_buf *key, - struct scoutfs_key_buf *end) + struct scoutfs_lock *lock) { struct scoutfs_sb_info *sbi = SCOUTFS_SB(sb); struct item_cache *cac = sbi->item_cache; @@ -1337,6 +1337,9 @@ int scoutfs_item_dirty(struct super_block *sb, struct scoutfs_key_buf *key, unsigned long flags; int ret; + if (WARN_ON_ONCE(!lock_coverage(lock, key, WRITE))) + return -EINVAL; + do { spin_lock_irqsave(&cac->lock, flags); @@ -1353,7 +1356,7 @@ int scoutfs_item_dirty(struct super_block *sb, struct scoutfs_key_buf *key, spin_unlock_irqrestore(&cac->lock, flags); } while (ret == -ENODATA && - (ret = scoutfs_manifest_read_items(sb, key, end)) == 0); + (ret = scoutfs_manifest_read_items(sb, key, lock->end)) == 0); trace_scoutfs_item_dirty_ret(sb, ret); return ret; diff --git a/kmod/src/item.h b/kmod/src/item.h index 8af12785..ece0c8c6 100644 --- a/kmod/src/item.h +++ b/kmod/src/item.h @@ -31,7 +31,7 @@ int scoutfs_item_next_same(struct super_block *sb, struct scoutfs_key_buf *key, int scoutfs_item_create(struct super_block *sb, struct scoutfs_key_buf *key, struct kvec *val); int scoutfs_item_dirty(struct super_block *sb, struct scoutfs_key_buf *key, - struct scoutfs_key_buf *end); + struct scoutfs_lock *lock); int scoutfs_item_update(struct super_block *sb, struct scoutfs_key_buf *key, struct kvec *val, struct scoutfs_key_buf *end); void scoutfs_item_delete_dirty(struct super_block *sb, diff --git a/kmod/src/xattr.c b/kmod/src/xattr.c index 72525470..e9ff58e1 100644 --- a/kmod/src/xattr.c +++ b/kmod/src/xattr.c @@ -321,7 +321,7 @@ static int scoutfs_xattr_set(struct dentry *dentry, const char *name, down_write(&si->xattr_rwsem); - ret = scoutfs_dirty_inode_item(inode, lck->end) ?: + ret = scoutfs_dirty_inode_item(inode, lck) ?: scoutfs_item_set_batch(sb, &list, key, last, sif, lck->end); if (ret == 0) { /* XXX do these want i_mutex or anything? */