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

adas at sourceware.org adas at sourceware.org
Thu May 31 22:32:40 UTC 2007


CVSROOT:	/cvs/cluster
Module name:	cluster
Changes by:	adas at sourceware.org	2007-05-31 22:32:40

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

Log message:
	Changes to fix broken code after Bob pulled out metafs mounting functionality from gfs2_quota into libgfs2.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/quota/check.c.diff?cvsroot=cluster&r1=1.4&r2=1.5
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/quota/gfs2_quota.h.diff?cvsroot=cluster&r1=1.3&r2=1.4
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/quota/main.c.diff?cvsroot=cluster&r1=1.5&r2=1.6

--- cluster/gfs2/quota/check.c	2007/05/10 15:47:45	1.4
+++ cluster/gfs2/quota/check.c	2007/05/31 22:32:40	1.5
@@ -191,19 +191,20 @@
 	int error;
 	char quota_file[BUF_SIZE];
 	
+	strcpy(sdp->path_name, comline->filesystem);
 	check_for_gfs2(sdp);
-	read_superblock(&sdp->sd_sb);
+	read_superblock(&sdp->sd_sb, sdp);
 	if (!find_gfs2_meta(sdp))
 		mount_gfs2_meta(sdp);
 	lock_for_admin(sdp);
 	
-	strcpy(quota_file, metafs_path);
+	strcpy(quota_file, sdp->metafs_path);
 	strcat(quota_file, "/quota");
 
 	fd = open(quota_file, O_RDONLY);
 	if (fd < 0) {
-		close(metafs_fd);
-		cleanup();
+		close(sdp->metafs_fd);
+		cleanup_metafs(sdp);
 		die("can't open file %s: %s\n", comline->filesystem,
 		    strerror(errno));
 	}
@@ -216,8 +217,8 @@
 		error = read(fd, buf, sizeof(struct gfs2_quota));
 		if (error < 0) {
 			close(fd);
-			close(metafs_fd);
-			cleanup();
+			close(sdp->metafs_fd);
+			cleanup_metafs(sdp);
 			die("can't read quota file (%d): %s\n",
 			    error, strerror(errno));
 		}
@@ -237,8 +238,8 @@
 	} while (error == sizeof(struct gfs2_quota));
 
 	close(fd);
-	close(metafs_fd);
-	cleanup();
+	close(sdp->metafs_fd);
+	cleanup_metafs(sdp);
 }
 
 /**
@@ -434,20 +435,22 @@
 	int error;
 	char quota_file[BUF_SIZE];
 	char sys_q_refresh[BUF_SIZE];
-	
+	char id_str[16];
+
+	strcpy(sdp->path_name, comline->filesystem);
 	check_for_gfs2(sdp);
-	read_superblock(&sdp->sd_sb);
+	read_superblock(&sdp->sd_sb, sdp);
 	if (!find_gfs2_meta(sdp))
 		mount_gfs2_meta(sdp);
 	lock_for_admin(sdp);
 	
-	strcpy(quota_file, metafs_path);
+	strcpy(quota_file, sdp->metafs_path);
 	strcat(quota_file, "/quota");
 
 	fd = open(quota_file, O_WRONLY);
 	if (fd < 0) {
-		close(metafs_fd);
-		cleanup();
+		close(sdp->metafs_fd);
+		cleanup_metafs(sdp);
 		die("can't open file %s: %s\n", comline->filesystem,
 		    strerror(errno));
 	}
@@ -471,7 +474,7 @@
 			goto out;
 		}
 
-		/* Write "1" to sysfs quota refresh file to refresh gfs quotas */
+		/* Write the id to sysfs quota refresh file to refresh gfs quotas */
 		sprintf(sys_q_refresh, "%s%s%s", "/sys/fs/gfs2/",
 			sdp->sd_sb.sb_locktable, 
 			(user) ? "/quota_refresh_user" :
@@ -483,7 +486,10 @@
 				sys_q_refresh, strerror(errno));
 			goto out;
 		}
-		if (write(fd1,(void*)"1", 1) != 1) {
+
+		sprintf(id_str, "%d", comline->id);
+		
+		if (write(fd1,(void*)id_str, strlen(id_str)) != strlen(id_str)) {
 			close(fd1);
 			fprintf(stderr, "failed to write to %s: %s\n", 
 				sys_q_refresh, strerror(errno));
@@ -494,8 +500,8 @@
 
 out:
 	close(fd);
-	close(metafs_fd);
-	cleanup();
+	close(sdp->metafs_fd);
+	cleanup_metafs(sdp);
 }
 
 /**
--- cluster/gfs2/quota/gfs2_quota.h	2007/05/10 15:47:45	1.3
+++ cluster/gfs2/quota/gfs2_quota.h	2007/05/31 22:32:40	1.4
@@ -69,13 +69,6 @@
 
 #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;
@@ -103,7 +96,7 @@
 void lock_for_admin();
 void mount_gfs2_meta();
 void cleanup();
-void read_superblock(struct gfs2_sb *sb);
+void read_superblock(struct gfs2_sb *sb, struct gfs2_sbd *sdp);
 
 /*  check.c  */
 
--- cluster/gfs2/quota/main.c	2007/05/14 22:26:31	1.5
+++ cluster/gfs2/quota/main.c	2007/05/31 22:32:40	1.6
@@ -279,28 +279,16 @@
 	}
 }
 
