From 19171f7a251ee2ad68039c3818c2427f049dec9a Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Wed, 12 Jul 2017 14:20:18 -0700 Subject: [PATCH] scoutfs: add end to _item_lookup The item cache can only be populated with items that are covered by locks. Require callers to provide the farthest key that can be covered by the locks. Locks provide a key for exactly this purpose. Signed-off-by: Zach Brown --- kmod/src/dir.c | 5 +++-- kmod/src/inode.c | 6 +++--- kmod/src/item.c | 23 ++++++++++------------- kmod/src/item.h | 4 ++-- kmod/src/xattr.c | 2 +- 5 files changed, 19 insertions(+), 21 deletions(-) diff --git a/kmod/src/dir.c b/kmod/src/dir.c index 7bb21fe0..4dc5b3da 100644 --- a/kmod/src/dir.c +++ b/kmod/src/dir.c @@ -251,7 +251,7 @@ static struct dentry *scoutfs_lookup(struct inode *dir, struct dentry *dentry, scoutfs_kvec_init(val, &dent, sizeof(dent)); - ret = scoutfs_item_lookup_exact(sb, key, val, sizeof(dent)); + ret = scoutfs_item_lookup_exact(sb, key, val, sizeof(dent), NULL); if (ret == -ENOENT) { ino = 0; ret = 0; @@ -689,7 +689,8 @@ static int symlink_item_ops(struct super_block *sb, int op, u64 ino, if (op == SYM_CREATE) ret = scoutfs_item_create(sb, &key, val); else if (op == SYM_LOOKUP) - ret = scoutfs_item_lookup_exact(sb, &key, val, bytes); + ret = scoutfs_item_lookup_exact(sb, &key, val, bytes, + NULL); else if (op == SYM_DELETE) ret = scoutfs_item_delete(sb, &key); if (ret) diff --git a/kmod/src/inode.c b/kmod/src/inode.c index cf3a1714..bd49c494 100644 --- a/kmod/src/inode.c +++ b/kmod/src/inode.c @@ -243,7 +243,7 @@ static int scoutfs_read_locked_inode(struct inode *inode) scoutfs_inode_init_key(&key, &ikey, scoutfs_ino(inode)); scoutfs_kvec_init(val, &sinode, sizeof(sinode)); - ret = scoutfs_item_lookup_exact(sb, &key, val, sizeof(sinode)); + ret = scoutfs_item_lookup_exact(sb, &key, val, sizeof(sinode), NULL); if (ret == 0) load_inode(inode, &sinode); @@ -838,7 +838,7 @@ static void delete_inode(struct super_block *sb, u64 ino) scoutfs_inode_init_key(&key, &ikey, ino); scoutfs_kvec_init(val, &sinode, sizeof(sinode)); - ret = scoutfs_item_lookup_exact(sb, &key, val, sizeof(sinode)); + ret = scoutfs_item_lookup_exact(sb, &key, val, sizeof(sinode), NULL); if (ret < 0) goto out; @@ -892,7 +892,7 @@ static int process_orphaned_inode(struct super_block *sb, u64 ino) scoutfs_inode_init_key(&key, &ikey, ino); scoutfs_kvec_init(val, &sinode, sizeof(sinode)); - ret = scoutfs_item_lookup_exact(sb, &key, val, sizeof(sinode)); + ret = scoutfs_item_lookup_exact(sb, &key, val, sizeof(sinode), NULL); if (ret < 0) { if (ret == -ENOENT) ret = 0; diff --git a/kmod/src/item.c b/kmod/src/item.c index 9dcc38c9..2e9de37c 100644 --- a/kmod/src/item.c +++ b/kmod/src/item.c @@ -717,25 +717,21 @@ restart: * Find an item with the given key and copy its value into the caller's * value vector. The amount of bytes copied is returned which can be 0 * or truncated if the caller's buffer isn't big enough. + * + * The end key limits how many keys after the search key can be read + * and inserted into the cache. */ int scoutfs_item_lookup(struct super_block *sb, struct scoutfs_key_buf *key, - struct kvec *val) + struct kvec *val, struct scoutfs_key_buf *end) { struct scoutfs_sb_info *sbi = SCOUTFS_SB(sb); struct item_cache *cac = sbi->item_cache; - struct scoutfs_key_buf *end; struct cached_item *item; unsigned long flags; int ret; trace_scoutfs_item_lookup(sb, key); - end = scoutfs_key_alloc(sb, SCOUTFS_MAX_KEY_SIZE); - if (!end) { - ret = -ENOMEM; - goto out; - } - do { spin_lock_irqsave(&cac->lock, flags); @@ -743,7 +739,7 @@ int scoutfs_item_lookup(struct super_block *sb, struct scoutfs_key_buf *key, if (item) { item_referenced(cac, item); ret = scoutfs_kvec_memcpy(val, item->val); - } else if (check_range(sb, &cac->ranges, key, end)) { + } else if (check_range(sb, &cac->ranges, key, NULL)) { ret = -ENOENT; } else { ret = -ENODATA; @@ -754,8 +750,6 @@ int scoutfs_item_lookup(struct super_block *sb, struct scoutfs_key_buf *key, } while (ret == -ENODATA && (ret = scoutfs_manifest_read_items(sb, key, end)) == 0); - scoutfs_key_free(sb, end); -out: trace_printk("ret %d\n", ret); return ret; } @@ -768,15 +762,18 @@ out: * overhead that comes from only detecting the size mismatch after the * copy by reusing the more permissive _lookup(). * + * The end key limits how many keys after the search key can be read + * and inserted into the cache. + * * Returns 0 or -errno. */ int scoutfs_item_lookup_exact(struct super_block *sb, struct scoutfs_key_buf *key, struct kvec *val, - int size) + int size, struct scoutfs_key_buf *end) { int ret; - ret = scoutfs_item_lookup(sb, key, val); + ret = scoutfs_item_lookup(sb, key, val, end); if (ret == size) ret = 0; else if (ret >= 0) diff --git a/kmod/src/item.h b/kmod/src/item.h index fb9c1df4..774f0ab7 100644 --- a/kmod/src/item.h +++ b/kmod/src/item.h @@ -13,10 +13,10 @@ struct scoutfs_segment; struct scoutfs_key_buf; int scoutfs_item_lookup(struct super_block *sb, struct scoutfs_key_buf *key, - struct kvec *val); + struct kvec *val, struct scoutfs_key_buf *end); int scoutfs_item_lookup_exact(struct super_block *sb, struct scoutfs_key_buf *key, struct kvec *val, - int size); + int size, struct scoutfs_key_buf *end); int scoutfs_item_next(struct super_block *sb, struct scoutfs_key_buf *key, struct scoutfs_key_buf *last, struct kvec *val); int scoutfs_item_next_same_min(struct super_block *sb, diff --git a/kmod/src/xattr.c b/kmod/src/xattr.c index 29aba33d..19dbce6f 100644 --- a/kmod/src/xattr.c +++ b/kmod/src/xattr.c @@ -189,7 +189,7 @@ ssize_t scoutfs_getxattr(struct dentry *dentry, const char *name, void *buffer, for_each_xattr_item(key, val, &vh, buffer, size, part, off, bytes) { - ret = scoutfs_item_lookup(sb, key, val); + ret = scoutfs_item_lookup(sb, key, val, lck->end); if (ret < 0) { if (ret == -ENOENT) ret = -EIO;