mirror of
https://github.com/versity/scoutfs.git
synced 2026-02-07 11:10:44 +00:00
Add item delete dirty and many interfaces
Add item functions for deleting items that we know to be dirty and add a user in another function that deletes many items without leaving parial deletions behind in the case of errors. Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
@@ -964,6 +964,23 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Turn an item that the caller has found while holding the lock into a
|
||||
* deletion item. The caller will free whatever we put in the deletion
|
||||
* value after releasing the lock.
|
||||
*/
|
||||
static void become_deletion_item(struct super_block *sb,
|
||||
struct item_cache *cac,
|
||||
struct cached_item *item,
|
||||
struct kvec *del_val)
|
||||
{
|
||||
scoutfs_kvec_clone(del_val, item->val);
|
||||
scoutfs_kvec_init_null(item->val);
|
||||
item->deletion = 1;
|
||||
mark_item_dirty(cac, item);
|
||||
scoutfs_inc_counter(sb, item_delete);
|
||||
}
|
||||
|
||||
/*
|
||||
* Delete an existing item with the given key.
|
||||
*
|
||||
@@ -999,10 +1016,7 @@ int scoutfs_item_delete(struct super_block *sb, struct scoutfs_key_buf *key)
|
||||
|
||||
item = find_item(sb, &cac->items, key);
|
||||
if (item) {
|
||||
scoutfs_kvec_swap(item->val, del_val);
|
||||
item->deletion = 1;
|
||||
mark_item_dirty(cac, item);
|
||||
scoutfs_inc_counter(sb, item_delete);
|
||||
become_deletion_item(sb, cac, item, del_val);
|
||||
ret = 0;
|
||||
} else if (check_range(sb, &cac->ranges, key, end)) {
|
||||
ret = -ENOENT;
|
||||
@@ -1022,6 +1036,62 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Delete an item that the caller knows must be dirty because they hold
|
||||
* locks and the transaction and have created or dirtied it. This can't
|
||||
* fail.
|
||||
*/
|
||||
void scoutfs_item_delete_dirty(struct super_block *sb,
|
||||
struct scoutfs_key_buf *key)
|
||||
{
|
||||
struct scoutfs_sb_info *sbi = SCOUTFS_SB(sb);
|
||||
struct item_cache *cac = sbi->item_cache;
|
||||
SCOUTFS_DECLARE_KVEC(del_val);
|
||||
struct cached_item *item;
|
||||
unsigned long flags;
|
||||
|
||||
scoutfs_kvec_init_null(del_val);
|
||||
|
||||
spin_lock_irqsave(&cac->lock, flags);
|
||||
|
||||
item = find_item(sb, &cac->items, key);
|
||||
if (item)
|
||||
become_deletion_item(sb, cac, item, del_val);
|
||||
|
||||
spin_unlock_irqrestore(&cac->lock, flags);
|
||||
|
||||
scoutfs_kvec_kfree(del_val);
|
||||
}
|
||||
|
||||
/*
|
||||
* A helper that deletes a set of items. It first dirties the items
|
||||
* will be pinned so that deletion won't fail as it tries to read and
|
||||
* populate the items.
|
||||
*
|
||||
* It's a little cleaner to have this helper than have the caller
|
||||
* iterate, but it could also give us the opportunity to reduce item
|
||||
* searches if we remembered the items we dirtied.
|
||||
*/
|
||||
int scoutfs_item_delete_many(struct super_block *sb,
|
||||
struct scoutfs_key_buf **keys, unsigned nr)
|
||||
{
|
||||
int ret = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nr; i++) {
|
||||
ret = scoutfs_item_dirty(sb, keys[i]);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0; i < nr; i++)
|
||||
scoutfs_item_delete_dirty(sb, keys[i]);
|
||||
|
||||
out:
|
||||
trace_printk("ret %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the first dirty node in the subtree starting at the given node.
|
||||
*/
|
||||
|
||||
@@ -26,6 +26,10 @@ 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);
|
||||
int scoutfs_item_update(struct super_block *sb, struct scoutfs_key_buf *key,
|
||||
struct kvec *val);
|
||||
void scoutfs_item_delete_dirty(struct super_block *sb,
|
||||
struct scoutfs_key_buf *key);
|
||||
int scoutfs_item_delete_many(struct super_block *sb,
|
||||
struct scoutfs_key_buf **keys, unsigned nr);
|
||||
int scoutfs_item_delete(struct super_block *sb, struct scoutfs_key_buf *key);
|
||||
|
||||
int scoutfs_item_add_batch(struct super_block *sb, struct list_head *list,
|
||||
|
||||
Reference in New Issue
Block a user