aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOGAWA Hirofumi <hirofumi@mail.parknet.co.jp>2013-12-03 20:16:04 +0900
committerDaniel Phillips <daniel@tux3.org>2013-12-03 20:16:04 +0900
commit745a9043084e68cecf9bcf62b57e0cf9e5ad35eb (patch)
treeb73e70ac2c83670a6e0cb70e760731f93700bb3d
parent71827018ba15f847402ba838a1ce0bb354545619 (diff)
downloadlinux-tux3-745a9043084e68cecf9bcf62b57e0cf9e5ad35eb.tar.gz
tux3: Add support to write across multiple leaves to btree_write()
New dleaf2_write() remains key->len if didn't write on current leaf. To write remaining key, this calls cursor_advance() before dirty leaf. Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
-rw-r--r--fs/tux3/btree.c45
1 files changed, 36 insertions, 9 deletions
diff --git a/fs/tux3/btree.c b/fs/tux3/btree.c
index a9b93fa534299e..d414efb7c34d1d 100644
--- a/fs/tux3/btree.c
+++ b/fs/tux3/btree.c
@@ -1138,6 +1138,29 @@ static int btree_leaf_split(struct cursor *cursor, tuxkey_t key, tuxkey_t hint)
return insert_leaf(cursor, newkey, newbuf, key < newkey);
}
+static int btree_advance(struct cursor *cursor, struct btree_key_range *key)
+{
+ tuxkey_t limit = cursor_next_key(cursor);
+ int skip = 0;
+
+ while (key->start >= limit) {
+ int ret = cursor_advance(cursor);
+ assert(ret != 0); /* wrong key range? */
+ if (ret < 0)
+ return ret;
+
+ limit = cursor_next_key(cursor);
+ skip++;
+ }
+ if (skip > 1) {
+ /* key should on next leaf */
+ tux3_dbg("skipped more than 1 leaf: why, and probe is better");
+ assert(0);
+ }
+
+ return 0;
+}
+
int btree_write(struct cursor *cursor, struct btree_key_range *key)
{
struct btree *btree = cursor->btree;
@@ -1145,18 +1168,22 @@ int btree_write(struct cursor *cursor, struct btree_key_range *key)
tuxkey_t split_hint;
int err;
- /* FIXME: we might be better to support multiple leaves */
-
- err = cursor_redirect(cursor);
- if (err)
- return err;
-
while (key->len > 0) {
- tuxkey_t bottom = cursor_this_key(cursor);
- tuxkey_t limit = cursor_next_key(cursor);
- void *leaf = bufdata(cursor_leafbuf(cursor));
+ tuxkey_t bottom, limit;
+ void *leaf;
int need_split;
+ err = btree_advance(cursor, key);
+ if (err)
+ return err; /* FIXME: error handling */
+
+ err = cursor_redirect(cursor);
+ if (err)
+ return err; /* FIXME: error handling */
+
+ bottom = cursor_this_key(cursor);
+ limit = cursor_next_key(cursor);
+ leaf = bufdata(cursor_leafbuf(cursor));
assert(bottom <= key->start && key->start < limit);
assert(ops->leaf_sniff(btree, leaf));