From 9f1d13adbbbd9cbda82ee42b0542aea76ad71878 Mon Sep 17 00:00:00 2001 From: tianzy <tianzy> Date: Tue, 27 Nov 2007 11:36:19 +0000 Subject: [PATCH] b=14036 r=andrew.perepechko r=johann Branch b1_6 With this patch, three improvements are included: 1. detete the softlimit in mds and osts when use "lfs quota". 2. display the inaccurate data in the output of "lfs quota". 3. try to get quota info when "lfs quota" is executed. --- lustre/ChangeLog | 9 ++++ lustre/llite/dir.c | 5 ++- lustre/lvfs/fsfilt_ext3.c | 2 + lustre/quota/quota_ctl.c | 22 +++++----- lustre/quota/quota_master.c | 23 ++++++----- lustre/tests/sanity-quota.sh | 9 +++- lustre/utils/lfs.c | 79 +++++++++++++++++++++++------------- 7 files changed, 95 insertions(+), 54 deletions(-) diff --git a/lustre/ChangeLog b/lustre/ChangeLog index d4f37e2130..08b767aefb 100644 --- a/lustre/ChangeLog +++ b/lustre/ChangeLog @@ -1656,6 +1656,15 @@ Description: Improve multi-block allocation algorithm to avoid fragmentation Details : The mballoc3 code (ldiskfs2 only) adds new mechanisms to improve allocation locality and avoid filesystem fragmentation. +Severity : normal +Frequency : rare +Bugzilla : 14036 +Description: lfs quota fails with deactivated OSTS +Details : With this patch, three improvements are included: + 1. detete the softlimit in mds and osts when use "lfs quota". + 2. display the inaccurate data in the output of "lfs quota". + 3. try to get quota info when "lfs quota" is executed. + ------------------------------------------------------------------------------ 2007-04-01 Cluster File Systems, Inc. <info@clusterfs.com> diff --git a/lustre/llite/dir.c b/lustre/llite/dir.c index b8d9702502..6e95fa3565 100644 --- a/lustre/llite/dir.c +++ b/lustre/llite/dir.c @@ -982,9 +982,12 @@ static int ll_dir_ioctl(struct inode *inode, struct file *file, /* XXX: dqb_valid is borrowed as a flag to mark that * only mds quota is wanted */ - if (qctl->qc_dqblk.dqb_valid) + if (qctl->qc_dqblk.dqb_valid) { qctl->obd_uuid = sbi->ll_mdc_exp->exp_obd-> u.cli.cl_target_uuid; + qctl->qc_dqblk.dqb_valid = 0; + } + break; case Q_GETINFO: break; diff --git a/lustre/lvfs/fsfilt_ext3.c b/lustre/lvfs/fsfilt_ext3.c index 1aa12a4dbe..e2f5e10d2b 100644 --- a/lustre/lvfs/fsfilt_ext3.c +++ b/lustre/lvfs/fsfilt_ext3.c @@ -1522,6 +1522,8 @@ static int fsfilt_ext3_quotactl(struct super_block *sb, if (!qcop->get_dqblk) GOTO(out, rc = -ENOSYS); rc = qcop->get_dqblk(sb, oqc->qc_type, oqc->qc_id, dqblk); + if (!rc) + dqblk->dqb_valid = QIF_LIMITS | QIF_USAGE; break; case Q_SYNC: if (!sb->s_qcop->quota_sync) diff --git a/lustre/quota/quota_ctl.c b/lustre/quota/quota_ctl.c index 4f50f7d30e..8876603058 100644 --- a/lustre/quota/quota_ctl.c +++ b/lustre/quota/quota_ctl.c @@ -223,19 +223,18 @@ int client_quota_ctl(struct obd_export *exp, struct obd_quotactl *oqctl) ptlrpc_req_set_repsize(req, 2, size); rc = ptlrpc_queue_wait(req); - if (!rc) { - oqc = lustre_swab_repbuf(req, REPLY_REC_OFF, sizeof(*oqc), - lustre_swab_obd_quotactl); - if (oqc == NULL) { - CERROR ("Can't unpack obd_quotactl\n"); - GOTO(out, rc = -EPROTO); - } - - *oqctl = *oqc; + oqc = lustre_swab_repbuf(req, REPLY_REC_OFF, sizeof(*oqc), + lustre_swab_obd_quotactl); + if (oqc == NULL) { + CERROR ("Can't unpack obd_quotactl\n"); + GOTO(out, rc = -EPROTO); } + + *oqctl = *oqc; + EXIT; out: ptlrpc_req_finished(req); - RETURN (rc); + return rc; } int lov_quota_ctl(struct obd_export *exp, struct obd_quotactl *oqctl) @@ -261,11 +260,10 @@ int lov_quota_ctl(struct obd_export *exp, struct obd_quotactl *oqctl) if (oqctl->qc_cmd == Q_GETOQUOTA) { CERROR("ost %d is inactive\n", i); rc = -EIO; - break; } else { CDEBUG(D_HA, "ost %d is inactive\n", i); - continue; } + continue; } err = obd_quotactl(lov->lov_tgts[i]->ltd_exp, oqctl); diff --git a/lustre/quota/quota_master.c b/lustre/quota/quota_master.c index a321faa60d..0a916a670e 100644 --- a/lustre/quota/quota_master.c +++ b/lustre/quota/quota_master.c @@ -877,7 +877,7 @@ static int mds_get_space(struct obd_device *obd, struct obd_quotactl *oqctl) { struct obd_quotactl *soqc; struct lvfs_run_ctxt saved; - int rc; + int rc, rc1; ENTRY; OBD_ALLOC_PTR(soqc); @@ -889,25 +889,26 @@ static int mds_get_space(struct obd_device *obd, struct obd_quotactl *oqctl) soqc->qc_type = oqctl->qc_type; rc = obd_quotactl(obd->u.mds.mds_osc_exp, soqc); - if (rc) - GOTO(out, rc); oqctl->qc_dqblk.dqb_curspace = soqc->qc_dqblk.dqb_curspace; push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); soqc->qc_dqblk.dqb_curspace = 0; - rc = fsfilt_quotactl(obd, obd->u.obt.obt_sb, soqc); + rc1 = fsfilt_quotactl(obd, obd->u.obt.obt_sb, soqc); pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); - if (rc) - GOTO(out, rc); - oqctl->qc_dqblk.dqb_curinodes += soqc->qc_dqblk.dqb_curinodes; + if (!rc1) + oqctl->qc_dqblk.dqb_valid |= QIF_INODES; oqctl->qc_dqblk.dqb_curspace += soqc->qc_dqblk.dqb_curspace; - EXIT; -out: + if (!rc && !rc1) + oqctl->qc_dqblk.dqb_valid |= QIF_USAGE; + OBD_FREE_PTR(soqc); - return rc; + + if (!rc) + rc = rc1; + RETURN(rc); } int mds_get_dqblk(struct obd_device *obd, struct obd_quotactl *oqctl) @@ -920,6 +921,7 @@ int mds_get_dqblk(struct obd_device *obd, struct obd_quotactl *oqctl) ENTRY; down(&mds->mds_qonoff_sem); + dqblk->dqb_valid = 0; if (qinfo->qi_files[oqctl->qc_type] == NULL) GOTO(out, rc = -ESRCH); @@ -934,6 +936,7 @@ int mds_get_dqblk(struct obd_device *obd, struct obd_quotactl *oqctl) dqblk->dqb_bsoftlimit = dquot->dq_dqb.dqb_bsoftlimit; dqblk->dqb_btime = dquot->dq_dqb.dqb_btime; dqblk->dqb_itime = dquot->dq_dqb.dqb_itime; + dqblk->dqb_valid |= QIF_LIMITS | QIF_TIMES; up(&dquot->dq_sem); lustre_dqput(dquot); diff --git a/lustre/tests/sanity-quota.sh b/lustre/tests/sanity-quota.sh index 10fb9bc5c6..1ca29e7c4d 100644 --- a/lustre/tests/sanity-quota.sh +++ b/lustre/tests/sanity-quota.sh @@ -977,11 +977,16 @@ run_test 13 "test multiple clients write block quota ===" check_if_quota_zero(){ line=`$LFS quota -$1 $2 $DIR | wc -l` for i in `seq 3 $line`; do - for j in 3 4 6 7; do + if [ $i -eq 3 ]; then + field="3 4 6 7" + else + field="3 5" + fi + for j in $field; do tmp=`$LFS quota -$1 $2 $DIR | sed -n ${i}p | awk '{print $'"$j"'}'` [ -n "$tmp" ] && [ $tmp -ne 0 ] && $LFS quota -$1 $2 $DIR && \ - error "quota on $1 isn't clean" + error "quota on $2 isn't clean" done done echo "pass check_if_quota_zero" diff --git a/lustre/utils/lfs.c b/lustre/utils/lfs.c index fa0f9e6f6f..bb0bb3b516 100644 --- a/lustre/utils/lfs.c +++ b/lustre/utils/lfs.c @@ -1529,7 +1529,11 @@ static void print_quota_title(char *name, struct if_quotactl *qctl) "files", "quota", "limit", "grace"); } -static void print_quota(char *mnt, struct if_quotactl *qctl, int ost_only) +#define GENERAL_QUOTA_INFO 1 +#define MDS_QUOTA_INFO 2 +#define OST_QUOTA_INFO 3 + +static void print_quota(char *mnt, struct if_quotactl *qctl, int type) { time_t now; @@ -1577,10 +1581,16 @@ static void print_quota(char *mnt, struct if_quotactl *qctl, int ost_only) if (bover) diff2str(dqb->dqb_btime, timebuf, now); - - sprintf(numbuf[0], LPU64, toqb(dqb->dqb_curspace)); - sprintf(numbuf[1], LPU64, dqb->dqb_bsoftlimit); - sprintf(numbuf[2], LPU64, dqb->dqb_bhardlimit); + sprintf(numbuf[0], (dqb->dqb_valid & QIF_SPACE) ? + LPU64 : "["LPU64"]", toqb(dqb->dqb_curspace)); + if (type == GENERAL_QUOTA_INFO) + sprintf(numbuf[1], (dqb->dqb_valid & QIF_BLIMITS) + ? LPU64 : "["LPU64"]", + dqb->dqb_bsoftlimit); + else + sprintf(numbuf[1], "%s", ""); + sprintf(numbuf[2], (dqb->dqb_valid & QIF_BLIMITS) + ? LPU64 : "["LPU64"]", dqb->dqb_bhardlimit); printf(" %7s%c %6s %7s %7s", numbuf[0], bover ? '*' : ' ', numbuf[1], numbuf[2], bover > 1 ? timebuf : ""); @@ -1588,10 +1598,17 @@ static void print_quota(char *mnt, struct if_quotactl *qctl, int ost_only) if (iover) diff2str(dqb->dqb_itime, timebuf, now); - sprintf(numbuf[0], LPU64, dqb->dqb_curinodes); - sprintf(numbuf[1], LPU64, dqb->dqb_isoftlimit); - sprintf(numbuf[2], LPU64, dqb->dqb_ihardlimit); - if (!ost_only) + sprintf(numbuf[0], (dqb->dqb_valid & QIF_INODES) ? + LPU64 : "["LPU64"]", dqb->dqb_curinodes); + if (type == GENERAL_QUOTA_INFO) + sprintf(numbuf[1], (dqb->dqb_valid & QIF_ILIMITS) + ? LPU64 : "["LPU64"]", + dqb->dqb_isoftlimit); + else + sprintf(numbuf[1], "%s", ""); + sprintf(numbuf[2], (dqb->dqb_valid & QIF_ILIMITS) ? + LPU64 : "["LPU64"]", dqb->dqb_ihardlimit); + if (type != OST_QUOTA_INFO) printf(" %7s%c %6s %7s %7s", numbuf[0], iover ? '*' : ' ', numbuf[1], numbuf[2], iover > 1 ? timebuf : ""); @@ -1609,7 +1626,7 @@ static void print_quota(char *mnt, struct if_quotactl *qctl, int ost_only) } } -static void print_mds_quota(char *mnt, struct if_quotactl *qctl) +static int print_mds_quota(char *mnt, struct if_quotactl *qctl) { int rc; @@ -1618,24 +1635,24 @@ static void print_mds_quota(char *mnt, struct if_quotactl *qctl) rc = llapi_quotactl(mnt, qctl); if (rc) { fprintf(stderr, "quotactl failed: %s\n", strerror(errno)); - return; + return rc; } - qctl->qc_dqblk.dqb_valid = 0; - print_quota(obd_uuid2str(&qctl->obd_uuid), qctl, 0); + print_quota(obd_uuid2str(&qctl->obd_uuid), qctl, MDS_QUOTA_INFO); + return 0; } -static void print_lov_quota(char *mnt, struct if_quotactl *qctl) +static int print_lov_quota(char *mnt, struct if_quotactl *qctl) { DIR *dir; struct obd_uuid *uuids = NULL, *uuidp; int obdcount = 1024; - int i, rc; + int i, rc, rc1=0; dir = opendir(mnt); if (!dir) { fprintf(stderr, "open %s failed: %s\n", mnt, strerror(errno)); - return; + return -ENOENT; } uuids = (struct obd_uuid *)malloc(INIT_ALLOC_NUM_OSTS * @@ -1668,17 +1685,21 @@ retry_get_uuids: qctl->qc_dqblk.dqb_valid = 0; rc = llapi_quotactl(mnt, qctl); if (rc) { + if (!rc1) + rc1 = rc; fprintf(stderr, "%s quotactl failed: %s\n", uuidp->uuid, strerror(errno)); continue; } - print_quota((char *)uuidp->uuid, qctl, 1); + print_quota((char *)uuidp->uuid, qctl, OST_QUOTA_INFO); } out: closedir(dir); - return; + if (!rc) + rc = rc1; + return rc; } static int lfs_quota(int argc, char **argv) @@ -1689,7 +1710,7 @@ static int lfs_quota(int argc, char **argv) .qc_type = 0x01 }; char *obd_type = (char *)qctl.obd_type; char *obd_uuid = (char *)qctl.obd_uuid.uuid; - int rc; + int rc, rc1 = 0, rc2 = 0, rc3 = 0; optind = 0; while ((c = getopt(argc, argv, "ugto:")) != -1) { @@ -1738,13 +1759,9 @@ static int lfs_quota(int argc, char **argv) mnt = argv[optind]; - rc = llapi_quotactl(mnt, &qctl); - if (rc) { - if (*obd_type) - fprintf(stderr, "%s %s ", obd_type, obd_uuid); - fprintf(stderr, "quota failed: %s\n", strerror(errno)); - return rc; - } + rc1 = llapi_quotactl(mnt, &qctl); + if (rc1 && *obd_type) + fprintf(stderr, "%s %s ", obd_type, obd_uuid); if (!name) rc = id2name(&name, getuid(), qctl.qc_type); @@ -1754,13 +1771,17 @@ static int lfs_quota(int argc, char **argv) name = obd_uuid; } - print_quota(mnt, &qctl, 0); + print_quota(mnt, &qctl, GENERAL_QUOTA_INFO); if (!*obd_uuid && qctl.qc_cmd != LUSTRE_Q_GETINFO) { - print_mds_quota(mnt, &qctl); - print_lov_quota(mnt, &qctl); + rc2 = print_mds_quota(mnt, &qctl); + rc3 = print_lov_quota(mnt, &qctl); } + if (rc1 || rc2 || rc3) + printf("Some errors happened when getting quota info. " + "Some devices may be not working or deactivated. " + "The data in \"[]\" is inaccurate.\n"); return 0; } #endif /* HAVE_QUOTA_SUPPORT */ -- GitLab