mirror of
https://github.com/linux-apfs/apfstests.git
synced 2026-05-01 15:01:44 -07:00
generic: Test that SEEK_HOLE can find a punched hole
Added a test case to seek_sanity_test and a test to run it. Signed-off-by: Amir Goldstein <amir73il@gmail.com> Reviewed-by: Eryu Guan <guaneryu@gmail.com> Signed-off-by: Eryu Guan <guaneryu@gmail.com>
This commit is contained in:
committed by
Eryu Guan
parent
3408108774
commit
f3c1bca7fb
+59
-4
@@ -16,6 +16,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include "global.h"
|
||||||
|
|
||||||
#ifndef SEEK_DATA
|
#ifndef SEEK_DATA
|
||||||
#define SEEK_DATA 3
|
#define SEEK_DATA 3
|
||||||
@@ -26,6 +27,7 @@ static blksize_t alloc_size;
|
|||||||
int allow_default_behavior = 1;
|
int allow_default_behavior = 1;
|
||||||
int default_behavior = 0;
|
int default_behavior = 0;
|
||||||
int unwritten_extents = 0;
|
int unwritten_extents = 0;
|
||||||
|
int punch_hole = 0;
|
||||||
char *base_file_path;
|
char *base_file_path;
|
||||||
|
|
||||||
static void get_file_system(int fd)
|
static void get_file_system(int fd)
|
||||||
@@ -118,8 +120,9 @@ static int do_fallocate(int fd, off_t offset, off_t length, int mode)
|
|||||||
|
|
||||||
ret = fallocate(fd, mode, offset, length);
|
ret = fallocate(fd, mode, offset, length);
|
||||||
if (ret)
|
if (ret)
|
||||||
fprintf(stderr, " ERROR %d: Failed to preallocate "
|
fprintf(stderr, " ERROR %d: Failed to %s of %ld bytes\n",
|
||||||
"space to %ld bytes\n", errno, (long) length);
|
errno, (mode & FALLOC_FL_PUNCH_HOLE) ? "punch hole" :
|
||||||
|
"preallocate space", (long) length);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -262,6 +265,52 @@ out:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make sure hole size is properly reported when punched in the middle of a file
|
||||||
|
*/
|
||||||
|
static int test21(int fd, int testnum)
|
||||||
|
{
|
||||||
|
char *buf = NULL;
|
||||||
|
int bufsz, filsz;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (!punch_hole) {
|
||||||
|
fprintf(stdout, "Test skipped as fs doesn't support punch hole.\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (default_behavior) {
|
||||||
|
fprintf(stdout, "Test skipped as fs doesn't support seeking a punched hole.\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
bufsz = alloc_size * 3;
|
||||||
|
buf = do_malloc(bufsz);
|
||||||
|
if (!buf) {
|
||||||
|
ret = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
memset(buf, 'a', bufsz);
|
||||||
|
|
||||||
|
ret = do_pwrite(fd, buf, bufsz, 0);
|
||||||
|
if (ret)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
filsz = bufsz;
|
||||||
|
ret = do_fallocate(fd, alloc_size, alloc_size,
|
||||||
|
FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE);
|
||||||
|
if (ret < 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
ret += do_lseek(testnum, 1, fd, filsz, SEEK_DATA, 0, 0);
|
||||||
|
ret += do_lseek(testnum, 2, fd, filsz, SEEK_HOLE, 0, alloc_size);
|
||||||
|
ret += do_lseek(testnum, 3, fd, filsz, SEEK_DATA, alloc_size, alloc_size * 2);
|
||||||
|
out:
|
||||||
|
if (buf)
|
||||||
|
free(buf);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make sure hole size is properly reported when starting in the middle of a
|
* Make sure hole size is properly reported when starting in the middle of a
|
||||||
* hole in ext? doubly indirect tree
|
* hole in ext? doubly indirect tree
|
||||||
@@ -1050,6 +1099,7 @@ struct testrec seek_tests[] = {
|
|||||||
{ 18, test18, "Test file with negative SEEK_{HOLE,DATA} offsets" },
|
{ 18, test18, "Test file with negative SEEK_{HOLE,DATA} offsets" },
|
||||||
{ 19, test19, "Test file SEEK_DATA from middle of a large hole" },
|
{ 19, test19, "Test file SEEK_DATA from middle of a large hole" },
|
||||||
{ 20, test20, "Test file SEEK_DATA from middle of a huge hole" },
|
{ 20, test20, "Test file SEEK_DATA from middle of a huge hole" },
|
||||||
|
{ 21, test21, "Test file SEEK_HOLE that was created by PUNCH_HOLE" },
|
||||||
};
|
};
|
||||||
|
|
||||||
static int run_test(struct testrec *tr)
|
static int run_test(struct testrec *tr)
|
||||||
@@ -1127,15 +1177,20 @@ static int test_basic_support(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ftruncate(fd, 0);
|
ftruncate(fd, 0);
|
||||||
if (fallocate(fd, 0, 0, alloc_size) == -1) {
|
if (fallocate(fd, 0, 0, alloc_size * 2) == -1) {
|
||||||
if (errno == EOPNOTSUPP)
|
if (errno == EOPNOTSUPP)
|
||||||
fprintf(stderr, "File system does not support fallocate.");
|
fprintf(stderr, "File system does not support fallocate.\n");
|
||||||
else {
|
else {
|
||||||
fprintf(stderr, "ERROR %d: Failed to preallocate "
|
fprintf(stderr, "ERROR %d: Failed to preallocate "
|
||||||
"space to %ld bytes. Aborting.\n", errno, (long) alloc_size);
|
"space to %ld bytes. Aborting.\n", errno, (long) alloc_size);
|
||||||
ret = -1;
|
ret = -1;
|
||||||
}
|
}
|
||||||
goto out;
|
goto out;
|
||||||
|
} else if (fallocate(fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
|
||||||
|
0, alloc_size) == -1) {
|
||||||
|
fprintf(stderr, "File system does not support punch hole.\n");
|
||||||
|
} else {
|
||||||
|
punch_hole = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pos = lseek(fd, 0, SEEK_DATA);
|
pos = lseek(fd, 0, SEEK_DATA);
|
||||||
|
|||||||
Executable
+46
@@ -0,0 +1,46 @@
|
|||||||
|
#! /bin/bash
|
||||||
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
|
# Copyright (C) 2019, CTERA Networks. All Rights Reserved.
|
||||||
|
#
|
||||||
|
# FS QA Test No. 539
|
||||||
|
#
|
||||||
|
# Check that SEEK_HOLE can find a punched hole.
|
||||||
|
#
|
||||||
|
seq=`basename $0`
|
||||||
|
seqres=$RESULT_DIR/$seq
|
||||||
|
echo "QA output created by $seq"
|
||||||
|
|
||||||
|
here=`pwd`
|
||||||
|
tmp=/tmp/$$
|
||||||
|
status=1 # failure is the default!
|
||||||
|
trap "_cleanup; exit \$status" 0 1 2 3 15
|
||||||
|
|
||||||
|
# get standard environment, filters and checks
|
||||||
|
. ./common/rc
|
||||||
|
|
||||||
|
_supported_fs generic
|
||||||
|
_supported_os Linux
|
||||||
|
|
||||||
|
_require_test
|
||||||
|
_require_seek_data_hole
|
||||||
|
_require_xfs_io_command "fpunch"
|
||||||
|
|
||||||
|
base_test_file=$TEST_DIR/seek_sanity_testfile.$seq
|
||||||
|
|
||||||
|
_require_test_program "seek_sanity_test"
|
||||||
|
|
||||||
|
_cleanup()
|
||||||
|
{
|
||||||
|
cd /
|
||||||
|
rm -f $tmp.*
|
||||||
|
rm -f $base_test_file*
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "Silence is golden"
|
||||||
|
|
||||||
|
_run_seek_sanity_test -s 21 -e 21 $base_test_file > $seqres.full 2>&1 ||
|
||||||
|
_fail "seek sanity check failed!"
|
||||||
|
|
||||||
|
# success, all done
|
||||||
|
status=0
|
||||||
|
exit
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
QA output created by 539
|
||||||
|
Silence is golden
|
||||||
@@ -541,3 +541,4 @@
|
|||||||
536 auto quick rw shutdown
|
536 auto quick rw shutdown
|
||||||
537 auto quick trim
|
537 auto quick trim
|
||||||
538 auto quick aio
|
538 auto quick aio
|
||||||
|
539 auto quick punch seek
|
||||||
|
|||||||
Reference in New Issue
Block a user