-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <linux/btrfs.h>
#include <linux/magic.h>
#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);
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 = {};
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;
if (ioctl(fd, XFS_IOC_FSGROWFSDATA, &d) < 0)
return -errno;
+ if (ret_size)
+ *ret_size = d.newblocks * geo.blocksize;
+
} else
return -EOPNOTSUPP;
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:
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;
+}