tux3: Rename dleaf2 files as dleaf
Signed-off-by: Daniel Phillips <d.phillips@partner.samsung.com>
Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
diff --git a/fs/tux3/Makefile b/fs/tux3/Makefile
index 93229a1..f5ceaea 100644
--- a/fs/tux3/Makefile
+++ b/fs/tux3/Makefile
@@ -7,7 +7,7 @@
make -C $(LINUX) M=`pwd` CONFIG_TUX3=m clean
else
obj-$(CONFIG_TUX3) += tux3.o
-tux3-objs += balloc.o btree.o buffer.o commit.o dir.o dleaf.o dleaf2.o \
+tux3-objs += balloc.o btree.o buffer.o commit.o dir.o dleaf.o \
filemap.o iattr.o ileaf.o inode.o log.o namei.o orphan.o replay.o \
super.o utility.o writeback.o xattr.o
EXTRA_CFLAGS += -Werror -std=gnu99 -Wno-declaration-after-statement
diff --git a/fs/tux3/dleaf2.c b/fs/tux3/dleaf.c
similarity index 99%
rename from fs/tux3/dleaf2.c
rename to fs/tux3/dleaf.c
index 6d0e32c..cbd32bf 100644
--- a/fs/tux3/dleaf2.c
+++ b/fs/tux3/dleaf.c
@@ -29,7 +29,7 @@
*/
#include "tux3.h"
-#include "dleaf2.h"
+#include "dleaf.h"
/*
* The uptag is for filesystem integrity checking and corruption
diff --git a/fs/tux3/dleaf.h b/fs/tux3/dleaf.h
index e0dd69f..ffbc2fa 100644
--- a/fs/tux3/dleaf.h
+++ b/fs/tux3/dleaf.h
@@ -1,136 +1,30 @@
-#ifndef TUX3_DLEAF_H
-#define TUX3_DLEAF_H
+#ifndef TUX3_DLEAF2_H
+#define TUX3_DLEAF2_H
-/* version:10, count:6, block:48 */
-struct diskextent { __be64 block_count_version; };
-#define MAX_GROUP_ENTRIES 255
-/* count:8, keyhi:24 */
-struct group { __be32 count_and_keyhi; };
-/* limit:8, keylo:24 */
-struct entry { __be32 limit_and_keylo; };
-struct dleaf { __be16 magic, groups, free, used; struct diskextent table[]; };
+struct dleaf_req {
+ struct btree_key_range key; /* index and count */
-/* Maximum size of one extent on dleaf. */
-#define DLEAF_MAX_EXTENT_SIZE \
- (sizeof(struct group)+sizeof(struct entry)+sizeof(struct diskextent))
+ int seg_cnt; /* How many segs are available */
+ int seg_max; /* Max size of seg[] */
+ struct block_segment *seg; /* Pointer to seg[] */
-struct dwalk {
- struct dleaf *leaf;
- struct group *group, *gstop, *gdict;
- struct entry *entry, *estop;
- struct diskextent *exbase, *extent, *exstop;
- struct {
- struct group group;
- struct entry entry;
- int used, free, groups;
- } mock;
+ int seg_idx; /* use by dleaf2_write() internally */
+ int overwrite;
+
+ /* Callback to allocate blocks to ->seg for write */
+ int (*seg_find)(struct btree *, struct dleaf_req *, int, unsigned,
+ unsigned *);
+ int (*seg_alloc)(struct btree *, struct dleaf_req *, int);
+ void (*seg_free)(struct btree *, block_t, unsigned);
};
-/* group wrappers */
-
-static inline struct group make_group(tuxkey_t keyhi, unsigned count)
+static inline unsigned seg_total_count(struct block_segment *seg, int nr_segs)
{
- return (struct group){ cpu_to_be32(keyhi | (count << 24)) };
+ unsigned total = 0;
+ int i;
+ for (i = 0; i < nr_segs; i++)
+ total += seg[i].count;
+ return total;
}
-static inline unsigned group_keyhi(struct group *group)
-{
- return be32_to_cpup((__be32 *)group) & 0xffffff;
-}
-
-static inline unsigned group_count(struct group *group)
-{
- return *(unsigned char *)group;
-}
-
-static inline void set_group_count(struct group *group, int n)
-{
- *(unsigned char *)group = n;
-}
-
-static inline void inc_group_count(struct group *group, int n)
-{
- *(unsigned char *)group += n;
-}
-
-/* entry wrappers */
-
-static inline struct entry make_entry(tuxkey_t keylo, unsigned limit)
-{
- return (struct entry){ cpu_to_be32(keylo | (limit << 24)) };
-}
-
-static inline unsigned entry_keylo(struct entry *entry)
-{
- return be32_to_cpup((__be32 *)entry) & ~(-1 << 24);
-}
-
-static inline unsigned entry_limit(struct entry *entry)
-{
- return *(unsigned char *)entry;
-}
-
-static inline void inc_entry_limit(struct entry *entry, int n)
-{
- *(unsigned char *)entry += n;
-}
-
-/* extent wrappers */
-
-static inline struct diskextent make_extent(block_t block, unsigned count)
-{
- assert(block < (1ULL << 48) && count - 1 < (1 << 6));
- return (struct diskextent){ cpu_to_be64(((u64)(count - 1) << 48) | block) };
-}
-
-static inline block_t extent_block(struct diskextent extent)
-{
- return be64_to_cpup((__be64 *)&extent) & ~(-1LL << 48);
-}
-
-static inline unsigned extent_count(struct diskextent extent)
-{
- return ((be64_to_cpup((__be64 *)&extent) >> 48) & 0x3f) + 1;
-}
-
-static inline unsigned extent_version(struct diskextent extent)
-{
- return be64_to_cpu(*(__be64 *)&extent) >> 54;
-}
-
-/* dleaf wrappers */
-
-static inline unsigned dleaf_groups(struct dleaf *leaf)
-{
- return be16_to_cpu(leaf->groups);
-}
-
-static inline void set_dleaf_groups(struct dleaf *leaf, int n)
-{
- leaf->groups = cpu_to_be16(n);
-}
-
-static inline void inc_dleaf_groups(struct dleaf *leaf, int n)
-{
- be16_add_cpu(&leaf->groups, n);
-}
-
-int dleaf_init(struct btree *btree, void *leaf);
-unsigned dleaf_free(struct btree *btree, void *leaf);
-void dleaf_dump(struct btree *btree, void *vleaf);
-int dleaf_merge(struct btree *btree, void *vinto, void *vfrom);
-extern struct btree_ops dtree1_ops;
-
-void dwalk_redirect(struct dwalk *walk, struct dleaf *src, struct dleaf *dst);
-int dwalk_end(struct dwalk *walk);
-block_t dwalk_block(struct dwalk *walk);
-unsigned dwalk_count(struct dwalk *walk);
-tuxkey_t dwalk_index(struct dwalk *walk);
-int dwalk_next(struct dwalk *walk);
-int dwalk_back(struct dwalk *walk);
-int dwalk_probe(struct dleaf *leaf, unsigned blocksize, struct dwalk *walk, tuxkey_t key);
-int dwalk_mock(struct dwalk *walk, tuxkey_t index, struct diskextent extent);
-void dwalk_copy(struct dwalk *walk, struct dleaf *dest);
-void dwalk_chop(struct dwalk *walk);
-int dwalk_add(struct dwalk *walk, tuxkey_t index, struct diskextent extent);
-#endif /* !TUX3_DLEAF_H */
+#endif /* !TUX3_DLEAF2_H */
diff --git a/fs/tux3/dleaf2.h b/fs/tux3/dleaf2.h
deleted file mode 100644
index ffbc2fa..0000000
--- a/fs/tux3/dleaf2.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef TUX3_DLEAF2_H
-#define TUX3_DLEAF2_H
-
-struct dleaf_req {
- struct btree_key_range key; /* index and count */
-
- int seg_cnt; /* How many segs are available */
- int seg_max; /* Max size of seg[] */
- struct block_segment *seg; /* Pointer to seg[] */
-
- int seg_idx; /* use by dleaf2_write() internally */
- int overwrite;
-
- /* Callback to allocate blocks to ->seg for write */
- int (*seg_find)(struct btree *, struct dleaf_req *, int, unsigned,
- unsigned *);
- int (*seg_alloc)(struct btree *, struct dleaf_req *, int);
- void (*seg_free)(struct btree *, block_t, unsigned);
-};
-
-static inline unsigned seg_total_count(struct block_segment *seg, int nr_segs)
-{
- unsigned total = 0;
- int i;
- for (i = 0; i < nr_segs; i++)
- total += seg[i].count;
- return total;
-}
-
-#endif /* !TUX3_DLEAF2_H */
diff --git a/fs/tux3/filemap.c b/fs/tux3/filemap.c
index 678c217..34407ba 100644
--- a/fs/tux3/filemap.c
+++ b/fs/tux3/filemap.c
@@ -45,7 +45,7 @@
*/
#include "tux3.h"
-#include "dleaf2.h"
+#include "dleaf.h"
#ifndef trace
#define trace trace_on
@@ -89,280 +89,6 @@
return 0;
}
-/* map_region() by using dleaf1 */
-static int map_region1(struct inode *inode, block_t start, unsigned count,
- struct block_segment seg[], unsigned seg_max,
- enum map_mode mode)
-{
- struct sb *sb = tux_sb(inode->i_sb);
- struct btree *btree = &tux_inode(inode)->btree;
- struct cursor *cursor = NULL;
- int err, segs = 0;
-
- assert(seg_max > 0);
-
- /*
- * bitmap enters here recursively.
- *
- * tux3_flush_inode_internal() (flush bitmap)
- * flush_list()
- * map_region() (for flush)
- * balloc()
- * read bitmap
- * map_region() (for read)
- *
- * But bitmap is used (read/write) only from backend.
- * So, no need to lock.
- */
- if (tux_inode(inode)->inum != TUX_BITMAP_INO) {
- if (mode == MAP_READ)
- down_read(&btree->lock);
- else {
- /* If write, must be backend */
- assert(tux3_under_backend(sb));
- down_write(&btree->lock);
- }
- } else {
- /* If bitmap, must be backend */
- assert(tux3_under_backend(sb));
- }
-
- if (!has_root(btree) && mode != MAP_READ) {
- /*
- * Allocate empty btree if this btree doesn't have it yet.
- * FIXME: this should be merged to insert_leaf() or something?
- */
- err = alloc_empty_btree(btree);
- if (err) {
- segs = err;
- goto out_unlock;
- }
- }
-
- /* dwalk_end(walk) is true with this. */
- struct dwalk *walk = &(struct dwalk){ };
- struct dleaf *leaf = NULL;
- if (has_root(btree)) {
- cursor = alloc_cursor(btree, 1); /* allows for depth increase */
- if (!cursor) {
- segs = -ENOMEM;
- goto out_unlock;
- }
-
- if ((err = btree_probe(cursor, start))) {
- segs = err;
- goto out_unlock;
- }
- leaf = bufdata(cursor_leafbuf(cursor));
- dleaf_dump(btree, leaf);
- dwalk_probe(leaf, sb->blocksize, walk, start);
- } else {
- assert(mode == MAP_READ);
- /* btree doesn't have root yet */
- }
-
- block_t limit = start + count;
- if (cursor) {
- assert(start >= cursor_this_key(cursor));
- /* do not overlap next leaf */
- if (limit > cursor_next_key(cursor))
- limit = cursor_next_key(cursor);
- }
- trace("--- index %Lx, limit %Lx ---", start, limit);
-
- block_t index = start, seg_start, block;
- struct dwalk headwalk = *walk;
- if (!dwalk_end(walk) && dwalk_index(walk) < start)
- seg_start = dwalk_index(walk);
- else
- seg_start = index;
- while (index < limit && segs < seg_max) {
- block_t ex_index;
- if (!dwalk_end(walk))
- ex_index = dwalk_index(walk);
- else
- ex_index = limit;
-
- if (index < ex_index) {
- /* There is hole */
- ex_index = min(ex_index, limit);
- unsigned gap = ex_index - index;
- index = ex_index;
- seg[segs++] = (struct block_segment){
- .count = gap,
- .state = BLOCK_SEG_HOLE,
- };
- } else {
- block = dwalk_block(walk);
- count = dwalk_count(walk);
- trace("emit %Lx/%x", block, count);
- seg[segs++] = (struct block_segment){
- .block = block,
- .count = count,
- };
- index = ex_index + count;
- dwalk_next(walk);
- }
- }
- assert(segs);
- unsigned below = start - seg_start, above = index - min(index, limit);
- seg[0].block += below;
- seg[0].count -= below;
- seg[segs - 1].count -= above;
-
- if (mode == MAP_READ)
- goto out_release;
-
- /* Save blocks before change seg[] for below or above. */
- block_t below_block, above_block;
- below_block = seg[0].block - below;
- above_block = seg[segs - 1].block + seg[segs - 1].count;
- if (mode == MAP_REDIRECT) {
- /* Change the seg[] to redirect this region as one extent */
- count = 0;
- for (int i = 0; i < segs; i++) {
- /* Logging overwritten extents as free */
- if (seg[i].state != BLOCK_SEG_HOLE)
- map_bfree(inode, seg[i].block, seg[i].count);
- count += seg[i].count;
- }
- segs = 1;
- seg[0].block = 0;
- seg[0].count = count;
- seg[0].state = BLOCK_SEG_HOLE;
- }
- for (int i = 0; i < segs; i++) {
- int newsegs;
- if (seg[i].state != BLOCK_SEG_HOLE)
- continue;
-
- count = seg[i].count;
- err = balloc_segs(sb, &seg[i], 1, &newsegs, &count);
- if (!err && count != 0) {
- /* FIXME: should handle partial allocation */
- err = -ENOSPC;
- }
- if (err) {
- /*
- * Out of space on file data allocation. It happens. Tread
- * carefully. We have not stored anything in the btree yet,
- * so we free what we allocated so far. We need to leave the
- * user with a nice ENOSPC return and all metadata consistent
- * on disk. We better have reserved everything we need for
- * metadata, just giving up is not an option.
- */
- /*
- * Alternatively, we can go ahead and try to record just what
- * we successfully allocated, then if the update fails on no
- * space for btree splits, free just the blocks for extents
- * we failed to store.
- */
- segs = err;
- goto out_release;
- }
- log_balloc(sb, seg[i].block, seg[i].count);
- trace("fill in %Lx/%i ", seg[i].block, seg[i].count);
-
- /* if mode == MAP_REDIRECT, buffer should be dirty */
- seg[i].state = (mode == MAP_REDIRECT) ? 0 : BLOCK_SEG_NEW;
- }
-
- /* Start to reflect the seg[] changes to the data btree */
- if ((err = cursor_redirect(cursor))) {
- segs = err;
- goto out_release;
- }
- /* Update redirected place for local variables */
- dwalk_redirect(walk, leaf, bufdata(cursor_leafbuf(cursor)));
- dwalk_redirect(&headwalk, leaf, bufdata(cursor_leafbuf(cursor)));
- leaf = bufdata(cursor_leafbuf(cursor));
-
- struct dleaf *tail = NULL;
- tuxkey_t tailkey = 0; // probably can just use limit instead
- if (!dwalk_end(walk)) {
- tail = kmalloc(sb->blocksize, GFP_NOFS); // error???
- dleaf_init(btree, tail);
- tailkey = dwalk_index(walk);
- dwalk_copy(walk, tail);
- }
- /* Go back to region start and pack in new seg */
- dwalk_chop(&headwalk);
- index = start;
- for (int i = -!!below; i < segs + !!above; i++) {
- if (dleaf_free(btree, leaf) < DLEAF_MAX_EXTENT_SIZE) {
- mark_buffer_dirty_non(cursor_leafbuf(cursor));
- struct buffer_head *newbuf = new_leaf(btree);
- if (IS_ERR(newbuf)) {
- segs = PTR_ERR(newbuf);
- goto out_create;
- }
- log_balloc(sb, bufindex(newbuf), 1);
- /*
- * ENOSPC on btree index split could leave the
- * cache state badly messed up. Going to have
- * to do this in two steps: first, look at the
- * cursor to see how many splits we need, then
- * make sure we have that, or give up before
- * starting.
- */
- btree_insert_leaf(cursor, index, newbuf);
- leaf = bufdata(cursor_leafbuf(cursor));
- dwalk_probe(leaf, sb->blocksize, &headwalk, index);
- }
- if (i < 0) {
- trace("emit below");
- dwalk_add(&headwalk, seg_start, make_extent(below_block, below));
- continue;
- }
- if (i == segs) {
- trace("emit above");
- dwalk_add(&headwalk, index, make_extent(above_block, above));
- continue;
- }
- trace("pack 0x%Lx => %Lx/%x", index, seg[i].block, seg[i].count);
- dleaf_dump(btree, leaf);
- dwalk_add(&headwalk, index, make_extent(seg[i].block, seg[i].count));
- dleaf_dump(btree, leaf);
- index += seg[i].count;
- }
- if (tail) {
- if (!dleaf_merge(btree, leaf, tail)) {
- mark_buffer_dirty_non(cursor_leafbuf(cursor));
- assert(dleaf_groups(tail) >= 1);
- /* Tail does not fit, add it as a new btree leaf */
- struct buffer_head *newbuf = new_leaf(btree);
- if (IS_ERR(newbuf)) {
- segs = PTR_ERR(newbuf);
- goto out_create;
- }
- memcpy(bufdata(newbuf), tail, sb->blocksize);
- log_balloc(sb, bufindex(newbuf), 1);
- if ((err = btree_insert_leaf(cursor, tailkey, newbuf))) {
- segs = err;
- goto out_create;
- }
- }
- }
- mark_buffer_dirty_non(cursor_leafbuf(cursor));
-out_create:
- if (tail)
- kfree(tail);
-out_release:
- if (cursor)
- release_cursor(cursor);
-out_unlock:
- if (tux_inode(inode)->inum != TUX_BITMAP_INO) {
- if (mode == MAP_READ)
- up_read(&btree->lock);
- else
- up_write(&btree->lock);
- }
- if (cursor)
- free_cursor(cursor);
-
- return segs;
-}
-
static void seg_free(struct btree *btree, block_t block, unsigned count)
{
map_bfree(btree_inode(btree), block, count);
@@ -562,7 +288,6 @@
struct block_segment seg[], unsigned seg_max,
enum map_mode mode)
{
- struct btree *btree = &tux_inode(inode)->btree;
int segs;
/*
@@ -581,10 +306,7 @@
}
}
- if (btree->ops == &dtree1_ops)
- segs = map_region1(inode, start, count, seg, seg_max, mode);
- else
- segs = map_region2(inode, start, count, seg, seg_max, mode);
+ segs = map_region2(inode, start, count, seg, seg_max, mode);
if (mode == MAP_READ) {
/* Update seg[] with hole information */