scoutfs: add scoutfs_extent_prev()

Add an extent function for iterating backwards through extents.  We add
the wrapper and have the extent IO functions call their storage _prev
functions.  Data extent IO can now call the new scoutfs_item_prev().

Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
Zach Brown
2018-06-20 15:36:37 -07:00
committed by Zach Brown
parent d53ec115bc
commit 04660dbfee
6 changed files with 42 additions and 5 deletions

View File

@@ -56,6 +56,7 @@
EXPAND_COUNTER(extent_delete) \
EXPAND_COUNTER(extent_insert) \
EXPAND_COUNTER(extent_next) \
EXPAND_COUNTER(extent_prev) \
EXPAND_COUNTER(extent_remove) \
EXPAND_COUNTER(item_alloc) \
EXPAND_COUNTER(item_batch_duplicate) \

View File

@@ -139,6 +139,7 @@ static int data_extent_io(struct super_block *sb, int op,
{
struct scoutfs_lock *lock = data;
struct scoutfs_file_extent fex;
struct scoutfs_key first;
struct scoutfs_key last;
struct scoutfs_key key;
struct kvec val;
@@ -164,6 +165,7 @@ static int data_extent_io(struct super_block *sb, int op,
if (ext->type == SCOUTFS_FILE_EXTENT_TYPE) {
init_file_extent_key(&key, ext->owner,
ext->start + ext->len - 1);
init_file_extent_key(&first, ext->owner, 0);
init_file_extent_key(&last, ext->owner, U64_MAX);
fex.blkno = cpu_to_le64(ext->map);
fex.len = cpu_to_le64(ext->len);
@@ -174,14 +176,20 @@ static int data_extent_io(struct super_block *sb, int op,
ext->start + ext->len - 1, ext->len);
if (ext->type == SCOUTFS_FREE_EXTENT_BLOCKS_TYPE)
swap(key.sknf_major, key.sknf_minor);
init_free_extent_key(&first, ext->type, ext->owner,
0, 0);
init_free_extent_key(&last, ext->type, ext->owner,
U64_MAX, U64_MAX);
kvec_init(&val, NULL, 0);
}
if (op == SEI_NEXT) {
if (op == SEI_NEXT || op == SEI_PREV) {
expected = val.iov_len;
ret = scoutfs_item_next(sb, &key, &last, &val, lock);
if (op == SEI_NEXT)
ret = scoutfs_item_next(sb, &key, &last, &val, lock);
else
ret = scoutfs_item_prev(sb, &key, &first, &val, lock);
if (ret >= 0 && ret != expected)
ret = -EIO;
if (ret == expected)

View File

@@ -153,6 +153,19 @@ int scoutfs_extent_next(struct super_block *sb, scoutfs_extent_io_t iof,
return ret;
}
int scoutfs_extent_prev(struct super_block *sb, scoutfs_extent_io_t iof,
struct scoutfs_extent *ext, void *data)
{
int ret;
scoutfs_inc_counter(sb, extent_prev);
trace_scoutfs_extent_prev_input(sb, ext);
ret = iof(sb, SEI_PREV, ext, data);
if (ret == 0)
trace_scoutfs_extent_prev_output(sb, ext);
return ret;
}
/*
* Search for a next extent and see if we can merge it with the caller's
* extent. The caller has initialized next for us to search from. If

View File

@@ -20,6 +20,7 @@ struct scoutfs_extent {
enum {
SEI_NEXT,
SEI_PREV,
SEI_INSERT,
SEI_DELETE,
};
@@ -33,6 +34,8 @@ bool scoutfs_extent_intersection(struct scoutfs_extent *a,
int scoutfs_extent_next(struct super_block *sb, scoutfs_extent_io_t iof,
struct scoutfs_extent *ext, void *data);
int scoutfs_extent_prev(struct super_block *sb, scoutfs_extent_io_t iof,
struct scoutfs_extent *ext, void *data);
int scoutfs_extent_add(struct super_block *sb, scoutfs_extent_io_t iof,
struct scoutfs_extent *add, void *data);
int scoutfs_extent_remove(struct super_block *sb, scoutfs_extent_io_t iof,

View File

@@ -2222,6 +2222,14 @@ DEFINE_EVENT(scoutfs_extent_class, scoutfs_extent_next_output,
TP_PROTO(struct super_block *sb, struct scoutfs_extent *ext),
TP_ARGS(sb, ext)
);
DEFINE_EVENT(scoutfs_extent_class, scoutfs_extent_prev_input,
TP_PROTO(struct super_block *sb, struct scoutfs_extent *ext),
TP_ARGS(sb, ext)
);
DEFINE_EVENT(scoutfs_extent_class, scoutfs_extent_prev_output,
TP_PROTO(struct super_block *sb, struct scoutfs_extent *ext),
TP_ARGS(sb, ext)
);
DEFINE_EVENT(scoutfs_extent_class, scoutfs_extent_add,
TP_PROTO(struct super_block *sb, struct scoutfs_extent *ext),
TP_ARGS(sb, ext)

View File

@@ -164,9 +164,13 @@ static int server_extent_io(struct super_block *sb, int op,
if (ext->type == SCOUTFS_FREE_EXTENT_BLOCKS_TYPE)
swap(ebk.major, ebk.minor);
if (op == SEI_NEXT) {
ret = scoutfs_btree_next(sb, &super->alloc_root,
&ebk, sizeof(ebk), &iref);
if (op == SEI_NEXT || op == SEI_PREV) {
if (op == SEI_NEXT)
ret = scoutfs_btree_next(sb, &super->alloc_root,
&ebk, sizeof(ebk), &iref);
else
ret = scoutfs_btree_prev(sb, &super->alloc_root,
&ebk, sizeof(ebk), &iref);
if (ret == 0) {
ret = init_extent_from_btree_key(ext, ext->type,
iref.key,