The guest memfd currently does not update the inode's i_blocks and i_bytes count when memory is allocated or freed. Hence, st_blocks returned from fstat() is always 0.
Introduce byte accounting for guest memfd inodes. When a new folio is added to the filemap, add the folio's size. Conversely, when folios are truncated and removed from the mapping, deduct the folio's size. With this change, stat.st_blocks for a guest_memfd will correctly report the number of 512-byte blocks allocated to the file, consistent with other memory-based filesystems like tmpfs. Signed-off-by: Ackerley Tng <[email protected]> --- virt/kvm/guest_memfd.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c index 2488d7b8f2b0d..b31e6612d16a8 100644 --- a/virt/kvm/guest_memfd.c +++ b/virt/kvm/guest_memfd.c @@ -137,6 +137,8 @@ static struct folio *__kvm_gmem_get_folio(struct inode *inode, pgoff_t index) return ERR_PTR(ret); } + inode_add_bytes(inode, folio_size(folio)); + return folio; } @@ -553,10 +555,16 @@ static void kvm_gmem_free_folio(struct folio *folio) } #endif +static void kvm_gmem_unaccount_folio(struct folio *folio) +{ + __inode_sub_bytes(folio_inode(folio), folio_size(folio)); +} + static const struct address_space_operations kvm_gmem_aops = { .dirty_folio = noop_dirty_folio, .migrate_folio = kvm_gmem_migrate_folio, .error_remove_folio = kvm_gmem_error_folio, + .unaccount_folio = kvm_gmem_unaccount_folio, #ifdef CONFIG_HAVE_KVM_ARCH_GMEM_INVALIDATE .free_folio = kvm_gmem_free_folio, #endif -- 2.53.0.414.gf7e9f6c205-goog

