aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Phillips <daniel@tux3.org>2014-02-19 03:51:48 +0900
committerDaniel Phillips <daniel@tux3.org>2014-02-19 03:51:48 +0900
commit18d5bc21bb104c99e8ecdd57153663238dbe8869 (patch)
tree5e2290259fbf78f0f45f2e47b9e2d63995f90216
parent1e78fd478ab812419cd4e61ad24d390124599532 (diff)
downloadlinux-tux3-18d5bc21bb104c99e8ecdd57153663238dbe8869.tar.gz
tux3: Introduce a new system inode to hold a table of allocation group counts.
Consistency semantics are the same as bitmap: update on unify and handle possible recursive update. Signed-off-by: Daniel Phillips <d.phillips@partner.samsung.com> Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
-rw-r--r--fs/tux3/commit.c6
-rw-r--r--fs/tux3/filemap.c10
-rw-r--r--fs/tux3/inode.c10
-rw-r--r--fs/tux3/super.c17
-rw-r--r--fs/tux3/tux3.h8
5 files changed, 44 insertions, 7 deletions
diff --git a/fs/tux3/commit.c b/fs/tux3/commit.c
index 19d7efdfd030ae..5cb0040e077498 100644
--- a/fs/tux3/commit.c
+++ b/fs/tux3/commit.c
@@ -256,6 +256,11 @@ static int unify_log(struct sb *sb)
tux3_flush_inode_internal(sb->bitmap, unify, REQ_META);
trace("< done bitmap %u", unify);
+ /* Flush bitmap */
+ trace("> flush countmap %u", unify);
+ tux3_flush_inode_internal(sb->countmap, unify, REQ_META);
+ trace("< done countmap %u", unify);
+
trace("> apply orphan inodes %u", unify);
{
int err;
@@ -629,6 +634,7 @@ unsigned tux3_inode_delta(struct inode *inode)
delta = TUX3_INIT_DELTA;
break;
case TUX_BITMAP_INO:
+ case TUX_COUNTMAP_INO:
delta = tux_sb(inode->i_sb)->unify;
break;
default:
diff --git a/fs/tux3/filemap.c b/fs/tux3/filemap.c
index 1882015a0d0d34..db60c79fd00d99 100644
--- a/fs/tux3/filemap.c
+++ b/fs/tux3/filemap.c
@@ -73,13 +73,19 @@ void show_segs(struct block_segment seg[], unsigned segs)
static int map_bfree(struct inode *inode, block_t block, unsigned count)
{
struct sb *sb = tux_sb(inode->i_sb);
- if (inode == sb->bitmap) {
+
+ switch (tux_inode(inode)->inum) {
+ case TUX_BITMAP_INO:
+ case TUX_COUNTMAP_INO:
log_bfree_on_unify(sb, block, count);
defer_bfree(sb, &sb->deunify, block, count);
- } else {
+ break;
+ default:
log_bfree(sb, block, count);
defer_bfree(sb, &sb->defree, block, count);
+ break;
}
+
return 0;
}
diff --git a/fs/tux3/inode.c b/fs/tux3/inode.c
index b76fb28db3b633..87cfaac6574af0 100644
--- a/fs/tux3/inode.c
+++ b/fs/tux3/inode.c
@@ -582,6 +582,7 @@ int tux3_save_inode(struct inode *inode, struct tux3_iattr_data *idata,
tux_inode(inode)->inum != TUX_INVALID_INO);
switch (tux_inode(inode)->inum) {
case TUX_BITMAP_INO:
+ case TUX_COUNTMAP_INO:
case TUX_VTABLE_INO:
case TUX_ATABLE_INO:
/* FIXME: assert(only btree should be changed); */
@@ -999,6 +1000,7 @@ static void tux_setup_inode(struct inode *inode)
/* FIXME: bitmap, logmap, vtable, atable doesn't have S_IFMT */
switch (inum) {
case TUX_BITMAP_INO:
+ case TUX_COUNTMAP_INO:
case TUX_VTABLE_INO:
case TUX_ATABLE_INO:
/* set fake i_size to escape the check of block_* */
@@ -1027,6 +1029,7 @@ static void tux_setup_inode(struct inode *inode)
/* Prevent reentering into our fs recursively by mem reclaim */
switch (inum) {
case TUX_BITMAP_INO:
+ case TUX_COUNTMAP_INO:
case TUX_VOLMAP_INO:
case TUX_LOGMAP_INO:
/* FIXME: we should use non-__GFP_FS for all? */
@@ -1044,8 +1047,13 @@ static void tux_setup_inode(struct inode *inode)
*
* See, FIXME in tux3_mark_buffer_unify().
*/
- if (inum == TUX_BITMAP_INO || inum == TUX_VOLMAP_INO)
+ switch (inum) {
+ case TUX_BITMAP_INO:
+ case TUX_COUNTMAP_INO:
+ case TUX_VOLMAP_INO:
tux3_set_inode_always_dirty(inode);
+ break;
+ }
break;
}
default:
diff --git a/fs/tux3/super.c b/fs/tux3/super.c
index 3cda49a2d90fc8..522a98da530bd2 100644
--- a/fs/tux3/super.c
+++ b/fs/tux3/super.c
@@ -61,16 +61,22 @@ static void cleanup_dirty_inode(struct inode *inode)
static void cleanup_dirty_for_umount(struct sb *sb)
{
unsigned unify = sb->unify;
+ struct list_head *head;
/*
* Pinned buffer and bitmap are not flushing always, it is
* normal. So, this clean those for unmount.
*/
if (sb->bitmap) {
- struct list_head *head = tux3_dirty_buffers(sb->bitmap, unify);
+ head = tux3_dirty_buffers(sb->bitmap, unify);
cleanup_dirty_buffers(sb->bitmap, head, unify);
cleanup_dirty_inode(sb->bitmap);
}
+ if (sb->countmap) {
+ head = tux3_dirty_buffers(sb->countmap, unify);
+ cleanup_dirty_buffers(sb->countmap, head, unify);
+ cleanup_dirty_inode(sb->countmap);
+ }
if (sb->volmap) {
cleanup_dirty_buffers(sb->volmap, &sb->unify_buffers, unify);
/*
@@ -110,6 +116,8 @@ static void __tux3_put_super(struct sb *sbi)
sbi->vtable = NULL;
iput(sbi->bitmap);
sbi->bitmap = NULL;
+ iput(sbi->countmap);
+ sbi->countmap = NULL;
iput(sbi->logmap);
sbi->logmap = NULL;
iput(sbi->volmap);
@@ -195,6 +203,13 @@ struct replay *tux3_init_fs(struct sb *sbi)
goto error_inode;
}
sbi->bitmap = inode;
+
+ inode = iget_or_create_inode(sbi, TUX_COUNTMAP_INO);
+ if (IS_ERR(inode)) {
+ name = "countmap";
+ goto error_inode;
+ }
+ sbi->countmap = inode;
#if 0
inode = tux3_iget(sbi, TUX_VTABLE_INO);
if (IS_ERR(inode)) {
diff --git a/fs/tux3/tux3.h b/fs/tux3/tux3.h
index 4161f8d25f445c..e9941f9840ecf8 100644
--- a/fs/tux3/tux3.h
+++ b/fs/tux3/tux3.h
@@ -125,9 +125,10 @@ static inline void *decode48(void *at, u64 *val)
/* Special inode numbers */
#define TUX_BITMAP_INO 0
-#define TUX_VTABLE_INO 1
-#define TUX_ATABLE_INO 2
-#define TUX_ROOTDIR_INO 3
+#define TUX_COUNTMAP_INO 1 /* Block group free count map */
+#define TUX_VTABLE_INO 2
+#define TUX_ATABLE_INO 3
+#define TUX_ROOTDIR_INO 4
#define TUX_VOLMAP_INO 61 /* This doesn't have entry in ileaf */
#define TUX_LOGMAP_INO 62 /* This is volmap for log blocks */
#define TUX_INVALID_INO 63 /* FIXME: just for debugging */
@@ -261,6 +262,7 @@ struct sb {
struct btree otree; /* Orphan btree */
struct inode *volmap; /* Volume metadata cache (like blockdev). */
struct inode *bitmap; /* allocation bitmap special file */
+ struct inode *countmap; /* block group free count map */
struct inode *rootdir; /* root directory special file */
struct inode *vtable; /* version table special file */
struct inode *atable; /* xattr atom special file */