All of lore.kernel.org
 help / color / mirror / Atom feed
From: rpeterso@sourceware.org <rpeterso@sourceware.org>
To: cluster-devel.redhat.com
Subject: [Cluster-devel] cluster/gfs2 libgfs2/libgfs2.h libgfs2/misc.c  ...
Date: 10 May 2007 15:47:49 -0000	[thread overview]
Message-ID: <20070510154749.24392.qmail@sourceware.org> (raw)

CVSROOT:	/cvs/cluster
Module name:	cluster
Changes by:	rpeterso at sourceware.org	2007-05-10 15:47:46

Modified files:
	gfs2/libgfs2   : libgfs2.h misc.c 
	gfs2/mkfs      : Makefile main.c main_jadd.c main_mkfs.c 
	gfs2/quota     : check.c gfs2_quota.h main.c 
	gfs2/tool      : gfs2_tool.h 
Added files:
	gfs2/mkfs      : main_grow.c 

Log message:
	Resolves: Bugzilla Bug 234844: Need to add a "gfs2_grow" command

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/libgfs2/libgfs2.h.diff?cvsroot=cluster&r1=1.11&r2=1.12
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/libgfs2/misc.c.diff?cvsroot=cluster&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/mkfs/main_grow.c.diff?cvsroot=cluster&r1=1.3&r2=1.4
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/mkfs/Makefile.diff?cvsroot=cluster&r1=1.15&r2=1.16
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/mkfs/main.c.diff?cvsroot=cluster&r1=1.8&r2=1.9
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/mkfs/main_jadd.c.diff?cvsroot=cluster&r1=1.10&r2=1.11
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/mkfs/main_mkfs.c.diff?cvsroot=cluster&r1=1.12&r2=1.13
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/quota/check.c.diff?cvsroot=cluster&r1=1.3&r2=1.4
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/quota/gfs2_quota.h.diff?cvsroot=cluster&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/quota/main.c.diff?cvsroot=cluster&r1=1.3&r2=1.4
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/tool/gfs2_tool.h.diff?cvsroot=cluster&r1=1.5&r2=1.6

--- cluster/gfs2/libgfs2/libgfs2.h	2007/05/01 16:43:39	1.11
+++ cluster/gfs2/libgfs2/libgfs2.h	2007/05/10 15:47:44	1.12
@@ -165,7 +165,7 @@
 	int expert;
 	int override;
 
-	char *device_name;
+	char device_name[PATH_MAX];
 	char *path_name;
 
 	/* Constants */
@@ -219,6 +219,9 @@
 
 	unsigned int spills;
 	unsigned int writes;
+	int metafs_fd;
+	int metafs_mounted; /* If metafs was already mounted */
+	char metafs_path[PATH_MAX]; /* where metafs is mounted */
 };
 
 extern char *prog_name;
@@ -343,7 +346,6 @@
 /* device_geometry.c */
 void device_geometry(struct gfs2_sbd *sdp);
 void fix_device_geometry(struct gfs2_sbd *sdp);
-void munge_device_geometry_for_grow(struct gfs2_sbd *sdp);
 
 /* fs_bits.c */
 #define BFITNOENT (0xFFFFFFFF)
@@ -497,6 +499,12 @@
 
 /* misc.c */
 void compute_constants(struct gfs2_sbd *sdp);
+int find_gfs2_meta(struct gfs2_sbd *sdp);
+int dir_exists(const char *dir);
+void check_for_gfs2(struct gfs2_sbd *sdp);
+void mount_gfs2_meta(struct gfs2_sbd *sdp);
+void lock_for_admin(struct gfs2_sbd *sdp);
+void cleanup_metafs(struct gfs2_sbd *sdp);
 
 /* rgrp.c */
 int gfs2_compute_bitstructs(struct gfs2_sbd *sdp, struct rgrp_list *rgd);
--- cluster/gfs2/libgfs2/misc.c	2006/06/06 14:20:41	1.2
+++ cluster/gfs2/libgfs2/misc.c	2007/05/10 15:47:44	1.3
@@ -2,7 +2,7 @@
 *******************************************************************************
 **
 **  Copyright (C) Sistina Software, Inc.  1997-2003  All rights reserved.
-**  Copyright (C) 2005 Red Hat, Inc.  All rights reserved.
+**  Copyright (C) 2005-2007 Red Hat, Inc.  All rights reserved.
 **
 **  This copyrighted material is made available to anyone wishing to use,
 **  modify, copy, or redistribute it subject to the terms and conditions
@@ -22,8 +22,10 @@
 #include <unistd.h>
 #include <time.h>
 #include <errno.h>
-
+#include <sys/mount.h>
 #include <linux/types.h>
+#include <sys/file.h>
+
 #include "libgfs2.h"
 
 void
@@ -102,3 +104,170 @@
 		die("bad constants (2)\n");
 }
 
+int 
+find_gfs2_meta(struct gfs2_sbd *sdp)
+{
+	FILE *fp = fopen("/proc/mounts", "r");
+	char name[] = "gfs2meta";
+	char buffer[PATH_MAX];
+	char fstype[80], mfsoptions[PATH_MAX];
+	char meta_device[PATH_MAX];
+	char meta_path[PATH_MAX];
+	int fsdump, fspass;
+
+	if (fp == NULL) {
+		perror("open: /proc/mounts");
+		exit(EXIT_FAILURE);
+	}
+	sdp->metafs_mounted = FALSE;
+	memset(sdp->metafs_path, 0, sizeof(sdp->metafs_path));
+	memset(meta_path, 0, sizeof(meta_path));
+	while ((fgets(buffer, PATH_MAX - 1, fp)) != NULL) {
+		buffer[PATH_MAX - 1] = '\0';
+		if (strstr(buffer, name) == 0)
+			continue;
+
+		if (sscanf(buffer, "%s %s %s %s %d %d", meta_device, 
+			   meta_path, fstype,mfsoptions, &fsdump, 
+			   &fspass) != 6)
+			continue;
+		
+		if (strcmp(meta_device, sdp->device_name) == 0 ||
+		    strcmp(meta_device, sdp->path_name) == 0) {
+			fclose(fp);
+			sdp->metafs_mounted = FALSE;
+			strcpy(sdp->metafs_path, meta_path);
+			return TRUE;
+		}
+	}
+	fclose(fp);
+	return FALSE;
+}
+
+int
+dir_exists(const char *dir)
+{
+	int fd, ret;
+	struct stat statbuf;
+	fd = open(dir, O_RDONLY);
+	if (fd<0) { 
+		if (errno == ENOENT)
+			return 0;
+		die("Couldn't open %s : %s\n", dir, strerror(errno));
+	}
+	ret = fstat(fd, &statbuf);
+	if (ret)
+		die("stat failed on %s : %s\n", dir, strerror(errno));
+	if (S_ISDIR(statbuf.st_mode)) {
+		close(fd);
+		return 1;
+	}
+	close(fd);
+	die("%s exists, but is not a directory. Cannot mount metafs here\n", dir);
+}
+
+void
+check_for_gfs2(struct gfs2_sbd *sdp)
+{
+	FILE *fp = fopen("/proc/mounts", "r");
+	char *name = sdp->path_name;
+	char buffer[PATH_MAX];
+	char fstype[80];
+	int fsdump, fspass, ret;
+	char fspath[PATH_MAX];
+	char fsoptions[PATH_MAX];
+
+	if (name[strlen(name) - 1] == '/')
+		name[strlen(name) - 1] = '\0';
+
+	if (fp == NULL) {
+		perror("open: /proc/mounts");
+		exit(EXIT_FAILURE);
+	}
+	while ((fgets(buffer, PATH_MAX - 1, fp)) != NULL) {
+		buffer[PATH_MAX - 1] = 0;
+
+		if (strstr(buffer, "0") == 0)
+			continue;
+
+		if ((ret = sscanf(buffer, "%s %s %s %s %d %d",
+				  sdp->device_name, fspath, 
+				  fstype, fsoptions, &fsdump, &fspass)) != 6) 
+			continue;
+
+		if (strcmp(fstype, "gfs2") != 0)
+			continue;
+
+		/* Check if they specified the device instead of mnt point */
+		if (strcmp(sdp->device_name, name) == 0)
+			strcpy(sdp->path_name, fspath); /* fix it */
+		else if (strcmp(fspath, name) != 0)
+			continue;
+
+		fclose(fp);
+		if (strncmp(sdp->device_name, "/dev/loop", 9) == 0)
+			die("Cannot perform this operation on a loopback GFS2 mount.\n");
+
+		return;
+	}
+	fclose(fp);
+	die("gfs2 Filesystem %s is not mounted.\n", name);
+}
+
+void 
+mount_gfs2_meta(struct gfs2_sbd *sdp)
+{
+	int ret;
+	/* mount the meta fs */
+	strcpy(sdp->metafs_path, "/tmp/.gfs2meta");
+	if (!dir_exists(sdp->metafs_path)) {
+		ret = mkdir(sdp->metafs_path, 0700);
+		if (ret)
+			die("Couldn't create %s : %s\n", sdp->metafs_path,
+			    strerror(errno));
+	}
+		
+	ret = mount(sdp->device_name, sdp->metafs_path, "gfs2meta", 0, NULL);
+	if (ret)
+		die("Couldn't mount %s : %s\n", sdp->metafs_path,
+		    strerror(errno));
+}
+
+void
+lock_for_admin(struct gfs2_sbd *sdp)
+{
+	int error;
+
+	if (sdp->debug)
+		printf("\nTrying to get admin lock...\n");
+
+	sdp->metafs_fd = open(sdp->metafs_path, O_RDONLY | O_NOFOLLOW);
+	if (sdp->metafs_fd < 0)
+		die("can't open %s: %s\n",
+		    sdp->metafs_path, strerror(errno));
+	
+	error = flock(sdp->metafs_fd, LOCK_EX);
+	if (error)
+		die("can't flock %s: %s\n", sdp->metafs_path, strerror(errno));
+	if (sdp->debug)
+		printf("Got it.\n");
+}
+
+void
+cleanup_metafs(struct gfs2_sbd *sdp)
+{
+	int ret;
+
+	if (sdp->metafs_fd <= 0)
+		return;
+
+	fsync(sdp->metafs_fd);
+	close(sdp->metafs_fd);
+	if (!sdp->metafs_mounted) { /* was mounted by us */
+		ret = umount(sdp->metafs_path);
+		if (ret)
+			fprintf(stderr, "Couldn't unmount %s : %s\n",
+				sdp->metafs_path, strerror(errno));
+	}
+}
+
--- cluster/gfs2/mkfs/main_grow.c	2006/02/08 14:32:47	1.3
+++ cluster/gfs2/mkfs/main_grow.c	2007/05/10 15:47:45	1.4
@@ -1,8 +1,7 @@
 /******************************************************************************
 *******************************************************************************
 **
-**  Copyright (C) Sistina Software, Inc.  1997-2003  All rights reserved.
-**  Copyright (C) 2004 Red Hat, Inc.  All rights reserved.
+**  Copyright (C) 2007 Red Hat, Inc.  All rights reserved.
 **
 **  This copyrighted material is made available to anyone wishing to use,
 **  modify, copy, or redistribute it subject to the terms and conditions
@@ -17,256 +16,331 @@
 #include <stdint.h>
 #include <inttypes.h>
 #include <sys/types.h>
+#include <dirent.h>
 #include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/file.h>
+#include <sys/vfs.h>
+#include <sys/mount.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <time.h>
 #include <errno.h>
-
+#include <stdarg.h>
 #include <linux/types.h>
+
+#include "libgfs2.h"
 #include "gfs2_mkfs.h"
 
-/**
- * print_usage - print out usage information
- *
- */
+#define BUF_SIZE 4096
+#define MB (1024 * 1024)
 
