Blame gfs2/mkfs/main_jadd.c

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/vfs.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 <libintl.h>
Packit Service 360c39
#include <locale.h>
Packit Service 360c39
#define _(String) gettext(String)
Packit Service 360c39
Packit Service 360c39
#include <linux/types.h>
Packit Service 360c39
#include <linux/fiemap.h>
Packit Service 360c39
#include <linux/fs.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 RANDOM(values) ((values) * (random() / (RAND_MAX + 1.0)))
Packit Service 360c39
Packit Service 360c39
struct jadd_opts {
Packit Service 360c39
	char *path;
Packit Service 360c39
	char *new_inode;
Packit Service 360c39
	char *per_node;
Packit Service 360c39
	char *jindex;
Packit Service 360c39
	unsigned orig_journals;
Packit Service 360c39
	unsigned journals;
Packit Service 360c39
	unsigned quiet:1;
Packit Service 360c39
	unsigned debug:1;
Packit Service 360c39
};
Packit Service 360c39
Packit Service 360c39
#define JA_FL_SET   0
Packit Service 360c39
#define JA_FL_CLEAR 1
Packit Service 360c39
static void set_flags(int fd, int op, uint32_t flags)
Packit Service 360c39
{
Packit Service 360c39
        int err;
Packit Service 360c39
	uint32_t val;
Packit Service 360c39
Packit Service 360c39
        err = ioctl(fd, FS_IOC_GETFLAGS, &val;;
Packit Service 360c39
        if (err) {
Packit Service 360c39
		perror("GETFLAGS");
Packit Service 360c39
		exit(EXIT_FAILURE);
Packit Service 360c39
	}
Packit Service 360c39
Packit Service 360c39
        if (op == JA_FL_SET)
Packit Service 360c39
                val |= flags;
Packit Service 360c39
        else if (op == JA_FL_CLEAR)
Packit Service 360c39
                val &= ~flags;
Packit Service 360c39
Packit Service 360c39
        err = ioctl(fd, FS_IOC_SETFLAGS, &val;;
Packit Service 360c39
        if (err) {
Packit Service 360c39
		perror("SETFLAGS");
Packit Service 360c39
		exit(EXIT_FAILURE);
Packit Service 360c39
	}
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
static int rename2system(struct jadd_opts *opts, const char *new_dir, const char *new_name)
Packit Service 360c39
{
Packit Service 360c39
	char *newpath;
Packit Service 360c39
	int ret;
Packit Service 360c39
Packit Service 360c39
	if (asprintf(&newpath, "%s/%s", new_dir, new_name) < 0) {
Packit Service 360c39
		perror(_("Failed to allocate new path"));
Packit Service 360c39
		return -1;
Packit Service 360c39
	}
Packit Service 360c39
Packit Service 360c39
	ret = rename(opts->new_inode, newpath);
Packit Service 360c39
	free(newpath);
Packit Service 360c39
	return ret;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
static int build_paths(const char *metafs_path, struct jadd_opts *opts)
Packit Service 360c39
{
Packit Service 360c39
	int i = 0;
Packit Service 360c39
	struct {
Packit Service 360c39
		char **path;
Packit Service 360c39
		const char *tail;
Packit Service 360c39
	} p[] = {
Packit Service 360c39
		{ &opts->new_inode, "new_inode" },
Packit Service 360c39
		{ &opts->per_node, "per_node" },
Packit Service 360c39
		{ &opts->jindex, "jindex" },
Packit Service 360c39
		{ NULL, NULL}
Packit Service 360c39
	};
Packit Service 360c39
Packit Service 360c39
	while (p[i].path != NULL) {
Packit Service 360c39
		if (asprintf(p[i].path, "%s/%s", metafs_path, p[i].tail) < 0) {
Packit Service 360c39
			while (i > 0)
Packit Service 360c39
				free(*p[--i].path);
Packit Service 360c39
			return 1;
Packit Service 360c39
		}
Packit Service 360c39
		if (opts->debug)
Packit Service 360c39
			printf("%d: %s\n", i, *p[i].path);
Packit Service 360c39
		i++;
Packit Service 360c39
	}
Packit Service 360c39
	return 0;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
/**
Packit Service 360c39
 * print_usage - print out usage information
Packit Service 360c39
 * @prog_name: The name of this program
Packit Service 360c39
 */
Packit Service 360c39
Packit Service 360c39
static void print_usage(const char *prog_name)
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
		/* Translators: This is a usage string printed with --help.
Packit Service 360c39
		   <size> and <number> here are the commandline parameters,
Packit Service 360c39
		   e.g. gfs2_jadd -j <number> /dev/sda */
Packit Service 360c39
		"-c", "<size>",   _("Size of quota change file, in megabytes"),
Packit Service 360c39
		"-D", NULL,       _("Enable debugging code"),
Packit Service 360c39
		"-h", NULL,       _("Display this help, then exit"),
Packit Service 360c39
		"-J", "<size>",   _("Size of journals, in megabytes"),
Packit Service 360c39
		"-j", "<number>", _("Number of journals"),
Packit Service 360c39
		"-q", NULL,       _("Don't print anything"),
Packit Service 360c39
		"-V", NULL,       _("Display version information, then exit"),
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("%s [%s] <%s>\n\n", prog_name, _("options"), _("device"));
Packit Service 360c39
	printf(_("Adds journals to a GFS2 file system."));
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
/**
Packit Service 360c39
 * decode_arguments - decode command line arguments and fill in the struct gfs2_sbd
Packit Service 360c39
 * @argc:
Packit Service 360c39
 * @argv:
Packit Service 360c39
 * @sdp: the decoded command line arguments
Packit Service 360c39
 *
Packit Service 360c39
 */
Packit Service 360c39
Packit Service 360c39
static void decode_arguments(int argc, char *argv[], struct gfs2_sbd *sdp, struct jadd_opts *opts)
Packit Service 360c39
{
Packit Service 360c39
	int cont = TRUE;
Packit Service 360c39
	int optchar;
Packit Service 360c39
Packit Service 360c39
	while (cont) {
Packit Service 360c39
		optchar = getopt(argc, argv, "c:DhJ:j:qu:V");
Packit Service 360c39
Packit Service 360c39
		switch (optchar) {
Packit Service 360c39
		case 'c':
Packit Service 360c39
			sdp->qcsize = atoi(optarg);
Packit Service 360c39
			break;
Packit Service 360c39
		case 'D':
Packit Service 360c39
			opts->debug = 1;
Packit Service 360c39
			lgfs2_set_debug(1);
Packit Service 360c39
			break;
Packit Service 360c39
		case 'h':
Packit Service 360c39
			print_usage(argv[0]);
Packit Service 360c39
			exit(0);
Packit Service 360c39
			break;
Packit Service 360c39
		case 'J':
Packit Service 360c39
			sdp->jsize = atoi(optarg);
Packit Service 360c39
			break;
Packit Service 360c39
		case 'j':
Packit Service 360c39
			opts->journals = atoi(optarg);
Packit Service 360c39
			break;
Packit Service 360c39
		case 'q':
Packit Service 360c39
			opts->quiet = 1;
Packit Service 360c39
			break;
Packit Service 360c39
		case 'V':
Packit Service 360c39
			printf("gfs2_jadd %s (built %s %s)\n", VERSION,
Packit Service 360c39
			       __DATE__, __TIME__);
Packit Service 360c39
			printf(REDHAT_COPYRIGHT "\n");
Packit Service 360c39
			exit(0);
Packit Service 360c39
			break;
Packit Service 360c39
		case ':':
Packit Service 360c39
		case '?':
Packit Service 360c39
			fprintf(stderr, _("Please use '-h' for help.\n"));
Packit Service 360c39
			exit(EXIT_FAILURE);
Packit Service 360c39
			break;
Packit Service 360c39
		case EOF:
Packit Service 360c39
			cont = FALSE;
Packit Service 360c39
			break;
Packit Service 360c39
		default:
Packit Service 360c39
			die( _("Invalid option: %c\n"), optchar);
Packit Service 360c39
			break;
Packit Service 360c39
		};
Packit Service 360c39
	}
Packit Service 360c39
Packit Service 360c39
	if (optind < argc) {
Packit Service 360c39
		opts->path = argv[optind];
Packit Service 360c39
		optind++;
Packit Service 360c39
	} else
Packit Service 360c39
		die( _("no path specified (try -h for help)\n"));
Packit Service 360c39
Packit Service 360c39
	if (optind < argc)
Packit Service 360c39
		die( _("Unrecognized argument: %s\n"), argv[optind]);
Packit Service 360c39
Packit Service 360c39
	if (opts->debug) {
Packit Service 360c39
		printf( _("Command line arguments:\n"));
Packit Service 360c39
		printf("  qcsize = %u\n", sdp->qcsize);
Packit Service 360c39
		printf("  jsize = %u\n", sdp->jsize);
Packit Service 360c39
		printf("  journals = %u\n", sdp->md.journals);
Packit Service 360c39
		printf("  quiet = %u\n", opts->quiet);
Packit Service 360c39
		printf("  path = %s\n", opts->path);
Packit Service 360c39
	}
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
static void verify_arguments(struct gfs2_sbd *sdp, struct jadd_opts *opts)
Packit Service 360c39
{
Packit Service 360c39
	if (!opts->journals)
Packit Service 360c39
		die( _("no journals specified\n"));
Packit Service 360c39
	if (sdp->jsize < 32 || sdp->jsize > 1024)
Packit Service 360c39
		die( _("bad journal size\n"));
Packit Service 360c39
	if (!sdp->qcsize || sdp->qcsize > 64)
Packit Service 360c39
		die( _("bad quota change size\n"));
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
static void print_results(struct jadd_opts *opts)
Packit Service 360c39
{
Packit Service 360c39
	if (opts->debug)
Packit Service 360c39
		printf("\n");
Packit Service 360c39
	else if (opts->quiet)
Packit Service 360c39
		return;
Packit Service 360c39
Packit Service 360c39
	printf( _("Filesystem: %s\n"), opts->path);
Packit Service 360c39
	printf( _("Old journals: %u\n"), opts->orig_journals);
Packit Service 360c39
	printf( _("New journals: %u\n"), opts->journals);
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
static int create_new_inode(struct jadd_opts *opts, uint64_t *addr)
Packit Service 360c39
{
Packit Service 360c39
	char *name = opts->new_inode;
Packit Service 360c39
	int fd;
Packit Service 360c39
	int error;
Packit Service 360c39
Packit Service 360c39
	for (;;) {
Packit Service 360c39
		fd = open(name, O_WRONLY | O_CREAT | O_EXCL | O_NOFOLLOW | O_CLOEXEC, 0600);
Packit Service 360c39
		if (fd >= 0)
Packit Service 360c39
			break;
Packit Service 360c39
		if (errno == EEXIST) {
Packit Service 360c39
			error = unlink(name);
Packit Service 360c39
			if (error){
Packit Service 360c39
				perror("unlink");
Packit Service 360c39
				exit(EXIT_FAILURE);
Packit Service 360c39
			}
Packit Service 360c39
		} else{
Packit Service 360c39
			perror("create");
Packit Service 360c39
			exit(EXIT_FAILURE);
Packit Service 360c39
		}
Packit Service 360c39
	}
Packit Service 360c39
	if (addr != NULL) {
Packit Service 360c39
		struct stat st;
Packit Service 360c39
Packit Service 360c39
		fstat(fd, &st);
Packit Service 360c39
		*addr = st.st_ino;
Packit Service 360c39
	}
Packit Service 360c39
Packit Service 360c39
	return fd;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
static void add_ir(struct jadd_opts *opts)
Packit Service 360c39
{
Packit Service 360c39
	int fd;
Packit Service 360c39
	char new_name[256];
Packit Service 360c39
	int error;
Packit Service 360c39
Packit Service 360c39
	fd = create_new_inode(opts, NULL);
Packit Service 360c39
Packit Service 360c39
	{
Packit Service 360c39
		struct gfs2_inum_range ir;
Packit Service 360c39
Packit Service 360c39
		set_flags(fd, JA_FL_SET, FS_JOURNAL_DATA_FL);
Packit Service 360c39
		memset(&ir, 0, sizeof(struct gfs2_inum_range));
Packit Service 360c39
		if (write(fd, (void*)&ir, sizeof(struct gfs2_inum_range)) !=
Packit Service 360c39
		    sizeof(struct gfs2_inum_range)) {
Packit Service 360c39
			perror("add_ir");
Packit Service 360c39
			exit(EXIT_FAILURE);
Packit Service 360c39
		}
Packit Service 360c39
	}
Packit Service 360c39
Packit Service 360c39
	close(fd);
Packit Service 360c39
Packit Service 360c39
	sprintf(new_name, "inum_range%u", opts->journals);
Packit Service 360c39
	error = rename2system(opts, opts->per_node, new_name);
Packit Service 360c39
	if (error < 0 && errno != EEXIST){
Packit Service 360c39
		perror("add_ir rename2system");
Packit Service 360c39
		exit(EXIT_FAILURE);
Packit Service 360c39
	}
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
static void add_sc(struct jadd_opts *opts)
Packit Service 360c39
{
Packit Service 360c39
	int fd;
Packit Service 360c39
	char new_name[256];
Packit Service 360c39
	int error;
Packit Service 360c39
Packit Service 360c39
	fd = create_new_inode(opts, NULL);
Packit Service 360c39
Packit Service 360c39
	{
Packit Service 360c39
		struct gfs2_statfs_change sc;
Packit Service 360c39
		set_flags(fd, JA_FL_SET, FS_JOURNAL_DATA_FL);
Packit Service 360c39
Packit Service 360c39
		memset(&sc, 0, sizeof(struct gfs2_statfs_change));
Packit Service 360c39
		if (write(fd, (void*)&sc, sizeof(struct gfs2_statfs_change)) !=
Packit Service 360c39
		    sizeof(struct gfs2_statfs_change)) {
Packit Service 360c39
			perror("add_sc");
Packit Service 360c39
			exit(EXIT_FAILURE);
Packit Service 360c39
		}
Packit Service 360c39
	}
Packit Service 360c39
Packit Service 360c39
	close(fd);
Packit Service 360c39
Packit Service 360c39
	sprintf(new_name, "statfs_change%u", opts->journals);
Packit Service 360c39
	error = rename2system(opts, opts->per_node, new_name);
Packit Service 360c39
	if (error < 0 && errno != EEXIST){
Packit Service 360c39
		perror("add_sc rename2system");
Packit Service 360c39
		exit(EXIT_FAILURE);
Packit Service 360c39
	}
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
static void add_qc(struct gfs2_sbd *sdp, struct jadd_opts *opts)
Packit Service 360c39
{
Packit Service 360c39
	int fd;
Packit Service 360c39
	char new_name[256];
Packit Service 360c39
	int error;
Packit Service 360c39
Packit Service 360c39
	fd = create_new_inode(opts, NULL);
Packit Service 360c39
Packit Service 360c39
	{
Packit Service 360c39
		char buf[sdp->bsize];
Packit Service 360c39
		unsigned int blocks =
Packit Service 360c39
			sdp->qcsize << (20 - sdp->sd_sb.sb_bsize_shift);
Packit Service 360c39
		unsigned int x;
Packit Service 360c39
		struct gfs2_meta_header mh;
Packit Service 360c39
Packit Service 360c39
		set_flags(fd, JA_FL_CLEAR, FS_JOURNAL_DATA_FL);
Packit Service 360c39
		memset(buf, 0, sdp->bsize);
Packit Service 360c39
Packit Service 360c39
		for (x=0; x
Packit Service 360c39
			if (write(fd, buf, sdp->bsize) != sdp->bsize) {
Packit Service 360c39
				perror("add_qc");
Packit Service 360c39
				exit(EXIT_FAILURE);
Packit Service 360c39
			}
Packit Service 360c39
		}
Packit Service 360c39
Packit Service 360c39
		lseek(fd, 0, SEEK_SET);
Packit Service 360c39
Packit Service 360c39
		memset(&mh, 0, sizeof(struct gfs2_meta_header));
Packit Service 360c39
		mh.mh_magic = GFS2_MAGIC;
Packit Service 360c39
		mh.mh_type = GFS2_METATYPE_QC;
Packit Service 360c39
		mh.mh_format = GFS2_FORMAT_QC;
Packit Service 360c39
		gfs2_meta_header_out(&mh, buf);
Packit Service 360c39
Packit Service 360c39
		for (x=0; x
Packit Service 360c39
			if (write(fd, buf, sdp->bsize) != sdp->bsize) {
Packit Service 360c39
				perror("add_qc");
Packit Service 360c39
				exit(EXIT_FAILURE);
Packit Service 360c39
			}
Packit Service 360c39
		}
Packit Service 360c39
Packit Service 360c39
		error = fsync(fd);
Packit Service 360c39
		if (error){
Packit Service 360c39
			perror("add_qc fsync");
Packit Service 360c39
			exit(EXIT_FAILURE);
Packit Service 360c39
		}
Packit Service 360c39
	}
Packit Service 360c39
Packit Service 360c39
	close(fd);
Packit Service 360c39
Packit Service 360c39
	sprintf(new_name, "quota_change%u", opts->journals);
Packit Service 360c39
	error = rename2system(opts, opts->per_node, new_name);
Packit Service 360c39
	if (error < 0 && errno != EEXIST){
Packit Service 360c39
		perror("add_qc rename2system");
Packit Service 360c39
		exit(EXIT_FAILURE);
Packit Service 360c39
	}
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
static void gather_info(struct gfs2_sbd *sdp, struct jadd_opts *opts)
Packit Service 360c39
{
Packit Service 360c39
	struct statfs statbuf;
Packit Service 360c39
	if (statfs(opts->path, &statbuf) < 0) {
Packit Service 360c39
		perror(opts->path);
Packit Service 360c39
		exit(EXIT_FAILURE);
Packit Service 360c39
	}
Packit Service 360c39
	sdp->bsize = statbuf.f_bsize;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
static void find_current_journals(struct jadd_opts *opts)
Packit Service 360c39
{
Packit Service 360c39
	struct dirent *dp;
Packit Service 360c39
	DIR *dirp;
Packit Service 360c39
	unsigned existing_journals = 0;
Packit Service 360c39
Packit Service 360c39
	dirp = opendir(opts->jindex);
Packit Service 360c39
	if (!dirp) {
Packit Service 360c39
		perror("jindex");
Packit Service 360c39
		exit(EXIT_FAILURE);
Packit Service 360c39
	}
Packit Service 360c39
	while (dirp) {
Packit Service 360c39
		if ((dp = readdir(dirp)) != NULL) {
Packit Service 360c39
			if (strncmp(dp->d_name, "journal", 7) == 0)
Packit Service 360c39
				existing_journals++;
Packit Service 360c39
		} else
Packit Service 360c39
			goto close;
Packit Service 360c39
	}
Packit Service 360c39
close:
Packit Service 360c39
	closedir(dirp);
Packit Service 360c39
	if (existing_journals == 0) {
Packit Service 360c39
		die( _("No journals found. Did you run mkfs.gfs2 correctly?\n"));
Packit Service 360c39
	}
Packit Service 360c39
Packit Service 360c39
	opts->orig_journals = existing_journals;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
#ifdef GFS2_HAS_LH_V2
Packit Service 360c39
static uint64_t find_block_address(int fd, off_t offset, unsigned bsize)
Packit Service 360c39
{
Packit Service 360c39
	struct {
Packit Service 360c39
		struct fiemap fm;
Packit Service 360c39
		struct fiemap_extent fe;
Packit Service 360c39
	} fme;
Packit Service 360c39
	int ret;
Packit Service 360c39
Packit Service 360c39
	fme.fm.fm_start = offset;
Packit Service 360c39
	fme.fm.fm_length = 1;
Packit Service 360c39
	fme.fm.fm_flags = FIEMAP_FLAG_SYNC;
Packit Service 360c39
	fme.fm.fm_extent_count = 1;
Packit Service 360c39
Packit Service 360c39
	ret = ioctl(fd, FS_IOC_FIEMAP, &fme.fm);
Packit Service 360c39
	if (ret != 0 || fme.fm.fm_mapped_extents != 1) {
Packit Service 360c39
		fprintf(stderr, "Failed to find log header block address\n");
Packit Service 360c39
		return 0;
Packit Service 360c39
	}
Packit Service 360c39
	return fme.fe.fe_physical / bsize;
Packit Service 360c39
}
Packit Service 360c39
#endif
Packit Service 360c39
Packit Service 360c39
static void add_j(struct gfs2_sbd *sdp, struct jadd_opts *opts)
Packit Service 360c39
{
Packit Service 360c39
	int fd;
Packit Service 360c39
	char new_name[256];
Packit Service 360c39
	int error;
Packit Service 360c39
	uint64_t addr;
Packit Service 360c39
Packit Service 360c39
	fd = create_new_inode(opts, &addr);
Packit Service 360c39
Packit Service 360c39
	{
Packit Service 360c39
		char buf[sdp->bsize];
Packit Service 360c39
		unsigned int blocks =
Packit Service 360c39
			sdp->jsize << (20 - sdp->sd_sb.sb_bsize_shift);
Packit Service 360c39
		unsigned int x;
Packit Service 360c39
		struct gfs2_log_header lh;
Packit Service 360c39
		uint64_t seq = RANDOM(blocks);
Packit Service 360c39
		off_t off = 0;
Packit Service 360c39
Packit Service 360c39
		set_flags(fd, JA_FL_CLEAR, FS_JOURNAL_DATA_FL);
Packit Service 360c39
		memset(buf, 0, sdp->bsize);
Packit Service 360c39
		for (x=0; x
Packit Service 360c39
			if (write(fd, buf, sdp->bsize) != sdp->bsize) {
Packit Service 360c39
				perror("add_j");
Packit Service 360c39
				exit(EXIT_FAILURE);
Packit Service 360c39
			}
Packit Service 360c39
		}
Packit Service 360c39
Packit Service 360c39
		lseek(fd, 0, SEEK_SET);
Packit Service 360c39
Packit Service 360c39
		memset(&lh, 0, sizeof(struct gfs2_log_header));
Packit Service 360c39
		lh.lh_header.mh_magic = GFS2_MAGIC;
Packit Service 360c39
		lh.lh_header.mh_type = GFS2_METATYPE_LH;
Packit Service 360c39
		lh.lh_header.mh_format = GFS2_FORMAT_LH;
Packit Service 360c39
		lh.lh_flags = GFS2_LOG_HEAD_UNMOUNT;
Packit Service 360c39
#ifdef GFS2_HAS_LH_V2
Packit Service 360c39
		lh.lh_flags |= GFS2_LOG_HEAD_USERSPACE;
Packit Service 360c39
		lh.lh_jinode = addr;
Packit Service 360c39
#endif
Packit Service 360c39
		for (x=0; x
Packit Service 360c39
			uint32_t hash;
Packit Service 360c39
Packit Service 360c39
			lh.lh_sequence = seq;
Packit Service 360c39
			lh.lh_blkno = x;
Packit Service 360c39
			gfs2_log_header_out(&lh, buf);
Packit Service 360c39
			hash = lgfs2_log_header_hash(buf);
Packit Service 360c39
			((struct gfs2_log_header *)buf)->lh_hash = cpu_to_be32(hash);
Packit Service 360c39
#ifdef GFS2_HAS_LH_V2
Packit Service 360c39
			((struct gfs2_log_header *)buf)->lh_addr = cpu_to_be64(
Packit Service 360c39
			                           find_block_address(fd, off, sdp->bsize));
Packit Service 360c39
			hash = lgfs2_log_header_crc(buf, sdp->bsize);
Packit Service 360c39
			((struct gfs2_log_header *)buf)->lh_crc = cpu_to_be32(hash);
Packit Service 360c39
#endif
Packit Service 360c39
			if (write(fd, buf, sdp->bsize) != sdp->bsize) {
Packit Service 360c39
				perror("add_j");
Packit Service 360c39
				exit(EXIT_FAILURE);
Packit Service 360c39
			}
Packit Service 360c39
Packit Service 360c39
			if (++seq == blocks)
Packit Service 360c39
				seq = 0;
Packit Service 360c39
			off += sdp->bsize;
Packit Service 360c39
		}
Packit Service 360c39
Packit Service 360c39
		error = fsync(fd);
Packit Service 360c39
		if (error){
Packit Service 360c39
			perror("add_j fsync");
Packit Service 360c39
			exit(EXIT_FAILURE);
Packit Service 360c39
		}
Packit Service 360c39
	}
Packit Service 360c39
Packit Service 360c39
	close(fd);
Packit Service 360c39
Packit Service 360c39
	sprintf(new_name, "journal%u", opts->journals);
Packit Service 360c39
	error = rename2system(opts, opts->jindex, new_name);
Packit Service 360c39
	if (error < 0 && errno != EEXIST){
Packit Service 360c39
		perror("add_j rename2system");
Packit Service 360c39
		exit(EXIT_FAILURE);
Packit Service 360c39
	}
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
int main(int argc, char *argv[])
Packit Service 360c39
{
Packit Service 360c39
	struct jadd_opts opts = {0};
Packit Service 360c39
	struct gfs2_sbd sbd, *sdp = &sbd;
Packit Service 360c39
	struct metafs mfs = {0};
Packit Service 360c39
	struct mntent *mnt;
Packit Service 360c39
	unsigned int total;
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->jsize = GFS2_DEFAULT_JSIZE;
Packit Service 360c39
	sdp->qcsize = GFS2_DEFAULT_QCSIZE;
Packit Service 360c39
	opts.journals = 1;
Packit Service 360c39
Packit Service 360c39
	decode_arguments(argc, argv, sdp, &opts);
Packit Service 360c39
	verify_arguments(sdp, &opts);
Packit Service 360c39
Packit Service 360c39
	sbd.path_fd = lgfs2_open_mnt_dir(opts.path, O_RDONLY|O_CLOEXEC, &mnt;;
Packit Service 360c39
	if (sbd.path_fd < 0) {
Packit Service 360c39
		fprintf(stderr, _("Error looking up mount '%s': %s\n"), opts.path, 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"), opts.path);
Packit Service 360c39
		exit(EXIT_FAILURE);
Packit Service 360c39
	}
Packit Service 360c39
	gather_info(sdp, &opts);
Packit Service 360c39
	mfs.context = copy_context_opt(mnt);
Packit Service 360c39
	if (mount_gfs2_meta(&mfs, mnt->mnt_dir, opts.debug)) {
Packit Service 360c39
		perror("GFS2 metafs");
Packit Service 360c39
		exit(EXIT_FAILURE);
Packit Service 360c39
	}
Packit Service 360c39
Packit Service 360c39
	if (build_paths(mfs.path, &opts)) {
Packit Service 360c39
		perror(_("Failed to build paths"));
Packit Service 360c39
		exit(EXIT_FAILURE);
Packit Service 360c39
	}
Packit Service 360c39
Packit Service 360c39
	if (compute_constants(sdp)) {
Packit Service 360c39
		perror(_("Failed to compute file system constants"));
Packit Service 360c39
		exit(EXIT_FAILURE);
Packit Service 360c39
	}
Packit Service 360c39
	find_current_journals(&opts);
Packit Service 360c39
Packit Service 360c39
	total = opts.orig_journals + opts.journals;
Packit Service 360c39
	for (opts.journals = opts.orig_journals;
Packit Service 360c39
	     opts.journals < total;
Packit Service 360c39
	     opts.journals++) {
Packit Service 360c39
		if (metafs_interrupted) {
Packit Service 360c39
			cleanup_metafs(&mfs;;
Packit Service 360c39
			exit(130);
Packit Service 360c39
		}
Packit Service 360c39
		add_ir(&opts);
Packit Service 360c39
		add_sc(&opts);
Packit Service 360c39
		add_qc(sdp, &opts);
Packit Service 360c39
		add_j(sdp, &opts);
Packit Service 360c39
	}
Packit Service 360c39
Packit Service 360c39
	free(opts.new_inode);
Packit Service 360c39
	free(opts.per_node);
Packit Service 360c39
	free(opts.jindex);
Packit Service 360c39
	close(sdp->path_fd);
Packit Service 360c39
	cleanup_metafs(&mfs;;
Packit Service 360c39
	sync();
Packit Service 360c39
	print_results(&opts);
Packit Service 360c39
Packit Service 360c39
	return 0;
Packit Service 360c39
}