|
Packit Service |
360c39 |
#include "clusterautoconfig.h"
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
#include <stdio.h>
|
|
Packit Service |
360c39 |
#include <stdlib.h>
|
|
Packit Service |
360c39 |
#include <string.h>
|
|
Packit Service |
360c39 |
#include <stdint.h>
|
|
Packit Service |
360c39 |
#include <inttypes.h>
|
|
Packit Service |
360c39 |
#include <sys/types.h>
|
|
Packit Service |
360c39 |
#include <dirent.h>
|
|
Packit Service |
360c39 |
#include <sys/stat.h>
|
|
Packit Service |
360c39 |
#include <sys/ioctl.h>
|
|
Packit Service |
360c39 |
#include <sys/mount.h>
|
|
Packit Service |
360c39 |
#include <fcntl.h>
|
|
Packit Service |
360c39 |
#include <unistd.h>
|
|
Packit Service |
360c39 |
#include <time.h>
|
|
Packit Service |
360c39 |
#include <errno.h>
|
|
Packit Service |
360c39 |
#include <stdarg.h>
|
|
Packit Service |
360c39 |
#include <linux/types.h>
|
|
Packit Service |
360c39 |
#include <blkid.h>
|
|
Packit Service |
360c39 |
#include <libintl.h>
|
|
Packit Service |
360c39 |
#include <locale.h>
|
|
Packit Service |
360c39 |
#define _(String) gettext(String)
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
#include <logging.h>
|
|
Packit Service |
360c39 |
#include "libgfs2.h"
|
|
Packit Service |
360c39 |
#include "gfs2_mkfs.h"
|
|
Packit Service |
360c39 |
#include "metafs.h"
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
#define BUF_SIZE 4096
|
|
Packit Service |
360c39 |
#define MB (1024 * 1024)
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
static uint64_t override_device_size = 0;
|
|
Packit Service |
360c39 |
static int test = 0;
|
|
Packit Service |
360c39 |
static uint64_t fssize = 0, fsgrowth;
|
|
Packit Service |
360c39 |
int print_level = MSG_NOTICE;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
extern int create_new_inode(struct gfs2_sbd *sdp);
|
|
Packit Service |
360c39 |
extern int rename2system(struct gfs2_sbd *sdp, char *new_dir, char *new_name);
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
#ifndef FALLOC_FL_KEEP_SIZE
|
|
Packit Service |
360c39 |
#define FALLOC_FL_KEEP_SIZE 0x01
|
|
Packit Service |
360c39 |
#endif
|
|
Packit Service |
360c39 |
#ifndef BLKDISCARD
|
|
Packit Service |
360c39 |
#define BLKDISCARD _IO(0x12,119)
|
|
Packit Service |
360c39 |
#endif
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
static int discard_blocks(int fd, uint64_t start, uint64_t len)
|
|
Packit Service |
360c39 |
{
|
|
Packit Service |
360c39 |
__uint64_t range[2] = { start, len };
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
if (ioctl(fd, BLKDISCARD, &range) < 0)
|
|
Packit Service |
360c39 |
return errno;
|
|
Packit Service |
360c39 |
return 0;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
/**
|
|
Packit Service |
360c39 |
* usage - Print out the usage message
|
|
Packit Service |
360c39 |
*
|
|
Packit Service |
360c39 |
* This function does not include documentation for the -D option
|
|
Packit Service |
360c39 |
* since normal users have no use for it at all. The -D option is
|
|
Packit Service |
360c39 |
* only for developers. It intended use is in combination with the
|
|
Packit Service |
360c39 |
* -T flag to find out what the result would be of trying different
|
|
Packit Service |
360c39 |
* device sizes without actually having to try them manually.
|
|
Packit Service |
360c39 |
*/
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
static void usage(void)
|
|
Packit Service |
360c39 |
{
|
|
Packit Service |
360c39 |
int i;
|
|
Packit Service |
360c39 |
const char *option, *param, *desc;
|
|
Packit Service |
360c39 |
const char *options[] = {
|
|
Packit Service |
360c39 |
"-h", NULL, _("Display this usage information"),
|
|
Packit Service |
360c39 |
"-q", NULL, _("Quiet, reduce verbosity"),
|
|
Packit Service |
360c39 |
"-T", NULL, _("Do everything except update file system"),
|
|
Packit Service |
360c39 |
"-V", NULL, _("Display version information"),
|
|
Packit Service |
360c39 |
"-v", NULL, _("Increase verbosity"),
|
|
Packit Service |
360c39 |
NULL, NULL, NULL /* Must be kept at the end */
|
|
Packit Service |
360c39 |
};
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
printf("%s\n", _("Usage:"));
|
|
Packit Service |
360c39 |
printf(" gfs2_grow [%s] <%s>\n\n", _("options"), _("device"));
|
|
Packit Service |
360c39 |
printf(_("Expands a GFS2 file system after the device containing the file system has been expanded"));
|
|
Packit Service |
360c39 |
printf("\n\n%s\n", _("Options:"));
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
for (i = 0; options[i] != NULL; i += 3) {
|
|
Packit Service |
360c39 |
option = options[i];
|
|
Packit Service |
360c39 |
param = options[i+1];
|
|
Packit Service |
360c39 |
desc = options[i+2];
|
|
Packit Service |
360c39 |
printf("%3s %-15s %s\n", option, param ? param : "", desc);
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
static void decode_arguments(int argc, char *argv[], struct gfs2_sbd *sdp)
|
|
Packit Service |
360c39 |
{
|
|
Packit Service |
360c39 |
int opt;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
while ((opt = getopt(argc, argv, "VD:hqTv?")) != EOF) {
|
|
Packit Service |
360c39 |
switch (opt) {
|
|
Packit Service |
360c39 |
case 'D': /* This option is for testing only */
|
|
Packit Service |
360c39 |
override_device_size = atoi(optarg);
|
|
Packit Service |
360c39 |
override_device_size <<= 20;
|
|
Packit Service |
360c39 |
break;
|
|
Packit Service |
360c39 |
case 'V':
|
|
Packit Service |
360c39 |
printf(_("%s %s (built %s %s)\n"), argv[0],
|
|
Packit Service |
360c39 |
VERSION, __DATE__, __TIME__);
|
|
Packit Service |
360c39 |
printf(REDHAT_COPYRIGHT "\n");
|
|
Packit Service |
360c39 |
exit(0);
|
|
Packit Service |
360c39 |
case 'h':
|
|
Packit Service |
360c39 |
usage();
|
|
Packit Service |
360c39 |
exit(0);
|
|
Packit Service |
360c39 |
case 'q':
|
|
Packit Service |
360c39 |
decrease_verbosity();
|
|
Packit Service |
360c39 |
break;
|
|
Packit Service |
360c39 |
case 'T':
|
|
Packit Service |
360c39 |
printf( _("(Test mode - file system will not "
|
|
Packit Service |
360c39 |
"be changed)\n"));
|
|
Packit Service |
360c39 |
test = 1;
|
|
Packit Service |
360c39 |
break;
|
|
Packit Service |
360c39 |
case 'v':
|
|
Packit Service |
360c39 |
increase_verbosity();
|
|
Packit Service |
360c39 |
break;
|
|
Packit Service |
360c39 |
case ':':
|
|
Packit Service |
360c39 |
case '?':
|
|
Packit Service |
360c39 |
/* Unknown flag */
|
|
Packit Service |
360c39 |
fprintf(stderr, _("Please use '-h' for help.\n"));
|
|
Packit Service |
360c39 |
exit(EXIT_FAILURE);
|
|
Packit Service |
360c39 |
default:
|
|
Packit Service |
360c39 |
fprintf(stderr, _("Invalid option '%c'\n"), opt);
|
|
Packit Service |
360c39 |
exit(EXIT_FAILURE);
|
|
Packit Service |
360c39 |
break;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
if (optind == argc) {
|
|
Packit Service |
360c39 |
usage();
|
|
Packit Service |
360c39 |
exit(EXIT_FAILURE);
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
static lgfs2_rgrps_t rgrps_init(struct gfs2_sbd *sdp)
|
|
Packit Service |
360c39 |
{
|
|
Packit Service |
360c39 |
int ret;
|
|
Packit Service |
360c39 |
int error;
|
|
Packit Service |
360c39 |
uint64_t al_base = 0;
|
|
Packit Service |
360c39 |
uint64_t al_off = 0;
|
|
Packit Service |
360c39 |
struct stat st;
|
|
Packit Service |
360c39 |
blkid_probe pr = blkid_new_probe();
|
|
Packit Service |
360c39 |
if (pr == NULL || blkid_probe_set_device(pr, sdp->device_fd, 0, 0) != 0
|
|
Packit Service |
360c39 |
|| blkid_probe_enable_superblocks(pr, TRUE) != 0
|
|
Packit Service |
360c39 |
|| blkid_probe_enable_partitions(pr, TRUE) != 0) {
|
|
Packit Service |
360c39 |
fprintf(stderr, _("Failed to create probe\n"));
|
|
Packit Service |
360c39 |
return NULL;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
error = fstat(sdp->device_fd, &st);
|
|
Packit Service |
360c39 |
if (error < 0) {
|
|
Packit Service |
360c39 |
fprintf(stderr, _("fstat failed\n"));
|
|
Packit Service |
360c39 |
return NULL;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
if (!S_ISREG(st.st_mode) && blkid_probe_enable_topology(pr, TRUE) != 0) {
|
|
Packit Service |
360c39 |
fprintf(stderr, _("Failed to create probe\n"));
|
|
Packit Service |
360c39 |
return NULL;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
ret = blkid_do_fullprobe(pr);
|
|
Packit Service |
360c39 |
if (ret == 0 && !S_ISREG(st.st_mode)) {
|
|
Packit Service |
360c39 |
blkid_topology tp = blkid_probe_get_topology(pr);
|
|
Packit Service |
360c39 |
if (tp != NULL) {
|
|
Packit Service |
360c39 |
unsigned long min_io_sz = blkid_topology_get_minimum_io_size(tp);
|
|
Packit Service |
360c39 |
unsigned long opt_io_sz = blkid_topology_get_optimal_io_size(tp);
|
|
Packit Service |
360c39 |
unsigned long phy_sector_sz = blkid_topology_get_physical_sector_size(tp);
|
|
Packit Service |
360c39 |
/* If optimal_io_size is not a multiple of minimum_io_size then
|
|
Packit Service |
360c39 |
the values are not reliable swidth and sunit values, so don't
|
|
Packit Service |
360c39 |
attempt rgrp alignment */
|
|
Packit Service |
360c39 |
if ((min_io_sz > phy_sector_sz) &&
|
|
Packit Service |
360c39 |
(opt_io_sz > phy_sector_sz) &&
|
|
Packit Service |
360c39 |
(opt_io_sz % min_io_sz == 0)) {
|
|
Packit Service |
360c39 |
al_base = opt_io_sz / sdp->bsize;
|
|
Packit Service |
360c39 |
al_off = min_io_sz / sdp->bsize;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
blkid_free_probe(pr);
|
|
Packit Service |
360c39 |
return lgfs2_rgrps_init(sdp, al_base, al_off);
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
/**
|
|
Packit Service |
360c39 |
* Calculate the size of the filesystem
|
|
Packit Service |
360c39 |
* Reads the lists of resource groups in order to work out where the last block
|
|
Packit Service |
360c39 |
* of the filesystem is located.
|
|
Packit Service |
360c39 |
* Returns: The calculated size
|
|
Packit Service |
360c39 |
*/
|
|
Packit Service |
360c39 |
static uint64_t filesystem_size(lgfs2_rgrps_t rgs)
|
|
Packit Service |
360c39 |
{
|
|
Packit Service |
360c39 |
lgfs2_rgrp_t rg = lgfs2_rgrp_last(rgs);
|
|
Packit Service |
360c39 |
const struct gfs2_rindex *ri = lgfs2_rgrp_index(rg);
|
|
Packit Service |
360c39 |
return ri->ri_data0 + ri->ri_data;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
/**
|
|
Packit Service |
360c39 |
* Write the new rg information to disk.
|
|
Packit Service |
360c39 |
*/
|
|
Packit Service |
360c39 |
static unsigned initialize_new_portion(struct gfs2_sbd *sdp, lgfs2_rgrps_t rgs)
|
|
Packit Service |
360c39 |
{
|
|
Packit Service |
360c39 |
unsigned rgcount = 0;
|
|
Packit Service |
360c39 |
uint64_t rgaddr = fssize;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
discard_blocks(sdp->device_fd, rgaddr * sdp->bsize, fsgrowth * sdp->bsize);
|
|
Packit Service |
360c39 |
/* Build the remaining resource groups */
|
|
Packit Service |
360c39 |
while (1) {
|
|
Packit Service |
360c39 |
int err = 0;
|
|
Packit Service |
360c39 |
lgfs2_rgrp_t rg;
|
|
Packit Service |
360c39 |
struct gfs2_rindex ri;
|
|
Packit Service |
360c39 |
uint64_t nextaddr;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
nextaddr = lgfs2_rindex_entry_new(rgs, &ri, rgaddr, 0);
|
|
Packit Service |
360c39 |
if (nextaddr == 0)
|
|
Packit Service |
360c39 |
break;
|
|
Packit Service |
360c39 |
rg = lgfs2_rgrps_append(rgs, &ri, nextaddr - rgaddr);
|
|
Packit Service |
360c39 |
if (rg == NULL) {
|
|
Packit Service |
360c39 |
perror(_("Failed to create resource group"));
|
|
Packit Service |
360c39 |
return 0;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
rgaddr = nextaddr;
|
|
Packit Service |
360c39 |
if (metafs_interrupted)
|
|
Packit Service |
360c39 |
return 0;
|
|
Packit Service |
360c39 |
if (!test)
|
|
Packit Service |
360c39 |
err = lgfs2_rgrp_write(sdp->device_fd, rg);
|
|
Packit Service |
360c39 |
if (err != 0) {
|
|
Packit Service |
360c39 |
perror(_("Failed to write resource group"));
|
|
Packit Service |
360c39 |
return 0;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
rgcount++;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
fsync(sdp->device_fd);
|
|
Packit Service |
360c39 |
return rgcount;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
static char *rindex_buffer(lgfs2_rgrps_t rgs, unsigned count)
|
|
Packit Service |
360c39 |
{
|
|
Packit Service |
360c39 |
lgfs2_rgrp_t rg;
|
|
Packit Service |
360c39 |
unsigned i = 0;
|
|
Packit Service |
360c39 |
char *buf;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
buf = calloc(count, sizeof(struct gfs2_rindex));
|
|
Packit Service |
360c39 |
if (buf == NULL) {
|
|
Packit Service |
360c39 |
perror(__FUNCTION__);
|
|
Packit Service |
360c39 |
exit(EXIT_FAILURE);
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
for (rg = lgfs2_rgrp_first(rgs); rg; rg = lgfs2_rgrp_next(rg)) {
|
|
Packit Service |
360c39 |
const struct gfs2_rindex *ri = lgfs2_rgrp_index(rg);
|
|
Packit Service |
360c39 |
gfs2_rindex_out(ri, buf + (sizeof(*ri) * i));
|
|
Packit Service |
360c39 |
i++;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
return buf;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
/**
|
|
Packit Service |
360c39 |
* fix_rindex - Add the new entries to the end of the rindex file.
|
|
Packit Service |
360c39 |
*/
|
|
Packit Service |
360c39 |
static void fix_rindex(int rindex_fd, lgfs2_rgrps_t rgs, unsigned old_rg_count, unsigned rgcount)
|
|
Packit Service |
360c39 |
{
|
|
Packit Service |
360c39 |
char *buf;
|
|
Packit Service |
360c39 |
ssize_t count;
|
|
Packit Service |
360c39 |
ssize_t writelen;
|
|
Packit Service |
360c39 |
off_t rindex_size;
|
|
Packit Service |
360c39 |
const size_t entrysize = sizeof(struct gfs2_rindex);
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
log_info( _("%d new rindex entries.\n"), rgcount);
|
|
Packit Service |
360c39 |
buf = rindex_buffer(rgs, rgcount);
|
|
Packit Service |
360c39 |
writelen = rgcount * entrysize;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
if (test)
|
|
Packit Service |
360c39 |
goto out;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
rindex_size = lseek(rindex_fd, 0, SEEK_END);
|
|
Packit Service |
360c39 |
if (rindex_size != old_rg_count * entrysize) {
|
|
Packit Service |
360c39 |
log_crit(_("Incorrect rindex size. Want %ld (%d resource groups), have %ld\n"),
|
|
Packit Service |
360c39 |
(long)(old_rg_count * entrysize), old_rg_count,
|
|
Packit Service |
360c39 |
(long)rindex_size);
|
|
Packit Service |
360c39 |
goto out;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
/* Write the first entry separately to ensure there's enough
|
|
Packit Service |
360c39 |
space in the fs for the rest */
|
|
Packit Service |
360c39 |
count = write(rindex_fd, buf, entrysize);
|
|
Packit Service |
360c39 |
if (count != entrysize) {
|
|
Packit Service |
360c39 |
log_crit(_("Error writing first new rindex entry; aborted.\n"));
|
|
Packit Service |
360c39 |
if (count > 0)
|
|
Packit Service |
360c39 |
goto trunc;
|
|
Packit Service |
360c39 |
else
|
|
Packit Service |
360c39 |
goto out;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
count = write(rindex_fd, (buf + entrysize), (writelen - entrysize));
|
|
Packit Service |
360c39 |
if (count != (writelen - entrysize)) {
|
|
Packit Service |
360c39 |
log_crit(_("Error writing new rindex entries; aborted.\n"));
|
|
Packit Service |
360c39 |
if (count > 0)
|
|
Packit Service |
360c39 |
goto trunc;
|
|
Packit Service |
360c39 |
else
|
|
Packit Service |
360c39 |
goto out;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
if (fallocate(rindex_fd, FALLOC_FL_KEEP_SIZE, (rindex_size + writelen), entrysize) != 0)
|
|
Packit Service |
360c39 |
perror("fallocate");
|
|
Packit Service |
360c39 |
fsync(rindex_fd);
|
|
Packit Service |
360c39 |
out:
|
|
Packit Service |
360c39 |
free(buf);
|
|
Packit Service |
360c39 |
return;
|
|
Packit Service |
360c39 |
trunc:
|
|
Packit Service |
360c39 |
count = (count / sizeof(struct gfs2_rindex)) + old_rg_count;
|
|
Packit Service |
360c39 |
log_crit(_("truncating rindex to %ld entries\n"),
|
|
Packit Service |
360c39 |
(long)count * sizeof(struct gfs2_rindex));
|
|
Packit Service |
360c39 |
if (ftruncate(rindex_fd, (off_t)count * sizeof(struct gfs2_rindex)))
|
|
Packit Service |
360c39 |
log_crit(_("Could not truncate rindex: %s\n"), strerror(errno));
|
|
Packit Service |
360c39 |
free(buf);
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
/**
|
|
Packit Service |
360c39 |
* print_info - Print out various bits of (interesting?) information
|
|
Packit Service |
360c39 |
*/
|
|
Packit Service |
360c39 |
static void print_info(struct gfs2_sbd *sdp, char *device, char *mnt_path)
|
|
Packit Service |
360c39 |
{
|
|
Packit Service |
360c39 |
log_notice("FS: %-25s%s\n", _("Mount point:"), mnt_path);
|
|
Packit Service |
360c39 |
log_notice("FS: %-25s%s\n", _("Device:"), device);
|
|
Packit Service |
360c39 |
log_notice("FS: %-25s%llu (0x%llx)\n", _("Size:"),
|
|
Packit Service |
360c39 |
(unsigned long long)fssize, (unsigned long long)fssize);
|
|
Packit Service |
360c39 |
log_notice("DEV: %-24s%llu (0x%llx)\n", _("Length:"),
|
|
Packit Service |
360c39 |
(unsigned long long)sdp->device.length,
|
|
Packit Service |
360c39 |
(unsigned long long)sdp->device.length);
|
|
Packit Service |
360c39 |
log_notice(_("The file system will grow by %lluMB.\n"),
|
|
Packit Service |
360c39 |
(unsigned long long)(fsgrowth * sdp->bsize) / MB);
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
static int open_rindex(char *metafs_path, int mode)
|
|
Packit Service |
360c39 |
{
|
|
Packit Service |
360c39 |
char *path;
|
|
Packit Service |
360c39 |
int fd;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
if (asprintf(&path, "%s/rindex", metafs_path) < 0) {
|
|
Packit Service |
360c39 |
perror(_("Failed to open rindex"));
|
|
Packit Service |
360c39 |
return -1;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
fd = open(path, (mode | O_CLOEXEC));
|
|
Packit Service |
360c39 |
if (fd < 0) {
|
|
Packit Service |
360c39 |
perror(path);
|
|
Packit Service |
360c39 |
fprintf(stderr, _("Please run fsck.gfs2\n"));
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
free(path);
|
|
Packit Service |
360c39 |
return fd;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
int main(int argc, char *argv[])
|
|
Packit Service |
360c39 |
{
|
|
Packit Service |
360c39 |
struct gfs2_sbd sbd, *sdp = &sbd;
|
|
Packit Service |
360c39 |
int rindex_fd;
|
|
Packit Service |
360c39 |
int error = EXIT_SUCCESS;
|
|
Packit Service |
360c39 |
int devflags = (test ? O_RDONLY : O_RDWR) | O_CLOEXEC;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
setlocale(LC_ALL, "");
|
|
Packit Service |
360c39 |
textdomain("gfs2-utils");
|
|
Packit Service |
360c39 |
srandom(time(NULL) ^ getpid());
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
memset(sdp, 0, sizeof(struct gfs2_sbd));
|
|
Packit Service |
360c39 |
sdp->bsize = GFS2_DEFAULT_BSIZE;
|
|
Packit Service |
360c39 |
sdp->rgsize = -1;
|
|
Packit Service |
360c39 |
sdp->jsize = GFS2_DEFAULT_JSIZE;
|
|
Packit Service |
360c39 |
sdp->qcsize = GFS2_DEFAULT_QCSIZE;
|
|
Packit Service |
360c39 |
sdp->md.journals = 1;
|
|
Packit Service |
360c39 |
decode_arguments(argc, argv, sdp);
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
for(; (argc - optind) > 0; optind++) {
|
|
Packit Service |
360c39 |
struct metafs mfs = {0};
|
|
Packit Service |
360c39 |
struct mntent *mnt;
|
|
Packit Service |
360c39 |
unsigned rgcount;
|
|
Packit Service |
360c39 |
unsigned old_rg_count;
|
|
Packit Service |
360c39 |
lgfs2_rgrps_t rgs;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
error = lgfs2_open_mnt(argv[optind], O_RDONLY|O_CLOEXEC, &sdp->path_fd,
|
|
Packit Service |
360c39 |
devflags, &sdp->device_fd, &mnt;;
|
|
Packit Service |
360c39 |
if (error != 0) {
|
|
Packit Service |
360c39 |
fprintf(stderr, _("Error looking up mount '%s': %s\n"), argv[optind], strerror(errno));
|
|
Packit Service |
360c39 |
exit(EXIT_FAILURE);
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
if (mnt == NULL) {
|
|
Packit Service |
360c39 |
fprintf(stderr, _("%s: not a mounted gfs2 file system\n"), argv[optind]);
|
|
Packit Service |
360c39 |
continue;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
if (lgfs2_get_dev_info(sdp->device_fd, &sdp->dinfo) < 0) {
|
|
Packit Service |
360c39 |
perror(mnt->mnt_fsname);
|
|
Packit Service |
360c39 |
exit(EXIT_FAILURE);
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
sdp->sd_sb.sb_bsize = GFS2_DEFAULT_BSIZE;
|
|
Packit Service |
360c39 |
sdp->bsize = sdp->sd_sb.sb_bsize;
|
|
Packit Service |
360c39 |
if (compute_constants(sdp)) {
|
|
Packit Service |
360c39 |
log_crit("%s\n", _("Failed to compute file system constants"));
|
|
Packit Service |
360c39 |
exit(EXIT_FAILURE);
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
if (read_sb(sdp) < 0) {
|
|
Packit Service |
360c39 |
fprintf(stderr, _("Error reading superblock.\n"));
|
|
Packit Service |
360c39 |
exit(EXIT_FAILURE);
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
if (sdp->gfs1) {
|
|
Packit Service |
360c39 |
fprintf(stderr, _("cannot grow gfs1 filesystem\n"));
|
|
Packit Service |
360c39 |
exit(EXIT_FAILURE);
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
fix_device_geometry(sdp);
|
|
Packit Service |
360c39 |
mfs.context = copy_context_opt(mnt);
|
|
Packit Service |
360c39 |
if (mount_gfs2_meta(&mfs, mnt->mnt_dir, (print_level > MSG_NOTICE))) {
|
|
Packit Service |
360c39 |
perror(_("Failed to mount GFS2 meta file system"));
|
|
Packit Service |
360c39 |
exit(EXIT_FAILURE);
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
rindex_fd = open_rindex(mfs.path, (test ? O_RDONLY : O_RDWR));
|
|
Packit Service |
360c39 |
if (rindex_fd < 0) {
|
|
Packit Service |
360c39 |
cleanup_metafs(&mfs;;
|
|
Packit Service |
360c39 |
exit(EXIT_FAILURE);
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
/* Get master dinode */
|
|
Packit Service |
360c39 |
sdp->master_dir = lgfs2_inode_read(sdp, sdp->sd_sb.sb_master_dir.no_addr);
|
|
Packit Service |
360c39 |
if (sdp->master_dir == NULL) {
|
|
Packit Service |
360c39 |
perror(_("Could not read master directory"));
|
|
Packit Service |
360c39 |
exit(EXIT_FAILURE);
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
rgs = rgrps_init(sdp);
|
|
Packit Service |
360c39 |
if (rgs == NULL) {
|
|
Packit Service |
360c39 |
perror(_("Could not initialise resource groups"));
|
|
Packit Service |
360c39 |
error = -1;
|
|
Packit Service |
360c39 |
goto out;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
/* Fetch the rindex from disk. We aren't using gfs2 here, */
|
|
Packit Service |
360c39 |
/* which means that the bitmaps will most likely be cached */
|
|
Packit Service |
360c39 |
/* and therefore out of date. It shouldn't matter because */
|
|
Packit Service |
360c39 |
/* we're only going to write out new RG information after */
|
|
Packit Service |
360c39 |
/* the existing RGs, and only write to the index at EOF. */
|
|
Packit Service |
360c39 |
log_info(_("Gathering resource group information for %s\n"), argv[optind]);
|
|
Packit Service |
360c39 |
old_rg_count = lgfs2_rindex_read_fd(rindex_fd, rgs);
|
|
Packit Service |
360c39 |
if (old_rg_count == 0) {
|
|
Packit Service |
360c39 |
perror(_("Failed to scan existing resource groups"));
|
|
Packit Service |
360c39 |
error = -EXIT_FAILURE;
|
|
Packit Service |
360c39 |
goto out;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
if (metafs_interrupted)
|
|
Packit Service |
360c39 |
goto out;
|
|
Packit Service |
360c39 |
fssize = lgfs2_rgrp_align_addr(rgs, filesystem_size(rgs) + 1);
|
|
Packit Service |
360c39 |
/* We're done with the old rgs now that we have the fssize and rg count */
|
|
Packit Service |
360c39 |
lgfs2_rgrps_free(&rgs);
|
|
Packit Service |
360c39 |
/* Now lets set up the new ones with alignment and all */
|
|
Packit Service |
360c39 |
rgs = rgrps_init(sdp);
|
|
Packit Service |
360c39 |
if (rgs == NULL) {
|
|
Packit Service |
360c39 |
perror(_("Could not initialise new resource groups"));
|
|
Packit Service |
360c39 |
error = -1;
|
|
Packit Service |
360c39 |
goto out;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
fsgrowth = (sdp->device.length - fssize);
|
|
Packit Service |
360c39 |
rgcount = lgfs2_rgrps_plan(rgs, fsgrowth, ((GFS2_MAX_RGSIZE << 20) / sdp->bsize));
|
|
Packit Service |
360c39 |
if (rgcount == 0) {
|
|
Packit Service |
360c39 |
log_err( _("The calculated resource group size is too small.\n"));
|
|
Packit Service |
360c39 |
log_err( _("%s has not grown.\n"), argv[optind]);
|
|
Packit Service |
360c39 |
error = -1;
|
|
Packit Service |
360c39 |
goto out;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
print_info(sdp, mnt->mnt_fsname, mnt->mnt_dir);
|
|
Packit Service |
360c39 |
rgcount = initialize_new_portion(sdp, rgs);
|
|
Packit Service |
360c39 |
if (rgcount == 0 || metafs_interrupted)
|
|
Packit Service |
360c39 |
goto out;
|
|
Packit Service |
360c39 |
fsync(sdp->device_fd);
|
|
Packit Service |
360c39 |
fix_rindex(rindex_fd, rgs, old_rg_count, rgcount);
|
|
Packit Service |
360c39 |
out:
|
|
Packit Service |
360c39 |
lgfs2_rgrps_free(&rgs);
|
|
Packit Service |
360c39 |
close(rindex_fd);
|
|
Packit Service |
360c39 |
cleanup_metafs(&mfs;;
|
|
Packit Service |
360c39 |
close(sdp->device_fd);
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
if (metafs_interrupted)
|
|
Packit Service |
360c39 |
break;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
close(sdp->path_fd);
|
|
Packit Service |
360c39 |
sync();
|
|
Packit Service |
360c39 |
if (metafs_interrupted) {
|
|
Packit Service |
360c39 |
log_notice( _("gfs2_grow interrupted.\n"));
|
|
Packit Service |
360c39 |
exit(1);
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
log_notice( _("gfs2_grow complete.\n"));
|
|
Packit Service |
360c39 |
return error;
|
|
Packit Service |
360c39 |
}
|