[Cluster-devel] cluster/gfs2/quota check.c main.c names.c gfs2 ...

adas at sourceware.org adas at sourceware.org
Thu May 10 22:43:13 UTC 2007


CVSROOT:	/cvs/cluster
Module name:	cluster
Branch: 	RHEL5
Changes by:	adas at sourceware.org	2007-05-10 22:43:12

Modified files:
	gfs2/quota     : check.c main.c names.c gfs2_quota.h Makefile 

Log message:
	bz 190196. gfs2_quota. Doesn't use sysfs anymore. Uses the gfs2meta filesystem instead.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/quota/check.c.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.2&r2=1.2.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/quota/main.c.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.2&r2=1.2.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/quota/names.c.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.1&r2=1.1.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/quota/gfs2_quota.h.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.1&r2=1.1.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/quota/Makefile.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.5&r2=1.5.2.1

--- cluster/gfs2/quota/check.c	2005/09/07 06:48:51	1.2
+++ cluster/gfs2/quota/check.c	2007/05/10 22:43:12	1.2.2.1
@@ -26,10 +26,7 @@
 #include <stdint.h>
 #include <inttypes.h>
 
-#include "linux_endian.h"
-#include <linux/gfs2_ondisk.h>
 #define __user
-#include <linux/gfs2_ioctl.h>
 #include "osi_list.h"
 
 #include "gfs2_quota.h"
@@ -182,44 +179,48 @@
  * @gid: returned list of GIDs for the filesystem
  *
  */
