From mboxrd@z Thu Jan 1 00:00:00 1970 From: adas@sourceware.org Date: 31 May 2007 22:39:15 -0000 Subject: [Cluster-devel] cluster/gfs2/quota check.c gfs2_quota.h main.c Message-ID: <20070531223915.15239.qmail@sourceware.org> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit CVSROOT: /cvs/cluster Module name: cluster Branch: RHEL5 Changes by: adas at sourceware.org 2007-05-31 22:39:15 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&only_with_tag=RHEL5&r1=1.2.2.2&r2=1.2.2.3 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/quota/gfs2_quota.h.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.1.2.2&r2=1.1.2.3 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/quota/main.c.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.2.2.3&r2=1.2.2.4 --- cluster/gfs2/quota/check.c 2007/05/11 16:53:33 1.2.2.2 +++ cluster/gfs2/quota/check.c 2007/05/31 22:39:15 1.2.2.3 @@ -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/11 16:53:33 1.1.2.2 +++ cluster/gfs2/quota/gfs2_quota.h 2007/05/31 22:39:15 1.1.2.3 @@ -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:01 1.2.2.3 +++ cluster/gfs2/quota/main.c 2007/05/31 22:39:15 1.2.2.4 @@ -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); }