summaryrefslogtreecommitdiff
path: root/src/test/test-fs-util.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2018-02-09 09:50:31 +0100
committerSven Eden <yamakuzure@gmx.net>2018-05-30 07:54:01 +0200
commitaa3cde5d453e3dd0f259827f7f02874d7260047e (patch)
tree1d46ce4596613bcae2a3a7a0cf5a5484a8e7ade8 /src/test/test-fs-util.c
parent743ac495b83a83e7336f55321d38a4ebe7389e58 (diff)
fs-util: add new unlinkat_deallocate() helper
This new helper not only removes a file from a directory but also ensures its space on disk is deallocated, by either punching a hole over the full file or truncating the file afterwards if the file's link counter is 0. This is useful in "vacuuming" algorithms to ensure that client's can't keep the disk space the vacuuming is supposed to recover pinned simply by keeping an fd open to it. (cherry picked from commit 43767d9d5e0ce8923828aebf9154da7af83916f7)
Diffstat (limited to 'src/test/test-fs-util.c')
-rw-r--r--src/test/test-fs-util.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/src/test/test-fs-util.c b/src/test/test-fs-util.c
index b41abd1e0..49883eeaa 100644
--- a/src/test/test-fs-util.c
+++ b/src/test/test-fs-util.c
@@ -531,6 +531,31 @@ static void test_touch_file(void) {
assert_se(timespec_load(&st.st_mtim) == test_mtime);
}
+static void test_unlinkat_deallocate(void) {
+ _cleanup_free_ char *p = NULL;
+ _cleanup_close_ int fd = -1;
+ struct stat st;
+
+ assert_se(tempfn_random_child(NULL, "unlink-deallocation", &p) >= 0);
+
+ fd = open(p, O_WRONLY|O_CLOEXEC|O_CREAT|O_EXCL, 0600);
+ assert_se(fd >= 0);
+
+ assert_se(write(fd, "hallo\n", 6) == 6);
+
+ assert_se(fstat(fd, &st) >= 0);
+ assert_se(st.st_size == 6);
+ assert_se(st.st_blocks > 0);
+ assert_se(st.st_nlink == 1);
+
+ assert_se(unlinkat_deallocate(AT_FDCWD, p, 0) >= 0);
+
+ assert_se(fstat(fd, &st) >= 0);
+ assert_se(IN_SET(st.st_size, 0, 6)); /* depending on whether hole punching worked the size will be 6 (it worked) or 0 (we had to resort to truncation) */
+ assert_se(st.st_blocks == 0);
+ assert_se(st.st_nlink == 0);
+}
+
int main(int argc, char *argv[]) {
test_unlink_noerrno();
test_get_files_in_directory();
@@ -544,6 +569,7 @@ int main(int argc, char *argv[]) {
test_access_fd();
#endif // 0
test_touch_file();
+ test_unlinkat_deallocate();
return 0;
}