]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/shared/resize-fs.c
run: also show a pretty string for main exit status, if any
[thirdparty/systemd.git] / src / shared / resize-fs.c
index 9f33dd77d88a3404148c987b039d6776c5f6b9b7..b1c4a49da1a353fa39ec6bea20e083424084d105 100644 (file)
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
 
 #include <linux/btrfs.h>
 #include <linux/magic.h>
@@ -13,9 +13,8 @@
 #include "resize-fs.h"
 #include "stat-util.h"
 
-int resize_fs(int fd, uint64_t sz) {
+int resize_fs(int fd, uint64_t sz, uint64_t *ret_size) {
         struct statfs sfs;
-        int r;
 
         assert(fd >= 0);
 
@@ -38,6 +37,9 @@ int resize_fs(int fd, uint64_t sz) {
                 if (ioctl(fd, EXT4_IOC_RESIZE_FS, &u) < 0)
                         return -errno;
 
+                if (ret_size)
+                        *ret_size = u * sfs.f_bsize;
+
         } else if (is_fs_type(&sfs, BTRFS_SUPER_MAGIC)) {
                 struct btrfs_ioctl_vol_args args = {};
 
@@ -49,13 +51,17 @@ int resize_fs(int fd, uint64_t sz) {
                 if (sz < BTRFS_MINIMAL_SIZE)
                         return -ERANGE;
 
-                r = snprintf(args.name, sizeof(args.name), "%" PRIu64, sz);
-                assert((size_t) r < sizeof(args.name));
+                sz -= sz % sfs.f_bsize;
+
+                xsprintf(args.name, "%" PRIu64, sz);
 
                 if (ioctl(fd, BTRFS_IOC_RESIZE, &args) < 0)
                         return -errno;
 
-        } else if (is_fs_type(&sfs, XFS_SB_MAGIC)) {
+                if (ret_size)
+                        *ret_size = sz;
+
+        } else if (is_fs_type(&sfs, XFS_SUPER_MAGIC)) {
                 xfs_fsop_geom_t geo;
                 xfs_growfs_data_t d;
 
@@ -73,6 +79,9 @@ int resize_fs(int fd, uint64_t sz) {
                 if (ioctl(fd, XFS_IOC_FSGROWFSDATA, &d) < 0)
                         return -errno;
 
+                if (ret_size)
+                        *ret_size = d.newblocks * geo.blocksize;
+
         } else
                 return -EOPNOTSUPP;
 
@@ -86,7 +95,7 @@ uint64_t minimal_size_by_fs_magic(statfs_f_type_t magic) {
         case (statfs_f_type_t) EXT4_SUPER_MAGIC:
                 return EXT4_MINIMAL_SIZE;
 
-        case (statfs_f_type_t) XFS_SB_MAGIC:
+        case (statfs_f_type_t) XFS_SUPER_MAGIC:
                 return XFS_MINIMAL_SIZE;
 
         case (statfs_f_type_t) BTRFS_SUPER_MAGIC:
@@ -110,3 +119,8 @@ uint64_t minimal_size_by_fs_name(const char *name) {
 
         return UINT64_MAX;
 }
+
+/* Returns true for the only fs that can online shrink *and* grow */
+bool fs_can_online_shrink_and_grow(statfs_f_type_t magic) {
+        return magic == (statfs_f_type_t) BTRFS_SUPER_MAGIC;
+}