nilfs2: record used amount of each checkpoint in checkpoint list
Ryusuke Konishi [Fri, 4 Mar 2011 15:19:32 +0000 (00:19 +0900)]
This records the number of used blocks per checkpoint in each
checkpoint entry of cpfile.  Even though userland tools can get the
block count via nilfs_get_cpinfo ioctl, it was not updated by the
nilfs2 kernel code.  This fixes the issue and makes it available for
userland tools to calculate used amount per checkpoint.

Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Cc: Jiro SEKIBA <jir@unicus.jp>

fs/nilfs2/bmap.c
fs/nilfs2/bmap.h
fs/nilfs2/btree.c
fs/nilfs2/direct.c
fs/nilfs2/inode.c
fs/nilfs2/nilfs.h
include/linux/nilfs2_fs.h

index 3ee67c6..85447a2 100644 (file)
@@ -425,17 +425,6 @@ int nilfs_bmap_test_and_clear_dirty(struct nilfs_bmap *bmap)
 /*
  * Internal use only
  */
-
-void nilfs_bmap_add_blocks(const struct nilfs_bmap *bmap, int n)
-{
-       inode_add_bytes(bmap->b_inode, (1 << bmap->b_inode->i_blkbits) * n);
-}
-
-void nilfs_bmap_sub_blocks(const struct nilfs_bmap *bmap, int n)
-{
-       inode_sub_bytes(bmap->b_inode, (1 << bmap->b_inode->i_blkbits) * n);
-}
-
 __u64 nilfs_bmap_data_get_key(const struct nilfs_bmap *bmap,
                              const struct buffer_head *bh)
 {
index bde1c0a..40d9f45 100644 (file)
@@ -240,9 +240,6 @@ __u64 nilfs_bmap_data_get_key(const struct nilfs_bmap *,
 __u64 nilfs_bmap_find_target_seq(const struct nilfs_bmap *, __u64);
 __u64 nilfs_bmap_find_target_in_group(const struct nilfs_bmap *);
 
-void nilfs_bmap_add_blocks(const struct nilfs_bmap *, int);
-void nilfs_bmap_sub_blocks(const struct nilfs_bmap *, int);
-
 
 /* Assume that bmap semaphore is locked. */
 static inline int nilfs_bmap_dirty(const struct nilfs_bmap *bmap)
index 300c2bc..d451ae0 100644 (file)
@@ -1174,7 +1174,7 @@ static int nilfs_btree_insert(struct nilfs_bmap *btree, __u64 key, __u64 ptr)
        if (ret < 0)
                goto out;
        nilfs_btree_commit_insert(btree, path, level, key, ptr);
-       nilfs_bmap_add_blocks(btree, stats.bs_nblocks);
+       nilfs_inode_add_blocks(btree->b_inode, stats.bs_nblocks);
 
  out:
        nilfs_btree_free_path(path);
@@ -1511,7 +1511,7 @@ static int nilfs_btree_delete(struct nilfs_bmap *btree, __u64 key)
        if (ret < 0)
                goto out;
        nilfs_btree_commit_delete(btree, path, level, dat);
-       nilfs_bmap_sub_blocks(btree, stats.bs_nblocks);
+       nilfs_inode_sub_blocks(btree->b_inode, stats.bs_nblocks);
 
 out:
        nilfs_btree_free_path(path);
@@ -1776,7 +1776,7 @@ int nilfs_btree_convert_and_insert(struct nilfs_bmap *btree,
                return ret;
        nilfs_btree_commit_convert_and_insert(btree, key, ptr, keys, ptrs, n,
                                              di, ni, bh);
-       nilfs_bmap_add_blocks(btree, stats.bs_nblocks);
+       nilfs_inode_add_blocks(btree->b_inode, stats.bs_nblocks);
        return 0;
 }
 
index 324d80c..82f4865 100644 (file)
@@ -146,7 +146,7 @@ static int nilfs_direct_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr)
                if (NILFS_BMAP_USE_VBN(bmap))
                        nilfs_bmap_set_target_v(bmap, key, req.bpr_ptr);
 
-               nilfs_bmap_add_blocks(bmap, 1);
+               nilfs_inode_add_blocks(bmap->b_inode, 1);
        }
        return ret;
 }
@@ -168,7 +168,7 @@ static int nilfs_direct_delete(struct nilfs_bmap *bmap, __u64 key)
        if (!ret) {
                nilfs_bmap_commit_end_ptr(bmap, &req, dat);
                nilfs_direct_set_ptr(bmap, key, NILFS_BMAP_INVALID_PTR);
-               nilfs_bmap_sub_blocks(bmap, 1);
+               nilfs_inode_sub_blocks(bmap->b_inode, 1);
        }
        return ret;
 }
index 2534af8..22a816b 100644 (file)
@@ -41,6 +41,24 @@ struct nilfs_iget_args {
        int for_gc;
 };
 
+void nilfs_inode_add_blocks(struct inode *inode, int n)
+{
+       struct nilfs_root *root = NILFS_I(inode)->i_root;
+
+       inode_add_bytes(inode, (1 << inode->i_blkbits) * n);
+       if (root)
+               atomic_add(n, &root->blocks_count);
+}
+
+void nilfs_inode_sub_blocks(struct inode *inode, int n)
+{
+       struct nilfs_root *root = NILFS_I(inode)->i_root;
+
+       inode_sub_bytes(inode, (1 << inode->i_blkbits) * n);
+       if (root)
+               atomic_sub(n, &root->blocks_count);
+}
+
 /**
  * nilfs_get_block() - get a file block on the filesystem (callback function)
  * @inode - inode struct of the target file
index 45b1fd1..03ba4d8 100644 (file)
@@ -251,6 +251,8 @@ int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *, struct nilfs_argv *,
                                       void **);
 
 /* inode.c */
+void nilfs_inode_add_blocks(struct inode *inode, int n);
+void nilfs_inode_sub_blocks(struct inode *inode, int n);
 extern struct inode *nilfs_new_inode(struct inode *, int);
 extern void nilfs_free_inode(struct inode *);
 extern int nilfs_get_block(struct inode *, sector_t, struct buffer_head *, int);
index 3a65e5a..ae33ac2 100644 (file)
@@ -216,8 +216,10 @@ struct nilfs_super_block {
  * If there is a bit set in the incompatible feature set that the kernel
  * doesn't know about, it should refuse to mount the filesystem.
  */
+#define NILFS_FEATURE_COMPAT_RO_BLOCK_COUNT    0x00000001ULL
+
 #define NILFS_FEATURE_COMPAT_SUPP      0ULL
-#define NILFS_FEATURE_COMPAT_RO_SUPP   0ULL
+#define NILFS_FEATURE_COMPAT_RO_SUPP   NILFS_FEATURE_COMPAT_RO_BLOCK_COUNT
 #define NILFS_FEATURE_INCOMPAT_SUPP    0ULL
 
 /*
@@ -509,7 +511,7 @@ struct nilfs_checkpoint {
        __le64 cp_create;
        __le64 cp_nblk_inc;
        __le64 cp_inodes_count;
-       __le64 cp_blocks_count;         /* Reserved (might be deleted) */
+       __le64 cp_blocks_count;
 
        /* Do not change the byte offset of ifile inode.
           To keep the compatibility of the disk format,