From: Hongchao Zhang Date: Sun, 24 Nov 2024 10:01:46 +0000 (+0800) Subject: LU-18453 quota: show default quota in lfs quota -a X-Git-Tag: 2.16.52~101 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=115562106b;p=fs%2Flustre-release.git LU-18453 quota: show default quota in lfs quota -a When getting all quota info by "lfs quota -a", the default quota should also be printed if some specific quota ID is using it. Signed-off-by: Hongchao Zhang Change-Id: Ib6cb42fe6ec62df0c2239c7098eabaf012f02b2e Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/57053 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Sergey Cheremencev Reviewed-by: Andreas Dilger Reviewed-by: Oleg Drokin --- diff --git a/lustre/osd-zfs/osd_quota.c b/lustre/osd-zfs/osd_quota.c index 4363565..c9e4645 100644 --- a/lustre/osd-zfs/osd_quota.c +++ b/lustre/osd-zfs/osd_quota.c @@ -289,6 +289,7 @@ static int osd_zap_cursor_retrieve_value(const struct lu_env *env, zap_attribute_t *za = &osd_oti_get(env)->oti_za; zap_cursor_t *zc = it->oiq_zc; struct osd_device *osd = osd_obj2dev(it->oiq_obj); + uint64_t acct_obj; int rc, actual_size; rc = -zap_cursor_retrieve(zc, za); @@ -308,9 +309,15 @@ static int osd_zap_cursor_retrieve_value(const struct lu_env *env, } /* use correct special ID to request bytes used */ - rc = osd_zap_lookup(osd, fid_oid(fid) == ACCT_GROUP_OID ? - DMU_GROUPUSED_OBJECT : DMU_USERUSED_OBJECT, NULL, - za->za_name, za->za_integer_length, buf_size, buf); + if (fid_oid(fid) == ACCT_USER_OID) + acct_obj = DMU_USERUSED_OBJECT; + else if (fid_oid(fid) == ACCT_GROUP_OID) + acct_obj = DMU_GROUPUSED_OBJECT; + else + acct_obj = DMU_PROJECTUSED_OBJECT; + + rc = osd_zap_lookup(osd, acct_obj, NULL, za->za_name, + za->za_integer_length, buf_size, buf); if (likely(rc == 0)) *bytes_read = actual_size; diff --git a/lustre/quota/lquota_internal.h b/lustre/quota/lquota_internal.h index efde391..c0ea3e5 100644 --- a/lustre/quota/lquota_internal.h +++ b/lustre/quota/lquota_internal.h @@ -431,8 +431,9 @@ int lquota_extract_fid(const struct lu_fid *, enum lquota_res_type *, enum lquota_type *); const struct dt_index_features *glb_idx_feature(struct lu_fid *); int lquota_obj_iter(const struct lu_env *env, struct dt_device *dev, - struct dt_object *obj, struct obd_quotactl *oqctl, - char *buffer, int size, bool is_glb, bool is_md); + struct dt_object *obj, struct lquota_entry *lqe_def, + struct obd_quotactl *oqctl, char *buffer, int size, + bool is_glb, bool is_md); /* lquota_entry.c */ /* site create/destroy */ diff --git a/lustre/quota/lquota_lib.c b/lustre/quota/lquota_lib.c index b6096e6..80544d4 100644 --- a/lustre/quota/lquota_lib.c +++ b/lustre/quota/lquota_lib.c @@ -162,8 +162,9 @@ static struct dt_object *quota_obj_lookup(const struct lu_env *env, * \param is_md - true to iterate LQUOTA_MD quota settings */ int lquota_obj_iter(const struct lu_env *env, struct dt_device *dev, - struct dt_object *obj, struct obd_quotactl *oqctl, - char *buf, int size, bool is_glb, bool is_md) + struct dt_object *obj, struct lquota_entry *lqe_def, + struct obd_quotactl *oqctl, char *buf, int size, + bool is_glb, bool is_md) { struct lquota_thread_info *qti = lquota_info(env); const struct dt_it_ops *iops; @@ -262,6 +263,20 @@ get_setting: memcpy(buf + cur, key, sizeof(__u64)); cur += sizeof(__u64); + if (is_glb && lqe_def != NULL) { + struct lquota_glb_rec *glb_rec; + + glb_rec = (struct lquota_glb_rec *)rec; + + if (glb_rec->qbr_hardlimit == 0 && + glb_rec->qbr_softlimit == 0 && + (LQUOTA_FLAG(glb_rec->qbr_time) & + LQUOTA_FLAG_DEFAULT)) { + glb_rec->qbr_softlimit = lqe_def->lqe_softlimit; + glb_rec->qbr_hardlimit = lqe_def->lqe_hardlimit; + } + } + memcpy(buf + cur, rec, rec_size); cur += rec_size; @@ -350,11 +365,11 @@ int lquotactl_slv(const struct lu_env *env, struct dt_device *dev, if (oqctl->qc_cmd == LUSTRE_Q_ITEROQUOTA) { if (lu_device_is_md(dev->dd_lu_dev.ld_site->ls_top_dev)) - rc = lquota_obj_iter(env, dev, obj, oqctl, buffer, size, - false, true); + rc = lquota_obj_iter(env, dev, obj, NULL, oqctl, buffer, + size, false, true); else - rc = lquota_obj_iter(env, dev, obj, oqctl, buffer, size, - false, false); + rc = lquota_obj_iter(env, dev, obj, NULL, oqctl, buffer, + size, false, false); GOTO(out, rc); } diff --git a/lustre/quota/qmt_handler.c b/lustre/quota/qmt_handler.c index ed1b74f..6918f65 100644 --- a/lustre/quota/qmt_handler.c +++ b/lustre/quota/qmt_handler.c @@ -541,6 +541,7 @@ static int qmt_quotactl(const struct lu_env *env, struct lu_device *ld, struct obd_dqblk *dqb = &oqctl->qc_dqblk; struct qmt_pool_info *pool; char *poolname; + int qtype = oqctl->qc_type; int rc = 0; bool is_default = false; bool is_first_iter = false; @@ -614,9 +615,10 @@ static int qmt_quotactl(const struct lu_env *env, struct lu_device *ld, if (IS_ERR(pool)) RETURN(PTR_ERR(pool)); - glb_obj = pool->qpi_glb_obj[oqctl->qc_type]; + glb_obj = pool->qpi_glb_obj[qtype]; rc = lquota_obj_iter(env, lu2dt_dev(ld), glb_obj, - oqctl, buffer, size / 2, true, true); + pool->qpi_grace_lqe[qtype], oqctl, + buffer, size / 2, true, true); qpi_putref(env, pool); @@ -634,10 +636,11 @@ static int qmt_quotactl(const struct lu_env *env, struct lu_device *ld, if (IS_ERR(pool)) RETURN(PTR_ERR(pool)); - glb_obj = pool->qpi_glb_obj[oqctl->qc_type]; + glb_obj = pool->qpi_glb_obj[qtype]; rc = lquota_obj_iter(env, lu2dt_dev(ld), glb_obj, - oqctl, buffer + size / 2, size / 2, - true, false); + pool->qpi_grace_lqe[qtype], oqctl, + buffer + size / 2, size / 2, + true, false); qpi_putref(env, pool); if (rc < 0 && rc != -ENOENT) diff --git a/lustre/tests/sanity-quota.sh b/lustre/tests/sanity-quota.sh index 2548d02..d4078fe 100755 --- a/lustre/tests/sanity-quota.sh +++ b/lustre/tests/sanity-quota.sh @@ -6428,6 +6428,129 @@ test_86() } run_test 86 "Pre-acquired quota should be released if quota is over limit" +test_87() +{ + (( $MDS1_VERSION >= $(version_code 2.16.50) )) || + skip "need MDS >= 2.16.50 to add default value in lfs quota -a" + + local blimit=102400 + local ilimit=10240 + local d_blimit=409600 + local d_ilimit=40960 + local u_blimits + local u_ilimits + local g_blimits + local g_ilimits + local p_blimits + local p_ilimits + + setup_quota_test || error "setup quota failed with $?" + + echo "test user quota for 'lfs quota -a' to print default quota" + $LFS setquota -U -b $d_blimit -B $d_blimit $MOUNT || + error "failed to set USR default block quota setting" + $LFS setquota -U -i $d_ilimit -I $d_ilimit $MOUNT || + error "failed to set USR default file quota setting" + $LFS setquota -G -b $d_blimit -B $d_blimit $MOUNT || + error "failed to set GRP default block quota setting" + $LFS setquota -G -i $d_ilimit -I $d_ilimit $MOUNT || + error "failed to set GRP default file quota setting" + + is_project_quota_supported && { + $LFS setquota -P -b $d_blimit -B $d_blimit $MOUNT || + error "failed to set PRJ default block quota setting" + $LFS setquota -P -i $d_ilimit -I $d_ilimit $MOUNT || + error "failed to set PRJ default file quota setting" + } + + #define OBD_FAIL_QUOTA_NOSYNC 0xA09 + do_facet mds1 $LCTL set_param fail_loc=0xa09 + + for ((i = 100; i < 150; i++)); do + $LFS setquota -u $i -b $blimit -B $blimit $MOUNT || + error "failed to set USR $i block quota setting" + $LFS setquota -u $i -i $ilimit -I $ilimit $MOUNT || + error "failed to set USR $i file quota setting" + + $LFS setquota -g $i -b $blimit -B $blimit $MOUNT || + error "failed to set GRP $i block quota setting" + $LFS setquota -g $i -i $ilimit -I $ilimit $MOUNT || + error "failed to set GRP $i file quota setting" + + is_project_quota_supported && { + $LFS setquota -p $i -b $blimit -B $blimit $MOUNT || + error "failed to set PRJ $i block quota setting" + $LFS setquota -p $i -i $ilimit -I $ilimit $MOUNT || + error "failed to set PRJ $i file quota setting" + } + done + + for ((i = 150; i < 200; i++)); do + $LFS setquota -u $i -D $MOUNT || + error "failed to set USR $i to use default quota" + $LFS setquota -g $i -D $MOUNT || + error "failed to set GRP $i to use default quota" + is_project_quota_supported && { + $LFS setquota -p $i -D $MOUNT || + error "failed to set PRJ $i to use default quota" + } + done + + do_facet mds1 $LCTL set_param fail_loc=0 + sync; sync_all_data || true + sleep 5 + + eval $($LFS quota -q -a -s 100 -e 199 -u $MOUNT | + awk '{printf("u_blimits[%d]=%d;u_ilimits[%d]=%d;", \ + NR, $5, NR, $9)}') + eval $($LFS quota -q -a -s 100 -e 199 -g $MOUNT | + awk '{printf("g_blimits[%d]=%d;g_ilimits[%d]=%d;", \ + NR, $5, NR, $9)}') + is_project_quota_supported && + eval $($LFS quota -q -a -s 100 -e 199 -p $MOUNT | + awk '{printf("p_blimits[%d]=%d;p_ilimits[%d]=%d;", \ + NR, $5, NR, $9)}') + + for i in $(seq 50); do + [ ${u_ilimits[$i]} -eq $ilimit ] || + error "file limit for USR ID $((100 + i - 1)) is wrong" + [ ${u_blimits[$i]} -eq $blimit ] || + error "block limit for USR ID $((100 + i - 1)) is wrong" + + [ ${g_ilimits[$i]} -eq $ilimit ] || + error "file limit for GRP ID $((100 + i - 1)) is wrong" + [ ${g_blimits[$i]} -eq $blimit ] || + error "block limit for GRP ID $((100 + i - 1)) is wrong" + + is_project_quota_supported && { + [ ${p_ilimits[$i]} -eq $ilimit ] || + error "file limit for PRJ ID $((100 + i - 1)) is wrong" + [ ${p_blimits[$i]} -eq $blimit ] || + error "block limit for PRJ ID $((100 + i - 1)) is wrong" + } + done + + for i in $(seq 50); do + [ ${u_ilimits[$((i + 50))]} -eq $d_ilimit ] || + error "file limit for USR ID $((150 + i - 1)) is wrong" + [ ${u_blimits[$((i + 50))]} -eq $d_blimit ] || + error "block limit for USR ID $((150 + i - 1)) is wrong" + + [ ${g_ilimits[$((i + 50))]} -eq $d_ilimit ] || + error "file limit for GRP ID $((150 + i - 1)) is wrong" + [ ${g_blimits[$((i + 50))]} -eq $d_blimit ] || + error "block limit for GRP ID $((150 + i - 1)) is wrong" + + is_project_quota_supported && { + [ ${p_ilimits[$((i + 50))]} -eq $d_ilimit ] || + error "file limit for PRJ ID $((150 + i - 1)) is wrong" + [ ${p_blimits[$((i + 50))]} -eq $d_blimit ] || + error "block limit for PRJ ID $((150 + i - 1)) is wrong" + } + done +} +run_test 87 "lfs quota -a should print default quota setting" + check_quota_no_mount() { local opts="$1"