-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 
-read_superblock(struct gfs2_sb *sb)
+read_superblock(struct gfs2_sb *sb, struct gfs2_sbd *sdp)
 {
 	int fd;
 	char buf[PATH_MAX];
 	
-	fd = open(device_name, O_RDONLY);
+	fd = open(sdp->device_name, O_RDONLY);
 	if (fd < 0) {
 		die("Could not open the block device %s: %s\n",
-			device_name, strerror(errno));
+			sdp->device_name, strerror(errno));
 	}
 	do_lseek(fd, 0x10 * 4096);
 	do_read(fd, buf, PATH_MAX);
@@ -330,19 +318,20 @@
 	if (!*comline->filesystem)
 		die("need a filesystem to work on\n");
 
+	strcpy(sdp->path_name, comline->filesystem);
 	check_for_gfs2(sdp);
-	read_superblock(&sdp->sd_sb);
+	read_superblock(&sdp->sd_sb, sdp);
 	if (!find_gfs2_meta(sdp))
 		mount_gfs2_meta(sdp);
 	lock_for_admin(sdp);
 	
-	strcpy(quota_file, metafs_path);
+	strcpy(quota_file, sdp->metafs_path);
 	strcat(quota_file, "/quota");
 
 	fd = open(quota_file, O_RDONLY);
 	if (fd < 0) {
-		close(metafs_fd);
-		cleanup();
+		close(sdp->metafs_fd);
+		cleanup_metafs(sdp);
 		die("can't open file %s: %s\n", quota_file,
 		    strerror(errno));
 	}
@@ -372,8 +361,8 @@
 	}
 
 	close(fd);
-	close(metafs_fd);
-	cleanup();
+	close(sdp->metafs_fd);
+	cleanup_metafs(sdp);
 }
 
 /**
@@ -393,19 +382,20 @@
 	int error;
 	char quota_file[BUF_SIZE];
 
+	strcpy(sdp->path_name, filesystem);
 	check_for_gfs2(sdp);
-	read_superblock(&sdp->sd_sb);
+	read_superblock(&sdp->sd_sb, sdp);
 	if (!find_gfs2_meta(sdp))
 		mount_gfs2_meta(sdp);
 	lock_for_admin(sdp);
 	
-	strcpy(quota_file, metafs_path);
+	strcpy(quota_file, sdp->metafs_path);
 	strcat(quota_file, "/quota");
 
 	fd = open(quota_file, O_RDONLY);
 	if (fd < 0) {
-		close(metafs_fd);
-		cleanup();
+		close(sdp->metafs_fd);
+		cleanup_metafs(sdp);
 		die("can't open file %s: %s\n", quota_file,
 		    strerror(errno));
 	}
@@ -421,8 +411,8 @@
 	error = read(fd, buf, sizeof(struct gfs2_quota));
 	if (error < 0) {
 		close(fd);
-		close(metafs_fd);
-		cleanup();
+		close(sdp->metafs_fd);
+		cleanup_metafs(sdp);
 		die("can't get quota info (%d): %s\n",
 		    error, strerror(errno));
 	}
@@ -435,8 +425,8 @@
 		    &q, &sdp->sd_sb);
 
 	close(fd);
-	close(metafs_fd);
-	cleanup();	
+	close(sdp->metafs_fd);
+	cleanup_metafs(sdp);	
 }
 
 /**
@@ -490,8 +480,9 @@
 	int fd;
 	char sys_quota_sync[PATH_MAX];
 
+	strcpy(sdp->path_name, filesystem);
 	check_for_gfs2(sdp);
-	read_superblock(&sdp->sd_sb);
+	read_superblock(&sdp->sd_sb, sdp);
 	sprintf(sys_quota_sync, "%s%s%s", 
 		"/sys/fs/gfs2/", sdp->sd_sb.sb_locktable, "/quota_sync");
 	
@@ -556,25 +547,27 @@
 	char quota_file[BUF_SIZE];
 	char sys_q_refresh[BUF_SIZE];
 	char id_str[16];
+	struct stat stat_buf;
 	
 	if (!*comline->filesystem)
 		die("need a filesystem to work on\n");
 	if (!comline->new_value_set)
 		die("need a new value\n");
 
+	strcpy(sdp->path_name, comline->filesystem);
 	check_for_gfs2(sdp);
-	read_superblock(&sdp->sd_sb);
+	read_superblock(&sdp->sd_sb, sdp);
 	if (!find_gfs2_meta(sdp))
 		mount_gfs2_meta(sdp);
 	lock_for_admin(sdp);
 	
-	strcpy(quota_file, metafs_path);
+	strcpy(quota_file, sdp->metafs_path);
 	strcat(quota_file, "/quota");
 
 	fd = open(quota_file, O_WRONLY);
 	if (fd < 0) {
-		close(metafs_fd);
-		cleanup();
+		close(sdp->metafs_fd);
+		cleanup_metafs(sdp);
 		die("can't open file %s: %s\n", quota_file,
 		    strerror(errno));
 	}
@@ -593,20 +586,6 @@
 		goto out;
 	}
 
-	switch (comline->operation) {
-	case GQ_OP_LIMIT:
-		offset += (unsigned long)(&((struct gfs2_quota *) NULL)->qu_limit);
-		break;
-
-	case GQ_OP_WARN:
-		offset += (unsigned long)(&((struct gfs2_quota *) NULL)->qu_warn);
-		break;
-
-	default:
-		fprintf(stderr, "invalid operation\n");
-		goto out;
-	};
-
 	switch (comline->units) {
 	case GQ_UNITS_MEGABYTE:
 		new_value =
@@ -636,16 +615,76 @@
 	}
 
 	new_value = cpu_to_be64(new_value);
-
-	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));
+	/*
+	 * Hack to force writing the entire gfs2_quota structure to 
+	 * the quota file instead of just the limit or warn values.
+	 * This is because of a bug in gfs2 which doesn't extend 
+	 * the quotafile appropriately to write the usage value of a 
+	 * given id. For instance, if you write a limit value (8 bytes) 
+	 * for userid x at offset 2*x, gfs2 will not extend the file and write 
+	 * 8 bytes at offset (2*x + 16) when it has to update the usage 
+	 * value for id x. Therefore, we extend the quota file to 
+	 * a struct gfs2_quota boundary. i.e. The size of the quota file
+	 * will always be a multiple of sizeof(struct gfs2_quota)
+	 */
+	if (fstat(fd, &stat_buf)) {
+		fprintf(stderr, "stat failed: %s\n", strerror(errno));
 		goto out;
 	}
