diff --git a/kmod/src/format.h b/kmod/src/format.h index 6cfb7322..42eecc90 100644 --- a/kmod/src/format.h +++ b/kmod/src/format.h @@ -481,10 +481,11 @@ struct scoutfs_super_block { __le64 total_meta_blocks; /* both static and dynamic */ __le64 first_meta_blkno; /* first dynamically allocated */ __le64 last_meta_blkno; + __le64 free_meta_blocks; __le64 total_data_blocks; __le64 first_data_blkno; __le64 last_data_blkno; - __le64 free_blocks; + __le64 free_data_blocks; __le64 quorum_fenced_term; __le64 quorum_server_term; __le64 unmount_barrier; diff --git a/kmod/src/server.c b/kmod/src/server.c index 93c89fa7..b05ef812 100644 --- a/kmod/src/server.c +++ b/kmod/src/server.c @@ -144,6 +144,18 @@ static inline int wait_for_commit(struct commit_waiter *cw) return cw->ret; } +/* + * The caller is about to overwrite a ref to an alloc tree. As we do + * so we update the given super free block counter with the difference + * between the old and new allocator roots. + */ +static void update_free_blocks(__le64 *blocks, struct scoutfs_radix_root *prev, + struct scoutfs_radix_root *next) +{ + le64_add_cpu(blocks, le64_to_cpu(next->ref.sm_total) - + le64_to_cpu(prev->ref.sm_total)); +} + /* * A core function of request processing is to modify the manifest and * allocator. Often the processing needs to make the modifications @@ -184,6 +196,11 @@ static void scoutfs_server_commit_func(struct work_struct *work) goto out; } + update_free_blocks(&super->free_meta_blocks, &super->core_meta_avail, + &server->alloc.avail); + update_free_blocks(&super->free_meta_blocks, &super->core_meta_freed, + &server->alloc.freed); + super->core_meta_avail = server->alloc.avail; super->core_meta_freed = server->alloc.freed; @@ -414,6 +431,15 @@ static int server_commit_log_trees(struct super_block *sb, /* XXX probably want to merge free blocks */ + update_free_blocks(&super->free_meta_blocks, <v.meta_avail, + <->meta_avail); + update_free_blocks(&super->free_meta_blocks, <v.meta_freed, + <->meta_freed); + update_free_blocks(&super->free_data_blocks, <v.data_avail, + <->data_avail); + update_free_blocks(&super->free_data_blocks, <v.data_freed, + <->data_freed); + ltv.meta_avail = lt->meta_avail; ltv.meta_freed = lt->meta_freed; ltv.item_root = lt->item_root; @@ -712,7 +738,9 @@ static int server_statfs(struct super_block *sb, nstatfs.total_blocks = super->total_meta_blocks; le64_add_cpu(&nstatfs.total_blocks, le64_to_cpu(super->total_data_blocks)); - nstatfs.bfree = super->free_blocks; + nstatfs.bfree = super->free_meta_blocks; + le64_add_cpu(&nstatfs.bfree, + le64_to_cpu(super->free_data_blocks)); up_read(&server->alloc_rwsem); ret = 0; } else {