From 6cd64f32286d0ba816dd9bfddecee0e79539139a Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Thu, 5 Oct 2017 12:06:32 -0700 Subject: [PATCH] scoutfs: add full lock arg to _item_update() Add the full lock arg to _item_update() so that it can verify lock coverage. Signed-off-by: Zach Brown --- kmod/src/data.c | 13 ++++++------- kmod/src/inode.c | 2 +- kmod/src/item.c | 7 +++++-- kmod/src/item.h | 2 +- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/kmod/src/data.c b/kmod/src/data.c index f1bd42ce..da146a2a 100644 --- a/kmod/src/data.c +++ b/kmod/src/data.c @@ -382,7 +382,7 @@ static int set_segno_free(struct super_block *sb, u64 segno) goto out; } - ret = scoutfs_item_update(sb, &key, val, lock->end); + ret = scoutfs_item_update(sb, &key, val, lock); out: trace_scoutfs_data_set_segno_free(sb, segno, be64_to_cpu(fbk.base), bit, ret); @@ -469,7 +469,7 @@ static int clear_segno_free(struct super_block *sb, u64 segno) if (bitmap_empty((long *)frb.bits, SCOUTFS_FREE_BITS_BITS)) ret = scoutfs_item_delete(sb, &key, lock->end); else - ret = scoutfs_item_update(sb, &key, val, lock->end); + ret = scoutfs_item_update(sb, &key, val, lock); if (ret) scoutfs_item_delete_dirty(sb, &b_key); out: @@ -518,7 +518,7 @@ static int set_blkno_free(struct super_block *sb, u64 blkno) } if (!bitmap_full((long *)frb.bits, SCOUTFS_FREE_BITS_BITS)) { - ret = scoutfs_item_update(sb, &key, val, lock->end); + ret = scoutfs_item_update(sb, &key, val, lock); goto out; } @@ -578,7 +578,7 @@ static int clear_blkno_free(struct super_block *sb, u64 blkno) if (bitmap_empty((long *)frb.bits, SCOUTFS_FREE_BITS_BITS)) ret = scoutfs_item_delete(sb, &key, lock->end); else - ret = scoutfs_item_update(sb, &key, val, lock->end); + ret = scoutfs_item_update(sb, &key, val, lock); out: return ret; } @@ -675,8 +675,7 @@ int scoutfs_data_truncate_items(struct super_block *sb, u64 ino, u64 iblock, if (!dirtied) { /* dirty item with full size encoded */ - ret = scoutfs_item_update(sb, &key, val, - lock->end); + ret = scoutfs_item_update(sb, &key, val, lock); if (ret) break; dirtied = true; @@ -960,7 +959,7 @@ static int find_alloc_block(struct super_block *sb, struct block_mapping *map, /* ensure that we can copy in encoded without failing */ scoutfs_kvec_init(val, map->encoded, sizeof(map->encoded)); if (map_exists) - ret = scoutfs_item_update(sb, map_key, val, data_lock->end); + ret = scoutfs_item_update(sb, map_key, val, data_lock); else ret = scoutfs_item_create(sb, map_key, val, data_lock); if (ret) diff --git a/kmod/src/inode.c b/kmod/src/inode.c index 998ce53c..57ad8287 100644 --- a/kmod/src/inode.c +++ b/kmod/src/inode.c @@ -736,7 +736,7 @@ void scoutfs_update_inode_item(struct inode *inode, struct scoutfs_lock *lock, scoutfs_inode_init_key(&key, &ikey, ino); scoutfs_kvec_init(val, &sinode, sizeof(sinode)); - err = scoutfs_item_update(sb, &key, val, lock->end); + err = scoutfs_item_update(sb, &key, val, lock); if (err) { scoutfs_err(sb, "inode %llu update err %d", ino, err); BUG_ON(err); diff --git a/kmod/src/item.c b/kmod/src/item.c index f4ce689d..f242aa88 100644 --- a/kmod/src/item.c +++ b/kmod/src/item.c @@ -1382,7 +1382,7 @@ int scoutfs_item_dirty(struct super_block *sb, struct scoutfs_key_buf *key, * Returns -ENOENT if the item doesn't exist. */ int scoutfs_item_update(struct super_block *sb, struct scoutfs_key_buf *key, - struct kvec *val, struct scoutfs_key_buf *end) + struct kvec *val, struct scoutfs_lock *lock) { struct scoutfs_sb_info *sbi = SCOUTFS_SB(sb); struct item_cache *cac = sbi->item_cache; @@ -1394,6 +1394,9 @@ int scoutfs_item_update(struct super_block *sb, struct scoutfs_key_buf *key, if (invalid_key_val(key, val)) return -EINVAL; + if (WARN_ON_ONCE(!lock_coverage(lock, key, WRITE))) + return -EINVAL; + if (val) { ret = scoutfs_kvec_dup_flatten(up_val, val); if (ret) @@ -1420,7 +1423,7 @@ int scoutfs_item_update(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); out: scoutfs_kvec_kfree(up_val); diff --git a/kmod/src/item.h b/kmod/src/item.h index 7ea43feb..e442c313 100644 --- a/kmod/src/item.h +++ b/kmod/src/item.h @@ -33,7 +33,7 @@ int scoutfs_item_create(struct super_block *sb, struct scoutfs_key_buf *key, int scoutfs_item_dirty(struct super_block *sb, struct scoutfs_key_buf *key, 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); + struct kvec *val, struct scoutfs_lock *lock); void scoutfs_item_delete_dirty(struct super_block *sb, struct scoutfs_key_buf *key); void scoutfs_item_update_dirty(struct super_block *sb,