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);
}
/* 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;
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 */
* \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;
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;
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);
}
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;
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);
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)
}
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"