mirror of
https://github.com/versity/scoutfs.git
synced 2026-08-27 19:36:52 +00:00
scoutfs: remove scoutfs_item_set_batch()
scoutfs_item_set_batch() has a rocky history of being a giant pain in the butt. It's been a lot simpler to have callers use individual item ops instead of trying to describe a compound item operation to sometihng like _set_batch(). Its last user has gone away so we can remove it and never speak of it again. And there was much rejoycing. Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
-137
@@ -47,11 +47,6 @@ static bool invalid_key_val(struct scoutfs_key_buf *key, struct kvec *val)
|
||||
(val && (scoutfs_kvec_length(val) > SCOUTFS_MAX_VAL_SIZE)));
|
||||
}
|
||||
|
||||
static bool invalid_flags(int sif)
|
||||
{
|
||||
return (sif & SIF_EXCLUSIVE) && (sif & SIF_REPLACE);
|
||||
}
|
||||
|
||||
struct item_cache {
|
||||
struct super_block *sb;
|
||||
|
||||
@@ -1241,138 +1236,6 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Atomically set the caller's items to be the only cached items in the
|
||||
* caller's range. Any existing items that overlap with the caller's
|
||||
* items are replaced. Any existing items in the range that aren't in
|
||||
* the caller's list will be replaced with deletion items. The deletion
|
||||
* items and the caller's inserted items will all be marked dirty.
|
||||
*
|
||||
* In practice this is used for relatively few items at a time, at most
|
||||
* on the order of 16. So we're not too worried with it walking a small
|
||||
* number of items a few times when the caller provides flags that have
|
||||
* to check for existing items.
|
||||
*
|
||||
* Returns -ENODATA if SIF_REPLACE is set and a batch item doesn't have
|
||||
* a matching existing item or -EEXIST if SIF_EXCLUSIVE is set and a
|
||||
* batch item does have an existing item.
|
||||
*/
|
||||
int scoutfs_item_set_batch(struct super_block *sb, struct list_head *list,
|
||||
struct scoutfs_key_buf *first,
|
||||
struct scoutfs_key_buf *last, int sif,
|
||||
struct scoutfs_lock *lock)
|
||||
{
|
||||
struct scoutfs_sb_info *sbi = SCOUTFS_SB(sb);
|
||||
struct item_cache *cac = sbi->item_cache;
|
||||
struct scoutfs_key_buf *range_end;
|
||||
struct cached_item *exist;
|
||||
struct cached_item *item;
|
||||
struct cached_item *tmp;
|
||||
unsigned long flags;
|
||||
int cmp;
|
||||
int ret;
|
||||
|
||||
if (WARN_ON_ONCE(invalid_flags(sif)))
|
||||
return -EINVAL;
|
||||
|
||||
list_for_each_entry(item, list, entry) {
|
||||
if (invalid_key_val(item->key, item->val))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
trace_scoutfs_item_set_batch(sb, first, last);
|
||||
|
||||
if (WARN_ON_ONCE(scoutfs_key_compare(first, last) > 0) ||
|
||||
WARN_ON_ONCE(!lock_coverage(lock, first, DLM_LOCK_EX)) ||
|
||||
WARN_ON_ONCE(!lock_coverage(lock, last, DLM_LOCK_EX)))
|
||||
return -EINVAL;
|
||||
|
||||
range_end = scoutfs_key_alloc(sb, SCOUTFS_MAX_KEY_SIZE);
|
||||
if (!range_end)
|
||||
return -ENOMEM;
|
||||
|
||||
spin_lock_irqsave(&cac->lock, flags);
|
||||
|
||||
/* make sure all of first through last are cached */
|
||||
scoutfs_key_copy(range_end, first);
|
||||
for (;;) {
|
||||
if (check_range(sb, &cac->ranges, range_end, range_end)) {
|
||||
if (scoutfs_key_compare(range_end, last) >= 0)
|
||||
break;
|
||||
/* start reading after the last key we have cached */
|
||||
scoutfs_key_inc(range_end);
|
||||
} else {
|
||||
/* start reading from the missing first */
|
||||
scoutfs_key_copy(range_end, first);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&cac->lock, flags);
|
||||
ret = scoutfs_manifest_read_items(sb, range_end, lock->end);
|
||||
spin_lock_irqsave(&cac->lock, flags);
|
||||
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* check for _EXCLUSIVE or _REPLACE errors before destroying items */
|
||||
if (!list_empty(list) && (sif & (SIF_EXCLUSIVE | SIF_REPLACE))) {
|
||||
|
||||
item = list_first_entry(list, struct cached_item, entry);
|
||||
exist = item_for_next(&cac->items, first, NULL, last);
|
||||
|
||||
while (item) {
|
||||
/* compare keys, with bias to finding _REPLACE err */
|
||||
if (exist)
|
||||
cmp = scoutfs_key_compare(item->key,
|
||||
exist->key);
|
||||
else
|
||||
cmp = -1;
|
||||
|
||||
if (cmp < 0) {
|
||||
if (sif & SIF_REPLACE) {
|
||||
ret = -ENODATA;
|
||||
goto out;
|
||||
}
|
||||
if (item->entry.next != list)
|
||||
item = list_next_entry(item, entry);
|
||||
else
|
||||
item = NULL;
|
||||
|
||||
} else if (cmp > 0) {
|
||||
exist = next_item_node(&cac->items, exist, last);
|
||||
|
||||
} else {
|
||||
/* cmp == 0 */
|
||||
if (sif & SIF_EXCLUSIVE) {
|
||||
ret = -EEXIST;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* delete everything in the range */
|
||||
for (exist = item_for_next(&cac->items, first, NULL, last);
|
||||
exist; exist = next_item_node(&cac->items, exist, last)) {
|
||||
|
||||
become_deletion_item(sb, cac, exist);
|
||||
}
|
||||
|
||||
/* insert the caller's items, overwriting any existing */
|
||||
list_for_each_entry_safe(item, tmp, list, entry) {
|
||||
list_del_init(&item->entry);
|
||||
insert_item(sb, cac, item, true, false);
|
||||
mark_item_dirty(sb, cac, item);
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
out:
|
||||
spin_unlock_irqrestore(&cac->lock, flags);
|
||||
scoutfs_key_free(sb, range_end);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void scoutfs_item_free_batch(struct super_block *sb, struct list_head *list)
|
||||
{
|
||||
struct cached_item *item;
|
||||
|
||||
@@ -3,12 +3,6 @@
|
||||
|
||||
#include <linux/uio.h>
|
||||
|
||||
/* behavioural flags for the item functions */
|
||||
enum {
|
||||
SIF_EXCLUSIVE = (1 << 1),
|
||||
SIF_REPLACE = (1 << 2),
|
||||
};
|
||||
|
||||
struct scoutfs_segment;
|
||||
struct scoutfs_key_buf;
|
||||
|
||||
@@ -58,10 +52,6 @@ int scoutfs_item_add_batch(struct super_block *sb, struct list_head *list,
|
||||
int scoutfs_item_insert_batch(struct super_block *sb, struct list_head *list,
|
||||
struct scoutfs_key_buf *start,
|
||||
struct scoutfs_key_buf *end);
|
||||
int scoutfs_item_set_batch(struct super_block *sb, struct list_head *list,
|
||||
struct scoutfs_key_buf *first,
|
||||
struct scoutfs_key_buf *last, int sif,
|
||||
struct scoutfs_lock *lock);
|
||||
void scoutfs_item_free_batch(struct super_block *sb, struct list_head *list);
|
||||
|
||||
bool scoutfs_item_has_dirty(struct super_block *sb);
|
||||
|
||||
@@ -1453,12 +1453,6 @@ DECLARE_EVENT_CLASS(scoutfs_range_class,
|
||||
__entry->fsid, __get_str(start), __get_str(end))
|
||||
);
|
||||
|
||||
DEFINE_EVENT(scoutfs_range_class, scoutfs_item_set_batch,
|
||||
TP_PROTO(struct super_block *sb, struct scoutfs_key_buf *start,
|
||||
struct scoutfs_key_buf *end),
|
||||
TP_ARGS(sb, start, end)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(scoutfs_range_class, scoutfs_item_insert_batch,
|
||||
TP_PROTO(struct super_block *sb, struct scoutfs_key_buf *start,
|
||||
struct scoutfs_key_buf *end),
|
||||
|
||||
Reference in New Issue
Block a user