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;