-
 static void
 read_quota_file(commandline_t *comline, osi_list_t *uid, osi_list_t *gid)
 {
 	int fd;
 	struct gfs2_sb sb;
-	struct gfs2_ioctl gi;
 	char buf[sizeof(struct gfs2_quota)];
 	struct gfs2_quota q;
 	uint64_t offset = 0;
 	uint32_t id;
 	int error;
-
-	fd = open(comline->filesystem, O_RDONLY);
-	if (fd < 0)
+	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();
+	
+	strcpy(quota_file, metafs_path);
+	strcat(quota_file, "/quota");
+
+	fd = open(quota_file, O_RDONLY);
+	if (fd < 0) {
+		close(metafs_fd);
+		cleanup();
 		die("can't open file %s: %s\n", comline->filesystem,
 		    strerror(errno));
-
-	check_for_gfs2(fd, comline->filesystem);
-
-	do_get_super(fd, &sb);
+	}
 
 	do {
-		char *argv[] = { "do_hfile_read", "quota" };
-
-		gi.gi_argc = 2;
-		gi.gi_argv = argv;
-		gi.gi_data = buf;
-		gi.gi_size = sizeof(struct gfs2_quota);
-		gi.gi_offset = offset;
-
+		
 		memset(buf, 0, sizeof(struct gfs2_quota));
-
-		error = ioctl(fd, GFS2_IOCTL_SUPER, &gi);
-		if (error < 0)
+		/* read hidden quota file here */
+		lseek(fd, offset, SEEK_SET);
+		error = read(fd, buf, sizeof(struct gfs2_quota));
+		if (error < 0) {
+			close(fd);
+			close(metafs_fd);
+			cleanup();
 			die("can't read quota file (%d): %s\n",
 			    error, strerror(errno));
-
+		}
 		gfs2_quota_in(&q, buf);
 
 		id = (offset / sizeof(struct gfs2_quota)) >> 1;
@@ -236,6 +237,8 @@
 	} while (error == sizeof(struct gfs2_quota));
 
 	close(fd);
+	close(metafs_fd);
+	cleanup();
 }
 
 /**
@@ -422,23 +425,32 @@
 static void
 set_list(commandline_t *comline, int user, osi_list_t *list, int64_t multiplier)
 {
-	int fd;
+	int fd, fd1;
 	struct gfs2_sb sb;
 	osi_list_t *tmp;
 	values_t *v;
 	uint64_t offset;
 	int64_t value;
-	struct gfs2_ioctl gi;
-	char buf[256];
 	int error;
-
-	fd = open(comline->filesystem, O_RDONLY);
-	if (fd < 0)
+	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();
+	
+	strcpy(quota_file, metafs_path);
+	strcat(quota_file, "/quota");
+
+	fd = open(quota_file, O_WRONLY);
+	if (fd < 0) {
+		close(metafs_fd);
+		cleanup();
 		die("can't open file %s: %s\n", comline->filesystem,
 		    strerror(errno));
-
-	check_for_gfs2(fd, comline->filesystem);
-	do_get_super(fd, &sb);
+	}
 
 	for (tmp = list->next; tmp != list; tmp = tmp->next) {
 		v = osi_list_entry(tmp, values_t, v_list);
@@ -449,51 +461,49 @@
 
 		value = v->v_blocks * multiplier;
 		value >>= sb.sb_bsize_shift - 9;
-		value = cpu_to_le64(value);
+		value = cpu_to_be64(value);
 
-		{
-			char *argv[] = { "do_hfile_write", "quota"};
-
-			gi.gi_argc = 2;
-			gi.gi_argv = argv;
-			gi.gi_data = (char *)&value;
-			gi.gi_size = sizeof(int64_t);
-			gi.gi_offset = offset;
-
-			error = ioctl(fd, GFS2_IOCTL_SUPER, &gi);
-			if (error != sizeof(int64_t))
-				die("can't write quota file (%d): %s\n",
-				    error, strerror(errno));
+		lseek(fd, offset, SEEK_SET);
+		error = write(fd, (char*)&value, sizeof(uint64_t));
+		if (error != sizeof(uint64_t)) {
+			fprintf(stderr, "can't write quota file (%d): %s\n",
+			    error, strerror(errno));
+			goto out;
 		}
 
-		sprintf(buf, "%s:%u",
-			(user) ? "u" : "g",
-			v->v_id);
-
-		{
-			char *argv[] = { "do_quota_refresh", buf };
-
-			gi.gi_argc = 2;
-			gi.gi_argv = argv;
-
-			error = ioctl(fd, GFS2_IOCTL_SUPER, &gi);
-			if (error)
-				die("can't refresh the quota LVB 1: %s\n",
-				    strerror(errno));
+		/* 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");
+		
+		fd1 = open(sys_q_refresh, O_WRONLY);
+		if (fd1 < 0) {
+			fprintf(stderr, "can't open file %s: %s\n", 
+				sys_q_refresh, strerror(errno));
+			goto out;
 		}
+		if (write(fd1,(void*)"1", 1) != 1) {
+			close(fd1);
+			fprintf(stderr, "failed to write to %s: %s\n", 
+				sys_q_refresh, strerror(errno));
+			goto out;
+		}
+		close(fd1);
 	}
 
+out:
 	close(fd);
+	close(metafs_fd);
+	cleanup();
 }
 
 /**
- * do_init - initialize the quota file
+ * do_quota_init - initialize the quota file
  * @comline: the command line arguments
  *
  */
 
 void
