[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