-static void
-print_usage(void)
-{
-	printf("Usage:\n");
-	printf("\n");
-	printf("%s [options] /path/to/filesystem\n", prog_name);
-	printf("\n");
-	printf("Options:\n");
-	printf("\n");
-	printf("  -D               Enable debugging code\n");
-	printf("  -h               Print this help, then exit\n");
-	printf("  -q               Don't print anything\n");
-	printf("  -r <MB>          Resource Group Size\n");
-	printf("  -T               Test, do everything except update FS\n");
-	printf("  -V               Print program version information, then exit\n");
-}
+static uint64_t override_device_size = 0;
+static int test = 0;
+static uint64_t fssize = 0, fsgrowth;
+static unsigned int rgsize = 0;
+
+extern int create_new_inode(struct gfs2_sbd *sdp);
+extern int rename2system(struct gfs2_sbd *sdp, char *new_dir, char *new_name);
 
 /**
- * decode_arguments - decode command line arguments and fill in the struct gfs2_sbd
- * @argc:
- * @argv:
- * @sdp: the decoded command line arguments
+ * usage - Print out the usage message
  *
+ * This function does not include documentation for the -D option
+ * since normal users have no use for it at all. The -D option is
+ * only for developers. It intended use is in combination with the
+ * -T flag to find out what the result would be of trying different
+ * device sizes without actually having to try them manually.
  */
 
-static void
-decode_arguments(int argc, char *argv[], struct gfs2_sbd *sdp)
+static void usage(void)
 {
-	int cont = TRUE;
-	int optchar;
+	fprintf(stdout,
+		"Usage:\n"
+		"\n"
+		"gfs2_grow [options] /path/to/filesystem\n"
+		"\n"
+		"Options:\n"
+		"  -h               Usage information\n"
+		"  -q               Quiet, reduce verbosity\n"
+		"  -T               Test, do everything except update FS\n"
+		"  -V               Version information\n"
+		"  -v               Verbose, increase verbosity\n");
+}
 
-	while (cont) {
-		optchar = getopt(argc, argv, "Dhqr:TVX");
+void decode_arguments(int argc, char *argv[], struct gfs2_sbd *sdp)
+{
+	int opt;
 
-		switch (optchar) {
-		case 'D':
-			sdp->debug = TRUE;
+	while ((opt = getopt(argc, argv, "VD:hqTv?")) != EOF) {
+		switch (opt) {
+		case 'D':	/* This option is for testing only */
+			override_device_size = atoi(optarg);
+			override_device_size <<= 20;
 			break;
-
+		case 'V':
+			printf("%s %s (built %s %s)\n", argv[0],
+			       GFS2_RELEASE_NAME, __DATE__, __TIME__);
+			printf("%s\n", REDHAT_COPYRIGHT);
+			exit(0);
 		case 'h':
-			print_usage();
-			exit(EXIT_SUCCESS);
-			break;
-
+			usage();
+			exit(0);
 		case 'q':
-			sdp->quiet = TRUE;
-			break;
-
-		case 'r':
-			sdp->rgsize = atoi(optarg);
+			decrease_verbosity();
 			break;
-
 		case 'T':
-			sdp->test = TRUE;
+			printf("(Test mode--File system will not "
+			       "be changed)\n");
+			test = 1;
 			break;
-
-		case 'V':
-			printf("gfs2_grow %s (built %s %s)\n", GFS2_RELEASE_NAME,
-			       __DATE__, __TIME__);
-			printf("%s\n", REDHAT_COPYRIGHT);
-			exit(EXIT_SUCCESS);
+		case 'v':
+			increase_verbosity();
 			break;
-
-		case 'X':
-			sdp->expert = TRUE;
-			break;
-
 		case ':':
 		case '?':
+			/* Unknown flag */
 			fprintf(stderr, "Please use '-h' for usage.\n");
 			exit(EXIT_FAILURE);
-			break;
-
-		case EOF:
-			cont = FALSE;
-			break;
-
 		default:
-			die("unknown option: %c\n", optchar);
+			fprintf(stderr, "Bad programmer! You forgot"
+				" to catch the %c flag\n", opt);
+			exit(EXIT_FAILURE);
 			break;
-		};
+		}
 	}
 
-	if (optind < argc) {
-		sdp->path_name = argv[optind];
-		optind++;
-	} else
-		die("no path specified (try -h for help)\n");
-
-	if (optind < argc)
-		die("Unrecognized option: %s\n", argv[optind]);
-
-	if (sdp->debug) {
-		printf("Command Line Arguments:\n");
-		printf("  quiet = %d\n", sdp->quiet);
-		printf("  rgsize = %u\n", sdp->rgsize);
-		printf("  test = %d\n", sdp->test);
-		printf("  path = %s\n", sdp->path_name);
+	if (optind == argc) {
+		usage();
+		exit(EXIT_FAILURE);
 	}
 }
 
-static void
-verify_arguments(struct gfs2_sbd *sdp)
+/**
+ * figure_out_rgsize
+ */
+void figure_out_rgsize(struct gfs2_sbd *sdp, unsigned int *rgsize)
 {
-	/* Look at this!  Why can't we go bigger than 2GB? */
-	if (sdp->expert) {
-		if (1 > sdp->rgsize || sdp->rgsize > 2048)
-			die("bad resource group size\n");
-	} else {
-		if (32 > sdp->rgsize || sdp->rgsize > 2048)
-			die("bad resource group size\n");
-	}
+	osi_list_t *head = &sdp->rglist;
+	struct rgrp_list *r1, *r2;
+
+	sdp->rgsize = GFS2_DEFAULT_RGSIZE;
+	r1 = osi_list_entry(head->next->next, struct rgrp_list, list);
+	r2 = osi_list_entry(head->next->next->next, struct rgrp_list, list);
+
+	*rgsize = r2->ri.ri_addr - r1->ri.ri_addr;
 }
 
 /**
- * print_results - print out summary information
- * @sdp: the command line
+ * filesystem_size - Calculate the size of the filesystem
+ *
+ * Reads the lists of resource groups in order to
+ * work out where the last block of the filesystem is located.
  *
+ * Returns: The calculated size
  */
 
-static void
-print_results(struct gfs2_sbd *sdp)
+uint64_t filesystem_size(struct gfs2_sbd *sdp)
 {
-	if (sdp->debug)
-		printf("\n");
-	else if (sdp->quiet)
-		return;
-
-	if (sdp->test)
-		printf("Test mode:                 on\n");
-	if (sdp->expert)
-		printf("Expert mode:               on\n");
-
-	printf("Filesystem:                %s\n", sdp->path_name);
-	printf("Device:                    %s\n", sdp->device_name);
-	printf("Blocksize:                 %u\n", sdp->bsize);
-
-	printf("Old Filesystem Size:       %.2f GB (%"PRIu64" blocks)\n",
-	       sdp->orig_fssize / ((float)(1 << 30)) * sdp->bsize, sdp->orig_fssize);
-	printf("Old Resource Groups:       %"PRIu64"\n", sdp->orig_rgrps);
-
-	printf("Device Size                %.2f GB (%"PRIu64" blocks)\n",
-	       sdp->device_size / ((float)(1 << 30)) * sdp->bsize, sdp->device_size);
-
-	printf("New Filesystem Size:       %.2f GB (%"PRIu64" blocks)\n",
-	       sdp->fssize / ((float)(1 << 30)) * sdp->bsize, sdp->fssize);
-	printf("New Resource Groups:       %"PRIu64"\n", sdp->rgrps);
-
-	if (sdp->debug) {
-		printf("\n");
-		printf("Spills:                    %u\n", sdp->spills);
-		printf("Writes:                    %u\n", sdp->writes);
+	osi_list_t *tmp;
+	struct rgrp_list *rgl;
+	uint64_t size = 0, extent;
+
+	tmp = &sdp->rglist;
+	for (;;) {
+		tmp = tmp->next;
+		if (tmp == &sdp->rglist)
+			break;
+		rgl = osi_list_entry(tmp, struct rgrp_list, list);
+		extent = rgl->ri.ri_addr + rgl->ri.ri_length + rgl->ri.ri_data;
+		if (extent > size)
+			size = extent;
+	}
+	return size;
+}
+
+/**
+ * initialize_new_portion - Write the new rg information to disk buffers.
+ */
+void initialize_new_portion(struct gfs2_sbd *sdp, int *old_rg_count)
+{
+	uint64_t rgrp = 0;
+	osi_list_t *head = &sdp->rglist;
+
+	*old_rg_count = 0;
+	/* Delete the old RGs from the rglist */
+	for (rgrp = 0; !osi_list_empty(head) &&
+		     rgrp < (sdp->rgrps - sdp->new_rgrps); rgrp++) {
+		(*old_rg_count)++;
+		osi_list_del(head->next);
 	}
+	/* Build the remaining resource groups */
+	build_rgrps(sdp, !test);
 
-	if (sdp->test)
-		printf("\nThe filesystem was not modified.\n");
+	/* Note: We do inode_put with not_updated because we only updated */
+	/* the new RGs/bitmaps themselves on disk.  The rindex file must  */
+	/* be updated through the meta_fs so the gfs2 kernel is informed. */
+	inode_put(sdp->md.riinode, not_updated);
+	inode_put(sdp->master_dir, not_updated);
+
+	/* We're done with the libgfs portion, so commit it to disk.      */
+	bsync(sdp);
 }
 
 /**
- * main - do everything
- * @argc:
- * @argv:
+ * fix_rindex - Add the new entries to the end of the rindex file.
+ */
+void fix_rindex(struct gfs2_sbd *sdp, int rindex_fd, int old_rg_count)
+{
+	int count, rg;
+	struct rgrp_list *rl;
+	char *buf, *bufptr;
+	osi_list_t *tmp;
+	ssize_t writelen;
+
+	/* Count the number of new RGs. */
+	rg = 0;
+	osi_list_foreach(tmp, &sdp->rglist)
+		rg++;
+	log_info("%d new rindex entries.\n", rg);
+	writelen = rg * sizeof(struct gfs2_rindex);
+	zalloc(buf, writelen);
+	if (!buf)
+		die("Unable to allocate memory for buffers.\n");
+	/* Now add the new rg entries to the rg index.  Here we     */
+	/* need to use the gfs2 kernel code rather than the libgfs2 */
+	/* code so we have a live update while mounted.             */
+	bufptr = buf;
+	osi_list_foreach(tmp, &sdp->rglist) {
+		rg++;
+		rl = osi_list_entry(tmp, struct rgrp_list, list);
+		gfs2_rindex_out(&rl->ri, bufptr);
+		bufptr += sizeof(struct gfs2_rindex);
+	}
+	if (!test) {
+		/* Now write the new RGs to the end of the rindex */
+		lseek(rindex_fd, 0, SEEK_END);
+		count = write(rindex_fd, buf, writelen);
+		if (count != writelen)
+			log_crit("Error writing new rindex entries;"
+				 "aborted.\n");
+		fsync(rindex_fd);
+	}
+	free(buf);
+}
+
+/**
+ * print_info - Print out various bits of (interesting?) information
  *
  */
+static void print_info(struct gfs2_sbd *sdp)
+{
+	log_notice("FS: Mount Point: %s\n", sdp->path_name);
+	log_notice("FS: Device:      %s\n", sdp->device_name);
+	log_notice("FS: Size:        %" PRIu64 " (0x%" PRIx64 ")\n",
+		   fssize, fssize);
+	log_notice("FS: RG size:     %u (0x%x)\n", rgsize, rgsize);
+	log_notice("DEV: Size:       %"PRIu64" (0x%" PRIx64")\n",
+		   sdp->device.length, sdp->device.length);
+	log_notice("The file system grew by %" PRIu64 "MB.\n",
+		   fsgrowth / MB);
+}
 
+/**
+ * main_grow - do everything
+ * @argc:
+ * @argv:
+ */
 void
 main_grow(int argc, char *argv[])
 {
 	struct gfs2_sbd sbd, *sdp = &sbd;
-	unsigned int x;
-	int error;
+	int rgcount, i, rindex_fd;
+	char rindex_name[PATH_MAX];
+	osi_list_t *head = &sdp->rglist;
 
 	memset(sdp, 0, sizeof(struct gfs2_sbd));
-	sdp->rgsize = MKFS_DEFAULT_RGSIZE;
-	osi_list_init(&sdp->rglist);
-	osi_list_init(&sdp->buf_list);
-	for (x = 0; x < BUF_HASH_SIZE; x++)
-		osi_list_init(&sdp->buf_hash[x]);
-
+	sdp->bsize = GFS2_DEFAULT_BSIZE;
+	sdp->rgsize = -1;
+	sdp->jsize = GFS2_DEFAULT_JSIZE;
+	sdp->qcsize = GFS2_DEFAULT_QCSIZE;
+	sdp->md.journals = 1;
 	decode_arguments(argc, argv, sdp);
-	verify_arguments(sdp);
-
-	sdp->path_fd = open(sdp->path_name, O_RDONLY);
-	if (sdp->path_fd < 0)
-		die("can't open root directory %s: %s\n",
-		    sdp->path_name, strerror(errno));
-
-	check_for_gfs2(sdp);
-	lock_for_admin(sdp);
-
-	path2device(sdp);
-	sdp->device_fd = open(sdp->device_name, O_RDWR);
-	if (sdp->device_fd < 0)
-		die("can't open device %s: %s\n",
-		    sdp->device_name, strerror(errno));
-
-	find_block_size(sdp);
-	compute_constants(sdp);
-	find_current_fssize(sdp);
-
-	device_geometry(sdp);
-	fix_device_geometry(sdp);
-
-	if (sdp->device_size < sdp->orig_fssize)
-		die("Did the device shrink?  "
-		    "The device says it's %.2f GB, "
-		    "but the filesystem thinks it takes up %.2f GB\n",
-		    sdp->device_size / ((float)(1 << 30)) * sdp->bsize,
-		    sdp->orig_fssize / ((float)(1 << 30)) * sdp->bsize);
-	else if (sdp->device_size < sdp->orig_fssize +
-		 (MKFS_MIN_GROW_SIZE << (20 - sdp->bsize_shift)))
-		die("Cowardly refusing to grow the filesystem by %"PRIu64" blocks\n",
-		    sdp->device_size - sdp->orig_fssize);
-
-	munge_device_geometry_for_grow(sdp);
-
-	compute_rgrp_layout(sdp, FALSE);
-	build_rgrps(sdp);
-
-	bsync(sdp);
-
-	error = fsync(sdp->device_fd);
-	if (error)
-		die("can't fsync device (%d): %s\n",
-		    error, strerror(errno));
-	error = close(sdp->device_fd);
-	if (error)
-		die("error closing device (%d): %s\n",
-		    error, strerror(errno));
-
-	if (!sdp->test)
-		add_to_rindex(sdp);
-
-	statfs_sync(sdp);
-
+	
+	while ((argc - optind) > 0) {
+		sdp->path_name = argv[optind++];
+		sdp->path_fd = open(sdp->path_name, O_RDONLY);
+		if (sdp->path_fd < 0)
+			die("can't open root directory %s: %s\n",
+			    sdp->path_name, strerror(errno));
+
+		check_for_gfs2(sdp);
+		sdp->device_fd = open(sdp->device_name,
+				      (test ? O_RDONLY : O_RDWR));
+		if (sdp->device_fd < 0)
+			die("can't open device %s: %s\n",
+			    sdp->device_name, strerror(errno));
+		device_geometry(sdp);
+		fix_device_geometry(sdp);
+		log_info("Initializing lists...\n");
+		osi_list_init(&sdp->rglist);
+		osi_list_init(&sdp->buf_list);
+		for(i = 0; i < BUF_HASH_SIZE; i++)
+			osi_list_init(&sdp->buf_hash[i]);
+
+		sdp->sd_sb.sb_bsize = GFS2_DEFAULT_BSIZE;
+		sdp->bsize = sdp->sd_sb.sb_bsize;
+		compute_constants(sdp);
+		if(read_sb(sdp) < 0)
+			die("gfs: Error reading superblock.\n");
+
+		if (!find_gfs2_meta(sdp))
+			mount_gfs2_meta(sdp);
+		lock_for_admin(sdp);
+
+		sprintf(rindex_name, "%s/rindex", sdp->metafs_path);
+		rindex_fd = open(rindex_name, (test ? O_RDONLY : O_RDWR));
+		if (rindex_fd < 0) {
+			cleanup_metafs(sdp);
+			die("GFS2 rindex not found.  Please run gfs2_fsck.\n");
+		}
+		/* Get master dinode */
+		sdp->master_dir =
+			gfs2_load_inode(sdp, sdp->sd_sb.sb_master_dir.no_addr);
+		gfs2_lookupi(sdp->master_dir, "rindex", 6, &sdp->md.riinode);
+		/* Fetch the rindex from disk.  We aren't using gfs2 here,  */
+		/* which means that the bitmaps will most likely be cached  */
+		/* and therefore out of date.  It shouldn't matter because  */
+		/* we're only going to write out new RG information after   */
+		/* the existing RGs, and only write to the index at EOF.    */
+		ri_update(sdp, rindex_fd, &rgcount);
+		fssize = filesystem_size(sdp);
+		figure_out_rgsize(sdp, &rgsize);
+		fsgrowth = ((sdp->device.length - fssize) * sdp->bsize);
+		if (fsgrowth < rgsize * sdp->bsize) {
+			log_err("Error: The device has grown by less than "
+				"one Resource Group (RG).\n");
+			log_err("The device grew by %" PRIu64 "MB.  ",
+				fsgrowth / MB);
+			log_err("One RG is %uMB for this file system.\n",
+				(rgsize * sdp->bsize) / MB);
+		}
+		else {
+			int old_rg_count;
+
+			compute_rgrp_layout(sdp, TRUE);
+			print_info(sdp);
+			initialize_new_portion(sdp, &old_rg_count);
+			fix_rindex(sdp, rindex_fd, old_rg_count);
+		}
+		/* Delete the remaining RGs from the rglist */
+		while (!osi_list_empty(head))
+			osi_list_del(head->next);
+		close(rindex_fd);
+		cleanup_metafs(sdp);
+		close(sdp->device_fd);
+	}
 	close(sdp->path_fd);
-
-	print_results(sdp);
+	sync();
+	log_notice("gfs2_grow complete.\n");
 }
--- cluster/gfs2/mkfs/Makefile	2007/05/03 16:55:56	1.15
+++ cluster/gfs2/mkfs/Makefile	2007/05/10 15:47:45	1.16
@@ -7,9 +7,11 @@
 
 TARGET1= mkfs.gfs2
 TARGET2= gfs2_jadd
+TARGET3= gfs2_grow
 
 OBJS=	main.o \
 	main_mkfs.o \
+	main_grow.o \
 	main_jadd.o
 
 CFLAGS += -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE
@@ -21,7 +23,7 @@
 LDFLAGS += -L${volidlibdir} -lvolume_id
 LDFLAGS += -L../libgfs2 -lgfs2
 
-all: ${TARGET1} ${TARGET2}
+all: ${TARGET1} ${TARGET2} ${TARGET3}
 
 ${TARGET1}: ${OBJS}
 	$(CC) -o $@ $^ $(LDFLAGS)
@@ -29,16 +31,20 @@
 ${TARGET2}: ${TARGET1}
 	ln -s ${TARGET1} ${TARGET2}
 
+${TARGET3}: ${TARGET1}
+	ln -s ${TARGET1} ${TARGET3}
+
 %.o: %.c
 	$(CC) $(CFLAGS) -c -o $@ $<
 
 install: all
 	install -m 0755 ${TARGET1} ${sbindir}
 	ln -f ${sbindir}/${TARGET1} ${sbindir}/${TARGET2}
+	ln -f ${sbindir}/${TARGET1} ${sbindir}/${TARGET3}
 
 uninstall:
-	${UNINSTALL} ${TARGET1} ${TARGET2} ${sbindir}
+	${UNINSTALL} ${TARGET1} ${TARGET2} ${TARGET3} ${sbindir}
 
 clean:
-	rm -f *.o ${TARGET1} ${TARGET2}
+	rm -f *.o ${TARGET1} ${TARGET2} ${TARGET3}
 
--- cluster/gfs2/mkfs/main.c	2007/05/01 14:36:40	1.8
+++ cluster/gfs2/mkfs/main.c	2007/05/10 15:47:45	1.9
@@ -53,9 +53,9 @@
 		main_jadd(argc, argv);
 	else if (!strcmp(whoami, "gfs2_mkfs") || !strcmp(whoami, "mkfs.gfs2"))
 		main_mkfs(argc, argv);
-#if 0
-	if (!strcmp(whoami, "gfs2_grow"))
+	else if (!strcmp(whoami, "gfs2_grow"))
 		main_grow(argc, argv);
+#if 0
 	else if (!strcmp(whoami, "gfs2_shrink"))
 		main_shrink(argc, argv);
 #endif
--- cluster/gfs2/mkfs/main_jadd.c	2006/10/26 18:42:25	1.10
+++ cluster/gfs2/mkfs/main_jadd.c	2007/05/10 15:47:45	1.11
@@ -1,3 +1,14 @@
+/*****************************************************************************
+******************************************************************************
+**
+**  Copyright (C) 2006-2007 Red Hat, Inc.  All rights reserved.
+**
+**  This copyrighted material is made available to anyone wishing to use,
+**  modify, copy, or redistribute it subject to the terms and conditions
+**  of the GNU General Public License v.2.
+**
+******************************************************************************
+*****************************************************************************/
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -23,15 +34,6 @@
 
 #define BUF_SIZE 4096
 
-static char device_name[PATH_MAX];
-static char fspath[BUF_SIZE];
-static char fsoptions[BUF_SIZE];
-static char metafs_path[BUF_SIZE];
-static char lock_table[PATH_MAX];
-static char meta_mount[PATH_MAX] = "/tmp/.gfs2meta";
-static int metafs_fd;
-static int metafs_mounted = 0; /* If metafs was already mounted */
-
 void
 make_jdata(int fd, char *value)
 {
@@ -56,45 +58,18 @@
 	char oldpath[PATH_MAX], newpath[PATH_MAX];
 	int error = 0;
 	error = snprintf(oldpath, PATH_MAX, "%s/new_inode", 
-			 metafs_path);
+			 sdp->metafs_path);
 	if (error >= PATH_MAX)
 		die("rename2system (1)\n");
 
 	error = snprintf(newpath, PATH_MAX, "%s/%s/%s",
-			 metafs_path, new_dir, new_name);
+			 sdp->metafs_path, new_dir, new_name);
 	if (error >= PATH_MAX)
 		die("rename2system (2)\n");
 	
 	return rename(oldpath, newpath);
 }
 
-void
-lock_for_admin(struct gfs2_sbd *sdp)
-{
-        int error;
-
-        if (sdp->debug)
-                printf("\nTrying to get admin lock...\n");
-
-        for (;;) {
-
-                metafs_fd = open(metafs_path, O_RDONLY | O_NOFOLLOW);
-                if (metafs_fd < 0)
-                        die("can't open %s: %s\n",
-                            metafs_path, strerror(errno));
-
-                error = flock(metafs_fd, LOCK_EX);
-                if (error)
-                        die("can't flock %s: %s\n", metafs_path,
-                            strerror(errno));
-
-                break;
-        }
-
-        if (sdp->debug)
-                printf("Got it.\n");
-}
-
 /**
  * print_usage - print out usage information
  *
@@ -238,7 +213,7 @@
 	int fd;
 	int error;
 
-	error = snprintf(name, PATH_MAX, "%s/new_inode", metafs_path);
+	error = snprintf(name, PATH_MAX, "%s/new_inode", sdp->metafs_path);
 	if (error >= PATH_MAX)
 		die("create_new_inode (1)\n");
 
@@ -377,7 +352,8 @@
 	gfs2_sb_in(&(sdp->sd_sb), buf);
 	sdp->bsize = sdp->sd_sb.sb_bsize;
 	strcpy(lock_table,sdp->sd_sb.sb_locktable);
-	sprintf(meta_mount, "%s%s%s", "/sys/fs/gfs2/", lock_table, "/meta");
+	sprintf(sdp->meta_mount, "%s%s%s", "/sys/fs/gfs2/", lock_table,
+		"/meta");
 
 	close(fd);
 }
@@ -408,7 +384,7 @@
 	DIR *dirp;
 	int existing_journals = 0;
 
-	sprintf(jindex, "%s/jindex", metafs_path);
+	sprintf(jindex, "%s/jindex", sdp->metafs_path);
 	dirp = opendir(jindex);
 	if (!dirp) {
 		die("Could not find the jindex directory "
@@ -491,139 +467,6 @@
 		    new_name, error, strerror(errno));
 }
 
-static int 
-find_gfs2_meta(struct gfs2_sbd *sdp)
-{
-	FILE *fp = fopen("/proc/mounts", "r");
-	char name[] = "gfs2meta";
-	char buffer[BUF_SIZE];
-	char fstype[80], mfsoptions[BUF_SIZE];
-	char meta_device[BUF_SIZE];
-	int fsdump, fspass;
-
-	if (fp == NULL) {
-		perror("open: /proc/mounts");
-		exit(EXIT_FAILURE);
-	}
-	while ((fgets(buffer, 4095, fp)) != NULL) {
-		buffer[4095] = 0;
-		if (strstr(buffer, name) == 0)
-			continue;
-
-		if (sscanf(buffer, "%s %s %s %s %d %d", meta_device, 
-			   metafs_path, fstype,mfsoptions, &fsdump, 
-			   &fspass) != 6)
-			continue;
-		
-		if (strcmp(meta_device, sdp->device_name) != 0
-		    && strcmp(meta_device, sdp->path_name) != 0)
-			continue;
-		
-		metafs_mounted = 1;
-		
-		fclose(fp);
-		return TRUE;
-	}
-	fclose(fp);
-	return FALSE;
-}
-
-static int
-dir_exists(const char *dir)
-{
-	int fd, ret;
-	struct stat statbuf;
-	fd = open(dir, O_RDONLY);
-	if (fd<0) { 
-		if (errno == ENOENT)
-			return 0;
-		die("Couldn't open %s : %s\n", dir, strerror(errno));
-	}
-	ret = fstat(fd, &statbuf);
-	if (ret)
-		die("stat failed on %s : %s\n", dir, strerror(errno));
-	if (S_ISDIR(statbuf.st_mode)) {
-		close(fd);
-		return 1;
-	}
-	close(fd);
-	die("%s exists, but is not a directory. Cannot mount metafs here\n", dir);
-}
-
-static void 
-mount_gfs2_meta(struct gfs2_sbd *sdp) 	 
-{
-	int ret;
-	/* mount the meta fs */
-	if (!dir_exists(meta_mount)) {
-		ret = mkdir(meta_mount, 0700);
-		if (ret)
-			die("Couldn't create %s : %s\n", meta_mount,
-			    strerror(errno));
-	}
-		
-	ret = mount(sdp->device_name, meta_mount, "gfs2meta", 0, NULL);
-	if (ret)
-		die("Couldn't mount %s : %s\n", meta_mount,
-		    strerror(errno));
-	strcpy(metafs_path, meta_mount);
-}
-
-static void
-check_for_gfs2(struct gfs2_sbd *sdp)
-{
-	FILE *fp = fopen("/proc/mounts", "r");
-	char *name = sdp->path_name;
-	char buffer[BUF_SIZE];
-	char fstype[80];
-	int fsdump, fspass, ret;
-
-	if (name[strlen(name) - 1] == '/')
-		name[strlen(name) - 1] = '\0';
-
-	if (fp == NULL) {
-		perror("open: /proc/mounts");
-		exit(EXIT_FAILURE);
-	}
-	while ((fgets(buffer, 4095, fp)) != NULL) {
-		buffer[4095] = 0;
-
-		if (strstr(buffer, "0") == 0)
-			continue;
-
-		if ((ret = sscanf(buffer, "%s %s %s %s %d %d", device_name, fspath, 
-				  fstype, fsoptions, &fsdump, &fspass)) != 6) 
-			continue;
-		sdp->device_name = device_name;
-
-		if (strcmp(fstype, "gfs2") != 0)
-			continue;
-
-		if (strcmp(fspath, name) != 0)
-			continue;
-
-		fclose(fp);
-		if (strncmp(device_name, "/dev/loop", 9) == 0)
-			die("Cannot add journal(s) to a loopback GFS mount\n");
-
-		return;
-	}
-	fclose(fp);
-	die("gfs2 Filesystem %s not found\n", name);
-}
-
-static void
-cleanup(struct gfs2_sbd *sdp)
-{
-	int ret;
-	if (!metafs_mounted) { /* was mounted by us */
-		ret = umount(meta_mount);
-		if (ret)
-			fprintf(stderr, "Couldn't unmount %s : %s\n", meta_mount, 
-			    strerror(errno));
-	}
-}
-
 /**
  * main_jadd - do everything
  * @argc:
@@ -654,7 +497,8 @@
 
 	gather_info(sdp);
 
-	if (!find_gfs2_meta(sdp))
+	find_gfs2_meta(sdp);
+	if (!sdp->metafs_mounted)
 		mount_gfs2_meta(sdp);
 	lock_for_admin(sdp);
 	
@@ -671,12 +515,8 @@
 		add_j(sdp);
 	}
 
-	close(metafs_fd);
 	close(sdp->path_fd);
-
-	cleanup(sdp);
-
+	cleanup_metafs(sdp);
 	sync();
-
 	print_results(sdp);
 }
--- cluster/gfs2/mkfs/main_mkfs.c	2007/05/01 16:43:39	1.12
+++ cluster/gfs2/mkfs/main_mkfs.c	2007/05/10 15:47:45	1.13
@@ -86,7 +86,7 @@
 	int cont = TRUE;
 	int optchar;
 
-	sdp->device_name = NULL;
+	memset(sdp->device_name, 0, sizeof(sdp->device_name));
 	sdp->md.journals = 1;
 	strcpy(sdp->lockproto, "lock_nolock");
 
@@ -169,10 +169,10 @@
 		case 1:
 			if (strcmp(optarg, "gfs2") == 0)
 				continue;
-			if (sdp->device_name) {
+			if (sdp->device_name[0]) {
 				die("More than one device specified (try -h for help)");
 			} 
-			sdp->device_name = optarg;
+			strcpy(sdp->device_name, optarg);
 			break;
 
 		default:
@@ -181,11 +181,10 @@
 		};
 	}
 
-	if ((sdp->device_name == NULL) && (optind < argc)) {
-		sdp->device_name = argv[optind++];
-	}
+	if ((sdp->device_name[0] == 0) && (optind < argc))
+		strcpy(sdp->device_name, argv[optind++]);
 
-	if (sdp->device_name == NULL)
+	if (sdp->device_name[0] == '\0')
 		die("no device specified (try -h for help)\n");
 
 	if (optind < argc)
@@ -264,8 +263,7 @@
 		die("error identifying the contents of %s: %s\n",
 		    sdp->device_name, strerror(errno));
 
-	printf("This will destroy any data on %s.\n",
-	       sdp->device_name);
+	printf("This will destroy any data on %s.\n", sdp->device_name);
 	if (volume_id_probe_all(vid, 0, sdp->device_size) == 0)
 		printf("  It appears to contain a %s %s.\n", vid->type,
 			   vid->usage_id == VOLUME_ID_OTHER? "partition" : vid->usage);
--- cluster/gfs2/quota/check.c	2006/12/01 21:28:06	1.3
+++ cluster/gfs2/quota/check.c	2007/05/10 15:47:45	1.4
@@ -2,7 +2,7 @@
 *******************************************************************************
 **
 **  Copyright (C) Sistina Software, Inc.  1997-2003  All rights reserved.
-**  Copyright (C) 2004 Red Hat, Inc.  All rights reserved.
+**  Copyright (C) 2004-2007 Red Hat, Inc.  All rights reserved.
 **
 **  This copyrighted material is made available to anyone wishing to use,
 **  modify, copy, or redistribute it subject to the terms and conditions
@@ -180,10 +180,10 @@
  *
  */
 static void
