diff options
author | Lennart Poettering <lennart@poettering.net> | 2018-02-09 09:50:31 +0100 |
---|---|---|
committer | Sven Eden <yamakuzure@gmx.net> | 2018-05-30 07:54:01 +0200 |
commit | aa3cde5d453e3dd0f259827f7f02874d7260047e (patch) | |
tree | 1d46ce4596613bcae2a3a7a0cf5a5484a8e7ade8 /src/test/test-fs-util.c | |
parent | 743ac495b83a83e7336f55321d38a4ebe7389e58 (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.c | 26 |
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; } |