hi,
On May 8, 10:02am, <marchuk@xxxxxxxxxxxxxxxxx> wrote:
> Subject: XFS 1.0/Quota
> Does quota work on XFS 1.0?
Yes, with a couple of caveats.
The first problem was that the XFS code and the Redhat patches
did not get merged correctly, so a system from the modified
installer will not work with quota currently. A patch to fix
this was sent out a few days ago.
Secondly, the quota userspace interacts badly with some versions
of libc - a change to the quota-tools fixed this & this patch
was also sent out a few days ago, and has been incorporated into
the cvs tree at http://sourceforge.net/projects/linuxquota/ .
I've attached the two patches - the first is a patch to the
XFS1.0+Redhat7.1 kernel, the second is a patch to the
quota-3.01-pre5 user tools.
Using the latest cvs quota tools, with the base 2.4.2 XFS 1.0
kernel patches, quota works without any patching at all.
cheers.
--
Nathan
--- fs/dquot.c.orig Fri May 4 10:17:40 2001
+++ fs/dquot.c Fri May 4 11:02:13 2001
@@ -2001,7 +2001,7 @@
type = cmd & SUBCMDMASK;
- if ((uint) type >= MAXQUOTAS || cmds > 0x0F00 || cmds < 0x100 || cmds
== 0x0300 ||
+ if ((uint) type >= MAXQUOTAS || cmds < 0x100 || cmds == 0x0300 ||
cmds == 0x0400 || cmds == 0x0500)
goto out;
@@ -2049,9 +2049,6 @@
unlock_kernel();
return sb->s_op->quotactl(sb, cmds, type, id, addr);
}
-
- if (id & ~0xFFFF)
- goto out;
ret = -EINVAL;
switch (cmds) {
diff -Naur -xpo -xdoc -xCVS pre5/quota-tools/convertquota.c
cvs/quota-tools/convertquota.c
--- pre5/quota-tools/convertquota.c Wed May 2 02:35:34 2001
+++ cvs/quota-tools/convertquota.c Fri May 4 16:51:09 2001
@@ -72,7 +72,7 @@
mntpoint = argstr[optind];
}
-int convert_dquot(struct dquot *dquot)
+int convert_dquot(struct dquot *dquot, char *name)
{
struct dquot newdquot;
@@ -88,8 +88,8 @@
newdquot.dq_dqb.dqb_btime = dquot->dq_dqb.dqb_btime;
newdquot.dq_dqb.dqb_itime = dquot->dq_dqb.dqb_itime;
if (qn->qh_ops->commit_dquot(&newdquot) < 0) {
- errstr(_("Can't commit dquot for id %u: %s\n"),
- (uint)dquot->dq_id, strerror(errno));
+ errstr(_("Can't commit dquot for id %u (%s): %s\n"),
+ (uint)dquot->dq_id, name, strerror(errno));
return -1;
}
return 0;
diff -Naur -xpo -xdoc -xCVS pre5/quota-tools/quotaio.h cvs/quota-tools/quotaio.h
--- pre5/quota-tools/quotaio.h Wed May 2 03:19:18 2001
+++ cvs/quota-tools/quotaio.h Fri May 4 15:57:40 2001
@@ -122,7 +122,7 @@
int (*write_info) (struct quota_handle * h); /* Write info about
quotafile */
struct dquot *(*read_dquot) (struct quota_handle * h, qid_t id);
/* Read dquot into memory */
int (*commit_dquot) (struct dquot * dquot); /* Write given dquot to
disk */
- int (*scan_dquots) (struct quota_handle * h, int (*process_dquot)
(struct dquot * dquot)); /* Scan quotafile and call callback on every
structure */
+ int (*scan_dquots) (struct quota_handle * h, int (*process_dquot)
(struct dquot * dquot, char * dqname)); /* Scan quotafile and call
callback on every structure */
int (*report) (struct quota_handle * h, int verbose); /* Function
called after 'repquota' to print format specific file information */
};
diff -Naur -xpo -xdoc -xCVS pre5/quota-tools/quotaio_v1.c
cvs/quota-tools/quotaio_v1.c
--- pre5/quota-tools/quotaio_v1.c Wed May 2 19:32:22 2001
+++ cvs/quota-tools/quotaio_v1.c Fri May 4 15:59:43 2001
@@ -46,13 +46,14 @@
#include "quotaio_v1.h"
#include "dqblk_v1.h"
#include "quotaio.h"
+#include "quotasys.h"
static int v1_init_io(struct quota_handle *h);
static int v1_new_io(struct quota_handle *h);
static int v1_write_info(struct quota_handle *h);
static struct dquot *v1_read_dquot(struct quota_handle *h, qid_t id);
static int v1_commit_dquot(struct dquot *dquot);
-static int v1_scan_dquots(struct quota_handle *h, int (*process_dquot) (struct
dquot * dquot));
+static int v1_scan_dquots(struct quota_handle *h, int (*process_dquot) (struct
dquot *dquot, char *dqname));
struct quotafile_ops quotafile_ops_1 = {
init_io: v1_init_io,
@@ -281,9 +282,10 @@
/*
* Scan all dquots in file and call callback on each
*/
-static int v1_scan_dquots(struct quota_handle *h, int (*process_dquot) (struct
dquot * dquot))
+static int v1_scan_dquots(struct quota_handle *h, int (*process_dquot) (struct
dquot *, char *))
{
int rd;
+ char name[MAXNAMELEN];
struct v1_disk_dqblk ddqblk;
struct dquot *dquot = get_empty_dquot();
qid_t id = 0;
@@ -303,7 +305,8 @@
continue;
v1_disk2memdqblk(&dquot->dq_dqb, &ddqblk);
dquot->dq_id = id;
- if ((rd = process_dquot(dquot)) < 0) {
+ id2name(dquot->dq_id, h->qh_type, name);
+ if ((rd = process_dquot(dquot, name)) < 0) {
free(dquot);
return rd;
}
diff -Naur -xpo -xdoc -xCVS pre5/quota-tools/quotaio_v2.c
cvs/quota-tools/quotaio_v2.c
--- pre5/quota-tools/quotaio_v2.c Wed May 2 20:00:57 2001
+++ cvs/quota-tools/quotaio_v2.c Fri May 4 15:59:20 2001
@@ -17,6 +17,7 @@
#include "quotaio_v2.h"
#include "dqblk_v2.h"
#include "quotaio.h"
+#include "quotasys.h"
typedef char *dqbuf_t;
@@ -25,7 +26,7 @@
static int v2_write_info(struct quota_handle *h);
static struct dquot *v2_read_dquot(struct quota_handle *h, qid_t id);
static int v2_commit_dquot(struct dquot *dquot);
-static int v2_scan_dquots(struct quota_handle *h, int (*process_dquot) (struct
dquot * dquot));
+static int v2_scan_dquots(struct quota_handle *h, int (*process_dquot) (struct
dquot *dquot, char *dqname));
static int v2_report(struct quota_handle *h, int verbose);
struct quotafile_ops quotafile_ops_2 = {
@@ -656,11 +657,12 @@
#define get_bit(bmp, ind) ((bmp)[(ind) >> 3] & (1 << ((ind) & 7)))
static int report_block(struct dquot *dquot, uint blk, char *bitmap,
- int (*process_dquot) (struct dquot *))
+ int (*process_dquot) (struct dquot *, char *))
{
dqbuf_t buf = getdqbuf();
struct v2_disk_dqdbheader *dh;
struct v2_disk_dqblk *ddata;
+ char name[MAXNAMELEN];
int entries, i;
set_bit(bitmap, blk);
@@ -672,7 +674,8 @@
if (!empty_dquot(ddata + i)) {
v2_disk2memdqblk(&dquot->dq_dqb, ddata + i);
dquot->dq_id = __le32_to_cpu(ddata[i].dqb_id);
- if (process_dquot(dquot) < 0)
+ id2name(dquot->dq_id, dquot->dq_h->qh_type, name);
+ if (process_dquot(dquot, name) < 0)
break;
}
freedqbuf(buf);
@@ -680,7 +683,7 @@
}
static int report_tree(struct dquot *dquot, uint blk, int depth, char *bitmap,
- int (*process_dquot) (struct dquot *))
+ int (*process_dquot) (struct dquot *, char *))
{
int entries = 0, i;
dqbuf_t buf = getdqbuf();
@@ -714,7 +717,7 @@
return used;
}
-static int v2_scan_dquots(struct quota_handle *h, int (*process_dquot) (struct
dquot * dquot))
+static int v2_scan_dquots(struct quota_handle *h, int (*process_dquot) (struct
dquot *, char *))
{
char *bitmap;
struct v2_mem_dqinfo *info = &h->qh_info.u.v2_mdqi;
diff -Naur -xpo -xdoc -xCVS pre5/quota-tools/quotaio_xfs.c
cvs/quota-tools/quotaio_xfs.c
--- pre5/quota-tools/quotaio_xfs.c Wed Apr 11 20:06:06 2001
+++ cvs/quota-tools/quotaio_xfs.c Fri May 4 15:38:40 2001
@@ -28,7 +28,7 @@
static int xfs_write_info(struct quota_handle *h);
static struct dquot *xfs_read_dquot(struct quota_handle *h, qid_t id);
static int xfs_commit_dquot(struct dquot *dquot);
-static int xfs_scan_dquots(struct quota_handle *h, int (*process_dquot)
(struct dquot * dquot));
+static int xfs_scan_dquots(struct quota_handle *h, int (*process_dquot)
(struct dquot *dquot, char *dqname));
static int xfs_report(struct quota_handle *h, int verbose);
struct quotafile_ops quotafile_ops_xfs = {
@@ -166,7 +166,8 @@
*/
static int xfs_scan_dquot(struct quota_handle *h,
struct xfs_kern_dqblk *d,
- struct dquot *dq, int (*process_dquot) (struct dquot
* dquot))
+ char *name, struct dquot *dq,
+ int (*process_dquot) (struct dquot *dquot, char
*dqname))
{
int qcmd = QCMD(Q_XFS_GETQUOTA, h->qh_type);
@@ -180,13 +181,13 @@
d->d_ino_hardlimit == 0 &&
d->d_ino_softlimit == 0 && d->d_bcount == 0 && d->d_icount == 0)
return 0;
xfs_kern2utildqblk(&dq->dq_dqb, d);
- return process_dquot(dq);
+ return process_dquot(dq, name);
}
/*
* Scan all known dquots and call callback on each
*/
-static int xfs_scan_dquots(struct quota_handle *h, int (*process_dquot)
(struct dquot * dquot))
+static int xfs_scan_dquots(struct quota_handle *h, int (*process_dquot)
(struct dquot *dquot, char *dqname))
{
struct dquot *dq;
struct xfs_kern_dqblk d;
@@ -203,7 +204,8 @@
setpwent();
while ((usr = getpwent()) != NULL) {
dq->dq_id = usr->pw_uid;
- if ((rd = xfs_scan_dquot(h, &d, dq, process_dquot)) < 0)
+ rd = xfs_scan_dquot(h, &d, usr->pw_name, dq,
process_dquot);
+ if (rd < 0)
break;
}
endpwent();
@@ -214,7 +216,8 @@
setgrent();
while ((grp = getgrent()) != NULL) {
dq->dq_id = grp->gr_gid;
- if ((rd = xfs_scan_dquot(h, &d, dq, process_dquot)) < 0)
+ rd = xfs_scan_dquot(h, &d, grp->gr_name, dq,
process_dquot);
+ if (rd < 0)
break;
}
endgrent();
diff -Naur -xpo -xdoc -xCVS pre5/quota-tools/repquota.c
cvs/quota-tools/repquota.c
--- pre5/quota-tools/repquota.c Wed May 2 03:16:07 2001
+++ cvs/quota-tools/repquota.c Fri May 4 15:48:50 2001
@@ -97,15 +97,13 @@
return '-';
}
-static int print(struct dquot *dquot)
+static int print(struct dquot *dquot, char *name)
{
- char name[MAXNAMELEN];
char time[MAXTIMELEN];
struct util_dqblk *entry = &dquot->dq_dqb;
if (!entry->dqb_curspace && !entry->dqb_curinodes && !(flags &
FL_VERBOSE))
return 0;
- id2name(dquot->dq_id, dquot->dq_h->qh_type, name);
difftime2str(entry->dqb_btime, time);
printf("%-10s%c%c%8Lu%8Lu%8Lu%7s", name,
overlim(qb2kb(toqb(entry->dqb_curspace)),
qb2kb(entry->dqb_bsoftlimit),
diff -Naur -xpo -xdoc -xCVS pre5/quota-tools/warnquota.c
cvs/quota-tools/warnquota.c
--- pre5/quota-tools/warnquota.c Wed May 2 19:32:22 2001
+++ cvs/quota-tools/warnquota.c Fri May 4 16:56:14 2001
@@ -25,7 +25,6 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
-#include <pwd.h>
#include "mntopt.h"
#include "pot.h"
@@ -92,26 +91,22 @@
*/
static struct offenderlist *offenders = (struct offenderlist *)0;
-struct offenderlist *add_offender(int id)
+struct offenderlist *add_offender(int id, char *name)
{
- struct passwd *pwd;
struct offenderlist *offender;
- if ((pwd = getpwuid(id)) == (struct passwd *)0)
- return ((struct offenderlist *)0);
-
offender = (struct offenderlist *)smalloc(sizeof(struct offenderlist));
offender->offender_id = id;
- offender->offender_name = (char *)smalloc(strlen(pwd->pw_name) + 1);
+ offender->offender_name = (char *)smalloc(strlen(name) + 1);
offender->usage = (struct usage *)NULL;
- strcpy(offender->offender_name, pwd->pw_name);
+ strcpy(offender->offender_name, name);
offender->next = offenders;
offenders = offender;
return offender;
}
-void add_offence(struct dquot *dquot)
+void add_offence(struct dquot *dquot, char *name)
{
struct offenderlist *lptr;
struct usage *usage;
@@ -121,7 +116,7 @@
break;
if (!lptr)
- if (!(lptr = add_offender(dquot->dq_id)))
+ if (!(lptr = add_offender(dquot->dq_id, name)))
return;
usage = (struct usage *)smalloc(sizeof(struct usage));
@@ -135,13 +130,13 @@
lptr->usage = usage;
}
-int check_offence(struct dquot *dquot)
+int check_offence(struct dquot *dquot, char *name)
{
if (
(dquot->dq_dqb.dqb_bsoftlimit
&& toqb(dquot->dq_dqb.dqb_curspace) >=
dquot->dq_dqb.dqb_bsoftlimit)
|| (dquot->dq_dqb.dqb_isoftlimit
- && dquot->dq_dqb.dqb_curinodes >=
dquot->dq_dqb.dqb_isoftlimit)) add_offence(dquot);
+ && dquot->dq_dqb.dqb_curinodes >=
dquot->dq_dqb.dqb_isoftlimit)) add_offence(dquot, name);
return 0;
}
|