Report free blocks in statfs

Our statfs callback was still using the old buddy allocator.

We add a free segments field to the super and have it track the number
of free segments in the allocator.  We then use that to calculate the
number of free blocks for statfs.

Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
Zach Brown
2017-02-01 13:56:57 -08:00
parent 9f5e42f7dd
commit 6516ce7d57
4 changed files with 28 additions and 2 deletions

View File

@@ -166,8 +166,10 @@ int scoutfs_alloc_segno(struct super_block *sb, u64 *segno)
ret = 0;
out:
if (ret == 0)
if (ret == 0) {
scoutfs_inc_counter(sb, alloc_alloc);
le64_add_cpu(&super->free_segs, -1);
}
up_write(&sal->rwsem);
trace_printk("segno %llu ret %d\n", *segno, ret);
@@ -180,6 +182,8 @@ out:
*/
int scoutfs_alloc_free(struct super_block *sb, u64 segno)
{
struct scoutfs_sb_info *sbi = SCOUTFS_SB(sb);
struct scoutfs_super_block *super = &sbi->super;
struct pending_region *pend;
DECLARE_SEG_ALLOC(sb, sal);
u64 ind;
@@ -205,6 +209,7 @@ int scoutfs_alloc_free(struct super_block *sb, u64 segno)
set_bit_le(nr, pend->reg.bits);
scoutfs_inc_counter(sb, alloc_free);
le64_add_cpu(&super->free_segs, 1);
ret = 0;
out:
up_write(&sal->rwsem);
@@ -281,6 +286,23 @@ out:
return ret;
}
/*
* Return the number of blocks free for statfs.
*/
u64 scoutfs_alloc_bfree(struct super_block *sb)
{
struct scoutfs_sb_info *sbi = SCOUTFS_SB(sb);
struct scoutfs_super_block *super = &sbi->super;
DECLARE_SEG_ALLOC(sb, sal);
u64 bfree;
down_read(&sal->rwsem);
bfree = le64_to_cpu(super->free_segs) << SCOUTFS_SEGMENT_BLOCK_SHIFT;
up_read(&sal->rwsem);
return bfree;
}
static int alloc_treap_compare(void *key, void *data)
{
u64 *ind = key;

View File

@@ -8,6 +8,7 @@ int scoutfs_alloc_free(struct super_block *sb, u64 segno);
int scoutfs_alloc_has_dirty(struct super_block *sb);
int scoutfs_alloc_dirty_ring(struct super_block *sb);
u64 scoutfs_alloc_bfree(struct super_block *sb);
int scoutfs_alloc_setup(struct super_block *sb);
void scoutfs_alloc_destroy(struct super_block *sb);

View File

@@ -23,6 +23,8 @@
#define SCOUTFS_SEGMENT_MASK (SCOUTFS_SEGMENT_SIZE - 1)
#define SCOUTFS_SEGMENT_PAGES (SCOUTFS_SEGMENT_SIZE / PAGE_SIZE)
#define SCOUTFS_SEGMENT_BLOCKS (SCOUTFS_SEGMENT_SIZE / SCOUTFS_BLOCK_SIZE)
#define SCOUTFS_SEGMENT_BLOCK_SHIFT \
(SCOUTFS_SEGMENT_SHIFT - SCOUTFS_BLOCK_SHIFT)
#define SCOUTFS_PAGES_PER_BLOCK (SCOUTFS_BLOCK_SIZE / PAGE_SIZE)
#define SCOUTFS_BLOCK_PAGE_ORDER (SCOUTFS_BLOCK_SHIFT - PAGE_SHIFT)
@@ -350,6 +352,7 @@ struct scoutfs_super_block {
__le64 next_ino;
__le64 alloc_uninit;
__le64 total_segs;
__le64 free_segs;
__le64 total_blocks;
__le64 free_blocks;
__le64 ring_blkno;

View File

@@ -56,7 +56,7 @@ static int scoutfs_statfs(struct dentry *dentry, struct kstatfs *kst)
struct scoutfs_super_block *super = &sbi->super;
__le32 * __packed uuid = (void *)super->uuid;
kst->f_bfree = scoutfs_buddy_bfree(sb);
kst->f_bfree = scoutfs_alloc_bfree(sb);
kst->f_type = SCOUTFS_SUPER_MAGIC;
kst->f_bsize = SCOUTFS_BLOCK_SIZE;
kst->f_blocks = le64_to_cpu(super->total_blocks);