quota_master.c
来自「lustre 1.6.5 source code」· C语言 代码 · 共 1,592 行 · 第 1/4 页
C
1,592 行
struct quota_adjust_qunit *oqaq = NULL; struct lustre_quota_info *qinfo = &mds->mds_quota_info; __u64 ihardlimit, isoftlimit, bhardlimit, bsoftlimit; time_t btime, itime; struct lustre_dquot *dquot; struct obd_dqblk *dqblk = &oqctl->qc_dqblk; int set, rc, rc2 = 0, flag = 0; ENTRY; OBD_ALLOC_PTR(oqaq); if (!oqaq) RETURN(-ENOMEM); down(&mds->mds_qonoff_sem); init_oqaq(oqaq, qctxt, oqctl->qc_id, oqctl->qc_type); if (qinfo->qi_files[oqctl->qc_type] == NULL) GOTO(out_sem, rc = -ESRCH); dquot = lustre_dqget(obd, qinfo, oqctl->qc_id, oqctl->qc_type); if (IS_ERR(dquot)) GOTO(out_sem, rc = PTR_ERR(dquot)); DQUOT_DEBUG(dquot, "get dquot in mds_set_blk\n"); QINFO_DEBUG(dquot->dq_info, "get dquot in mds_set_blk\n"); down(&dquot->dq_sem); if (dquot->dq_status) { up(&dquot->dq_sem); lustre_dqput(dquot); GOTO(out_sem, rc = -EBUSY); } dquot->dq_status |= DQ_STATUS_SET; ihardlimit = dquot->dq_dqb.dqb_ihardlimit; isoftlimit = dquot->dq_dqb.dqb_isoftlimit; bhardlimit = dquot->dq_dqb.dqb_bhardlimit; bsoftlimit = dquot->dq_dqb.dqb_bsoftlimit; btime = dquot->dq_dqb.dqb_btime; itime = dquot->dq_dqb.dqb_itime; if (dqblk->dqb_valid & QIF_BTIME) dquot->dq_dqb.dqb_btime = dqblk->dqb_btime; if (dqblk->dqb_valid & QIF_ITIME) dquot->dq_dqb.dqb_itime = dqblk->dqb_itime; if (dqblk->dqb_valid & QIF_BLIMITS) { dquot->dq_dqb.dqb_bhardlimit = dqblk->dqb_bhardlimit; dquot->dq_dqb.dqb_bsoftlimit = dqblk->dqb_bsoftlimit; /* clear usage (limit pool) */ if (!dquot->dq_dqb.dqb_bhardlimit && !dquot->dq_dqb.dqb_bsoftlimit) dquot->dq_dqb.dqb_curspace = 0; /* clear grace time */ if (!dqblk->dqb_bsoftlimit || toqb(dquot->dq_dqb.dqb_curspace) <= dqblk->dqb_bsoftlimit) dquot->dq_dqb.dqb_btime = 0; /* set grace only if user hasn't provided his own */ else if (!(dqblk->dqb_valid & QIF_BTIME)) dquot->dq_dqb.dqb_btime = cfs_time_current_sec() + qinfo->qi_info[dquot->dq_type].dqi_bgrace; flag |= LQUOTA_FLAGS_ADJBLK; } if (dqblk->dqb_valid & QIF_ILIMITS) { dquot->dq_dqb.dqb_ihardlimit = dqblk->dqb_ihardlimit; dquot->dq_dqb.dqb_isoftlimit = dqblk->dqb_isoftlimit; /* clear usage (limit pool) */ if (!dquot->dq_dqb.dqb_ihardlimit && !dquot->dq_dqb.dqb_isoftlimit) dquot->dq_dqb.dqb_curinodes = 0; if (!dqblk->dqb_isoftlimit || dquot->dq_dqb.dqb_curinodes <= dqblk->dqb_isoftlimit) dquot->dq_dqb.dqb_itime = 0; else if (!(dqblk->dqb_valid & QIF_ITIME)) dquot->dq_dqb.dqb_itime = cfs_time_current_sec() + qinfo->qi_info[dquot->dq_type].dqi_igrace; flag |= LQUOTA_FLAGS_ADJINO; } QAQ_DEBUG(oqaq, "before dquot_create_oqaq\n"); rc = dquot_create_oqaq(qctxt, dquot, lov->desc.ld_tgt_count, 1, flag, oqaq); QAQ_DEBUG(oqaq, "after dquot_create_oqaq\n"); if (rc < 0) CDEBUG(D_QUOTA, "adjust qunit size failed! (rc:%d)\n", rc); rc = fsfilt_dquot(obd, dquot, QFILE_WR_DQUOT); up(&dquot->dq_sem); if (rc) { CERROR("set limit failed! (rc:%d)\n", rc); goto out; } up(&mds->mds_qonoff_sem); if (dqblk->dqb_valid & QIF_ILIMITS) { set = !(ihardlimit || isoftlimit); down(&dquot->dq_sem); dquot->dq_dqb.dqb_curinodes = 0; up(&dquot->dq_sem); rc = mds_init_slave_ilimits(obd, oqctl, set, oqaq); if (rc) { CERROR("init slave ilimits failed! (rc:%d)\n", rc); goto revoke_out; } } if (dqblk->dqb_valid & QIF_BLIMITS) { set = !(bhardlimit || bsoftlimit); down(&dquot->dq_sem); dquot->dq_dqb.dqb_curspace = 0; up(&dquot->dq_sem); rc = mds_init_slave_blimits(obd, oqctl, set, oqaq); if (rc) { CERROR("init slave blimits failed! (rc:%d)\n", rc); goto revoke_out; } }revoke_out: down(&mds->mds_qonoff_sem); down(&dquot->dq_sem); if (rc) { /* cancel previous setting */ dquot->dq_dqb.dqb_ihardlimit = ihardlimit; dquot->dq_dqb.dqb_isoftlimit = isoftlimit; dquot->dq_dqb.dqb_bhardlimit = bhardlimit; dquot->dq_dqb.dqb_bsoftlimit = bsoftlimit; dquot->dq_dqb.dqb_btime = btime; dquot->dq_dqb.dqb_itime = itime; } rc2 = fsfilt_dquot(obd, dquot, QFILE_WR_DQUOT); up(&dquot->dq_sem);out: down(&dquot->dq_sem); dquot->dq_status &= ~DQ_STATUS_SET; up(&dquot->dq_sem); lustre_dqput(dquot); EXIT;out_sem: up(&mds->mds_qonoff_sem); if (oqaq) OBD_FREE_PTR(oqaq); return rc ? rc : rc2;}static int mds_get_space(struct obd_device *obd, struct obd_quotactl *oqctl){ struct obd_quotactl *soqc; struct lvfs_run_ctxt saved; int rc, rc1; ENTRY; OBD_ALLOC_PTR(soqc); if (!soqc) RETURN(-ENOMEM); soqc->qc_cmd = Q_GETOQUOTA; soqc->qc_id = oqctl->qc_id; soqc->qc_type = oqctl->qc_type; rc = obd_quotactl(obd->u.mds.mds_osc_exp, soqc); oqctl->qc_dqblk.dqb_curspace = soqc->qc_dqblk.dqb_curspace; push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); soqc->qc_dqblk.dqb_curspace = 0; rc1 = fsfilt_quotactl(obd, obd->u.obt.obt_sb, soqc); pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); 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; if (!rc && !rc1) oqctl->qc_dqblk.dqb_valid |= QIF_USAGE; OBD_FREE_PTR(soqc); if (!rc) rc = rc1; RETURN(rc);}int mds_get_dqblk(struct obd_device *obd, struct obd_quotactl *oqctl){ struct mds_obd *mds = &obd->u.mds; struct lustre_quota_info *qinfo = &mds->mds_quota_info; struct lustre_dquot *dquot; struct obd_dqblk *dqblk = &oqctl->qc_dqblk; int rc; ENTRY; down(&mds->mds_qonoff_sem); dqblk->dqb_valid = 0; if (qinfo->qi_files[oqctl->qc_type] == NULL) GOTO(out, rc = -ESRCH); dquot = lustre_dqget(obd, qinfo, oqctl->qc_id, oqctl->qc_type); if (IS_ERR(dquot)) GOTO(out, rc = PTR_ERR(dquot)); down(&dquot->dq_sem); dqblk->dqb_ihardlimit = dquot->dq_dqb.dqb_ihardlimit; dqblk->dqb_isoftlimit = dquot->dq_dqb.dqb_isoftlimit; dqblk->dqb_bhardlimit = dquot->dq_dqb.dqb_bhardlimit; 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); /* the usages in admin quota file is inaccurate */ dqblk->dqb_curinodes = 0; dqblk->dqb_curspace = 0; rc = mds_get_space(obd, oqctl); EXIT;out: up(&mds->mds_qonoff_sem); return rc;}int mds_get_obd_quota(struct obd_device *obd, struct obd_quotactl *oqctl){ struct lvfs_run_ctxt saved; int rc; ENTRY; push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); rc = fsfilt_quotactl(obd, obd->u.obt.obt_sb, oqctl); pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); RETURN(rc);}/* FIXME we only recovery block limit by now, need recovery inode * limits also after CMD involved in */static int dquot_recovery(struct obd_device *obd, unsigned int id, unsigned short type){ struct mds_obd *mds = &obd->u.mds; struct lustre_quota_info *qinfo= &obd->u.mds.mds_quota_info; struct lustre_dquot *dquot; struct obd_quotactl *qctl; __u64 total_limits = 0; int rc; ENTRY; OBD_ALLOC_PTR(qctl); if (qctl == NULL) RETURN(-ENOMEM); dquot = lustre_dqget(obd, qinfo, id, type); if (IS_ERR(dquot)) { CERROR("Get dquot failed. (rc:%ld)\n", PTR_ERR(dquot)); OBD_FREE_PTR(qctl); RETURN(PTR_ERR(dquot)); } down(&dquot->dq_sem); /* don't recovery the dquot without limits or under setting */ if (!(dquot->dq_dqb.dqb_bhardlimit || dquot->dq_dqb.dqb_bsoftlimit) || dquot->dq_status) GOTO(skip, rc = 0); dquot->dq_status |= DQ_STATUS_RECOVERY; up(&dquot->dq_sem); /* get real bhardlimit from all slaves. */ qctl->qc_cmd = Q_GETOQUOTA; qctl->qc_type = type; qctl->qc_id = id; qctl->qc_stat = QUOTA_RECOVERING; rc = obd_quotactl(obd->u.mds.mds_osc_exp, qctl); if (rc) GOTO(out, rc); total_limits = qctl->qc_dqblk.dqb_bhardlimit; /* get real bhardlimit from master */ rc = fsfilt_quotactl(obd, obd->u.obt.obt_sb, qctl); if (rc) GOTO(out, rc); total_limits += qctl->qc_dqblk.dqb_bhardlimit; /* amend the usage of the administrative quotafile */ down(&mds->mds_qonoff_sem); down(&dquot->dq_sem); dquot->dq_dqb.dqb_curspace = total_limits << QUOTABLOCK_BITS; rc = fsfilt_dquot(obd, dquot, QFILE_WR_DQUOT); if (rc) CERROR("write dquot failed! (rc:%d)\n", rc); up(&dquot->dq_sem); up(&mds->mds_qonoff_sem); EXIT;out: down(&dquot->dq_sem); dquot->dq_status &= ~DQ_STATUS_RECOVERY;skip: up(&dquot->dq_sem); lustre_dqput(dquot); OBD_FREE_PTR(qctl); return rc;}struct qmaster_recov_thread_data { struct obd_device *obd; struct completion comp;};static int qmaster_recovery_main(void *arg){ struct qmaster_recov_thread_data *data = arg; struct obd_device *obd = data->obd; int rc = 0; unsigned short type; ENTRY; ptlrpc_daemonize("qmaster_recovd"); complete(&data->comp); for (type = USRQUOTA; type < MAXQUOTAS; type++) { struct mds_obd *mds = &obd->u.mds; struct lustre_quota_info *qinfo = &mds->mds_quota_info; struct list_head id_list; struct dquot_id *dqid, *tmp; down(&mds->mds_qonoff_sem); if (qinfo->qi_files[type] == NULL) { up(&mds->mds_qonoff_sem); continue; } INIT_LIST_HEAD(&id_list); rc = fsfilt_qids(obd, qinfo->qi_files[type], NULL, type, &id_list); up(&mds->mds_qonoff_sem); if (rc) CERROR("error get ids from admin quotafile.(%d)\n", rc); list_for_each_entry_safe(dqid, tmp, &id_list, di_link) { list_del_init(&dqid->di_link); if (rc) goto free; rc = dquot_recovery(obd, dqid->di_id, type); if (rc) CERROR("qmaster recovery failed! (id:%d type:%d" " rc:%d)\n", dqid->di_id, type, rc);free: kfree(dqid); } } RETURN(rc);}int mds_quota_recovery(struct obd_device *obd){ struct lov_obd *lov = &obd->u.mds.mds_osc_obd->u.lov; struct qmaster_recov_thread_data data; int rc = 0; ENTRY; mutex_down(&lov->lov_lock); if (lov->desc.ld_tgt_count != lov->desc.ld_active_tgt_count) { CWARN("Not all osts are active, abort quota recovery\n"); mutex_up(&lov->lov_lock); RETURN(rc); } mutex_up(&lov->lov_lock); data.obd = obd; init_completion(&data.comp); rc = kernel_thread(qmaster_recovery_main, &data, CLONE_VM|CLONE_FILES); if (rc < 0) CERROR("Cannot start quota recovery thread: rc %d\n", rc); wait_for_completion(&data.comp); RETURN(rc);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?