Test that st_blocks in struct stat (inode->i_blocks) is updated. Change-Id: I67d814f130671b6b64b575e6a25fd17b1994c640 Signed-off-by: Ackerley Tng <ackerleytng@xxxxxxxxxx> --- .../testing/selftests/kvm/guest_memfd_test.c | 55 ++++++++++++++++--- 1 file changed, 46 insertions(+), 9 deletions(-) diff --git a/tools/testing/selftests/kvm/guest_memfd_test.c b/tools/testing/selftests/kvm/guest_memfd_test.c index c8acccaa9e1d..f51cd876d7dc 100644 --- a/tools/testing/selftests/kvm/guest_memfd_test.c +++ b/tools/testing/selftests/kvm/guest_memfd_test.c @@ -142,41 +142,78 @@ static void test_file_size(int fd, size_t page_size, size_t total_size) TEST_ASSERT_EQ(sb.st_blksize, page_size); } -static void test_fallocate(int fd, size_t page_size, size_t total_size) +static void assert_st_blocks_equals_size(int fd, size_t page_size, size_t expected_size) { + struct stat sb; + int ret; + + /* TODO: st_blocks is not updated for 4K-page guest_memfd. */ + if (page_size == getpagesize()) + return; + + ret = fstat(fd, &sb); + TEST_ASSERT(!ret, "fstat should succeed"); + TEST_ASSERT_EQ(sb.st_blocks, expected_size / 512); +} + +static void test_fallocate(int fd, size_t test_page_size, size_t total_size) +{ + size_t page_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_equals_size(fd, test_page_size, total_size); ret = fallocate(fd, FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE, - page_size - 1, page_size); + test_page_size - 1, test_page_size); TEST_ASSERT(ret, "fallocate with unaligned offset should fail"); + assert_st_blocks_equals_size(fd, test_page_size, total_size); - ret = fallocate(fd, FALLOC_FL_KEEP_SIZE, total_size, page_size); + ret = fallocate(fd, FALLOC_FL_KEEP_SIZE, total_size, test_page_size); TEST_ASSERT(ret, "fallocate beginning at total_size should fail"); + assert_st_blocks_equals_size(fd, test_page_size, total_size); - ret = fallocate(fd, FALLOC_FL_KEEP_SIZE, total_size + page_size, page_size); + ret = fallocate(fd, FALLOC_FL_KEEP_SIZE, total_size + test_page_size, test_page_size); TEST_ASSERT(ret, "fallocate beginning after total_size should fail"); + assert_st_blocks_equals_size(fd, test_page_size, total_size); ret = fallocate(fd, FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE, - total_size, page_size); + total_size, test_page_size); TEST_ASSERT(!ret, "fallocate(PUNCH_HOLE) at total_size should succeed"); + assert_st_blocks_equals_size(fd, test_page_size, total_size); ret = fallocate(fd, FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE, - total_size + page_size, page_size); + total_size + test_page_size, test_page_size); TEST_ASSERT(!ret, "fallocate(PUNCH_HOLE) after total_size should succeed"); + assert_st_blocks_equals_size(fd, test_page_size, total_size); ret = fallocate(fd, FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE, - page_size, page_size - 1); + test_page_size, test_page_size - 1); TEST_ASSERT(ret, "fallocate with unaligned size should fail"); + assert_st_blocks_equals_size(fd, test_page_size, total_size); ret = fallocate(fd, FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE, - page_size, page_size); + test_page_size, test_page_size); TEST_ASSERT(!ret, "fallocate(PUNCH_HOLE) with aligned offset and size should succeed"); + assert_st_blocks_equals_size(fd, test_page_size, total_size - test_page_size); - ret = fallocate(fd, FALLOC_FL_KEEP_SIZE, page_size, page_size); + ret = fallocate(fd, FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE, + test_page_size, test_page_size); + TEST_ASSERT(!ret, "fallocate(PUNCH_HOLE) in a hole should succeed"); + assert_st_blocks_equals_size(fd, test_page_size, total_size - test_page_size); + + ret = fallocate(fd, FALLOC_FL_KEEP_SIZE, test_page_size, test_page_size); TEST_ASSERT(!ret, "fallocate to restore punched hole should succeed"); + assert_st_blocks_equals_size(fd, test_page_size, total_size); + + page_size = getpagesize(); + if (test_page_size == page_size) { + ret = fallocate(fd, FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE, + test_page_size + page_size, page_size); + TEST_ASSERT(!ret, "fallocate(PUNCH_HOLE) of a subfolio should succeed"); + assert_st_blocks_equals_size(fd, test_page_size, total_size); + } } static void test_invalid_punch_hole(int fd, size_t page_size, size_t total_size) -- 2.49.0.1045.g170613ef41-goog