summaryrefslogtreecommitdiffstats
path: root/src/home/homework-luks.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2020-04-01 18:06:25 +0200
committerLennart Poettering <lennart@poettering.net>2020-04-01 18:19:07 +0200
commite46f877c5c9a82c36f1bd6ba6b801f3853bf60c0 (patch)
tree426398dbb78253ab17075503a4d3ff79cbf9b025 /src/home/homework-luks.c
parentMerge pull request #15253 from DaanDeMeyer/object-vtable-error-docs (diff)
downloadsystemd-e46f877c5c9a82c36f1bd6ba6b801f3853bf60c0.tar.xz
systemd-e46f877c5c9a82c36f1bd6ba6b801f3853bf60c0.zip
homed: fall back to ftruncate() if fallocate() is not supported on backing fs
This means "discard" mode is enabled implicitly on such simpler backing fs. Fixes: #15059
Diffstat (limited to '')
-rw-r--r--src/home/homework-luks.c70
1 files changed, 44 insertions, 26 deletions
diff --git a/src/home/homework-luks.c b/src/home/homework-luks.c
index d731d0d64f..de7535fc60 100644
--- a/src/home/homework-luks.c
+++ b/src/home/homework-luks.c
@@ -1765,6 +1765,45 @@ static int calculate_disk_size(UserRecord *h, const char *parent_dir, uint64_t *
return 0;
}
+static int home_truncate(
+ UserRecord *h,
+ int fd,
+ const char *path,
+ uint64_t size) {
+
+ bool trunc;
+ int r;
+
+ assert(h);
+ assert(fd >= 0);
+ assert(path);
+
+ trunc = user_record_luks_discard(h);
+ if (!trunc) {
+ r = fallocate(fd, 0, 0, size);
+ if (r < 0 && ERRNO_IS_NOT_SUPPORTED(errno)) {
+ /* Some file systems do not support fallocate(), let's gracefully degrade
+ * (ZFS, reiserfs, …) and fall back to truncation */
+ log_notice_errno(errno, "Backing file system does not support fallocate(), falling back to ftruncate(), i.e. implicitly using non-discard mode.");
+ trunc = true;
+ }
+ }
+
+ if (trunc)
+ r = ftruncate(fd, size);
+
+ if (r < 0) {
+ if (ERRNO_IS_DISK_SPACE(errno)) {
+ log_error_errno(errno, "Not enough disk space to allocate home.");
+ return -ENOSPC; /* make recognizable */
+ }
+
+ return log_error_errno(errno, "Failed to truncate home image %s: %m", path);
+ }
+
+ return 0;
+}
+
int home_create_luks(
UserRecord *h,
char **pkcs11_decrypted_passwords,
@@ -1917,20 +1956,9 @@ int home_create_luks(
if (r < 0)
log_warning_errno(r, "Failed to set file attributes on %s, ignoring: %m", temporary_image_path);
- if (user_record_luks_discard(h))
- r = ftruncate(image_fd, host_size);
- else
- r = fallocate(image_fd, 0, 0, host_size);
- if (r < 0) {
- if (ERRNO_IS_DISK_SPACE(errno)) {
- log_debug_errno(errno, "Not enough disk space to allocate home.");
- r = -ENOSPC; /* make recognizable */
- goto fail;
- }
-
- r = log_error_errno(errno, "Failed to truncate home image %s: %m", temporary_image_path);
+ r = home_truncate(h, image_fd, temporary_image_path, host_size);
+ if (r < 0)
goto fail;
- }
log_info("Allocating image file completed.");
}
@@ -2625,19 +2653,9 @@ int home_resize_luks(
if (S_ISREG(st.st_mode)) {
/* Grow file size */
-
- if (user_record_luks_discard(h))
- r = ftruncate(image_fd, new_image_size);
- else
- r = fallocate(image_fd, 0, 0, new_image_size);
- if (r < 0) {
- if (ERRNO_IS_DISK_SPACE(errno)) {
- log_debug_errno(errno, "Not enough disk space to grow home.");
- return -ENOSPC; /* make recognizable */
- }
-
- return log_error_errno(errno, "Failed to grow image file %s: %m", ip);
- }
+ r = home_truncate(h, image_fd, ip, new_image_size);
+ if (r < 0)
+ return r;
log_info("Growing of image file completed.");
}