diff --git a/lustre/ChangeLog b/lustre/ChangeLog index d4f37e213087c13ec8db46ab66f67280b2c8c2d6..08b767aefb070b4b706c1341ea569f6dc8e18c19 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 b8d97025023b0cf92d0d748f079df3634166d7a3..6e95fa3565f16b59550363d766b64cb55db45443 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 1aa12a4dbe4f930fe768280bea8411c266c48161..e2f5e10d2b60b71cb6600f83f689ba6d2633e090 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 4f50f7d30ee17765e06aab7e9ce30828828326f3..8876603058cd1f1ebdbc4a6c9c61a916dedb36b1 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 a321faa60d21c337aa8bd4c763a50313b104a12d..0a916a670e0dda6b74a5f44e9586501955a3fc57 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 10fb9bc5c6c882db017d4a230b43005921030200..1ca29e7c4d5d84921b2153e8b8c25d809993ed87 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 fa0f9e6f6f3f1805188d65dc73e9a2a0c8d009fd..bb0bb3b516195204b7d74ed8db1a89c2d8f41e93 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 */