* [Cluster-devel] cluster gfs-kernel/src/gfs/ioctl.c gfs/gfs_quo ...
@ 2007-04-04 21:31 adas
2007-04-20 10:48 ` Fabio Massimo Di Nitto
0 siblings, 1 reply; 3+ messages in thread
From: adas @ 2007-04-04 21:31 UTC (permalink / raw)
To: cluster-devel.redhat.com
CVSROOT: /cvs/cluster
Module name: cluster
Changes by: adas at sourceware.org 2007-04-04 22:31:33
Modified files:
gfs-kernel/src/gfs: ioctl.c
gfs/gfs_quota : Makefile main.c gfs_quota.h
Added files:
gfs/gfs_quota : layout.c
Log message:
fix for bz 225199 - Same as GFS1 fix in RHEL4 (bz 210362). We don't run throug the entire gfs_quota sparse file to do a list operation anymore. We get the layout of the gfs_quota file on disk and only read quota information off the data blocks that are actually in use. Also added functionality to GFS_IOCTL_SUPER to provide the metadata of the hidden quota file.
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs-kernel/src/gfs/ioctl.c.diff?cvsroot=cluster&r1=1.14&r2=1.15
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs/gfs_quota/layout.c.diff?cvsroot=cluster&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs/gfs_quota/Makefile.diff?cvsroot=cluster&r1=1.5&r2=1.6
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs/gfs_quota/main.c.diff?cvsroot=cluster&r1=1.3&r2=1.4
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs/gfs_quota/gfs_quota.h.diff?cvsroot=cluster&r1=1.2&r2=1.3
--- cluster/gfs-kernel/src/gfs/ioctl.c 2006/11/13 22:47:48 1.14
+++ cluster/gfs-kernel/src/gfs/ioctl.c 2007/04/04 21:31:33 1.15
@@ -1464,6 +1464,8 @@
error = gi_set_file_flag(ip, &gi);
else if (strcmp(arg0, "get_file_meta") == 0)
error = gi_get_file_meta(ip, &gi);
+ else if (strcmp(arg0, "get_file_meta_quota") == 0)
+ error = gi_get_file_meta(ip->i_sbd->sd_qinode, &gi);
else if (strcmp(arg0, "do_file_flush") == 0)
error = gi_do_file_flush(ip, &gi);
else if (strcmp(arg0, "get_hfile_stat") == 0)
--- cluster/gfs/gfs_quota/layout.c 2007/01/10 17:53:54 1.1
+++ cluster/gfs/gfs_quota/layout.c 2007/04/04 21:31:33 1.2
@@ -0,0 +1,613 @@
+/******************************************************************************
+*******************************************************************************
+**
+** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
+** Copyright (C) 2004 Red Hat, Inc. All rights reserved.
+**
+** This copyrighted material is made available to anyone wishing to use,
+** modify, copy, or redistribute it subject to the terms and conditions
+** of the GNU General Public License v.2.
+**
+*******************************************************************************
+******************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <limits.h>
+#include <errno.h>
+
+#define __user
+#include <linux/gfs_ioctl.h>
+#include <linux/gfs_ondisk.h>
+
+#include "osi_list.h"
+#include "linux_endian.h"
+
+#include "gfs_quota.h"
+
+#define LAYOUT_DATA_QUANTUM (4194304)
+
+extern void
+print_quota(commandline_t *comline,
+ int user, uint32_t id,
+ struct gfs_quota *q,
+ struct gfs_sb *sb);
+
+struct extent {
+ osi_list_t list;
+
+ uint64_t offset;
+ uint64_t start;
+ unsigned int len;
+};
+typedef struct extent extent_t;
+
+struct buffer {
+ osi_list_t list;
+ uint64_t blkno;
+ char *data;
+
+ int touched;
+};
+typedef struct buffer buffer_t;
+
+struct lblk_range {
+ osi_list_t list;
+
+ uint64_t start;
+ unsigned int len;
+};
+typedef struct lblk_range lblk_range_t;
+
+struct world {
+ char *buf_data;
+ unsigned int buf_size;
+ int buf_count;
+ osi_list_t blist;
+ osi_list_t elist;
+
+ struct gfs_sb sb;
+ unsigned int diptrs;
+ unsigned int inptrs;
+ unsigned int jbsize;
+ unsigned int hash_bsize;
+ unsigned int hash_ptrs;
+
+ buffer_t *dibh;
+ struct gfs_dinode di;
+};
+typedef struct world world_t;
+
+typedef void (*pointer_call_t) (world_t *w,
+ unsigned int height, uint64_t bn, void *data);
+
+static lblk_range_t *lblk_range_list;
+static unsigned int j_blk_size;
+
+/**
+ * add_lblk_range - Add a range of logical block numbers to lblk_list
+ * @lblk_list: the list to add to
+ * @start: the starting block number of the range
+ * @len: the length of the range
+ *
+ */
+
+static void
+add_lblk_range(lblk_range_t *lblk_list, uint64_t start, unsigned int len)
+{
+ lblk_range_t *tmp;
+
+ tmp = malloc(sizeof(lblk_range_t));
+ if (!tmp)
+ die("out of memory\n");
+
+ tmp->start = start;
+ tmp->len = len;
+
+ osi_list_add_prev(&tmp->list, &lblk_list->list);
+}
+
+/**
+ * build_list - build a list of buffer_t's to represent the data from the kernel
+ * @w: the world structure
+ *
+ */
+
+static void
+build_list(world_t *w)
+{
+ buffer_t *b;
+ unsigned int x;
+
+ for (x = 0; x < w->buf_count; x += sizeof(uint64_t) + w->sb.sb_bsize) {
+ b = malloc(sizeof(buffer_t));
+ if (!b)
+ die("out of memory\n");
+
+ memset(b, 0, sizeof(buffer_t));
+
+ b->blkno = *(uint64_t *) (w->buf_data + x);
+ b->data = w->buf_data + x + sizeof(uint64_t);
+
+ osi_list_add_prev(&b->list, &w->blist);
+ }
+
+ if (x != w->buf_count)
+ die("the kernel passed back unaligned data\n");
+}
+
+/**
+ * check_list - check the buffers passed back by the kernel
+ * @w: the world
+ *
+ */
+
+static void
+check_list(world_t *w)
+{
+ osi_list_t *tmp;
+ buffer_t *b;
+ struct gfs_meta_header mh;
+ char *type;
+
+ for (tmp = w->blist.next; tmp != &w->blist; tmp = tmp->next) {
+ b = osi_list_entry(tmp, buffer_t, list);
+
+ gfs_meta_header_in(&mh, b->data);
+
+ if (mh.mh_magic != GFS_MAGIC)
+ die("bad magic number on block\n");
+
+ switch (mh.mh_type) {
+ case GFS_METATYPE_DI:
+ type = "GFS_METATYPE_DI";
+
+ if (w->dibh)
+ die("more than one dinode in file\n");
+ else {
+ w->dibh = b;
+ gfs_dinode_in(&w->di, b->data);
+
+ b->touched = TRUE;
+ }
+ break;
+ case GFS_METATYPE_IN:
+ type = "GFS_METATYPE_IN";
+ break;
+ case GFS_METATYPE_LF:
+ type = "GFS_METATYPE_LF";
+ break;
+ case GFS_METATYPE_JD:
+ type = "GFS_METATYPE_JD";
+ break;
+ case GFS_METATYPE_EA:
+ type = "GFS_METATYPE_EA";
+ break;
+ case GFS_METATYPE_ED:
+ die("GFS_METATYPE_ED shouldn't be present\n");
+ default:
+ die("strange meta type\n");
+ }
+ }
+
+ if (!w->dibh)
+ die("no dinode\n");
+}
+
+/**
+ * getbuf - get the buffer_t for a given block number
+ * @w: the world
+ * @blkno: the block number
+ *
+ * Returns: the buffer_t
+ */
+
+static buffer_t *
+getbuf(world_t *w, uint64_t blkno)
+{
+ osi_list_t *tmp;
+ buffer_t *b;
+
+ for (tmp = w->blist.next; tmp != &w->blist; tmp = tmp->next) {
+ b = osi_list_entry(tmp, buffer_t, list);
+ if (b->blkno == blkno) {
+ osi_list_del(&b->list);
+ osi_list_add(&b->list, &w->blist);
+
+ b->touched = TRUE;
+
+ return b;
+ }
+ }
+
+ die("buffer not found\n");
+}
+
+/**
+ * recursive_scan - call a function for each block pointer in a file
+ * @w: the world
+ * @height: the height of the block being pointed to
+ * @block: the block being pointed to
+ * @pc: the function to call
+ * @data: private data for the @pc function
+ *
+ */
+
+static void
+recursive_scan(world_t *w, unsigned int height,
+ uint64_t block, pointer_call_t pc, void *data)
+{
+ buffer_t *b = NULL;
+ uint64_t *top, *bottom;
+ uint64_t bn;
+
+ if (!height) {
+ b = w->dibh;
+
+ top = (uint64_t *) (b->data + sizeof(struct gfs_dinode));
+ bottom =
+ (uint64_t *) (b->data + sizeof(struct gfs_dinode)) +
+ w->diptrs;
+ } else {
+ b = getbuf(w, block);
+
+ top = (uint64_t *) (b->data + sizeof(struct gfs_indirect));
+ bottom =
+ (uint64_t *) (b->data + sizeof(struct gfs_indirect)) +
+ w->inptrs;
+ }
+
+ for (; top < bottom; top++) {
+ bn = gfs64_to_cpu(*top);
+
+ pc(w, height, bn, data);
+
+ if (bn && height < w->di.di_height - 1)
+ recursive_scan(w, height + 1, bn, pc, data);
+ }
+}
+
+/**
+ * add_extent - add an extend to the list of the file's data extents
+ * @w: the world
+ * @offset: the starting logical block of the extent
+ * @start: the starting disk block of the extent
+ * @len: the number of blocks in the extent
+ *
+ */
+
+static void
+add_extent(world_t *w, uint64_t offset, uint64_t start, unsigned int len)
+{
+ extent_t *e;
+
+ e = malloc(sizeof(extent_t));
+ if (!e)
+ die("out of memory\n");
+
+ memset(e, 0, sizeof(extent_t));
+
+ e->offset = offset;
+ e->start = start;
+ e->len = len;
+
+ osi_list_add_prev(&e->list, &w->elist);
+}
+
+struct do_pf_s {
+ unsigned int height;
+ uint64_t offset;
+ uint64_t start;
+ uint64_t skip;
+ unsigned int len;
+};
+typedef struct do_pf_s do_pf_t;
+
+/**
+ * do_pf: called for every pointer in the file (prints/collects extent info)
+ * @w: the world
+ * @height: the height of the block containing the pointer
+ * @bn: the contents of the pointer
+ * @data: a do_pf_t structure
+ *
+ */
+
+static void
+do_pf(world_t *w, unsigned int height, uint64_t bn, void *data)
+{
+ do_pf_t *pf = (do_pf_t *) data;
+ unsigned int x;
+ uint64_t skip;
+
+ if (pf->height < height + 1)
+ return;
+
+ if (!bn) {
+ if (pf->height == height + 1)
+ pf->skip++;
+ else {
+ x = pf->height - height - 1;
+ skip = w->inptrs;
+ while (--x)
+ skip *= w->inptrs;
+ pf->skip += skip;
+ }
+
+ return;
+ }
+
+ if (pf->height == height + 1) {
+ if (pf->start + pf->len == bn && pf->len == pf->skip) {
+ pf->len++;
+ pf->skip++;
+ } else {
+ if (pf->start) {
+ if (pf->height == w->di.di_height) {
+ add_extent(w, pf->offset, pf->start,
+ pf->len);
+ add_lblk_range(lblk_range_list,
+ pf->offset, pf->len);
+ }
+ }
+
+ pf->offset += pf->skip;
+ pf->start = bn;
+ pf->len = 1;
+ pf->skip = 1;
+ }
+ }
+}
+
+/**
+ * get_dblk_ranges - Run through the file and add valid data block ranges to
+ * lblk_range_list
+ * @w: the world
+ *
+ */
+
+static void
+get_dblk_ranges(world_t *w)
+{
+ do_pf_t pf;
+ unsigned int h;
+
+ for (h = 1; h <= w->di.di_height; h++) {
+
+ memset(&pf, 0, sizeof(do_pf_t));
+ pf.height = h;
+
+ recursive_scan(w, 0, 0, do_pf, &pf);
+
+ if (pf.start) {
+ if (h == w->di.di_height) {
+ add_extent(w, pf.offset, pf.start, pf.len);
+ add_lblk_range(lblk_range_list, pf.offset,
+ pf.len);
+ }
+ }
+ }
+}
+
+/**
+ * compute_layout - Computes the layout and store the valid data page ranges
+ * in lblk_range_list
+ * @argc:
+ * @argv:
+ *
+ */
+
+void
+compute_layout(char *path)
+{
+ world_t w;
+ int fd;
+ int retry = TRUE;
+ struct gfs_ioctl gi;
+ int error;
+
+ memset(&w, 0, sizeof(world_t));
+ w.buf_size = LAYOUT_DATA_QUANTUM;
+ osi_list_init(&w.blist);
+ osi_list_init(&w.elist);
+
+
+ fd = open(path, O_RDONLY);
+ if (fd < 0)
+ die("can't open %s: %s\n", path, strerror(errno));
+
+ check_for_gfs(fd, path);
+
+ {
+ char *argv[] = { "get_super" };
+
+ gi.gi_argc = 1;
+ gi.gi_argv = argv;
+ gi.gi_data = (char *)&w.sb;
+ gi.gi_size = sizeof(struct gfs_sb);
+
+ error = ioctl(fd, GFS_IOCTL_SUPER, &gi);
+ if (error != gi.gi_size)
+ die("error doing get_super (%d): %s\n",
+ error, strerror(errno));
+ }
+
+ w.diptrs = (w.sb.sb_bsize - sizeof(struct gfs_dinode)) /
+ sizeof(uint64_t);
+ w.inptrs = (w.sb.sb_bsize - sizeof(struct gfs_indirect)) /
+ sizeof(uint64_t);
+ w.jbsize = w.sb.sb_bsize - sizeof(struct gfs_meta_header);
+ j_blk_size = w.jbsize;
+ w.hash_bsize = w.sb.sb_bsize / 2;
+ w.hash_ptrs = w.hash_bsize / sizeof(uint64_t);
+
+ for (;;) {
+ char *argv[] = { "get_file_meta_quota" };
+
+ w.buf_data = malloc(w.buf_size);
+ if (!w.buf_data)
+ die("out of memory\n");
+
+ gi.gi_argc = 1;
+ gi.gi_argv = argv;
+ gi.gi_data = w.buf_data;
+ gi.gi_size = w.buf_size;
+
+ w.buf_count = ioctl(fd, GFS_IOCTL_SUPER, &gi);
+ if (w.buf_count >= 0)
+ break;
+
+ if (errno == ENOMEM) {
+ if (retry) {
+ free(w.buf_data);
+ w.buf_size += LAYOUT_DATA_QUANTUM;
+ continue;
+ } else
+ die("%u bytes isn't enough memory\n",
+ w.buf_size);
+ }
+ die("error doing get_file_meta: %s\n",
+ strerror(errno));
+ }
+
+ build_list(&w);
+ check_list(&w);
+
+ get_dblk_ranges(&w);
+
+ close(fd);
+}
+
+/**
+ * print_quota_range - print the quota information in the given sequence of
+ * blocks
+ * @argc:
+ * @argv:
+ *
+ */
+void
+print_quota_range(commandline_t *comline, int type, uint64_t start,
+ unsigned int len)
+{
+ uint64_t blk_offt, blk_end_offt, offset;
+ uint64_t quo;
+ unsigned int rem;
+ int fd;
+ struct gfs_sb sb;
+ struct gfs_ioctl gi;
+ char buf[sizeof(struct gfs_quota)];
+ struct gfs_quota q;
+ uint64_t hidden_blocks = 0;
+ uint32_t id;
+ int error;
+
+ blk_offt = start * (uint64_t)j_blk_size;
+ blk_end_offt = blk_offt + (uint64_t)(len * j_blk_size);
+
+ quo = blk_offt / (uint64_t)(2 * sizeof(struct gfs_quota));
+ rem = blk_offt % (uint64_t)(2 * sizeof(struct gfs_quota));
+
+ offset = type == GQ_ID_USER ? blk_offt :
+ blk_offt + sizeof(struct gfs_quota);
+
+ if (rem && type == GQ_ID_USER)
+ offset = (quo + 1) * (uint64_t)(2 * sizeof(struct gfs_quota));
+
+ if (rem && type == GQ_ID_GROUP) {
+ if (rem <= sizeof(struct gfs_quota))
+ offset = quo * (uint64_t)(2 * sizeof(struct gfs_quota))
+ + sizeof(struct gfs_quota);
+ else
+ offset = (quo + 1) *
+ (uint64_t)(2 * sizeof(struct gfs_quota)) +
+ sizeof(struct gfs_quota);
+ }
+
+ fd = open(comline->filesystem, O_RDONLY);
+ if (fd < 0)
+ die("can't open file %s: %s\n", comline->filesystem,
+ strerror(errno));
+
+ check_for_gfs(fd, comline->filesystem);
+ do_get_super(fd, &sb);
+
+ if (comline->no_hidden_file_blocks)
+ hidden_blocks = compute_hidden_blocks(comline, fd);
+
+ do {
+ char *argv[] = { "do_hfile_read", "quota" };
+
+ gi.gi_argc = 2;
+ gi.gi_argv = argv;
+ gi.gi_data = buf;
+ gi.gi_size = sizeof(struct gfs_quota);
+ gi.gi_offset = offset;
+
+ memset(buf, 0, sizeof(struct gfs_quota));
+
+ error = ioctl(fd, GFS_IOCTL_SUPER, &gi);
+ if (error < 0)
+ die("can't read quota file: %s\n",
+ strerror(errno));
+
+ gfs_quota_in(&q, buf);
+
+ id = (offset / sizeof(struct gfs_quota)) >> 1;
+ if (!id && comline->no_hidden_file_blocks)
+ q.qu_value -= hidden_blocks;
+
+ if (q.qu_limit || q.qu_warn || q.qu_value)
+ print_quota(comline, type == GQ_ID_GROUP ? FALSE : TRUE,
+ id, &q, &sb);
+
+ offset += 2 * sizeof(struct gfs_quota);
+ } while ((error == sizeof(struct gfs_quota)) &&
+ (offset < blk_end_offt));
+
+ close(fd);
+}
+
+void
+print_quota_file(commandline_t *comline)
+{
+ lblk_range_t lblk_range, *bar;
+ osi_list_t *t, *x;
+
+ lblk_range_list = &lblk_range;
+
+ osi_list_init(&lblk_range_list->list);
+
+ compute_layout(comline->filesystem);
+
+ if (osi_list_empty(&lblk_range_list->list)) {
+ /* stuffed quota inode */
+ print_quota_range(comline, GQ_ID_USER, 0, 1);
+ print_quota_range(comline, GQ_ID_GROUP, 0, 1);
+ } else {
+ /* print the user quotas */
+ osi_list_foreach(t, &lblk_range_list->list) {
+ bar = osi_list_entry(t, lblk_range_t, list);
+ print_quota_range(comline, GQ_ID_USER, bar->start,
+ bar->len);
+ }
+ /* print the group quotas */
+ osi_list_foreach(t, &lblk_range_list->list) {
+ bar = osi_list_entry(t, lblk_range_t, list);
+ print_quota_range(comline, GQ_ID_GROUP, bar->start,
+ bar->len);
+ }
+ /* free the list */
+ osi_list_foreach_safe(t, &lblk_range_list->list, x) {
+ bar = osi_list_entry(t, lblk_range_t, list);
+ osi_list_del(&bar->list);
+ free(bar);
+ }
+ }
+}
--- cluster/gfs/gfs_quota/Makefile 2006/08/11 15:18:11 1.5
+++ cluster/gfs/gfs_quota/Makefile 2007/04/04 21:31:33 1.6
@@ -19,7 +19,8 @@
check.c \
main.c \
names.c \
- ondisk.c
+ ondisk.c \
+ layout.c
CFLAGS+= -O2 -DHELPER_PROGRAM -D_FILE_OFFSET_BITS=64 \
-DGFS_RELEASE_NAME=\"${RELEASE}\"
--- cluster/gfs/gfs_quota/main.c 2006/08/21 21:44:28 1.3
+++ cluster/gfs/gfs_quota/main.c 2007/04/04 21:31:33 1.4
@@ -345,7 +345,7 @@
*
*/
-static void
+void
print_quota(commandline_t *comline,
int user, uint32_t id,
struct gfs_quota *q,
@@ -402,68 +402,7 @@
static void
do_list(commandline_t *comline)
{
- int fd;
- struct gfs_sb sb;
- struct gfs_ioctl gi;
- char buf[sizeof(struct gfs_quota)];
- struct gfs_quota q;
- uint64_t offset;
- uint64_t hidden_blocks = 0;
- uint32_t id;
- int pass = 0;
- int error;
-
- 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,
- strerror(errno));
-
- check_for_gfs(fd, comline->filesystem);
- do_get_super(fd, &sb);
-
- if (comline->no_hidden_file_blocks)
- hidden_blocks = compute_hidden_blocks(comline, fd);
-
- for (pass = 0; pass < 2; pass++) {
- if (!pass)
- offset = 0;
- else
- offset = sizeof(struct gfs_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 gfs_quota);
- gi.gi_offset = offset;
-
- memset(buf, 0, sizeof(struct gfs_quota));
-
- error = ioctl(fd, GFS_IOCTL_SUPER, &gi);
- if (error < 0)
- die("can't read quota file: %s\n",
- strerror(errno));
-
- gfs_quota_in(&q, buf);
-
- id = (offset / sizeof(struct gfs_quota)) >> 1;
- if (!id && comline->no_hidden_file_blocks)
- q.qu_value -= hidden_blocks;
-
- if (q.qu_limit || q.qu_warn || q.qu_value)
- print_quota(comline, (pass) ? FALSE : TRUE, id,
- &q, &sb);
-
- offset += 2 * sizeof(struct gfs_quota);
- } while (error == sizeof(struct gfs_quota));
- }
-
- close(fd);
+ print_quota_file(comline);
}
/**
--- cluster/gfs/gfs_quota/gfs_quota.h 2005/01/04 10:07:09 1.2
+++ cluster/gfs/gfs_quota/gfs_quota.h 2007/04/04 21:31:33 1.3
@@ -101,4 +101,7 @@
uint32_t name_to_id(int user, char *name, int numbers);
char *id_to_name(int user, uint32_t id, int numbers);
+/* layout.c */
+
+void print_quota_file(commandline_t *comline);
#endif /* __GFS_QUOTA_DOT_H__ */
^ permalink raw reply [flat|nested] 3+ messages in thread* [Cluster-devel] cluster gfs-kernel/src/gfs/ioctl.c gfs/gfs_quo ...
2007-04-04 21:31 [Cluster-devel] cluster gfs-kernel/src/gfs/ioctl.c gfs/gfs_quo adas
@ 2007-04-20 10:48 ` Fabio Massimo Di Nitto
0 siblings, 0 replies; 3+ messages in thread
From: Fabio Massimo Di Nitto @ 2007-04-20 10:48 UTC (permalink / raw)
To: cluster-devel.redhat.com
Hi,
adas at sourceware.org wrote:
> +
> +#define __user
> +#include <linux/gfs_ioctl.h>
> +#include <linux/gfs_ondisk.h>
> +
could it be possible to:
-#include <linux/gfs_ioctl.h>
-#include <linux/gfs_ondisk.h>
+#include "gfs_ioctl.h"
+#include "gfs_ondisk.h"
inline with the rest of the tree? it helps when building the suite on its own
and gfs1 headers are not exported from the kernel.
tested with CVS HEAD checkout updated as today.
Thanks
Fabio
--
I'm going to make him an offer he can't refuse.
^ permalink raw reply [flat|nested] 3+ messages in thread
* [Cluster-devel] cluster gfs-kernel/src/gfs/ioctl.c gfs/gfs_quo ...
@ 2007-01-10 17:53 adas
0 siblings, 0 replies; 3+ messages in thread
From: adas @ 2007-01-10 17:53 UTC (permalink / raw)
To: cluster-devel.redhat.com
CVSROOT: /cvs/cluster
Module name: cluster
Branch: RHEL4
Changes by: adas at sourceware.org 2007-01-10 17:53:54
Modified files:
gfs-kernel/src/gfs: ioctl.c
gfs/gfs_quota : Makefile main.c gfs_quota.h
Added files:
gfs/gfs_quota : layout.c
Log message:
fix bz 210362: We don't run through the entire gfs_quota sparse file to do a list operation anymore. We get the layout of the gfs_quota file on disk and only read quota information off the data blocks that are actually in use. Also added functionality to GFS_IOCTL_SUPER to provide the metadata of the hidden quota file.
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs-kernel/src/gfs/ioctl.c.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.7.2.4&r2=1.7.2.5
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs/gfs_quota/layout.c.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=NONE&r2=1.1.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs/gfs_quota/Makefile.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.3&r2=1.3.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs/gfs_quota/main.c.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.2&r2=1.2.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs/gfs_quota/gfs_quota.h.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.2&r2=1.2.2.1
--- cluster/gfs-kernel/src/gfs/ioctl.c 2006/11/13 19:25:46 1.7.2.4
+++ cluster/gfs-kernel/src/gfs/ioctl.c 2007/01/10 17:53:53 1.7.2.5
@@ -1464,6 +1464,8 @@
error = gi_set_file_flag(ip, &gi);
else if (strcmp(arg0, "get_file_meta") == 0)
error = gi_get_file_meta(ip, &gi);
+ else if (strcmp(arg0, "get_file_meta_quota") == 0)
+ error = gi_get_file_meta(ip->i_sbd->sd_qinode, &gi);
else if (strcmp(arg0, "do_file_flush") == 0)
error = gi_do_file_flush(ip, &gi);
else if (strcmp(arg0, "get_hfile_stat") == 0)
--- cluster/gfs/gfs_quota/Makefile 2004/09/10 19:02:15 1.3
+++ cluster/gfs/gfs_quota/Makefile 2007/01/10 17:53:54 1.3.2.1
@@ -19,7 +19,8 @@
check.c \
main.c \
names.c \
- ondisk.c
+ ondisk.c \
+ layout.c
CFLAGS+= -O2 -DHELPER_PROGRAM -D_FILE_OFFSET_BITS=64 \
-DGFS_RELEASE_NAME=\"${RELEASE}\"
--- cluster/gfs/gfs_quota/main.c 2005/01/04 10:07:09 1.2
+++ cluster/gfs/gfs_quota/main.c 2007/01/10 17:53:54 1.2.2.1
@@ -345,7 +345,7 @@
*
*/
-static void
+void
print_quota(commandline_t *comline,
int user, uint32_t id,
struct gfs_quota *q,
@@ -399,71 +399,10 @@
*
*/
-static void
+static void
do_list(commandline_t *comline)
{
- int fd;
- struct gfs_sb sb;
- struct gfs_ioctl gi;
- char buf[sizeof(struct gfs_quota)];
- struct gfs_quota q;
- uint64_t offset;
- uint64_t hidden_blocks = 0;
- uint32_t id;
- int pass = 0;
- int error;
-
- 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,
- strerror(errno));
-
- check_for_gfs(fd, comline->filesystem);
- do_get_super(fd, &sb);
-
- if (comline->no_hidden_file_blocks)
- hidden_blocks = compute_hidden_blocks(comline, fd);
-
- for (pass = 0; pass < 2; pass++) {
- if (!pass)
- offset = 0;
- else
- offset = sizeof(struct gfs_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 gfs_quota);
- gi.gi_offset = offset;
-
- memset(buf, 0, sizeof(struct gfs_quota));
-
- error = ioctl(fd, GFS_IOCTL_SUPER, &gi);
- if (error < 0)
- die("can't read quota file: %s\n",
- strerror(errno));
-
- gfs_quota_in(&q, buf);
-
- id = (offset / sizeof(struct gfs_quota)) >> 1;
- if (!id && comline->no_hidden_file_blocks)
- q.qu_value -= hidden_blocks;
-
- if (q.qu_limit || q.qu_warn || q.qu_value)
- print_quota(comline, (pass) ? FALSE : TRUE, id,
- &q, &sb);
-
- offset += 2 * sizeof(struct gfs_quota);
- } while (error == sizeof(struct gfs_quota));
- }
-
- close(fd);
+ print_quota_file(comline);
}
/**
--- cluster/gfs/gfs_quota/gfs_quota.h 2005/01/04 10:07:09 1.2
+++ cluster/gfs/gfs_quota/gfs_quota.h 2007/01/10 17:53:54 1.2.2.1
@@ -101,4 +101,7 @@
uint32_t name_to_id(int user, char *name, int numbers);
char *id_to_name(int user, uint32_t id, int numbers);
+/* layout.c */
+
+void print_quota_file(commandline_t *comline);
#endif /* __GFS_QUOTA_DOT_H__ */
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2007-04-20 10:48 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-04-04 21:31 [Cluster-devel] cluster gfs-kernel/src/gfs/ioctl.c gfs/gfs_quo adas
2007-04-20 10:48 ` Fabio Massimo Di Nitto
-- strict thread matches above, loose matches on Subject: below --
2007-01-10 17:53 adas
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).