From 9b27bdbb36e724dd7dce080a3660e00f007424e6 Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Wed, 30 Mar 2005 03:45:42 +0000 Subject: [PATCH] Marge Dans project/group quota coexistence code changes so db/repair can also support project quota. Merge of master-melb:xfs-cmds:21991a by kenmcd. --- db/check.c | 66 ++++++++++++++++++++++++++++++++++++--------- db/dquot.c | 26 +++++++++++------- include/xfs_fs.h | 2 ++ include/xfs_quota.h | 2 +- repair/Makefile | 2 ++ repair/globals.h | 3 ++- repair/phase4.c | 9 ++++--- repair/versions.c | 14 +++++----- repair/xfs_repair.c | 14 +++++++++- 9 files changed, 104 insertions(+), 34 deletions(-) diff --git a/db/check.c b/db/check.c index 90b229123..efb859279 100644 --- a/db/check.c +++ b/db/check.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -43,6 +43,10 @@ #include "init.h" #include "malloc.h" +typedef enum { + IS_USER_QUOTA, IS_PROJECT_QUOTA, IS_GROUP_QUOTA, +} qtype_t; + typedef enum { DBM_UNKNOWN, DBM_AGF, DBM_AGFL, DBM_AGI, DBM_ATTR, DBM_BTBMAPA, DBM_BTBMAPD, DBM_BTBNO, @@ -134,10 +138,12 @@ static inodata_t ***inomap; static int nflag; static int pflag; static int tflag; -static qdata_t **qgdata; -static int qgdo; +static qdata_t **qpdata; +static int qpdo; static qdata_t **qudata; static int qudo; +static qdata_t **qgdata; +static int qgdo; static unsigned sbversion; static int sbver_err; static int serious_error; @@ -316,7 +322,7 @@ static void process_leaf_node_dir_v2_int(inodata_t *id, int v, freetab_t *freetab); static xfs_ino_t process_node_dir_v1(blkmap_t *blkmap, int *dot, int *dotdot, inodata_t *id); -static void process_quota(int isgrp, inodata_t *id, +static void process_quota(qtype_t qtype, inodata_t *id, blkmap_t *blkmap); static void process_rtbitmap(blkmap_t *blkmap); static void process_rtsummary(blkmap_t *blkmap); @@ -324,7 +330,7 @@ static xfs_ino_t process_sf_dir_v2(xfs_dinode_t *dip, int *dot, int *dotdot, inodata_t *id); static xfs_ino_t process_shortform_dir_v1(xfs_dinode_t *dip, int *dot, int *dotdot, inodata_t *id); -static void quota_add(xfs_dqid_t grpid, xfs_dqid_t usrid, +static void quota_add(xfs_dqid_t p, xfs_dqid_t g, xfs_dqid_t u, int dq, xfs_qcnt_t bc, xfs_qcnt_t ic, xfs_qcnt_t rc); static void quota_add1(qdata_t **qt, xfs_dqid_t id, int dq, @@ -899,6 +905,8 @@ blockget_f( } if (qudo) quota_check("user", qudata); + if (qpdo) + quota_check("project", qpdata); if (qgdo) quota_check("group", qgdata); if (sbver_err > mp->m_sb.sb_agcount / 2) @@ -2771,7 +2779,7 @@ process_inode( break; } } - if (qgdo || qudo) { + if (qgdo || qpdo || qudo) { switch (type) { case DBM_DATA: case DBM_DIR: @@ -2792,7 +2800,8 @@ process_inode( break; } if (ic) - quota_add(dic->di_gid, dic->di_uid, 0, bc, ic, rc); + quota_add(dic->di_projid, dic->di_gid, dic->di_uid, + 0, bc, ic, rc); } totblocks = totdblocks + totiblocks + atotdblocks + atotiblocks; if (totblocks != dic->di_nblocks) { @@ -2829,11 +2838,15 @@ process_inode( if (id->ino == mp->m_sb.sb_uquotino && (mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) && (mp->m_sb.sb_qflags & XFS_UQUOTA_CHKD)) - process_quota(0, id, blkmap); + process_quota(IS_USER_QUOTA, id, blkmap); else if (id->ino == mp->m_sb.sb_gquotino && (mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) && (mp->m_sb.sb_qflags & XFS_GQUOTA_CHKD)) - process_quota(1, id, blkmap); + process_quota(IS_GROUP_QUOTA, id, blkmap); + else if (id->ino == mp->m_sb.sb_gquotino && + (mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) && + (mp->m_sb.sb_qflags & XFS_GQUOTA_CHKD)) /* yep, G */ + process_quota(IS_PROJECT_QUOTA, id, blkmap); } if (blkmap) blkmap_free(blkmap); @@ -3329,7 +3342,7 @@ process_node_dir_v1( static void process_quota( - int isgrp, + qtype_t qtype, inodata_t *id, blkmap_t *blkmap) { @@ -3345,9 +3358,24 @@ process_quota( int scicb; int t; + switch (qtype) { + case IS_USER_QUOTA: + s = "user"; + exp_flags = XFS_DQ_USER; + break; + case IS_PROJECT_QUOTA: + s = "project"; + exp_flags = XFS_DQ_PROJ; + break; + case IS_GROUP_QUOTA: + s = "group"; + exp_flags = XFS_DQ_GROUP; + break; + default: + ASSERT(0); + } + perblock = (int)(mp->m_sb.sb_blocksize / sizeof(*dqb)); - s = isgrp ? "group" : "user"; - exp_flags = isgrp ? XFS_DQ_GROUP : XFS_DQ_USER; dqid = 0; qbno = NULLFILEOFF; while ((qbno = blkmap_next_off(blkmap, qbno, &t)) != @@ -3414,7 +3442,10 @@ process_quota( error++; continue; } - quota_add(isgrp ? dqid : -1, isgrp ? -1 : dqid, 1, + quota_add((qtype == IS_PROJECT_QUOTA) ? dqid : -1, + (qtype == IS_GROUP_QUOTA) ? dqid : -1, + (qtype == IS_USER_QUOTA) ? dqid : -1, + 1, INT_GET(dqb->dd_diskdq.d_bcount, ARCH_CONVERT), INT_GET(dqb->dd_diskdq.d_icount, ARCH_CONVERT), INT_GET(dqb->dd_diskdq.d_rtbcount, ARCH_CONVERT)); @@ -3711,6 +3742,7 @@ process_shortform_dir_v1( static void quota_add( + xfs_dqid_t prjid, xfs_dqid_t grpid, xfs_dqid_t usrid, int dq, @@ -3722,6 +3754,8 @@ quota_add( quota_add1(qudata, usrid, dq, bc, ic, rc); if (qgdo && grpid != -1) quota_add1(qgdata, grpid, dq, bc, ic, rc); + if (qpdo && prjid != -1) + quota_add1(qpdata, prjid, dq, bc, ic, rc); } static void @@ -3814,10 +3848,16 @@ quota_init(void) mp->m_sb.sb_gquotino != NULLFSINO && (mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) && (mp->m_sb.sb_qflags & XFS_GQUOTA_CHKD); + qpdo = mp->m_sb.sb_gquotino != 0 && + mp->m_sb.sb_gquotino != NULLFSINO && + (mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) && + (mp->m_sb.sb_qflags & XFS_GQUOTA_CHKD); /* yep, G */ if (qudo) qudata = xcalloc(QDATA_HASH_SIZE, sizeof(qdata_t *)); if (qgdo) qgdata = xcalloc(QDATA_HASH_SIZE, sizeof(qdata_t *)); + if (qpdo) + qpdata = xcalloc(QDATA_HASH_SIZE, sizeof(qdata_t *)); } static void diff --git a/db/dquot.c b/db/dquot.c index 906544077..9eb434c82 100644 --- a/db/dquot.c +++ b/db/dquot.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -48,8 +48,8 @@ static int dquot_f(int argc, char **argv); static void dquot_help(void); static const cmdinfo_t dquot_cmd = - { "dquot", NULL, dquot_f, 1, 2, 1, "[gid|uid]", - "set current address to group or user quota block", dquot_help }; + { "dquot", NULL, dquot_f, 1, 2, 1, "[projid|gid|uid]", + "set current address to project, group or user quota block", dquot_help }; const field_t dqblk_hfld[] = { { "", FLDT_DQBLK, OI(0), C1, 0, TYP_NONE }, @@ -110,6 +110,7 @@ dquot_f( bmap_ext_t bm; int c; int dogrp; + int doprj; xfs_dqid_t id; xfs_ino_t ino; int nex; @@ -119,27 +120,34 @@ dquot_f( int qoff; char *s; - dogrp = optind = 0; - while ((c = getopt(argc, argv, "gu")) != EOF) { + dogrp = doprj = optind = 0; + while ((c = getopt(argc, argv, "gpu")) != EOF) { switch (c) { case 'g': dogrp = 1; + doprj = 0; break; - case 'u': + case 'p': + doprj = 1; dogrp = 0; break; + case 'u': + dogrp = doprj = 0; + break; default: dbprintf("bad option for dquot command\n"); return 0; } } - s = dogrp ? "group" : "user"; + s = doprj ? "project" : dogrp ? "group" : "user"; if (optind != argc - 1) { dbprintf("dquot command requires one %s id argument\n", s); return 0; } - ino = dogrp ? mp->m_sb.sb_gquotino : mp->m_sb.sb_uquotino; - if (ino == 0 || ino == NULLFSINO) { + ino = (dogrp || doprj) ? mp->m_sb.sb_gquotino : mp->m_sb.sb_uquotino; + if (ino == 0 || ino == NULLFSINO || + (dogrp && (mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT)) || + (doprj && (mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT))) { dbprintf("no %s quota inode present\n", s); return 0; } diff --git a/include/xfs_fs.h b/include/xfs_fs.h index 6ee8443bf..a7bd4687f 100644 --- a/include/xfs_fs.h +++ b/include/xfs_fs.h @@ -477,6 +477,8 @@ typedef struct xfs_handle { /* XFS_IOC_SETBIOSIZE ---- deprecated 46 */ /* XFS_IOC_GETBIOSIZE ---- deprecated 47 */ #define XFS_IOC_GETBMAPX _IOWR('X', 56, struct getbmap) +#define XFS_IOC_SETPROJID _IOWR('X', 57, __uint32_t) +#define XFS_IOC_GETPROJID _IOWR('X', 58, __uint32_t) /* * ioctl commands that replace IRIX syssgi()'s diff --git a/include/xfs_quota.h b/include/xfs_quota.h index 703ec4efc..ea58b5c23 100644 --- a/include/xfs_quota.h +++ b/include/xfs_quota.h @@ -96,7 +96,7 @@ typedef struct xfs_dqblk { * flags for q_flags field in the dquot. */ #define XFS_DQ_USER 0x0001 /* a user quota */ -/* #define XFS_DQ_PROJ 0x0002 -- project quota (IRIX) */ +#define XFS_DQ_PROJ 0x0002 /* project quota */ #define XFS_DQ_GROUP 0x0004 /* a group quota */ #define XFS_DQ_FLOCKED 0x0008 /* flush lock taken */ #define XFS_DQ_DIRTY 0x0010 /* dquot is dirty */ diff --git a/repair/Makefile b/repair/Makefile index ef6c0c780..d8c0043bb 100644 --- a/repair/Makefile +++ b/repair/Makefile @@ -51,6 +51,8 @@ LLDFLAGS = -static default: $(LTCOMMAND) +globals.o: globals.h + include $(BUILDRULES) # diff --git a/repair/globals.h b/repair/globals.h index b5642f950..fa96b561d 100644 --- a/repair/globals.h +++ b/repair/globals.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -153,6 +153,7 @@ EXTERN int have_uquotino; EXTERN int have_gquotino; EXTERN int lost_uquotino; EXTERN int lost_gquotino; +EXTERN int lost_pquotino; EXTERN xfs_agino_t first_prealloc_ino; EXTERN xfs_agino_t last_prealloc_ino; diff --git a/repair/phase4.c b/repair/phase4.c index 2250a4ff2..bf0da1cdc 100644 --- a/repair/phase4.c +++ b/repair/phase4.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -1090,9 +1090,12 @@ quotino_check(xfs_mount_t *mp) if (irec == NULL || is_inode_free(irec, mp->m_sb.sb_gquotino - irec->ino_startnum)) { mp->m_sb.sb_gquotino = NULLFSINO; - lost_gquotino = 1; + if (mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) + lost_gquotino = 1; + else + lost_pquotino = 1; } else - lost_gquotino = 0; + lost_gquotino = lost_pquotino = 0; } } diff --git a/repair/versions.c b/repair/versions.c index a7db36fb2..5c072821c 100644 --- a/repair/versions.c +++ b/repair/versions.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -79,7 +79,8 @@ update_sb_version(xfs_mount_t *mp) */ if (sb->sb_qflags & ~(XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD| XFS_UQUOTA_CHKD|XFS_GQUOTA_ACCT| - XFS_GQUOTA_ENFD|XFS_GQUOTA_CHKD)) { + XFS_GQUOTA_ENFD|XFS_GQUOTA_CHKD| + XFS_PQUOTA_ACCT)) { /* * update the incore superblock, if we're in * no_modify mode, it'll never get flushed out @@ -89,12 +90,13 @@ update_sb_version(xfs_mount_t *mp) sb->sb_qflags & ~(XFS_UQUOTA_ACCT| XFS_UQUOTA_ENFD| XFS_UQUOTA_CHKD|XFS_GQUOTA_ACCT| - XFS_GQUOTA_ENFD|XFS_GQUOTA_CHKD)); + XFS_GQUOTA_ENFD|XFS_GQUOTA_CHKD| + XFS_PQUOTA_ACCT)); - sb->sb_qflags &= (XFS_UQUOTA_ACCT| - XFS_UQUOTA_ENFD| + sb->sb_qflags &= (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD| XFS_UQUOTA_CHKD|XFS_GQUOTA_ACCT| - XFS_GQUOTA_ENFD|XFS_GQUOTA_CHKD); + XFS_GQUOTA_ENFD|XFS_GQUOTA_CHKD| + XFS_PQUOTA_ACCT); if (!no_modify) do_warn(_(", bogus flags will be cleared\n")); diff --git a/repair/xfs_repair.c b/repair/xfs_repair.c index f1225f68f..0de0130ed 100644 --- a/repair/xfs_repair.c +++ b/repair/xfs_repair.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -567,6 +567,18 @@ _("Warning: group quota information would be cleared.\n" "Group quotas could not be enforced until limit information was recreated.\n")); } } + + if (lost_pquotino) { + if (!no_modify) { + do_warn( +_("Warning: project quota information was cleared.\n" + "Project quotas can not be enforced until limit information is recreated.\n")); + } else { + do_warn( +_("Warning: project quota information would be cleared.\n" + "Project quotas could not be enforced until limit information was recreated.\n")); + } + } } if (no_modify) { -- 2.47.2