Add scoutfs_item_forget()

Add a forget call which forcefully removes an item, no matter it's
state.   The page cache will use this in invalidate page to drop
ephemeral items that reference a dirty page that's being truncated.

Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
Zach Brown
2017-04-18 13:44:54 -07:00
parent 9f885b4c12
commit c3307e941b
3 changed files with 28 additions and 0 deletions
+1
View File
@@ -28,6 +28,7 @@
EXPAND_COUNTER(item_lookup_hit) \
EXPAND_COUNTER(item_lookup_miss) \
EXPAND_COUNTER(item_delete) \
EXPAND_COUNTER(item_forget) \
EXPAND_COUNTER(item_range_hit) \
EXPAND_COUNTER(item_range_miss) \
EXPAND_COUNTER(item_range_insert)
+26
View File
@@ -1105,6 +1105,32 @@ out:
return ret;
}
/*
* Forcefully remove an item from the cache regardless of its state or
* relationship to persistent items.
*
* The caller is entirely responsible for the correctness of having this
* item vanish.
*/
void scoutfs_item_forget(struct super_block *sb, struct scoutfs_key_buf *key)
{
struct scoutfs_sb_info *sbi = SCOUTFS_SB(sb);
struct item_cache *cac = sbi->item_cache;
struct cached_item *item;
unsigned long flags;
spin_lock_irqsave(&cac->lock, flags);
item = find_item(sb, &cac->items, key);
if (item) {
trace_printk("forgetting item %p\n", item);
scoutfs_inc_counter(sb, item_forget);
erase_item(sb, cac, item);
}
spin_unlock_irqrestore(&cac->lock, flags);
}
/*
* Return the first dirty node in the subtree starting at the given node.
*/
+1
View File
@@ -31,6 +31,7 @@ void scoutfs_item_delete_dirty(struct super_block *sb,
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);
void scoutfs_item_forget(struct super_block *sb, struct scoutfs_key_buf *key);
int scoutfs_item_add_batch(struct super_block *sb, struct list_head *list,
struct scoutfs_key_buf *key, struct kvec *val);