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 <zab@versity.com>
This commit is contained in:
Zach Brown
2017-07-19 13:30:03 -07:00
parent 67cc4fb697
commit 19171f7a25
5 changed files with 19 additions and 21 deletions
+3 -2
View File
@@ -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)
+3 -3
View File
@@ -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;
+10 -13
View File
@@ -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)
+2 -2
View File
@@ -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,
+1 -1
View File
@@ -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;