+	if (stat_buf.st_size < (offset + sizeof(struct gfs2_quota))) {
+		struct gfs2_quota tmp;
+		memset((void*)(&tmp), 0, sizeof(struct gfs2_quota));
+		switch (comline->operation) {
+		case GQ_OP_LIMIT:
+			tmp.qu_limit = new_value; break;
+		case GQ_OP_WARN:
+			tmp.qu_warn = new_value; break;
+		}
+		
+		lseek(fd, offset, SEEK_SET);
+		error = write(fd, (void*)(&tmp), sizeof(struct gfs2_quota));
+		if (error != sizeof(struct gfs2_quota)) {
+			fprintf(stderr, "can't write quota file (%d): %s\n", 
+				error, strerror(errno));
+			goto out;
+		}
+		/* Also, if the id type is USER, append another empty 
+		 * struct gfs2_quota for the GROUP with the same id
+		 */
+		if (comline->id_type == GQ_ID_USER) {
+			memset((void*)(&tmp), 0, sizeof(struct gfs2_quota));
+			error = write(fd, (void*)(&tmp), sizeof(struct gfs2_quota));
+			if (error != sizeof(struct gfs2_quota)) {
+				fprintf(stderr, "can't write quota file (%d): %s\n", 
+					error, strerror(errno));
+				goto out;
+			}
+		}
+	} else {
+		switch (comline->operation) {
+		case GQ_OP_LIMIT:
+			offset += (unsigned long)(&((struct gfs2_quota *) NULL)->qu_limit);
+			break;
+			
+		case GQ_OP_WARN:
+			offset += (unsigned long)(&((struct gfs2_quota *) NULL)->qu_warn);
+			break;
+			
+		default:
+			fprintf(stderr, "invalid operation\n");
+			goto out;
+		};
+
+		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;
+		}
+	}
 
-	/* Write "1" to sysfs quota refresh file to refresh gfs quotas */
+	/* Write the id to sysfs quota refresh file to refresh gfs quotas */
 	sprintf(sys_q_refresh, "%s%s%s", "/sys/fs/gfs2/",
 		sdp->sd_sb.sb_locktable, 
 		comline->id_type == GQ_ID_USER ? "/quota_refresh_user" : 
@@ -669,8 +708,8 @@
 	close(fd1);
 out:
 	close(fd);
-	close(metafs_fd);
-	cleanup();
+	close(sdp->metafs_fd);
+	cleanup_metafs(sdp);
 }
 
 /**
@@ -684,17 +723,19 @@
 int
 main(int argc, char *argv[])
 {
-        struct gfs2_sbd sbd, *sdp = &sbd;
+    struct gfs2_sbd sbd, *sdp = &sbd;
 	commandline_t comline;
 
 	prog_name = argv[0];
-	metafs_mounted = 0;
+	sdp->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);
+	sdp->path_name = (char*) malloc(512);
+	if (!sdp->path_name)
+		die("Can't malloc! %s\n", strerror(errno));
 
 	switch (comline.operation) {
 	case GQ_OP_LIST:
@@ -732,6 +773,8 @@
 		do_get(sdp, &comline);
 		break;
 	}
+	
+	free(sdp->path_name);
 
 	exit(EXIT_SUCCESS);
 }




More information about the Cluster-devel mailing list