-do_init(commandline_t *comline)
+do_quota_init(commandline_t *comline)
 {
 	dev_t device;
 	osi_list_t fs_uid, fs_gid, qf_uid, qf_gid;
@@ -530,7 +540,7 @@
 	set_list(comline, FALSE, &qf_gid, 0);
 	set_list(comline, TRUE, &fs_uid, 1);
 	set_list(comline, FALSE, &fs_gid, 1);
-
+	
 	do_sync(comline);
 
 	do_check(comline);
--- cluster/gfs2/quota/main.c	2005/09/07 06:48:51	1.2
+++ cluster/gfs2/quota/main.c	2007/05/10 22:43:12	1.2.2.1
@@ -10,13 +10,14 @@
 **
 *******************************************************************************
 ******************************************************************************/
-
 #include <stdio.h>
 #include <stdlib.h>
+#include <stdarg.h>
 #include <string.h>
 #include <ctype.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <sys/file.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <errno.h>
@@ -28,14 +29,13 @@
 #include <stdint.h>
 #include <inttypes.h>
 
-#include "linux_endian.h"
-#include <linux/gfs2_ondisk.h>
+#include <linux/types.h>
+#include "gfs2_quota.h"
+
 #define __user
-#include <linux/gfs2_ioctl.h>
 
 #include "copyright.cf"
 
-#include "gfs2_quota.h"
 
 /*  Constants  */
 
@@ -44,6 +44,19 @@
 char *prog_name;
 
 /**
+ * This function is for libgfs2's sake.
+ */
+void print_it(const char *label, const char *fmt, const char *fmt2, ...)
+{
+        va_list args;
+
+        va_start(args, fmt2);
+        printf("%s: ", label);
+        vprintf(fmt, args);
+        va_end(args);
+}
+
+/**
  * print_usage - print usage info to the user
  *
  */
@@ -86,42 +99,6 @@
  *
  */
 
-void
-check_for_gfs2(int fd, char *path)
-{
-	unsigned int magic = 0;
-	int error;
-
-	error = ioctl(fd, GFS2_IOCTL_IDENTIFY, &magic);
-	if (error || magic != GFS2_MAGIC)
-		die("%s is not a GFS2 file/filesystem\n", path);
-}
-
-/**
- * do_get_super
- * fd:
- * sb:
- *
- */
-
-void
-do_get_super(int fd, struct gfs2_sb *sb)
-{
-	struct gfs2_ioctl gi;
-	char *argv[] = { "get_super" };
-	int error;
-
-	gi.gi_argc = 1;
-	gi.gi_argv = argv;
-	gi.gi_data = (char *)sb;
-	gi.gi_size = sizeof(struct gfs2_sb);
-
-	error = ioctl(fd, GFS2_IOCTL_SUPER, &gi);
-	if (error != gi.gi_size)
-		die("can't read the superblock (%d): %s\n",
-		    error, strerror(errno));
-}
-
 /**
  * decode_arguments - parse command line arguments
  * @argc: well, it's argc...
@@ -309,57 +286,225 @@
 	}
 }
 
+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;
+	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));
+	}
+}
+
+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)
+{
+	int fd;
+	char buf[PATH_MAX];
+	
+	fd = open(device_name, O_RDONLY);
+	if (fd < 0) {
+		die("Could not open the block device %s: %s\n",
+			device_name, strerror(errno));
+	}
+	do_lseek(fd, 0x10 * 4096);
+	do_read(fd, buf, PATH_MAX);
+	gfs2_sb_in(sb, buf);
+
+	close(fd);
+}
+
 /**
  * do_list - List all the quota data for a filesystem
  * @comline: the struct containing the parsed command line arguments
  *
  */
 
-static void
+static void 
 do_list(commandline_t *comline)
 {
 	int fd;
 	struct gfs2_sb sb;
-	struct gfs2_ioctl gi;
-	char buf[sizeof(struct gfs2_quota)];
 	struct gfs2_quota q;
+	char buf[sizeof(struct gfs2_quota)];
 	uint64_t offset;
 	uint32_t id;
 	int pass = 0;
-	int error;
-
+	int error = 0;
+	char quota_file[BUF_SIZE];
+	
 	if (!*comline->filesystem)
 		die("need a filesystem to work on\n");
 
-	fd = open(comline->filesystem, O_RDONLY);
-	if (fd < 0)
-		die("can't open file %s: %s\n", comline->filesystem,
+	check_for_gfs2(comline->filesystem);
+	read_superblock(&sb);
+	if (!find_gfs2_meta(comline->filesystem))
+		mount_gfs2_meta();
+	lock_for_admin();
+	
+	strcpy(quota_file, metafs_path);
+	strcat(quota_file, "/quota");
+
+	fd = open(quota_file, O_RDONLY);
+	if (fd < 0) {
+		close(metafs_fd);
+		cleanup();
+		die("can't open file %s: %s\n", quota_file,
 		    strerror(errno));
-
-	check_for_gfs2(fd, comline->filesystem);
-	do_get_super(fd, &sb);
-
-	for (pass = 0; pass < 2; pass++) {
+	}
+	for (pass=0; pass<2; pass++) {
 		if (!pass)
 			offset = 0;
 		else
 			offset = sizeof(struct gfs2_quota);
 
 		do {
-			char *argv[] = { "do_hfile_read", "quota" };
-
-			gi.gi_argc = 2;
-			gi.gi_argv = argv;
-			gi.gi_data = buf;
-			gi.gi_size = sizeof(struct gfs2_quota);
-			gi.gi_offset = offset;
-
 			memset(buf, 0, sizeof(struct gfs2_quota));
 
-			error = ioctl(fd, GFS2_IOCTL_SUPER, &gi);
-			if (error < 0)
-				die("can't read quota file: %s\n",
-				    strerror(errno));
+			/* read hidden quota file here */
+			lseek(fd, offset, SEEK_SET);
+			error = read(fd, buf, sizeof(struct gfs2_quota));
 
 			gfs2_quota_in(&q, buf);
 
@@ -374,51 +519,87 @@
 	}
 
 	close(fd);
+	close(metafs_fd);
+	cleanup();
 }
 
 /**
- * do_sync_one - sync the quotas on one GFS2 filesystem
- * @path: a file/directory in the filesystem
+ * do_get_one - Get a quota value from one FS
+ * @comline: the struct containing the parsed command line arguments
+ * @filesystem: the filesystem to get from
  *
  */
 
-static void
-do_sync_one(char *filesystem)
+static void 
+do_get_one(commandline_t *comline, char *filesystem)
 {
 	int fd;
-	char *argv[] = { "do_quota_sync" };
-	struct gfs2_ioctl gi;
+	char buf[256];
+	struct gfs2_quota q;
+	struct gfs2_sb sb;
+	uint64_t offset;
 	int error;
+	char quota_file[BUF_SIZE];
 
-	fd = open(filesystem, O_RDONLY);
-	if (fd < 0)
-		die("can't open file %s: %s\n", filesystem, strerror(errno));
+	check_for_gfs2(filesystem);
+	read_superblock(&sb);
+	if (!find_gfs2_meta(filesystem))
+		mount_gfs2_meta();
+	lock_for_admin();
+	
+	strcpy(quota_file, metafs_path);
+	strcat(quota_file, "/quota");
+
+	fd = open(quota_file, O_RDONLY);
+	if (fd < 0) {
+		close(metafs_fd);
+		cleanup();
+		die("can't open file %s: %s\n", quota_file,
+		    strerror(errno));
+	}
 
-	check_for_gfs2(fd, filesystem);
+	if (comline->id_type == GQ_ID_USER)
+		offset = (2 * (uint64_t)comline->id) * sizeof(struct gfs2_quota);
+	else
+		offset = (2 * (uint64_t)comline->id + 1) * sizeof(struct gfs2_quota);
+
+	memset(&q, 0, sizeof(struct gfs2_quota));
+	
+	lseek(fd, offset, SEEK_SET);
+	error = read(fd, buf, sizeof(struct gfs2_quota));
+	if (error < 0) {
+		close(fd);
+		close(metafs_fd);
+		cleanup();
+		die("can't get quota info (%d): %s\n",
+		    error, strerror(errno));
+	}
+
+	gfs2_quota_in(&q, buf);
 
-	gi.gi_argc = 1;
-	gi.gi_argv = argv;
 
-	error = ioctl(fd, GFS2_IOCTL_SUPER, &gi);
-	if (error)
-		die("can't sync quotas: %s\n", strerror(errno));
+	print_quota(comline,
+		    (comline->id_type == GQ_ID_USER), comline->id,
+		    &q, &sb);
 
 	close(fd);
+	close(metafs_fd);
+	cleanup();	
 }
 
 /**
- * do_sync - sync out unsyned quotas
+ * do_get - Get a quota value
  * @comline: the struct containing the parsed command line arguments
  *
  */
 
-void
-do_sync(commandline_t *comline)
+static void
+do_get(commandline_t *comline)
 {
-	sync();
+	int first = TRUE;
 
 	if (*comline->filesystem)
-		do_sync_one(comline->filesystem);
+		do_get_one(comline, comline->filesystem);
 	else {
 		char buf[256], device[256], path[256], type[256];
 		FILE *file;
@@ -433,7 +614,13 @@
 			if (strcmp(type, "gfs2") != 0)
 				continue;
 
-			do_sync_one(path);
+			if (first)
+				first = FALSE;
+			else
+				printf("\n");
+
+			printf("%s\n", path);
+			do_get_one(comline, path);
 		}
 
 		fclose(file);
@@ -441,71 +628,46 @@
 }
 
 /**
- * do_get_one - Get a quota value from one FS
- * @comline: the struct containing the parsed command line arguments
- * @filesystem: the filesystem to get from
+ * do_sync_one - sync the quotas on one GFS2 filesystem
+ * @path: a file/directory in the filesystem
  *
  */
-
-static void
-do_get_one(commandline_t *comline, char *filesystem)
+static void 
+do_sync_one(char *filesystem)
 {
 	int fd;
-	char buf[256];
-	struct gfs2_ioctl gi;
-	struct gfs2_quota q;
 	struct gfs2_sb sb;
-	int error;
+	char sys_quota_sync[PATH_MAX];
 
-	fd = open(filesystem, O_RDONLY);
+	check_for_gfs2(filesystem);
+	read_superblock(&sb);
+	sprintf(sys_quota_sync, "%s%s%s", 
+		"/sys/fs/gfs2/", sb.sb_locktable, "/quota_sync");
+	
+	fd = open(sys_quota_sync, O_WRONLY);
 	if (fd < 0)
-		die("can't open file %s: %s\n", comline->filesystem,
-		    strerror(errno));
-
-	check_for_gfs2(fd, filesystem);
-
-	sprintf(buf, "%s:%u",
-		(comline->id_type == GQ_ID_USER) ? "u" : "g",
-		comline->id);
-
-	{
-		char *argv[] = { "do_quota_read", buf };
-
-		gi.gi_argc = 2;
-		gi.gi_argv = argv;
-		gi.gi_data = (char *)&q;
-		gi.gi_size = sizeof(struct gfs2_quota);
-
-		memset(&q, 0, sizeof(struct gfs2_quota));
-
-		error = ioctl(fd, GFS2_IOCTL_SUPER, &gi);
-		if (error < 0)
-			die("can't get quota info (%d): %s\n",
-			    error, strerror(errno));
-	}
-
-	do_get_super(fd, &sb);
-
-	print_quota(comline,
-		    (comline->id_type == GQ_ID_USER), comline->id,
-		    &q, &sb);
-
+		die("can't open file %s: %s\n", sys_quota_sync, strerror(errno));
+	
+	if (write(fd,(void*)"1", 1) != 1)
+		die("failed to write to %s: %s\n", 
+		    sys_quota_sync, strerror(errno));
+	
 	close(fd);
 }
 
 /**
- * do_get - Get a quota value
+ * do_sync - sync out unsyned quotas
  * @comline: the struct containing the parsed command line arguments
  *
  */
 
-static void
-do_get(commandline_t *comline)
+void
+do_sync(commandline_t *comline)
 {
-	int first = TRUE;
+	sync();
 
 	if (*comline->filesystem)
-		do_get_one(comline, comline->filesystem);
+		do_sync_one(comline->filesystem);
 	else {
 		char buf[256], device[256], path[256], type[256];
 		FILE *file;
@@ -520,13 +682,7 @@
 			if (strcmp(type, "gfs2") != 0)
 				continue;
 
-			if (first)
-				first = FALSE;
-			else
-				printf("\n");
-
-			printf("%s:\n", path);
-			do_get_one(comline, path);
+			do_sync_one(path);
 		}
 
 		fclose(file);
@@ -542,26 +698,36 @@
 static void
 do_set(commandline_t *comline)
 {
-	int fd;
+	int fd, fd1;
 	uint64_t offset;
-	struct gfs2_ioctl gi;
 	struct gfs2_sb sb;
 	uint64_t new_value;
-	char buf[256];
 	int error;
-
+	char quota_file[BUF_SIZE];
+	char sys_q_refresh[BUF_SIZE];
+	
 	if (!*comline->filesystem)
 		die("need a filesystem to work on\n");
 	if (!comline->new_value_set)
 		die("need a new value\n");
 
-	fd = open(comline->filesystem, O_RDONLY);
-	if (fd < 0)
-		die("can't open file %s: %s\n", comline->filesystem,
+	check_for_gfs2(comline->filesystem);
+	read_superblock(&sb);
+	if (!find_gfs2_meta(comline->filesystem))
+		mount_gfs2_meta();
+	lock_for_admin();
+	
+	strcpy(quota_file, metafs_path);
+	strcat(quota_file, "/quota");
+
+	fd = open(quota_file, O_WRONLY);
+	if (fd < 0) {
+		close(metafs_fd);
+		cleanup();
+		die("can't open file %s: %s\n", quota_file,
 		    strerror(errno));
-
-	check_for_gfs2(fd, comline->filesystem);
-
+	}
+	
 	switch (comline->id_type) {
 	case GQ_ID_USER:
 		offset = (2 * (uint64_t)comline->id) * sizeof(struct gfs2_quota);
@@ -572,8 +738,8 @@
 		break;
 
 	default:
-		die("invalid user/group ID\n");
-		break;
+		fprintf(stderr, "invalid user/group ID\n");
+		goto out;
 	}
 
 	switch (comline->operation) {
@@ -586,12 +752,10 @@
 		break;
 
 	default:
-		die("invalid operation\n");
-		break;
+		fprintf(stderr, "invalid operation\n");
+		goto out;
 	};
 
-	do_get_super(fd, &sb);
-
 	switch (comline->units) {
 	case GQ_UNITS_MEGABYTE:
 		new_value = comline->new_value << (20 - sb.sb_bsize_shift);
@@ -613,44 +777,43 @@
 		break;
 
 	default:
-		die("bad units\n");
-		break;
+		fprintf(stderr, "bad units\n");
+		goto out;
 	}
 
-	new_value = cpu_to_le64(new_value);
-
-	{
-		char *argv[] = { "do_hfile_write", "quota" };
-
-		gi.gi_argc = 2;
-		gi.gi_argv = argv;
-		gi.gi_data = (char *)&new_value;
-		gi.gi_size = sizeof(uint64_t);
-		gi.gi_offset = offset;
+	new_value = cpu_to_be64(new_value);
 
-		error = ioctl(fd, GFS2_IOCTL_SUPER, &gi);
-		if (error != gi.gi_size)
-			die("can't write quota file (%d): %s\n",
-			    error, strerror(errno));
+	lseek(fd, offset, SEEK_SET);
+	error = write(fd, (char*)&new_value, sizeof(uint64_t));
+	if (error != sizeof(uint64_t)) {
+		fprintf(stderr, "can't write quota file (%d): %s\n",
+		    error, strerror(errno));
+		goto out;
 	}
 
-	sprintf(buf, "%s:%u",
-		(comline->id_type == GQ_ID_USER) ? "u" : "g",
-		comline->id);
-
-	{
-		char *argv[] = { "do_quota_refresh", buf };
-
-		gi.gi_argc = 2;
-		gi.gi_argv = argv;
-
-		error = ioctl(fd, GFS2_IOCTL_SUPER, &gi);
-		if (error)
-			die("can't refresh the quota LVB: %s\n",
-			    strerror(errno));
+	/* Write "1" to sysfs quota refresh file to refresh gfs quotas */
+	sprintf(sys_q_refresh, "%s%s%s", "/sys/fs/gfs2/", sb.sb_locktable, 
+		comline->id_type == GQ_ID_USER ? "/quota_refresh_user" : 
+		"/quota_refresh_group");
+	
+	fd1 = open(sys_q_refresh, O_WRONLY);
+	if (fd1 < 0) {
+		fprintf(stderr, "can't open file %s: %s\n", sys_q_refresh, 
+			strerror(errno));
+		goto out;
+	}
+	
+	if (write(fd1,(void*)"1", 1) != 1) {
+		close(fd1);
+		fprintf(stderr, "failed to write to %s: %s\n", 
+			sys_q_refresh, strerror(errno));
+		goto out;
 	}
-
+	close(fd1);
+out:
 	close(fd);
+	close(metafs_fd);
+	cleanup();
 }
 
 /**
@@ -667,6 +830,7 @@
 	commandline_t comline;
 
 	prog_name = argv[0];
+	metafs_mounted = 0;
 
 	memset(&comline, 0, sizeof(commandline_t));
 
@@ -677,10 +841,6 @@
 		do_list(&comline);
 		break;
 
-	case GQ_OP_SYNC:
-		do_sync(&comline);
-		break;
-
 	case GQ_OP_GET:
 		do_get(&comline);
 		break;
@@ -690,6 +850,10 @@
 		do_set(&comline);
 		break;
 
+	case GQ_OP_SYNC:
+		do_sync(&comline);
+		break;
+
 	case GQ_OP_CHECK:
 		do_sync(&comline);
 		do_check(&comline);
@@ -697,7 +861,7 @@
 
 	case GQ_OP_INIT:
 		do_sync(&comline);
-		do_init(&comline);
+		do_quota_init(&comline);
 		break;
 
 	default:
--- cluster/gfs2/quota/names.c	2005/04/26 02:58:57	1.1
+++ cluster/gfs2/quota/names.c	2007/05/10 22:43:12	1.1.2.1
@@ -28,9 +28,6 @@
 #include <grp.h>
 #include <stdint.h>
 #include <inttypes.h>
-
-#include <linux/gfs2_ondisk.h>
-
 #include "gfs2_quota.h"
 
 uint32_t
--- cluster/gfs2/quota/gfs2_quota.h	2005/04/26 02:58:57	1.1
+++ cluster/gfs2/quota/gfs2_quota.h	2007/05/10 22:43:12	1.1.2.1
@@ -14,6 +14,9 @@
 #ifndef __GFS2_QUOTA_DOT_H__
 #define __GFS2_QUOTA_DOT_H__
 
+#include "libgfs2.h"
+#include "linux_endian.h"
+#include <linux/gfs2_ondisk.h>
 
 #ifndef TRUE
 #define TRUE (1)
@@ -64,6 +67,16 @@
 #define GQ_UNITS_FSBLOCK     (35)
 #define GQ_UNITS_BASICBLOCK  (36)
 
+#define BUF_SIZE 4096
+#define meta_mount "/tmp/.gfs2meta"
+char device_name[256];
+char fspath[256];
+char fsoptions[256];
+//char meta_mount[PATH_MAX]; = "/tmp/.gfs2meta";
+char metafs_path[BUF_SIZE];
+int metafs_fd;
+int metafs_mounted; /* If metafs was already mounted */
+
 struct commandline {
 	unsigned int operation;
 
@@ -85,18 +98,64 @@
 
 /*  main.c  */
 
-void check_for_gfs2(int fd, char *path);
+void check_for_gfs2(const char *path);
 void do_get_super(int fd, struct gfs2_sb *sb);
 void do_sync(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_init(commandline_t *comline);
+void do_quota_init(commandline_t *comline);
 
 /*  names.c  */
 
 uint32_t name_to_id(int user, char *name, int numbers);
 char *id_to_name(int user, uint32_t id, int numbers);
 
+
+static inline int __do_read(int fd, char *buff, size_t len, 
+			    const char *file, int line)
+{
+	int ret = read(fd, buff, len);
+	if (ret < 0) {
+		die("bad read: %s on line %d of file %s\n", 
+		    strerror(errno), line, file);
+	}
+	return ret;
+}
+
+#define do_read(fd, buf, len) \
+	__do_read((fd), (buf), (len), __FILE__, __LINE__)
+
+static inline int __do_write(int fd, char *buff, size_t len,
+			     const char *file, int line)
+{
+	int ret = write(fd, buff, len);
+	if (ret != len) {
+		die("bad write: %s on line %d of file %s\n",
+		    strerror(errno), line, file);
+	}
+	return ret;
+}
+
+#define do_write(fd, buf, len) \
+	__do_write((fd), (buf), (len), __FILE__, __LINE__)
+
+static inline int __do_lseek(int fd, off_t off, const char *file, int line)
+{
+	if (lseek(fd, off, SEEK_SET) != off) {
+		die("bad seek: %s on line %d of file %s\n",
+		    strerror(errno), line, file);
+	}
+	return 0;
+}
+
+#define do_lseek(fd, off) \
+	__do_lseek((fd), (off), __FILE__, __LINE__)
+
 #endif /* __GFS2_QUOTA_DOT_H__ */
--- cluster/gfs2/quota/Makefile	2006/08/11 15:18:13	1.5
+++ cluster/gfs2/quota/Makefile	2007/05/10 22:43:12	1.5.2.1
@@ -15,16 +15,15 @@
 
 TARGET= gfs2_quota
 
-SOURCE=	\
-	check.c \
-	main.c \
-	names.c \
-	ondisk.c
+SOURCE=	main.c names.c check.c
+
+INSTALL=install
 
 CFLAGS+= -O2 -DHELPER_PROGRAM -D_FILE_OFFSET_BITS=64 \
-	-DGFS2_RELEASE_NAME=\"${RELEASE}\"
+	-D_GNU_SOURCE -DGFS2_RELEASE_NAME=\"${RELEASE}\"
+LDFLAGS=-L${top_srcdir}/libgfs2 -L${libdir}
 
-INCLUDE= -I${top_srcdir}/include -I${top_srcdir}/config -I${gfs2kincdir}
+INCLUDE= -I${top_srcdir}/include -I${top_srcdir}/config -I${gfs2kincdir} -I${top_srcdir}/libgfs2/
 
 ifneq (${KERNEL_SRC}, )
 # Use the kernel tree if patched, otherwise, look where cluster headers
@@ -36,17 +35,20 @@
 INCLUDE += -I${incdir}
 endif
 
-all:
-#all: ${TARGET}
+#all:
+all: ${TARGET}
 
 gfs2_quota: ${SOURCE}
-	${CC} ${CFLAGS} ${INCLUDE} ${LDFLAGS} ${SOURCE} ${LOADLIBES} ${LDLIBS} -o $@
+	${CC} ${CFLAGS} ${INCLUDE} ${LDFLAGS} ${SOURCE} ${LOADLIBES} ${LDLIBS} -o $@ -lgfs2
+
+copytobin:
+#copytobin: ${TARGET}
+#	cp ${TARGET} ${top_srcdir}/bin
 
 install: all
-#	if [ ! -d ${sbindir} ]; then \
-#		install -d ${sbindir}; \
-#	fi
-#	install -m755 ${TARGET} ${sbindir}
+	${INSTALL} -m 0755 ${TARGET} ${sbindir}
 
 clean:
 	rm -f *.o ${TARGET}
+
+




More information about the Cluster-devel mailing list