Gitweb:
http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: aa83b6f3b2606964e602bed3c6f467641f31891d
Parent: 276b437eadbcb3a7f96a4fd008f0bb98ecdc8819
Author: Abhijith Das <adas(a)redhat.com>
AuthorDate: Wed Mar 3 15:01:17 2010 -0600
Committer: Abhijith Das <adas(a)redhat.com>
CommitterDate: Wed Mar 3 15:01:17 2010 -0600
gfs2_quota: initialize fiemap flags and fix boundary conditions
This patch initializes fiemap flags before calling
the ioctl and also fixes gfs2_quota for some
boundary conditions that prevent some quotas from
being set/listed.
rhbz#536902
---
gfs2/quota/check.c | 5 ++-
gfs2/quota/main.c | 114 ++++++++++++++++------------------------------------
2 files changed, 39 insertions(+), 80 deletions(-)
diff --git a/gfs2/quota/check.c b/gfs2/quota/check.c
index f33aa17..59c287f 100644
--- a/gfs2/quota/check.c
+++ b/gfs2/quota/check.c
@@ -222,6 +222,7 @@ read_quota_file(struct gfs2_sbd *sdp, commandline_t *comline,
}
quota_file_size = statbuf.st_size;
/* First find the number of extents in the quota file */
+ fmap.fm_flags = 0;
fmap.fm_start = 0;
fmap.fm_length = (~0ULL);
error = ioctl(fd, FS_IOC_FIEMAP, &fmap);
@@ -235,6 +236,7 @@ read_quota_file(struct gfs2_sbd *sdp, commandline_t *comline,
fprintf(stderr, "malloc error (%d): %s\n", errno, strerror(errno));
goto out;
}
+ fmap2->fm_flags = 0;
fmap2->fm_start = 0;
fmap2->fm_length = (~0ULL);
fmap2->fm_extent_count = fmap.fm_mapped_extents;
@@ -264,6 +266,7 @@ read_quota_file(struct gfs2_sbd *sdp, commandline_t *comline,
}
gfs2_quota_in(&q, buf);
id = (offset / sizeof(struct gfs2_quota)) >> 1;
+ /* We want value in 512 byte blocks (1 << 9 = 512) */
q.qu_value <<= sdp->sd_sb.sb_bsize_shift - 9;
if (q.qu_value) {
@@ -274,7 +277,7 @@ read_quota_file(struct gfs2_sbd *sdp, commandline_t *comline,
}
offset += sizeof(struct gfs2_quota);
- } while ((offset + sizeof(struct gfs2_quota)) <
+ } while ((offset + sizeof(struct gfs2_quota)) <=
end);
}
}
diff --git a/gfs2/quota/main.c b/gfs2/quota/main.c
index e8b0fa2..36b6f2d 100644
--- a/gfs2/quota/main.c
+++ b/gfs2/quota/main.c
@@ -321,7 +321,7 @@ read_quota_internal(int fd, uint32_t id, int id_type, struct
gfs2_quota *q)
if (error < 0)
die("failed to read from quota file: %s\n", strerror(errno));
if (error != sizeof(struct gfs2_quota))
- die("Couldn't read %u bytes from quota file at offset %llu\n",
+ die("Couldn't read %lu bytes from quota file at offset %llu\n",
sizeof(struct gfs2_quota), (unsigned long long)offset);
gfs2_quota_in(q, buf);
}
@@ -360,8 +360,8 @@ do_reset(struct gfs2_sbd *sdp, commandline_t *comline)
if (!*comline->filesystem)
die("need a filesystem to work on\n");
- printf("This operation will permanently erase all quota information. "
- "You will have to re-assign all quota limit/warn values. "
+ printf("This operation will permanently erase all quota information.\n"
+ "You will have to re-assign all quota limit/warn values.\n"
"Proceed [y/N]? ");
c = getchar();
if (c != 'y' && c != 'Y')
@@ -411,8 +411,9 @@ do_list(struct gfs2_sbd *sdp, commandline_t *comline)
{
int fd;
struct gfs2_quota q;
- uint32_t startid, endid;
- int id_type;
+ char buf[sizeof(struct gfs2_quota)];
+ uint64_t offset;
+ uint32_t id, startid;
int pass = 0;
int error = 0;
char quota_file[BUF_SIZE];
@@ -447,6 +448,7 @@ do_list(struct gfs2_sbd *sdp, commandline_t *comline)
}
quota_file_size = statbuf.st_size;
/* First find the number of extents in the quota file */
+ fmap.fm_flags = 0;
fmap.fm_start = 0;
fmap.fm_length = (~0ULL);
error = ioctl(fd, FS_IOC_FIEMAP, &fmap);
@@ -460,6 +462,7 @@ do_list(struct gfs2_sbd *sdp, commandline_t *comline)
fprintf(stderr, "malloc error (%d): %s\n", errno, strerror(errno));
goto out;
}
+ fmap2->fm_flags = 0;
fmap2->fm_start = 0;
fmap2->fm_length = (~0ULL);
fmap2->fm_extent_count = fmap.fm_mapped_extents;
@@ -478,19 +481,26 @@ do_list(struct gfs2_sbd *sdp, commandline_t *comline)
end = end > quota_file_size ? quota_file_size : end;
startid = DIV_RU(fe->fe_logical, sizeof(struct gfs2_quota));
- endid = end /(2 * sizeof(struct gfs2_quota));
if (startid % 2 != pass)
startid++;
-
- startid = DIV_RU(startid, 2);
- id_type = pass == 0 ? GQ_ID_USER : GQ_ID_GROUP;
+ offset = startid * sizeof(struct gfs2_quota);
do {
- read_quota_internal(fd, startid, id_type, &q);
+ memset(buf, 0, sizeof(struct gfs2_quota));
+ /* read hidden quota file here */
+ lseek(fd, offset, SEEK_SET);
+ error = read(fd, buf, sizeof(struct gfs2_quota));
+ if (error < 0) {
+ fprintf(stderr, "read error (%d): %s\n",
+ errno, strerror(errno));
+ goto fmap2_free;
+ }
+ gfs2_quota_in(&q, buf);
+ id = (offset / sizeof(struct gfs2_quota)) >> 1;
if (q.qu_limit || q.qu_warn || q.qu_value)
- print_quota(comline, (pass) ? FALSE : TRUE, startid,
+ print_quota(comline, (pass) ? FALSE : TRUE, id,
&q, &sdp->sd_sb);
- startid++;
- } while (startid < endid);
+ offset += 2 * sizeof(struct gfs2_quota);
+ } while (offset < end);
}
if (!pass) {
pass = 1;
@@ -666,10 +676,10 @@ do_set(struct gfs2_sbd *sdp, commandline_t *comline)
int fd;
uint64_t offset;
uint64_t new_value;
- int error;
char quota_file[BUF_SIZE];
char id_str[16];
struct stat stat_buf;
+ struct gfs2_quota q;
char *fs;
if (!*comline->filesystem)
@@ -685,7 +695,7 @@ do_set(struct gfs2_sbd *sdp, commandline_t *comline)
strcpy(quota_file, sdp->metafs_path);
strcat(quota_file, "/quota");
- fd = open(quota_file, O_WRONLY);
+ fd = open(quota_file, O_RDWR);
if (fd < 0) {
close(sdp->metafs_fd);
cleanup_metafs(sdp);
@@ -735,76 +745,22 @@ do_set(struct gfs2_sbd *sdp, commandline_t *comline)
goto out;
}
- new_value = cpu_to_be64(new_value);
- /*
- * 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)
- */
+ memset(&q, 0, 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;
- };
+ if (stat_buf.st_size >= (offset + sizeof(struct gfs2_quota)))
+ read_quota_internal(fd, comline->id, comline->id_type, &q);
- 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;
- }
+ switch (comline->operation) {
+ case GQ_OP_LIMIT:
+ q.qu_limit = new_value; break;
+ case GQ_OP_WARN:
+ q.qu_warn = new_value; break;
}
+ write_quota_internal(fd, comline->id, comline->id_type, &q);
fs = mp2fsname(comline->filesystem);
sprintf(id_str, "%d", comline->id);
set_sysfs(fs, comline->id_type == GQ_ID_USER ?