From: Niu Yawei Date: Thu, 15 Sep 2011 03:36:19 +0000 (-0700) Subject: LU-847 quota: client retrieve quota usage directly X-Git-Tag: 2.1.54~32 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=fb7c149abff469705f7997d1b7e9f73573bd3442;ds=sidebyside LU-847 quota: client retrieve quota usage directly Current 'lfs quota' sends getquota RPC to MDS, and MDS is responsible for retrieving disk usage from all targets, this scheme will be changed to client retrieving disk usage from all targets directly. This patch addresses the compatibility issue as well: If the getquota returned by MDS has QIF_SPACE, client just trust the disk usage returned by MDS, otherwise, client has to issue RPCs to all OSTs to collect disk usage by itself. Signed-off-by: Niu Yawei Change-Id: Ia94d3b3ba280d5b31d2d3c508412d662f4e95321 Reviewed-on: http://review.whamcloud.com/1382 Tested-by: Hudson Reviewed-by: Fan Yong Reviewed-by: Johann Lombardi Tested-by: Maloo --- diff --git a/lustre/llite/dir.c b/lustre/llite/dir.c index b6c9b2f..dcd4331 100644 --- a/lustre/llite/dir.c +++ b/lustre/llite/dir.c @@ -980,7 +980,47 @@ static int quotactl_ioctl(struct ll_sb_info *sbi, struct if_quotactl *qctl) OBD_FREE_PTR(oqctl); RETURN(rc); } + /* If QIF_SPACE is not set, client should collect the + * space usage from OSSs by itself */ + if (cmd == Q_GETQUOTA && + !(oqctl->qc_dqblk.dqb_valid & QIF_SPACE) && + !oqctl->qc_dqblk.dqb_curspace) { + struct obd_quotactl *oqctl_tmp; + + OBD_ALLOC_PTR(oqctl_tmp); + if (oqctl_tmp == NULL) + GOTO(out, rc = -ENOMEM); + + oqctl_tmp->qc_cmd = Q_GETOQUOTA; + oqctl_tmp->qc_id = oqctl->qc_id; + oqctl_tmp->qc_type = oqctl->qc_type; + + /* collect space usage from OSTs */ + oqctl_tmp->qc_dqblk.dqb_curspace = 0; + rc = obd_quotactl(sbi->ll_dt_exp, oqctl_tmp); + if (!rc || rc == -EREMOTEIO) { + oqctl->qc_dqblk.dqb_curspace = + oqctl_tmp->qc_dqblk.dqb_curspace; + oqctl->qc_dqblk.dqb_valid |= QIF_SPACE; + } + + /* collect space & inode usage from MDTs */ + oqctl_tmp->qc_dqblk.dqb_curspace = 0; + oqctl_tmp->qc_dqblk.dqb_curinodes = 0; + rc = obd_quotactl(sbi->ll_md_exp, oqctl_tmp); + if (!rc || rc == -EREMOTEIO) { + oqctl->qc_dqblk.dqb_curspace += + oqctl_tmp->qc_dqblk.dqb_curspace; + oqctl->qc_dqblk.dqb_curinodes = + oqctl_tmp->qc_dqblk.dqb_curinodes; + oqctl->qc_dqblk.dqb_valid |= QIF_INODES; + } else { + oqctl->qc_dqblk.dqb_valid &= ~QIF_SPACE; + } + OBD_FREE_PTR(oqctl_tmp); + } +out: QCTL_COPY(qctl, oqctl); OBD_FREE_PTR(oqctl); } diff --git a/lustre/quota/quota_ctl.c b/lustre/quota/quota_ctl.c index 4fd1551..bce3546 100644 --- a/lustre/quota/quota_ctl.c +++ b/lustre/quota/quota_ctl.c @@ -352,7 +352,9 @@ int lmv_quota_ctl(struct obd_device *unused, struct obd_export *exp, struct obd_device *obd = class_exp2obd(exp); struct lmv_obd *lmv = &obd->u.lmv; struct lmv_tgt_desc *tgt = &lmv->tgts[0]; - int rc; + int rc = 0, i; + __u64 curspace; + __u64 curinodes; ENTRY; if (!lmv->desc.ld_tgt_count || !tgt->ltd_active) { @@ -360,7 +362,36 @@ int lmv_quota_ctl(struct obd_device *unused, struct obd_export *exp, RETURN(-EIO); } - rc = obd_quotactl(tgt->ltd_exp, oqctl); + if (oqctl->qc_cmd != Q_GETOQUOTA) { + rc = obd_quotactl(tgt->ltd_exp, oqctl); + RETURN(rc); + } + + curspace = curinodes = 0; + for (i = 0; i < lmv->desc.ld_tgt_count; i++) { + int err; + tgt = &lmv->tgts[i]; + + if (tgt->ltd_exp == NULL) + continue; + if (!tgt->ltd_active) { + CDEBUG(D_HA, "mdt %d is inactive.\n", i); + continue; + } + + err = obd_quotactl(tgt->ltd_exp, oqctl); + if (err) { + CERROR("getquota on mdt %d failed. %d\n", i, err); + if (!rc) + rc = err; + } else { + curspace += oqctl->qc_dqblk.dqb_curspace; + curinodes += oqctl->qc_dqblk.dqb_curinodes; + } + } + oqctl->qc_dqblk.dqb_curspace = curspace; + oqctl->qc_dqblk.dqb_curinodes = curinodes; + RETURN(rc); } diff --git a/lustre/quota/quota_master.c b/lustre/quota/quota_master.c index 05a8dac..591a130 100644 --- a/lustre/quota/quota_master.c +++ b/lustre/quota/quota_master.c @@ -1562,17 +1562,6 @@ int mds_get_dqblk(struct obd_device *obd, struct obd_quotactl *oqctl) dqblk->dqb_curspace = 0; rc = mds_get_space(obd, oqctl); - /* - * Querying of curinodes and/or curspace may have failed, administrative - * quota data are likely to be better approximation to the real usage in - * this case. - */ - if (!(dqblk->dqb_valid & QIF_INODES) && dquot->dq_dqb.dqb_curinodes > 0) - dqblk->dqb_curinodes = dquot->dq_dqb.dqb_curinodes; - - if (!(dqblk->dqb_valid & QIF_SPACE) && dquot->dq_dqb.dqb_curspace > 0) - dqblk->dqb_curspace = dquot->dq_dqb.dqb_curspace; - RETURN(rc); out: