[Cluster-devel] cluster/gfs2 libgfs2/libgfs2.h libgfs2/misc.c ...

rpeterso at sourceware.org rpeterso at sourceware.org
Thu May 10 15:47:49 UTC 2007


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);




More information about the Cluster-devel mailing list