The st_blocks field reported by fstat should reflect the number of
allocated 512-byte blocks for the guest memfd file.

Extend the fallocate test to verify that st_blocks is correctly updated
when memory is allocated or deallocated via
fallocate(FALLOC_FL_PUNCH_HOLE).

Add checks after each fallocate call to ensure that st_blocks increases on
allocation, decreases when a hole is punched, and is restored when the hole
is re-allocated. Also verify that st_blocks remains unchanged for failing
fallocate calls.

Signed-off-by: Ackerley Tng <[email protected]>
---
 tools/testing/selftests/kvm/guest_memfd_test.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/tools/testing/selftests/kvm/guest_memfd_test.c 
b/tools/testing/selftests/kvm/guest_memfd_test.c
index 81387f06e770a..89228d73fa736 100644
--- a/tools/testing/selftests/kvm/guest_memfd_test.c
+++ b/tools/testing/selftests/kvm/guest_memfd_test.c
@@ -218,41 +218,58 @@ static void test_file_size(int fd, size_t total_size)
        TEST_ASSERT_EQ(sb.st_blksize, page_size);
 }
 
+static void assert_st_blocks_matches_size(int fd, size_t expected_size)
+{
+       struct stat sb;
+
+       kvm_fstat(fd, &sb);
+       TEST_ASSERT_EQ(sb.st_blocks, expected_size / 512);
+}
+
 static void test_fallocate(int fd, size_t total_size)
 {
        int ret;
 
        ret = fallocate(fd, FALLOC_FL_KEEP_SIZE, 0, total_size);
        TEST_ASSERT(!ret, "fallocate with aligned offset and size should 
succeed");
+       assert_st_blocks_matches_size(fd, total_size);
 
        ret = fallocate(fd, FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE,
                        page_size - 1, page_size);
        TEST_ASSERT(ret, "fallocate with unaligned offset should fail");
+       assert_st_blocks_matches_size(fd, total_size);
 
        ret = fallocate(fd, FALLOC_FL_KEEP_SIZE, total_size, page_size);
        TEST_ASSERT(ret, "fallocate beginning at total_size should fail");
+       assert_st_blocks_matches_size(fd, total_size);
 
        ret = fallocate(fd, FALLOC_FL_KEEP_SIZE, total_size + page_size, 
page_size);
        TEST_ASSERT(ret, "fallocate beginning after total_size should fail");
+       assert_st_blocks_matches_size(fd, total_size);
 
        ret = fallocate(fd, FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE,
                        total_size, page_size);
        TEST_ASSERT(!ret, "fallocate(PUNCH_HOLE) at total_size should succeed");
+       assert_st_blocks_matches_size(fd, total_size);
 
        ret = fallocate(fd, FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE,
                        total_size + page_size, page_size);
        TEST_ASSERT(!ret, "fallocate(PUNCH_HOLE) after total_size should 
succeed");
+       assert_st_blocks_matches_size(fd, total_size);
 
        ret = fallocate(fd, FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE,
                        page_size, page_size - 1);
        TEST_ASSERT(ret, "fallocate with unaligned size should fail");
+       assert_st_blocks_matches_size(fd, total_size);
 
        ret = fallocate(fd, FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE,
                        page_size, page_size);
        TEST_ASSERT(!ret, "fallocate(PUNCH_HOLE) with aligned offset and size 
should succeed");
+       assert_st_blocks_matches_size(fd, total_size - page_size);
 
        ret = fallocate(fd, FALLOC_FL_KEEP_SIZE, page_size, page_size);
        TEST_ASSERT(!ret, "fallocate to restore punched hole should succeed");
+       assert_st_blocks_matches_size(fd, total_size);
 }
 
 static void test_invalid_punch_hole(int fd, size_t total_size)
-- 
2.53.0.345.g96ddfc5eaa-goog


Reply via email to