From: fanyong Date: Fri, 26 Jun 2009 06:31:01 +0000 (+0000) Subject: Branch HEAD X-Git-Tag: v1_9_220~91 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=4cf8e6eabbd366d9d9b7cb64bb468312ba995e7b;hp=a4f8b35cb2fdbf28a5c98c372506ad13ce84d4f1 Branch HEAD b=19435 i=tianzy i=andrew.perepechko Process quota on/off/invalid serially. --- diff --git a/lustre/include/lustre_quota.h b/lustre/include/lustre_quota.h index 7cdf1d1..3222ca3 100644 --- a/lustre/include/lustre_quota.h +++ b/lustre/include/lustre_quota.h @@ -449,7 +449,7 @@ struct quotacheck_thread_args { struct obd_device *qta_obd; /** obd device */ struct obd_quotactl qta_oqctl; /** obd_quotactl args */ struct super_block *qta_sb; /** obd super block */ - atomic_t *qta_sem; /** obt_quotachecking */ + struct semaphore *qta_sem; /** obt_quotachecking */ }; struct obd_trans_info; diff --git a/lustre/include/obd.h b/lustre/include/obd.h index a7c53bc..18d92a2 100644 --- a/lustre/include/obd.h +++ b/lustre/include/obd.h @@ -261,7 +261,7 @@ struct obd_device_target { spinlock_t obt_translock; /** Number of mounts */ __u64 obt_mount_count; - atomic_t obt_quotachecking; + struct semaphore obt_quotachecking; struct lustre_quota_ctxt obt_qctxt; lustre_quota_version_t obt_qfmt; struct rw_semaphore obt_rwsem; diff --git a/lustre/quota/lproc_quota.c b/lustre/quota/lproc_quota.c index 93a2882..3231926 100644 --- a/lustre/quota/lproc_quota.c +++ b/lustre/quota/lproc_quota.c @@ -208,33 +208,25 @@ static int auto_quota_on(struct obd_device *obd, int type, struct obd_quotactl *oqctl; struct lvfs_run_ctxt saved; int rc = 0, id; - struct obd_device_target *obt; + struct obd_device_target *obt = &obd->u.obt; ENTRY; LASSERT(type == USRQUOTA || type == GRPQUOTA || type == UGQUOTA); - obt = &obd->u.obt; - OBD_ALLOC_PTR(oqctl); if (!oqctl) RETURN(-ENOMEM); - if (!atomic_dec_and_test(&obt->obt_quotachecking)) { - CDEBUG(D_INFO, "other people are doing quotacheck\n"); - atomic_inc(&obt->obt_quotachecking); - RETURN(-EBUSY); - } - + down(&obt->obt_quotachecking); id = UGQUOTA2LQC(type); /* quota already turned on */ - if ((obt->obt_qctxt.lqc_flags & id) == id) { - rc = 0; - goto out; - } + if ((obt->obt_qctxt.lqc_flags & id) == id) + GOTO(out, rc); + if (obt->obt_qctxt.lqc_immutable) { LCONSOLE_ERROR("Failed to turn Quota on, immutable mode " "(is SOM enabled?)\n"); - goto out; + GOTO(out, rc); } oqctl->qc_type = type; @@ -265,12 +257,12 @@ static int auto_quota_on(struct obd_device *obd, int type, } pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); + EXIT; out: - atomic_inc(&obt->obt_quotachecking); - + up(&obt->obt_quotachecking); OBD_FREE_PTR(oqctl); - RETURN(rc); + return rc; } int lprocfs_quota_wr_type(struct file *file, const char *buffer, diff --git a/lustre/quota/quota_check.c b/lustre/quota/quota_check.c index c2238e2..dab8a89 100644 --- a/lustre/quota/quota_check.c +++ b/lustre/quota/quota_check.c @@ -115,9 +115,7 @@ static int target_quotacheck_thread(void *data) rc = target_quotacheck_callback(exp, oqctl); class_export_put(exp); - - atomic_inc(qta->qta_sem); - + up(qta->qta_sem); OBD_FREE_PTR(qta); return rc; } @@ -130,14 +128,11 @@ int target_quota_check(struct obd_device *obd, struct obd_export *exp, int rc = 0; ENTRY; - if (!atomic_dec_and_test(&obt->obt_quotachecking)) { - CDEBUG(D_INFO, "other people are doing quotacheck\n"); - GOTO(out, rc = -EBUSY); - } - OBD_ALLOC_PTR(qta); if (!qta) - GOTO(out, rc = -ENOMEM); + RETURN(ENOMEM); + + down(&obt->obt_quotachecking); qta->qta_exp = exp; qta->qta_obd = obd; @@ -151,7 +146,6 @@ int target_quota_check(struct obd_device *obd, struct obd_export *exp, rc = init_admin_quotafiles(obd, &qta->qta_oqctl); if (rc) { CERROR("init_admin_quotafiles failed: %d\n", rc); - OBD_FREE_PTR(qta); GOTO(out, rc); } } @@ -164,15 +158,17 @@ int target_quota_check(struct obd_device *obd, struct obd_export *exp, CDEBUG(D_INFO, "%s: target_quotacheck_thread: %d\n", obd->obd_name, rc); RETURN(0); + } else { + CERROR("%s: error starting quotacheck_thread: %d\n", + obd->obd_name, rc); + class_export_put(exp); + EXIT; } - class_export_put(exp); - CERROR("%s: error starting quotacheck_thread: %d\n", - obd->obd_name, rc); - OBD_FREE_PTR(qta); out: - atomic_inc(&obt->obt_quotachecking); - RETURN(rc); + up(&obt->obt_quotachecking); + OBD_FREE_PTR(qta); + return rc; } #endif /* __KERNEL__ */ diff --git a/lustre/quota/quota_context.c b/lustre/quota/quota_context.c index fd85997..dec240a 100644 --- a/lustre/quota/quota_context.c +++ b/lustre/quota/quota_context.c @@ -1451,6 +1451,31 @@ exit: EXIT; } +int quota_is_on(struct lustre_quota_ctxt *qctxt, struct obd_quotactl *oqctl) +{ + unsigned int type; + + for (type = USRQUOTA; type < MAXQUOTAS; type++) { + if (!Q_TYPESET(oqctl, type)) + continue; + if (!(qctxt->lqc_flags & UGQUOTA2LQC(oqctl->qc_type))) + return 0; + } + return 1; +} + +int quota_is_off(struct lustre_quota_ctxt *qctxt, struct obd_quotactl *oqctl) +{ + unsigned int type; + + for (type = USRQUOTA; type < MAXQUOTAS; type++) { + if (!Q_TYPESET(oqctl, type)) + continue; + if (qctxt->lqc_flags & UGQUOTA2LQC(oqctl->qc_type)) + return 0; + } + return 1; +} /** * lqs<->qctxt hash operations diff --git a/lustre/quota/quota_ctl.c b/lustre/quota/quota_ctl.c index 8a982c1..cae30c4 100644 --- a/lustre/quota/quota_ctl.c +++ b/lustre/quota/quota_ctl.c @@ -195,15 +195,11 @@ int filter_quota_ctl(struct obd_device *unused, struct obd_export *exp, case Q_FINVALIDATE: case Q_QUOTAON: case Q_QUOTAOFF: - if (!atomic_dec_and_test(&obt->obt_quotachecking)) { - CDEBUG(D_INFO, "other people are doing quotacheck\n"); - atomic_inc(&obt->obt_quotachecking); - rc = -EBUSY; - break; - } + down(&obt->obt_quotachecking); if (oqctl->qc_cmd == Q_FINVALIDATE && (obt->obt_qctxt.lqc_flags & UGQUOTA2LQC(oqctl->qc_type))) { - atomic_inc(&obt->obt_quotachecking); + CWARN("quota[%u] is on yet\n", oqctl->qc_type); + up(&obt->obt_quotachecking); rc = -EBUSY; break; } @@ -227,11 +223,21 @@ int filter_quota_ctl(struct obd_device *unused, struct obd_export *exp, if (oqctl->qc_cmd == Q_QUOTAON || oqctl->qc_cmd == Q_QUOTAOFF || oqctl->qc_cmd == Q_FINVALIDATE) { - if (!rc && oqctl->qc_cmd == Q_QUOTAON) - obt->obt_qctxt.lqc_flags |= UGQUOTA2LQC(oqctl->qc_type); - if (!rc && oqctl->qc_cmd == Q_QUOTAOFF) - obt->obt_qctxt.lqc_flags &= ~UGQUOTA2LQC(oqctl->qc_type); - atomic_inc(&obt->obt_quotachecking); + if (oqctl->qc_cmd == Q_QUOTAON) { + if (!rc) + obt->obt_qctxt.lqc_flags |= + UGQUOTA2LQC(oqctl->qc_type); + else if (rc == -EBUSY && + quota_is_on(qctxt, oqctl)) + rc = -EALREADY; + } else if (oqctl->qc_cmd == Q_QUOTAOFF) { + if (!rc) + obt->obt_qctxt.lqc_flags &= + ~UGQUOTA2LQC(oqctl->qc_type); + else if (quota_is_off(qctxt, oqctl)) + rc = -EALREADY; + } + up(&obt->obt_quotachecking); } /* when quotaon, create lqs for every quota uid/gid b=18574 */ diff --git a/lustre/quota/quota_interface.c b/lustre/quota/quota_interface.c index e6d376f..0f6e7c2 100644 --- a/lustre/quota/quota_interface.c +++ b/lustre/quota/quota_interface.c @@ -78,7 +78,7 @@ static int filter_quota_setup(struct obd_device *obd) init_rwsem(&obt->obt_rwsem); obt->obt_qfmt = LUSTRE_QUOTA_V2; - atomic_set(&obt->obt_quotachecking, 1); + sema_init(&obt->obt_quotachecking, 1); rc = qctxt_init(obd, NULL); if (rc) CERROR("initialize quota context failed! (rc:%d)\n", rc); @@ -619,7 +619,7 @@ static int mds_quota_setup(struct obd_device *obd) init_rwsem(&obt->obt_rwsem); obt->obt_qfmt = LUSTRE_QUOTA_V2; mds->mds_quota_info.qi_version = LUSTRE_QUOTA_V2; - atomic_set(&obt->obt_quotachecking, 1); + sema_init(&obt->obt_quotachecking, 1); /* initialize quota master and quota context */ sema_init(&mds->mds_qonoff_sem, 1); rc = qctxt_init(obd, dqacq_handler); diff --git a/lustre/quota/quota_internal.h b/lustre/quota/quota_internal.h index 692e562..54dc220 100644 --- a/lustre/quota/quota_internal.h +++ b/lustre/quota/quota_internal.h @@ -114,6 +114,8 @@ int compute_remquota(struct obd_device *obd, int isblk); int check_qm(struct lustre_quota_ctxt *qctxt); void dqacq_interrupt(struct lustre_quota_ctxt *qctxt); +int quota_is_on(struct lustre_quota_ctxt *qctxt, struct obd_quotactl *oqctl); +int quota_is_off(struct lustre_quota_ctxt *qctxt, struct obd_quotactl *oqctl); void* quota_barrier(struct lustre_quota_ctxt *qctxt, struct obd_quotactl *oqctl, int isblk); void quota_unbarrier(void *handle); diff --git a/lustre/quota/quota_master.c b/lustre/quota/quota_master.c index 3c9f1c9..9edffbe 100644 --- a/lustre/quota/quota_master.c +++ b/lustre/quota/quota_master.c @@ -583,20 +583,22 @@ int mds_quota_invalidate(struct obd_device *obd, struct obd_quotactl *oqctl) { struct mds_obd *mds = &obd->u.mds; struct lustre_quota_info *qinfo = &mds->mds_quota_info; - int rc = 0, i; + struct obd_device_target *obt = &obd->u.obt; + int rc = 0, i, rc1 = 0; char *quotafile[] = LUSTRE_ADMIN_QUOTAFILES_V2; char name[64]; struct lvfs_run_ctxt saved; + ENTRY; LASSERT(qinfo->qi_version == LUSTRE_QUOTA_V2); if (oqctl->qc_type != USRQUOTA && oqctl->qc_type != GRPQUOTA && oqctl->qc_type != UGQUOTA) - return -EINVAL; + RETURN(-EINVAL); + down(&obt->obt_quotachecking); push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); - down(&mds->mds_qonoff_sem); for (i = 0; i < MAXQUOTAS; i++) { @@ -607,8 +609,9 @@ int mds_quota_invalidate(struct obd_device *obd, struct obd_quotactl *oqctl) /* quota file has been opened ? */ if (qinfo->qi_files[i]) { - rc = -EBUSY; - goto out; + CWARN("quota[%d] is on yet\n", i); + rc1 = -EBUSY; + continue; } LASSERT(strlen(quotafile[i]) + sizeof(prefix) <= sizeof(name)); @@ -624,25 +627,26 @@ int mds_quota_invalidate(struct obd_device *obd, struct obd_quotactl *oqctl) filp_close(fp, 0); } -out: up(&mds->mds_qonoff_sem); - pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); - - return rc; + up(&obt->obt_quotachecking); + RETURN(rc ? : rc1); } int mds_quota_finvalidate(struct obd_device *obd, struct obd_quotactl *oqctl) { struct mds_obd *mds = &obd->u.mds; + struct obd_device_target *obt = &obd->u.obt; int rc; struct lvfs_run_ctxt saved; + ENTRY; if (oqctl->qc_type != USRQUOTA && oqctl->qc_type != GRPQUOTA && oqctl->qc_type != UGQUOTA) RETURN(-EINVAL); + down(&obt->obt_quotachecking); push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); down(&mds->mds_qonoff_sem); @@ -653,8 +657,8 @@ int mds_quota_finvalidate(struct obd_device *obd, struct obd_quotactl *oqctl) up(&mds->mds_qonoff_sem); pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); - - return rc; + up(&obt->obt_quotachecking); + RETURN(rc); } int init_admin_quotafiles(struct obd_device *obd, struct obd_quotactl *oqctl) @@ -756,7 +760,8 @@ static int close_quota_files(struct obd_quotactl *oqctl, if (!Q_TYPESET(oqctl, i)) continue; if (qinfo->qi_files[i] == NULL) { - rc = -ESRCH; + CWARN("quota[%d] is off already\n", i); + rc = -EALREADY; continue; } filp_close(qinfo->qi_files[i], 0); @@ -771,7 +776,7 @@ int mds_admin_quota_on(struct obd_device *obd, struct obd_quotactl *oqctl) struct lustre_quota_info *qinfo = &mds->mds_quota_info; const char *quotafile[] = LUSTRE_ADMIN_QUOTAFILES_V2; char name[64]; - int i, rc = 0; + int i, rc = 0, rc1 = 0; ENTRY; LASSERT(qinfo->qi_version == LUSTRE_QUOTA_V2); @@ -788,8 +793,9 @@ int mds_admin_quota_on(struct obd_device *obd, struct obd_quotactl *oqctl) sprintf(name, "%s%s", prefix, quotafile[i]); if (qinfo->qi_files[i] != NULL) { - rc = -EBUSY; - break; + CWARN("quota[%d] is on already\n", i); + rc1 = -EALREADY; + continue; } fp = filp_open(name, O_RDWR, 0); @@ -814,10 +820,10 @@ int mds_admin_quota_on(struct obd_device *obd, struct obd_quotactl *oqctl) } } - if (rc && rc != -EBUSY) + if (rc && rc1 != -EALREADY) close_quota_files(oqctl, qinfo); - RETURN(rc); + RETURN(rc ? : rc1); } int mds_admin_quota_off(struct obd_device *obd, @@ -837,8 +843,9 @@ int mds_quota_on(struct obd_device *obd, struct obd_quotactl *oqctl) { struct mds_obd *mds = &obd->u.mds; struct obd_device_target *obt = &obd->u.obt; + struct lustre_quota_ctxt *qctxt = &obt->obt_qctxt; struct lvfs_run_ctxt saved; - int rc; + int rc = 0, rc1 = 0, rc2 = 0; ENTRY; if (oqctl->qc_type != USRQUOTA && @@ -846,40 +853,62 @@ int mds_quota_on(struct obd_device *obd, struct obd_quotactl *oqctl) oqctl->qc_type != UGQUOTA) RETURN(-EINVAL); - if (!atomic_dec_and_test(&obt->obt_quotachecking)) { - CDEBUG(D_INFO, "other people are doing quotacheck\n"); - atomic_inc(&obt->obt_quotachecking); - RETURN(-EBUSY); - } - + down(&obt->obt_quotachecking); LASSERT(!obt->obt_qctxt.lqc_immutable); - down(&mds->mds_qonoff_sem); push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); - rc = mds_admin_quota_on(obd, oqctl); - if (rc) - GOTO(out, rc); + down(&mds->mds_qonoff_sem); + rc2 = mds_admin_quota_on(obd, oqctl); + if (rc2 && rc2 != -EALREADY) { + CWARN("mds quota[%d] is failed to be on for %d\n", oqctl->qc_type, rc2); + GOTO(out, rc2); + } - rc = fsfilt_quotactl(obd, obd->u.obt.obt_sb, oqctl); - if (!rc) - obt->obt_qctxt.lqc_flags |= UGQUOTA2LQC(oqctl->qc_type); - else - GOTO(out, rc); + rc1 = fsfilt_quotactl(obd, obd->u.obt.obt_sb, oqctl); + if (!rc1) { + qctxt->lqc_flags |= UGQUOTA2LQC(oqctl->qc_type); + } else if (rc1 == -EBUSY && quota_is_on(qctxt, oqctl)) { + CWARN("mds local quota[%d] is on already\n", oqctl->qc_type); + rc1 = -EALREADY; + } else { + if (rc2 != -EALREADY) { + CWARN("mds local quota[%d] is failed to be on for %d\n", + oqctl->qc_type, rc1); + oqctl->qc_cmd = Q_QUOTAOFF; + mds_admin_quota_off(obd, oqctl); + oqctl->qc_cmd = Q_QUOTAON; + } + GOTO(out, rc1); + } rc = obd_quotactl(mds->mds_osc_exp, oqctl); + if (rc && rc != -EALREADY) { + CWARN("mds remote quota[%d] is failed to be on for %d\n", + oqctl->qc_type, rc); + oqctl->qc_cmd = Q_QUOTAOFF; + if (rc2 != -EALREADY) + mds_admin_quota_off(obd, oqctl); + if (rc1 != -EALREADY) { + fsfilt_quotactl(obd, obd->u.obt.obt_sb, oqctl); + qctxt->lqc_flags &= ~UGQUOTA2LQC(oqctl->qc_type); + } + oqctl->qc_cmd = Q_QUOTAON; + } + EXIT; out: - pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); up(&mds->mds_qonoff_sem); - atomic_inc(&obt->obt_quotachecking); - RETURN(rc); + pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); + up(&obt->obt_quotachecking); + return rc ? : (rc1 ? : rc2); } int mds_quota_off(struct obd_device *obd, struct obd_quotactl *oqctl) { struct mds_obd *mds = &obd->u.mds; struct obd_device_target *obt = &obd->u.obt; + struct lustre_quota_ctxt *qctxt = &obt->obt_qctxt; struct lvfs_run_ctxt saved; - int rc, rc2, imm; + int rc = 0, rc1 = 0, rc2 = 0, imm; ENTRY; imm = oqctl->qc_type & IMMQUOTA; @@ -890,29 +919,57 @@ int mds_quota_off(struct obd_device *obd, struct obd_quotactl *oqctl) oqctl->qc_type != UGQUOTA) RETURN(-EINVAL); - if (!atomic_dec_and_test(&obt->obt_quotachecking)) { - CDEBUG(D_INFO, "other people are doing quotacheck\n"); - atomic_inc(&obt->obt_quotachecking); - RETURN(-EBUSY); - } - + down(&obt->obt_quotachecking); + push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); down(&mds->mds_qonoff_sem); /* close admin quota files */ - push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); - mds_admin_quota_off(obd, oqctl); + rc2 = mds_admin_quota_off(obd, oqctl); + if (rc2 && rc2 != -EALREADY) { + CWARN("mds quota[%d] is failed to be off for %d\n", oqctl->qc_type, rc2); + GOTO(out, rc2); + } - rc = obd_quotactl(mds->mds_osc_exp, oqctl); - rc2 = fsfilt_quotactl(obd, obd->u.obt.obt_sb, oqctl); - if (!rc2) { + rc1 = fsfilt_quotactl(obd, obd->u.obt.obt_sb, oqctl); + if (!rc1) { if (imm) obt->obt_qctxt.lqc_immutable = 1; obt->obt_qctxt.lqc_flags &= ~UGQUOTA2LQC(oqctl->qc_type); + } else if (quota_is_off(qctxt, oqctl)) { + CWARN("mds local quota[%d] is off already\n", oqctl->qc_type); + rc1 = -EALREADY; + } else { + if (rc2 != -EALREADY) { + CWARN("mds local quota[%d] is failed to be off for %d\n", + oqctl->qc_type, rc1); + oqctl->qc_cmd = Q_QUOTAON; + mds_admin_quota_on(obd, oqctl); + oqctl->qc_cmd = Q_QUOTAOFF; + } + GOTO(out, rc1); } - pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); - up(&mds->mds_qonoff_sem); - atomic_inc(&obt->obt_quotachecking); - RETURN(rc ?: rc2); + rc = obd_quotactl(mds->mds_osc_exp, oqctl); + if (rc && rc != -EALREADY) { + CWARN("mds remote quota[%d] is failed to be off for %d\n", + oqctl->qc_type, rc); + oqctl->qc_cmd = Q_QUOTAON; + if (rc2 != -EALREADY) + mds_admin_quota_on(obd, oqctl); + if (rc1 != -EALREADY) { + fsfilt_quotactl(obd, obd->u.obt.obt_sb, oqctl); + if (imm) + obt->obt_qctxt.lqc_immutable = 0; + qctxt->lqc_flags |= UGQUOTA2LQC(oqctl->qc_type); + } + oqctl->qc_cmd = Q_QUOTAOFF; + } + EXIT; + +out: + up(&mds->mds_qonoff_sem); + pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); + up(&obt->obt_quotachecking); + return rc ? : (rc1 ? : rc2); } int mds_set_dqinfo(struct obd_device *obd, struct obd_quotactl *oqctl) @@ -929,8 +986,8 @@ int mds_set_dqinfo(struct obd_device *obd, struct obd_quotactl *oqctl) down(&mds->mds_qonoff_sem); if (qinfo->qi_files[oqctl->qc_type] == NULL) { - rc = -ESRCH; - goto out; + CWARN("quota[%u] is off\n", oqctl->qc_type); + GOTO(out, rc = -ESRCH); } qinfo->qi_info[oqctl->qc_type].dqi_bgrace = dqinfo->dqi_bgrace; @@ -938,10 +995,11 @@ int mds_set_dqinfo(struct obd_device *obd, struct obd_quotactl *oqctl) qinfo->qi_info[oqctl->qc_type].dqi_flags = dqinfo->dqi_flags; rc = fsfilt_quotainfo(obd, qinfo, oqctl->qc_type, QFILE_WR_INFO); + EXIT; out: up(&mds->mds_qonoff_sem); - RETURN(rc); + return rc; } int mds_get_dqinfo(struct obd_device *obd, struct obd_quotactl *oqctl) @@ -958,17 +1016,18 @@ int mds_get_dqinfo(struct obd_device *obd, struct obd_quotactl *oqctl) down(&mds->mds_qonoff_sem); if (qinfo->qi_files[oqctl->qc_type] == NULL) { - rc = -ESRCH; - goto out; + CWARN("quota[%u] is off\n", oqctl->qc_type); + GOTO(out, rc = -ESRCH); } dqinfo->dqi_bgrace = qinfo->qi_info[oqctl->qc_type].dqi_bgrace; dqinfo->dqi_igrace = qinfo->qi_info[oqctl->qc_type].dqi_igrace; dqinfo->dqi_flags = qinfo->qi_info[oqctl->qc_type].dqi_flags; + EXIT; out: up(&mds->mds_qonoff_sem); - RETURN(rc); + return rc; } int dquot_create_oqaq(struct lustre_quota_ctxt *qctxt, @@ -1274,8 +1333,10 @@ int mds_set_dqblk(struct obd_device *obd, struct obd_quotactl *oqctl) down(&mds->mds_qonoff_sem); init_oqaq(oqaq, qctxt, oqctl->qc_id, oqctl->qc_type); - if (qinfo->qi_files[oqctl->qc_type] == NULL) + if (qinfo->qi_files[oqctl->qc_type] == NULL) { + CWARN("quota[%u] is off\n", oqctl->qc_type); GOTO(out_sem, rc = -ESRCH); + } dquot = lustre_dqget(obd, qinfo, oqctl->qc_id, oqctl->qc_type); if (IS_ERR(dquot)) @@ -1473,8 +1534,10 @@ int mds_get_dqblk(struct obd_device *obd, struct obd_quotactl *oqctl) down(&mds->mds_qonoff_sem); dqblk->dqb_valid = 0; - if (qinfo->qi_files[oqctl->qc_type] == NULL) + if (qinfo->qi_files[oqctl->qc_type] == NULL) { + CWARN("quota[%u] is off\n", oqctl->qc_type); GOTO(out, rc = -ESRCH); + } dquot = lustre_dqget(obd, qinfo, oqctl->qc_id, oqctl->qc_type); if (IS_ERR(dquot)) @@ -1497,6 +1560,7 @@ int mds_get_dqblk(struct obd_device *obd, struct obd_quotactl *oqctl) dqblk->dqb_curspace = 0; rc = mds_get_space(obd, oqctl); EXIT; + out: up(&mds->mds_qonoff_sem); return rc; diff --git a/lustre/tests/test-framework.sh b/lustre/tests/test-framework.sh index aaecb61..11fae0e 100644 --- a/lustre/tests/test-framework.sh +++ b/lustre/tests/test-framework.sh @@ -568,6 +568,7 @@ setup_quota(){ # Suppose that quota type the same on mds and ost local quota_type=$(quota_type | grep MDT | cut -d "=" -f2) [ ${PIPESTATUS[0]} -eq 0 ] || error "quota_type failed!" + echo "[HOST:$HOSTNAME] [old_quota_type:$quota_type] [new_quota_type:$QUOTA_TYPE]" if [ "$quota_type" != "$QUOTA_TYPE" ]; then export old_QUOTA_TYPE=$quota_type quota_save_version $QUOTA_TYPE @@ -589,7 +590,7 @@ setup_quota(){ local cmd for usr in $quota_usrs; do - echo "Setting up quota on $client:$mntpt for $usr..." + echo "Setting up quota on $HOSTNAME:$mntpt for $usr..." for type in u g; do cmd="$LFS setquota -$type $usr -b $blk_soft -B $blk_hard -i $i_soft -I $i_hard $mntpt" echo "+ $cmd" @@ -2817,7 +2818,7 @@ wait_osc_import_state() { local i=0 CONN_PROC="osc.${FSNAME}-${ost}.ost_server_uuid" - CONN_STATE=$(do_facet $node lctl get_param -n $CONN_PROC | cut -f2) + CONN_STATE=$(do_facet $node lctl get_param -n $CONN_PROC 2>/dev/null | cut -f2) while [ "${CONN_STATE}" != "${expected}" ]; do # for disconn we can check after proc entry is removed [ "x${CONN_STATE}" == "x" -a "${expected}" == "DISCONN" ] && return 0 @@ -2825,7 +2826,7 @@ wait_osc_import_state() { [ $i -ge $(($TIMEOUT * 3 / 2)) ] && \ error "can't put import for ${ost}(${ost_facet}) into ${expected} state" && return 1 sleep 1 - CONN_STATE=$(do_facet $node lctl get_param -n $CONN_PROC | cut -f2) + CONN_STATE=$(do_facet $node lctl get_param -n $CONN_PROC 2>/dev/null | cut -f2) i=$(($i + 1)) done diff --git a/lustre/utils/lfs.c b/lustre/utils/lfs.c index 5f6e224..6d2ac85 100644 --- a/lustre/utils/lfs.c +++ b/lustre/utils/lfs.c @@ -1399,7 +1399,7 @@ static int lfs_quotacheck(int argc, char **argv) qctl.qc_cmd = LUSTRE_Q_QUOTAOFF; qctl.qc_type = check_type; rc = llapi_quotactl(mnt, &qctl); - if (rc) { + if (rc && errno != EALREADY) { fprintf(stderr, "quota off failed: %s\n", strerror(errno)); return rc; } @@ -1423,7 +1423,7 @@ static int lfs_quotacheck(int argc, char **argv) qctl.qc_cmd = LUSTRE_Q_QUOTAON; qctl.qc_type = check_type; rc = llapi_quotactl(mnt, &qctl); - if (rc) { + if (rc && errno != EALREADY) { if (*obd_type) fprintf(stderr, "%s %s ", (char *)qctl.obd_type, obd_uuid2str(&qctl.obd_uuid)); @@ -1477,14 +1477,21 @@ static int lfs_quotaon(int argc, char **argv) rc = llapi_quotactl(mnt, &qctl); if (rc) { - if (*obd_type) - fprintf(stderr, "%s %s ", obd_type, - obd_uuid2str(&qctl.obd_uuid)); - fprintf(stderr, "%s failed: %s\n", argv[0], strerror(errno)); - return rc; + if (errno == EALREADY) { + fprintf(stderr, "\n%s quotas are enabled already.\n", + qctl.qc_type == 0x02 ? "user/group" : + (qctl.qc_type == 0x00 ? "user" : "group")); + rc = 0; + } else { + if (*obd_type) + fprintf(stderr, "%s %s ", obd_type, + obd_uuid2str(&qctl.obd_uuid)); + fprintf(stderr, "%s failed: %s\n", argv[0], + strerror(errno)); + } } - return 0; + return rc; } static int lfs_quotaoff(int argc, char **argv) @@ -1525,20 +1532,22 @@ static int lfs_quotaoff(int argc, char **argv) mnt = argv[optind]; rc = llapi_quotactl(mnt, &qctl); - if (rc == -1 && errno == ESRCH) { - fprintf(stderr, "\n%s quotas are not enabled.\n", - qctl.qc_type == 0x00 ? "user" : "group"); - return 0; - } if (rc) { - if (*obd_type) - fprintf(stderr, "%s %s ", obd_type, - obd_uuid2str(&qctl.obd_uuid)); - fprintf(stderr, "quotaoff failed: %s\n", strerror(errno)); - return rc; + if (errno == EALREADY) { + fprintf(stderr, "\n%s quotas are disabled already.\n", + qctl.qc_type == 0x02 ? "user/group" : + (qctl.qc_type == 0x00 ? "user" : "group")); + rc = 0; + } else { + if (*obd_type) + fprintf(stderr, "%s %s ", obd_type, + obd_uuid2str(&qctl.obd_uuid)); + fprintf(stderr, "quotaoff failed: %s\n", + strerror(errno)); + } } - return 0; + return rc; } static int lfs_quotainv(int argc, char **argv) @@ -2184,7 +2193,7 @@ ug_output: mnt = argv[optind]; rc1 = llapi_quotactl(mnt, &qctl); - if (rc1 == -1 && errno == ESRCH) { + if (rc1 == -1 && errno == EALREADY) { fprintf(stderr, "\n%s quotas are not enabled.\n", qctl.qc_type == USRQUOTA ? "user" : "group"); goto out;