mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-03-10 00:58:20 +03:00
growfs: port over to resize_fs()
This commit is contained in:
parent
2b82a99fe0
commit
d6f1e66076
@ -19,57 +19,14 @@
|
||||
#include "format-util.h"
|
||||
#include "log.h"
|
||||
#include "main-func.h"
|
||||
#include "missing_fs.h"
|
||||
#include "mountpoint-util.h"
|
||||
#include "parse-util.h"
|
||||
#include "path-util.h"
|
||||
#include "pretty-print.h"
|
||||
#include "stat-util.h"
|
||||
#include "strv.h"
|
||||
#include "util.h"
|
||||
#include "resize-fs.h"
|
||||
|
||||
static const char *arg_target = NULL;
|
||||
static bool arg_dry_run = false;
|
||||
|
||||
static int resize_ext4(const char *path, int mountfd, int devfd, uint64_t numblocks, uint64_t blocksize) {
|
||||
assert((uint64_t) (int) blocksize == blocksize);
|
||||
|
||||
if (arg_dry_run)
|
||||
return 0;
|
||||
|
||||
if (ioctl(mountfd, EXT4_IOC_RESIZE_FS, &numblocks) != 0)
|
||||
return log_error_errno(errno, "Failed to resize \"%s\" to %"PRIu64" blocks (ext4): %m",
|
||||
path, numblocks);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int resize_btrfs(const char *path, int mountfd, int devfd, uint64_t numblocks, uint64_t blocksize) {
|
||||
struct btrfs_ioctl_vol_args args = {};
|
||||
int r;
|
||||
|
||||
assert((uint64_t) (int) blocksize == blocksize);
|
||||
|
||||
/* https://bugzilla.kernel.org/show_bug.cgi?id=118111 */
|
||||
if (numblocks * blocksize < 256*1024*1024) {
|
||||
log_warning("%s: resizing of btrfs volumes smaller than 256M is not supported", path);
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
r = snprintf(args.name, sizeof(args.name), "%"PRIu64, numblocks * blocksize);
|
||||
/* The buffer is large enough for any number to fit... */
|
||||
assert((size_t) r < sizeof(args.name));
|
||||
|
||||
if (arg_dry_run)
|
||||
return 0;
|
||||
|
||||
if (ioctl(mountfd, BTRFS_IOC_RESIZE, &args) != 0)
|
||||
return log_error_errno(errno, "Failed to resize \"%s\" to %"PRIu64" blocks (btrfs): %m",
|
||||
path, numblocks);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if HAVE_LIBCRYPTSETUP
|
||||
static int resize_crypt_luks_device(dev_t devno, const char *fstype, dev_t main_devno) {
|
||||
_cleanup_free_ char *devpath = NULL, *main_devpath = NULL;
|
||||
@ -160,7 +117,7 @@ static int maybe_resize_slave_device(const char *mountpath, dev_t main_devno) {
|
||||
return resize_crypt_luks_device(devno, fstype, main_devno);
|
||||
#endif
|
||||
|
||||
log_debug("Don't know how to resize %s of type %s, ignoring", devpath, strnull(fstype));
|
||||
log_debug("Don't know how to resize %s of type %s, ignoring.", devpath, strnull(fstype));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -235,11 +192,9 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
static int run(int argc, char *argv[]) {
|
||||
_cleanup_close_ int mountfd = -1, devfd = -1;
|
||||
_cleanup_free_ char *devpath = NULL;
|
||||
uint64_t size, numblocks;
|
||||
uint64_t size, newsize;
|
||||
char fb[FORMAT_BYTES_MAX];
|
||||
struct statfs sfs;
|
||||
dev_t devno;
|
||||
int blocksize;
|
||||
int r;
|
||||
|
||||
log_setup_service();
|
||||
@ -274,37 +229,24 @@ static int run(int argc, char *argv[]) {
|
||||
if (devfd < 0)
|
||||
return log_error_errno(errno, "Failed to open \"%s\": %m", devpath);
|
||||
|
||||
if (ioctl(devfd, BLKBSZGET, &blocksize) != 0)
|
||||
return log_error_errno(errno, "Failed to query block size of \"%s\": %m", devpath);
|
||||
|
||||
if (ioctl(devfd, BLKGETSIZE64, &size) != 0)
|
||||
return log_error_errno(errno, "Failed to query size of \"%s\": %m", devpath);
|
||||
|
||||
if (size % blocksize != 0)
|
||||
log_notice("Partition size %"PRIu64" is not a multiple of the blocksize %d,"
|
||||
" ignoring %"PRIu64" bytes", size, blocksize, size % blocksize);
|
||||
|
||||
numblocks = size / blocksize;
|
||||
|
||||
if (fstatfs(mountfd, &sfs) < 0)
|
||||
return log_error_errno(errno, "Failed to stat file system \"%s\": %m", arg_target);
|
||||
|
||||
switch(sfs.f_type) {
|
||||
case EXT4_SUPER_MAGIC:
|
||||
r = resize_ext4(arg_target, mountfd, devfd, numblocks, blocksize);
|
||||
break;
|
||||
case BTRFS_SUPER_MAGIC:
|
||||
r = resize_btrfs(arg_target, mountfd, devfd, numblocks, blocksize);
|
||||
break;
|
||||
default:
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
|
||||
"Don't know how to resize fs %llx on \"%s\"",
|
||||
(long long unsigned) sfs.f_type, arg_target);
|
||||
}
|
||||
if (r > 0)
|
||||
log_info("Successfully resized \"%s\" to %s bytes (%"PRIu64" blocks of %d bytes).",
|
||||
arg_target, format_bytes(fb, sizeof fb, size), numblocks, blocksize);
|
||||
return r;
|
||||
log_debug("Resizing \"%s\" to %"PRIu64" bytes...", arg_target, size);
|
||||
r = resize_fs(mountfd, size, &newsize);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to resize \"%s\" to %"PRIu64" bytes: %m",
|
||||
arg_target, size);
|
||||
if (newsize == size)
|
||||
log_info("Successfully resized \"%s\" to %s bytes.",
|
||||
arg_target,
|
||||
format_bytes(fb, sizeof fb, newsize));
|
||||
else
|
||||
log_info("Successfully resized \"%s\" to %s bytes (%"PRIu64" bytes lost due to blocksize).",
|
||||
arg_target,
|
||||
format_bytes(fb, sizeof fb, newsize),
|
||||
size - newsize);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_MAIN_FUNCTION(run);
|
||||
|
@ -13,7 +13,7 @@
|
||||
#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;
|
||||
|
||||
@ -38,6 +38,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,12 +52,17 @@ int resize_fs(int fd, uint64_t sz) {
|
||||
if (sz < BTRFS_MINIMAL_SIZE)
|
||||
return -ERANGE;
|
||||
|
||||
sz -= sz % sfs.f_bsize;
|
||||
|
||||
r = snprintf(args.name, sizeof(args.name), "%" PRIu64, sz);
|
||||
assert((size_t) r < sizeof(args.name));
|
||||
|
||||
if (ioctl(fd, BTRFS_IOC_RESIZE, &args) < 0)
|
||||
return -errno;
|
||||
|
||||
if (ret_size)
|
||||
*ret_size = sz;
|
||||
|
||||
} else if (is_fs_type(&sfs, XFS_SB_MAGIC)) {
|
||||
xfs_fsop_geom_t geo;
|
||||
xfs_growfs_data_t d;
|
||||
@ -73,6 +81,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;
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
#include "stat-util.h"
|
||||
|
||||
int resize_fs(int fd, uint64_t sz);
|
||||
int resize_fs(int fd, uint64_t sz, uint64_t *ret_size);
|
||||
|
||||
#define BTRFS_MINIMAL_SIZE (256U*1024U*1024U)
|
||||
#define XFS_MINIMAL_SIZE (14U*1024U*1024U)
|
||||
|
Loading…
x
Reference in New Issue
Block a user