-read_quota_file(commandline_t *comline, osi_list_t *uid, osi_list_t *gid)
+read_quota_file(struct gfs2_sbd *sdp, commandline_t *comline,
+		osi_list_t *uid, osi_list_t *gid)
 {
 	int fd;
-	struct gfs2_sb sb;
 	char buf[sizeof(struct gfs2_quota)];
 	struct gfs2_quota q;
 	uint64_t offset = 0;
@@ -191,11 +191,11 @@
 	int error;
 	char quota_file[BUF_SIZE];
 	
-	check_for_gfs2(comline->filesystem);
-	read_superblock(&sb);
-	if (!find_gfs2_meta(comline->filesystem))
-		mount_gfs2_meta();
-	lock_for_admin();
+	check_for_gfs2(sdp);
+	read_superblock(&sdp->sd_sb);
+	if (!find_gfs2_meta(sdp))
+		mount_gfs2_meta(sdp);
+	lock_for_admin(sdp);
 	
 	strcpy(quota_file, metafs_path);
 	strcat(quota_file, "/quota");
@@ -224,7 +224,7 @@
 		gfs2_quota_in(&q, buf);
 
 		id = (offset / sizeof(struct gfs2_quota)) >> 1;
-		q.qu_value <<= sb.sb_bsize_shift - 9;
+		q.qu_value <<= sdp->sd_sb.sb_bsize_shift - 9;
 
 		if (q.qu_value) {
 			if (id * sizeof(struct gfs2_quota) * 2 == offset)
@@ -383,7 +383,7 @@
  */
 
 void
-do_check(commandline_t *comline)
+do_check(struct gfs2_sbd *sdp, commandline_t *comline)
 {
 	dev_t device;
 	osi_list_t fs_uid, fs_gid, qf_uid, qf_gid;
@@ -399,7 +399,7 @@
 	device = verify_pathname(comline);
 
 	scan_fs(device, comline->filesystem, &fs_uid, &fs_gid, &hl);
-	read_quota_file(comline, &qf_uid, &qf_gid);
+	read_quota_file(sdp, comline, &qf_uid, &qf_gid);
 
 	print_list("fs user ", &fs_uid);
 	print_list("fs group", &fs_gid);
@@ -423,10 +423,10 @@
  */
 
 static void
-set_list(commandline_t *comline, int user, osi_list_t *list, int64_t multiplier)
+set_list(struct gfs2_sbd *sdp, commandline_t *comline, int user, 
+	 osi_list_t *list, int64_t multiplier)
 {
 	int fd, fd1;
-	struct gfs2_sb sb;
 	osi_list_t *tmp;
 	values_t *v;
 	uint64_t offset;
@@ -435,11 +435,11 @@
 	char quota_file[BUF_SIZE];
 	char sys_q_refresh[BUF_SIZE];
 	
-	check_for_gfs2(comline->filesystem);
-	read_superblock(&sb);
-	if (!find_gfs2_meta(comline->filesystem))
-		mount_gfs2_meta();
-	lock_for_admin();
+	check_for_gfs2(sdp);
+	read_superblock(&sdp->sd_sb);
+	if (!find_gfs2_meta(sdp))
+		mount_gfs2_meta(sdp);
+	lock_for_admin(sdp);
 	
 	strcpy(quota_file, metafs_path);
 	strcat(quota_file, "/quota");
@@ -460,7 +460,7 @@
 		offset += (unsigned long)(&((struct gfs2_quota *)NULL)->qu_value);
 
 		value = v->v_blocks * multiplier;
-		value >>= sb.sb_bsize_shift - 9;
+		value >>= sdp->sd_sb.sb_bsize_shift - 9;
 		value = cpu_to_be64(value);
 
 		lseek(fd, offset, SEEK_SET);
@@ -472,8 +472,10 @@
 		}
 
 		/* Write "1" to sysfs quota refresh file to refresh gfs quotas */
-		sprintf(sys_q_refresh, "%s%s%s", "/sys/fs/gfs2/", sb.sb_locktable, 
-			(user) ? "/quota_refresh_user" : "/quota_refresh_group");
+		sprintf(sys_q_refresh, "%s%s%s", "/sys/fs/gfs2/",
+			sdp->sd_sb.sb_locktable, 
+			(user) ? "/quota_refresh_user" :
+			"/quota_refresh_group");
 		
 		fd1 = open(sys_q_refresh, O_WRONLY);
 		if (fd1 < 0) {
@@ -503,7 +505,7 @@
  */
 
 void
-do_quota_init(commandline_t *comline)
+do_quota_init(struct gfs2_sbd *sdp, commandline_t *comline)
 {
 	dev_t device;
 	osi_list_t fs_uid, fs_gid, qf_uid, qf_gid;
@@ -519,7 +521,7 @@
 	device = verify_pathname(comline);
 
 	scan_fs(device, comline->filesystem, &fs_uid, &fs_gid, &hl);
-	read_quota_file(comline, &qf_uid, &qf_gid);
+	read_quota_file(sdp, comline, &qf_uid, &qf_gid);
 
 	type_zalloc(v, values_t, 1);
 	v->v_id = 0;
@@ -536,12 +538,12 @@
 	print_list("qf user ", &qf_uid);
 	print_list("qf group", &qf_gid);
 
-	set_list(comline, TRUE, &qf_uid, 0);
-	set_list(comline, FALSE, &qf_gid, 0);
-	set_list(comline, TRUE, &fs_uid, 1);
-	set_list(comline, FALSE, &fs_gid, 1);
+	set_list(sdp, comline, TRUE, &qf_uid, 0);
+	set_list(sdp, comline, FALSE, &qf_gid, 0);
+	set_list(sdp, comline, TRUE, &fs_uid, 1);
+	set_list(sdp, comline, FALSE, &fs_gid, 1);
 	
-	do_sync(comline);
+	do_sync(sdp, comline);
 
-	do_check(comline);
+	do_check(sdp, comline);
 }
--- cluster/gfs2/quota/gfs2_quota.h	2006/12/01 21:28:06	1.2
+++ cluster/gfs2/quota/gfs2_quota.h	2007/05/10 15:47:45	1.3
@@ -2,7 +2,7 @@
 *******************************************************************************
 **
 **  Copyright (C) Sistina Software, Inc.  1997-2003  All rights reserved.
-**  Copyright (C) 2004 Red Hat, Inc.  All rights reserved.
+**  Copyright (C) 2004-2007 Red Hat, Inc.  All rights reserved.
 **
 **  This copyrighted material is made available to anyone wishing to use,
 **  modify, copy, or redistribute it subject to the terms and conditions
@@ -98,19 +98,17 @@
 
 /*  main.c  */
 
-void check_for_gfs2(const char *path);
 void do_get_super(int fd, struct gfs2_sb *sb);
-void do_sync(commandline_t *comline);
+void do_sync(struct gfs2_sbd *sdp, commandline_t *comline);
 void lock_for_admin();
-int find_gfs2_meta(const char *mnt);
 void mount_gfs2_meta();
 void cleanup();
 void read_superblock(struct gfs2_sb *sb);
 
 /*  check.c  */
 
-void do_check(commandline_t *comline);
-void do_quota_init(commandline_t *comline);
+void do_check(struct gfs2_sbd *sdp, commandline_t *comline);
+void do_quota_init(struct gfs2_sbd *sdp, commandline_t *comline);
 
 /*  names.c  */
 
--- cluster/gfs2/quota/main.c	2006/12/01 21:28:06	1.3
+++ cluster/gfs2/quota/main.c	2007/05/10 15:47:45	1.4
@@ -2,7 +2,7 @@
 *******************************************************************************
 **
 **  Copyright (C) Sistina Software, Inc.  1997-2003  All rights reserved.
-**  Copyright (C) 2004 Red Hat, Inc.  All rights reserved.
+**  Copyright (C) 2004-2007 Red Hat, Inc.  All rights reserved.
 **
 **  This copyrighted material is made available to anyone wishing to use,
 **  modify, copy, or redistribute it subject to the terms and conditions
@@ -93,13 +93,6 @@
 }
 
 /**
- * check_for_gfs2 - Check to see if a descriptor is a file on a GFS2 filesystem
- * @fd: the file descriptor
- * @path: the path used to open the descriptor
- *
- */
-
-/**
  * decode_arguments - parse command line arguments
  * @argc: well, it's argc...
  * @argv: well, it's argv...
@@ -287,107 +280,6 @@
 }
 
 void
-lock_for_admin()
-{
-        int error;
-
-        for (;;) {
-
-                metafs_fd = open(metafs_path, O_RDONLY | O_NOFOLLOW);
-                if (metafs_fd < 0)
-                        die("can't open %s: %s\n",
-                            metafs_path, strerror(errno));
-
-                error = flock(metafs_fd, LOCK_EX);
-                if (error)
-                        die("can't flock %s: %s\n", metafs_path,
-                            strerror(errno));
-
-                break;
-        }
-}
-
-int 
-find_gfs2_meta(const char *mnt)
-{
-	FILE *fp = fopen("/proc/mounts", "r");
-	char name[] = "gfs2meta";
-	char buffer[BUF_SIZE];
-	char fstype[80], mfsoptions[BUF_SIZE];
-	char meta_device[BUF_SIZE];
-	int fsdump, fspass;
-
-	metafs_mounted = 0;
-
-	if (fp == NULL) {
-		perror("open: /proc/mounts");
-		exit(EXIT_FAILURE);
-	}
-	while ((fgets(buffer, 4095, fp)) != NULL) {
-		buffer[4095] = 0;
-		if (strstr(buffer, name) == 0)
-			continue;
-
-		if (sscanf(buffer, "%s %s %s %s %d %d", meta_device, 
-			   metafs_path, fstype,mfsoptions, &fsdump, 
-			   &fspass) != 6)
-			continue;
-		
-		if (strcmp(meta_device, device_name) != 0
-		    && strcmp(meta_device, mnt) != 0)
-			continue;
-		
-		metafs_mounted = 1;
-		
-		fclose(fp);
-		return TRUE;
-	}
-	fclose(fp);
-	return FALSE;
-}
-
-static int
-dir_exists(const char *dir)
-{
-	int fd, ret;
-	struct stat statbuf;
-	fd = open(dir, O_RDONLY);
-	if (fd<0) { 
-		if (errno == ENOENT)
-			return 0;
-		die("Couldn't open %s : %s\n", dir, strerror(errno));
-	}
-	ret = fstat(fd, &statbuf);
-	if (ret)
-		die("stat failed on %s : %s\n", dir, strerror(errno));
-	if (S_ISDIR(statbuf.st_mode)) {
-		close(fd);
-		return 1;
-	}
-	close(fd);
-	die("%s exists, but is not a directory. Cannot mount metafs here\n", dir);
-}
-
-void 
-mount_gfs2_meta()	 
-{
-	int ret;
-	/* mount the meta fs */
-	if (!dir_exists(meta_mount)) {
-		ret = mkdir(meta_mount, 0700);
-		if (ret)
-			die("Couldn't create %s : %s\n", meta_mount,
-			    strerror(errno));
-	}
-		
-	ret = mount(device_name, meta_mount, "gfs2meta", 0, NULL);
-	if (ret)
-		die("Couldn't mount %s : %s\n", meta_mount,
-		    strerror(errno));
-	strcpy(metafs_path, meta_mount);
-}
-
-void
 cleanup()
 {
 	int ret;
@@ -399,44 +291,6 @@
 	}
 }
 
-void
-check_for_gfs2(const char *mnt)
-{
-	FILE *fp = fopen("/proc/mounts", "r");
-	char buffer[4096];
-	char fstype[80];
-	int fsdump, fspass, ret;
-
-	if (fp == NULL) {
-		perror("open: /proc/mounts");
-		exit(EXIT_FAILURE);
-	}
-	while ((fgets(buffer, 4095, fp)) != NULL) {
-		buffer[4095] = 0;
-
-		if (strstr(buffer, "0") == 0)
-			continue;
-
-		if ((ret = sscanf(buffer, "%s %s %s %s %d %d", device_name, fspath, 
-				  fstype, fsoptions, &fsdump, &fspass)) != 6) 
-			continue;
-
-		if (strcmp(fstype, "gfs2") != 0)
-			continue;
-
-		if (strcmp(fspath, mnt) != 0)
-			continue;
-
-		fclose(fp);
-		if (strncmp(device_name, "/dev/loop", 9) == 0)
-			die("Cannot add journal(s) to a loopback GFS mount\n");
-		
-		return;
-	}
-	fclose(fp);
-	die("gfs2 Filesystem %s not found\n", mnt);
-}
-
 void 
 read_superblock(struct gfs2_sb *sb)
 {
@@ -462,10 +316,9 @@
  */
 
 static void 
-do_list(commandline_t *comline)
+do_list(struct gfs2_sbd *sdp, commandline_t *comline)
 {
 	int fd;
-	struct gfs2_sb sb;
 	struct gfs2_quota q;
 	char buf[sizeof(struct gfs2_quota)];
 	uint64_t offset;
@@ -477,11 +330,11 @@
 	if (!*comline->filesystem)
 		die("need a filesystem to work on\n");
 
-	check_for_gfs2(comline->filesystem);
-	read_superblock(&sb);
-	if (!find_gfs2_meta(comline->filesystem))
-		mount_gfs2_meta();
-	lock_for_admin();
+	check_for_gfs2(sdp);
+	read_superblock(&sdp->sd_sb);
+	if (!find_gfs2_meta(sdp))
+		mount_gfs2_meta(sdp);
+	lock_for_admin(sdp);
 	
 	strcpy(quota_file, metafs_path);
 	strcat(quota_file, "/quota");
@@ -512,7 +365,7 @@
 
 			if (q.qu_limit || q.qu_warn || q.qu_value)
 				print_quota(comline, (pass) ? FALSE : TRUE, id,
-					    &q, &sb);
+					    &q, &sdp->sd_sb);
 
 			offset += 2 * sizeof(struct gfs2_quota);
 		} while (error == sizeof(struct gfs2_quota));
@@ -531,21 +384,20 @@
  */
 
 static void 
-do_get_one(commandline_t *comline, char *filesystem)
+do_get_one(struct gfs2_sbd *sdp, commandline_t *comline, char *filesystem)
 {
 	int fd;
 	char buf[256];
 	struct gfs2_quota q;
-	struct gfs2_sb sb;
 	uint64_t offset;
 	int error;
 	char quota_file[BUF_SIZE];
 
-	check_for_gfs2(filesystem);
-	read_superblock(&sb);
-	if (!find_gfs2_meta(filesystem))
-		mount_gfs2_meta();
-	lock_for_admin();
+	check_for_gfs2(sdp);
+	read_superblock(&sdp->sd_sb);
+	if (!find_gfs2_meta(sdp))
+		mount_gfs2_meta(sdp);
+	lock_for_admin(sdp);
 	
 	strcpy(quota_file, metafs_path);
 	strcat(quota_file, "/quota");
@@ -580,7 +432,7 @@
 
 	print_quota(comline,
 		    (comline->id_type == GQ_ID_USER), comline->id,
-		    &q, &sb);
+		    &q, &sdp->sd_sb);
 
 	close(fd);
 	close(metafs_fd);
@@ -594,12 +446,12 @@
  */
 
 static void
-do_get(commandline_t *comline)
+do_get(struct gfs2_sbd *sdp, commandline_t *comline)
 {
 	int first = TRUE;
 
 	if (*comline->filesystem)
-		do_get_one(comline, comline->filesystem);
+		do_get_one(sdp, comline, comline->filesystem);
 	else {
 		char buf[256], device[256], path[256], type[256];
 		FILE *file;
@@ -620,7 +472,7 @@
 				printf("\n");
 
 			printf("%s\n", path);
-			do_get_one(comline, path);
+			do_get_one(sdp, comline, path);
 		}
 
 		fclose(file);
@@ -633,16 +485,15 @@
  *
  */
 static void 
-do_sync_one(char *filesystem)
+do_sync_one(struct gfs2_sbd *sdp, char *filesystem)
 {
 	int fd;
-	struct gfs2_sb sb;
 	char sys_quota_sync[PATH_MAX];
 
-	check_for_gfs2(filesystem);
-	read_superblock(&sb);
+	check_for_gfs2(sdp);
+	read_superblock(&sdp->sd_sb);
 	sprintf(sys_quota_sync, "%s%s%s", 
-		"/sys/fs/gfs2/", sb.sb_locktable, "/quota_sync");
+		"/sys/fs/gfs2/", sdp->sd_sb.sb_locktable, "/quota_sync");
 	
 	fd = open(sys_quota_sync, O_WRONLY);
 	if (fd < 0)
@@ -662,12 +513,12 @@
  */
 
 void
-do_sync(commandline_t *comline)
+do_sync(struct gfs2_sbd *sdp, commandline_t *comline)
 {
 	sync();
 
 	if (*comline->filesystem)
-		do_sync_one(comline->filesystem);
+		do_sync_one(sdp, comline->filesystem);
 	else {
 		char buf[256], device[256], path[256], type[256];
 		FILE *file;
@@ -682,7 +533,7 @@
 			if (strcmp(type, "gfs2") != 0)
 				continue;
 
-			do_sync_one(path);
+			do_sync_one(sdp, path);
 		}
 
 		fclose(file);
@@ -696,11 +547,10 @@
  */
 
 static void
-do_set(commandline_t *comline)
+do_set(struct gfs2_sbd *sdp, commandline_t *comline)
 {
 	int fd, fd1;
 	uint64_t offset;
-	struct gfs2_sb sb;
 	uint64_t new_value;
 	int error;
 	char quota_file[BUF_SIZE];
@@ -711,11 +561,11 @@
 	if (!comline->new_value_set)
 		die("need a new value\n");
 
-	check_for_gfs2(comline->filesystem);
-	read_superblock(&sb);
-	if (!find_gfs2_meta(comline->filesystem))
-		mount_gfs2_meta();
-	lock_for_admin();
+	check_for_gfs2(sdp);
+	read_superblock(&sdp->sd_sb);
+	if (!find_gfs2_meta(sdp))
+		mount_gfs2_meta(sdp);
+	lock_for_admin(sdp);
 	
 	strcpy(quota_file, metafs_path);
 	strcat(quota_file, "/quota");
@@ -758,14 +608,16 @@
 
 	switch (comline->units) {
 	case GQ_UNITS_MEGABYTE:
-		new_value = comline->new_value << (20 - sb.sb_bsize_shift);
+		new_value =
+			comline->new_value << (20 - sdp->sd_sb.sb_bsize_shift);
 		break;
 
 	case GQ_UNITS_KILOBYTE:
-		if (sb.sb_bsize == 512)
+		if (sdp->sd_sb.sb_bsize == 512)
 			new_value = comline->new_value * 2;
 		else
-			new_value = comline->new_value >> (sb.sb_bsize_shift - 10);
+			new_value = comline->new_value >>
+				(sdp->sd_sb.sb_bsize_shift - 10);
 		break;
 
 	case GQ_UNITS_FSBLOCK:
@@ -773,7 +625,8 @@
 		break;
 
 	case GQ_UNITS_BASICBLOCK:
-		new_value = comline->new_value >> (sb.sb_bsize_shift - 9);
+		new_value = comline->new_value >>
+			(sdp->sd_sb.sb_bsize_shift - 9);
 		break;
 
 	default:
@@ -792,7 +645,8 @@
 	}
 
 	/* Write "1" to sysfs quota refresh file to refresh gfs quotas */
-	sprintf(sys_q_refresh, "%s%s%s", "/sys/fs/gfs2/", sb.sb_locktable, 
+	sprintf(sys_q_refresh, "%s%s%s", "/sys/fs/gfs2/",
+		sdp->sd_sb.sb_locktable, 
 		comline->id_type == GQ_ID_USER ? "/quota_refresh_user" : 
 		"/quota_refresh_group");
 	
@@ -827,41 +681,44 @@
 int
 main(int argc, char *argv[])
 {
+        struct gfs2_sbd sbd, *sdp = &sbd;
 	commandline_t comline;
 
 	prog_name = argv[0];
 	metafs_mounted = 0;
 
+	memset(sdp, 0, sizeof(struct gfs2_sbd));
 	memset(&comline, 0, sizeof(commandline_t));
 
 	decode_arguments(argc, argv, &comline);
+	strcpy(sdp->path_name, comline.filesystem);
 
 	switch (comline.operation) {
 	case GQ_OP_LIST:
-		do_list(&comline);
+		do_list(sdp, &comline);
 		break;
 
 	case GQ_OP_GET:
-		do_get(&comline);
+		do_get(sdp, &comline);
 		break;
 
 	case GQ_OP_LIMIT:
 	case GQ_OP_WARN:
-		do_set(&comline);
+		do_set(sdp, &comline);
 		break;
 
 	case GQ_OP_SYNC:
-		do_sync(&comline);
+		do_sync(sdp, &comline);
 		break;
 
 	case GQ_OP_CHECK:
-		do_sync(&comline);
-		do_check(&comline);
+		do_sync(sdp, &comline);
+		do_check(sdp, &comline);
 		break;
 
 	case GQ_OP_INIT:
-		do_sync(&comline);
-		do_quota_init(&comline);
+		do_sync(sdp, &comline);
+		do_quota_init(sdp, &comline);
 		break;
 
 	default:
@@ -869,7 +726,7 @@
 			comline.id_type = GQ_ID_USER;
 			comline.id = geteuid();
 		}
-		do_get(&comline);
+		do_get(sdp, &comline);
 		break;
 	}
 
--- cluster/gfs2/tool/gfs2_tool.h	2005/10/13 16:39:19	1.5
+++ cluster/gfs2/tool/gfs2_tool.h	2007/05/10 15:47:45	1.6
@@ -2,7 +2,7 @@
 *******************************************************************************
 **
 **  Copyright (C) Sistina Software, Inc.  1997-2003  All rights reserved.
-**  Copyright (C) 2004 Red Hat, Inc.  All rights reserved.
+**  Copyright (C) 2004-2007 Red Hat, Inc.  All rights reserved.
 **
 **  This copyrighted material is made available to anyone wishing to use,
 **  modify, copy, or redistribute it subject to the terms and conditions
@@ -95,6 +95,7 @@
 void check_for_gfs2(int fd, char *path);
 char *get_list(void);
 char **str2lines(char *str);
+const char *find_debugfs_mount(void);
 char *mp2fsname(char *mp);
 char *name2value(char *str, char *name);
 uint32_t name2u32(char *str, char *name);



             reply	other threads:[~2007-05-10 15:47 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-05-10 15:47 rpeterso [this message]
  -- strict thread matches above, loose matches on Subject: below --
2007-05-11 16:53 [Cluster-devel] cluster/gfs2 libgfs2/libgfs2.h libgfs2/misc.c rpeterso

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20070510154749.24392.qmail@sourceware.org \
    --to=rpeterso@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.