/** * Disconnect a connected client. * * This function terminates the client connection. The client export is * disconnected (cleaned up) and client data on persistent storage is removed. * * \param[in] exp OBD export * * \retval 0 if successful * \retval negative value on error */ int ofd_obd_disconnect(struct obd_export *exp) { struct ofd_device *ofd = ofd_exp(exp); struct lu_env env; int rc; ENTRY; LASSERT(exp); class_export_get(exp); if (!(exp->exp_flags & OBD_OPT_FORCE)) ofd_grant_sanity_check(ofd_obd(ofd), __FUNCTION__); nodemap_del_member(exp); rc = server_disconnect_export(exp); ofd_grant_discard(exp); /* Do not erase record for recoverable client. */ if (exp->exp_obd->obd_replayable && (!exp->exp_obd->obd_fail || exp->exp_failed)) { rc = lu_env_init(&env, LCT_DT_THREAD); if (rc) GOTO(out, rc); tgt_client_del(&env, exp); lu_env_fini(&env); } out: class_export_put(exp); RETURN(rc); }
/** * Prepare bulk descriptor for specified incoming request \a req that * can fit \a npages * pages. \a type is bulk type. \a portal is where * the bulk to be sent. Used on server-side after request was already * received. * Returns pointer to newly allocatrd initialized bulk descriptor or NULL on * error. */ struct ptlrpc_bulk_desc *ptlrpc_prep_bulk_exp(struct ptlrpc_request *req, unsigned npages, unsigned max_brw, unsigned type, unsigned portal) { struct obd_export *exp = req->rq_export; struct ptlrpc_bulk_desc *desc; ENTRY; LASSERT(type == BULK_PUT_SOURCE || type == BULK_GET_SINK); desc = ptlrpc_new_bulk(npages, max_brw, type, portal); if (desc == NULL) RETURN(NULL); desc->bd_export = class_export_get(exp); desc->bd_req = req; desc->bd_cbid.cbid_fn = server_bulk_callback; desc->bd_cbid.cbid_arg = desc; /* NB we don't assign rq_bulk here; server-side requests are * re-used, and the handler frees the bulk desc explicitly. */ return desc; }
/** * Prepare bulk descriptor for specified incoming request \a req that * can fit \a nfrags * pages. \a type is bulk type. \a portal is where * the bulk to be sent. Used on server-side after request was already * received. * Returns pointer to newly allocatrd initialized bulk descriptor or NULL on * error. */ struct ptlrpc_bulk_desc *ptlrpc_prep_bulk_exp(struct ptlrpc_request *req, unsigned nfrags, unsigned max_brw, unsigned int type, unsigned portal, const struct ptlrpc_bulk_frag_ops *ops) { struct obd_export *exp = req->rq_export; struct ptlrpc_bulk_desc *desc; ENTRY; LASSERT(ptlrpc_is_bulk_op_active(type)); desc = ptlrpc_new_bulk(nfrags, max_brw, type, portal, ops); if (desc == NULL) RETURN(NULL); desc->bd_export = class_export_get(exp); desc->bd_req = req; desc->bd_cbid.cbid_fn = server_bulk_callback; desc->bd_cbid.cbid_arg = desc; /* NB we don't assign rq_bulk here; server-side requests are * re-used, and the handler frees the bulk desc explicitly. */ return desc; }
static int seq_client_init(struct lu_client_seq *seq, struct obd_export *exp, enum lu_cli_type type, const char *prefix) { int rc; LASSERT(seq); LASSERT(prefix); seq->lcs_type = type; mutex_init(&seq->lcs_mutex); if (type == LUSTRE_SEQ_METADATA) seq->lcs_width = LUSTRE_METADATA_SEQ_MAX_WIDTH; else seq->lcs_width = LUSTRE_DATA_SEQ_MAX_WIDTH; init_waitqueue_head(&seq->lcs_waitq); /* Make sure that things are clear before work is started. */ seq_client_flush(seq); seq->lcs_exp = class_export_get(exp); snprintf(seq->lcs_name, sizeof(seq->lcs_name), "cli-%s", prefix); rc = seq_client_debugfs_init(seq); if (rc) seq_client_fini(seq); return rc; }
static int mgs_disconnect(struct obd_export *exp) { int rc; ENTRY; LASSERT(exp); mgs_fsc_cleanup(exp); class_export_get(exp); mgs_counter_incr(exp, LPROC_MGS_DISCONNECT); rc = server_disconnect_export(exp); class_export_put(exp); RETURN(rc); }
int seq_client_init(struct lu_client_seq *seq, struct obd_export *exp, enum lu_cli_type type, const char *prefix, struct lu_server_seq *srv) { int rc; ENTRY; LASSERT(seq != NULL); LASSERT(prefix != NULL); seq->lcs_srv = srv; seq->lcs_type = type; mutex_init(&seq->lcs_mutex); if (type == LUSTRE_SEQ_METADATA) seq->lcs_width = LUSTRE_METADATA_SEQ_MAX_WIDTH; else seq->lcs_width = LUSTRE_DATA_SEQ_MAX_WIDTH; cfs_waitq_init(&seq->lcs_waitq); /* Make sure that things are clear before work is started. */ seq_client_flush(seq); if (exp != NULL) seq->lcs_exp = class_export_get(exp); else if (type == LUSTRE_SEQ_METADATA) LASSERT(seq->lcs_srv != NULL); snprintf(seq->lcs_name, sizeof(seq->lcs_name), "cli-%s", prefix); rc = seq_client_proc_init(seq); if (rc) seq_client_fini(seq); RETURN(rc); }
int llog_setup(const struct lu_env *env, struct obd_device *obd, struct obd_llog_group *olg, int index, struct obd_device *disk_obd, struct llog_operations *op) { struct llog_ctxt *ctxt; int rc = 0; if (index < 0 || index >= LLOG_MAX_CTXTS) return -EINVAL; LASSERT(olg != NULL); ctxt = llog_new_ctxt(obd); if (!ctxt) return -ENOMEM; ctxt->loc_obd = obd; ctxt->loc_olg = olg; ctxt->loc_idx = index; ctxt->loc_logops = op; mutex_init(&ctxt->loc_mutex); ctxt->loc_exp = class_export_get(disk_obd->obd_self_export); ctxt->loc_flags = LLOG_CTXT_FLAG_UNINITIALIZED; rc = llog_group_set_ctxt(olg, ctxt, index); if (rc) { llog_ctxt_destroy(ctxt); if (rc == -EEXIST) { ctxt = llog_group_get_ctxt(olg, index); if (ctxt) { /* * mds_lov_update_desc() might call here multiple * times. So if the llog is already set up then * don't to do it again. */ CDEBUG(D_CONFIG, "obd %s ctxt %d already set up\n", obd->obd_name, index); LASSERT(ctxt->loc_olg == olg); LASSERT(ctxt->loc_obd == obd); LASSERT(ctxt->loc_exp == disk_obd->obd_self_export); LASSERT(ctxt->loc_logops == op); llog_ctxt_put(ctxt); } rc = 0; } return rc; } if (op->lop_setup) { if (OBD_FAIL_CHECK(OBD_FAIL_OBD_LLOG_SETUP)) rc = -EOPNOTSUPP; else rc = op->lop_setup(env, obd, olg, index, disk_obd); } if (rc) { CERROR("%s: ctxt %d lop_setup=%p failed: rc = %d\n", obd->obd_name, index, op->lop_setup, rc); llog_group_clear_ctxt(olg, index); llog_ctxt_destroy(ctxt); } else { CDEBUG(D_CONFIG, "obd %s ctxt %d is initialized\n", obd->obd_name, index); ctxt->loc_flags &= ~LLOG_CTXT_FLAG_UNINITIALIZED; } return rc; }
static int osp_precreate_thread(void *_arg) { struct osp_device *d = _arg; struct ptlrpc_thread *thread = &d->opd_pre_thread; struct l_wait_info lwi = { 0 }; struct lu_env env; int rc; ENTRY; rc = lu_env_init(&env, d->opd_dt_dev.dd_lu_dev.ld_type->ldt_ctx_tags); if (rc) { CERROR("%s: init env error: rc = %d\n", d->opd_obd->obd_name, rc); RETURN(rc); } spin_lock(&d->opd_pre_lock); thread->t_flags = SVC_RUNNING; spin_unlock(&d->opd_pre_lock); wake_up(&thread->t_ctl_waitq); while (osp_precreate_running(d)) { /* * need to be connected to OST */ while (osp_precreate_running(d)) { l_wait_event(d->opd_pre_waitq, !osp_precreate_running(d) || d->opd_new_connection, &lwi); if (!d->opd_new_connection) continue; d->opd_new_connection = 0; d->opd_got_disconnected = 0; break; } if (!osp_precreate_running(d)) break; LASSERT(d->opd_obd->u.cli.cl_seq != NULL); if (d->opd_obd->u.cli.cl_seq->lcs_exp == NULL) { /* Get new sequence for client first */ LASSERT(d->opd_exp != NULL); d->opd_obd->u.cli.cl_seq->lcs_exp = class_export_get(d->opd_exp); rc = osp_init_pre_fid(d); if (rc != 0) { class_export_put(d->opd_exp); d->opd_obd->u.cli.cl_seq->lcs_exp = NULL; CERROR("%s: init pre fid error: rc = %d\n", d->opd_obd->obd_name, rc); continue; } } osp_statfs_update(d); /* * Clean up orphans or recreate missing objects. */ rc = osp_precreate_cleanup_orphans(&env, d); if (rc != 0) continue; /* * connected, can handle precreates now */ while (osp_precreate_running(d)) { l_wait_event(d->opd_pre_waitq, !osp_precreate_running(d) || osp_precreate_near_empty(&env, d) || osp_statfs_need_update(d) || d->opd_got_disconnected, &lwi); if (!osp_precreate_running(d)) break; /* something happened to the connection * have to start from the beginning */ if (d->opd_got_disconnected) break; if (osp_statfs_need_update(d)) osp_statfs_update(d); /* To avoid handling different seq in precreate/orphan * cleanup, it will hold precreate until current seq is * used up. */ if (unlikely(osp_precreate_end_seq(&env, d) && !osp_create_end_seq(&env, d))) continue; if (unlikely(osp_precreate_end_seq(&env, d) && osp_create_end_seq(&env, d))) { LCONSOLE_INFO("%s:"LPX64" is used up." " Update to new seq\n", d->opd_obd->obd_name, fid_seq(&d->opd_pre_last_created_fid)); rc = osp_precreate_rollover_new_seq(&env, d); if (rc) continue; } if (osp_precreate_near_empty(&env, d)) { rc = osp_precreate_send(&env, d); /* osp_precreate_send() sets opd_pre_status * in case of error, that prevent the using of * failed device. */ if (rc < 0 && rc != -ENOSPC && rc != -ETIMEDOUT && rc != -ENOTCONN) CERROR("%s: cannot precreate objects:" " rc = %d\n", d->opd_obd->obd_name, rc); } } } thread->t_flags = SVC_STOPPED; lu_env_fini(&env); wake_up(&thread->t_ctl_waitq); RETURN(0); }
int llog_setup(const struct lu_env *env, struct obd_device *obd, struct obd_llog_group *olg, int index, struct obd_device *disk_obd, struct llog_operations *op) { struct llog_ctxt *ctxt; int rc = 0; ENTRY; if (index < 0 || index >= LLOG_MAX_CTXTS) RETURN(-EINVAL); LASSERT(olg != NULL); ctxt = llog_new_ctxt(obd); if (!ctxt) RETURN(-ENOMEM); ctxt->loc_obd = obd; ctxt->loc_olg = olg; ctxt->loc_idx = index; ctxt->loc_logops = op; mutex_init(&ctxt->loc_mutex); if (disk_obd != NULL) ctxt->loc_exp = class_export_get(disk_obd->obd_self_export); else ctxt->loc_exp = class_export_get(obd->obd_self_export); ctxt->loc_flags = LLOG_CTXT_FLAG_UNINITIALIZED; ctxt->loc_chunk_size = LLOG_MIN_CHUNK_SIZE; rc = llog_group_set_ctxt(olg, ctxt, index); if (rc) { llog_ctxt_destroy(ctxt); if (rc == -EEXIST) { ctxt = llog_group_get_ctxt(olg, index); if (ctxt) { CDEBUG(D_CONFIG, "%s: ctxt %d already set up\n", obd->obd_name, index); LASSERT(ctxt->loc_olg == olg); LASSERT(ctxt->loc_obd == obd); if (disk_obd != NULL) LASSERT(ctxt->loc_exp == disk_obd->obd_self_export); else LASSERT(ctxt->loc_exp == obd->obd_self_export); LASSERT(ctxt->loc_logops == op); llog_ctxt_put(ctxt); } rc = 0; } RETURN(rc); } if (op->lop_setup) { if (OBD_FAIL_CHECK(OBD_FAIL_OBD_LLOG_SETUP)) rc = -EOPNOTSUPP; else rc = op->lop_setup(env, obd, olg, index, disk_obd); } if (rc) { CERROR("%s: ctxt %d lop_setup=%p failed: rc = %d\n", obd->obd_name, index, op->lop_setup, rc); llog_group_clear_ctxt(olg, index); llog_ctxt_destroy(ctxt); } else { CDEBUG(D_CONFIG, "obd %s ctxt %d is initialized\n", obd->obd_name, index); ctxt->loc_flags &= ~LLOG_CTXT_FLAG_UNINITIALIZED; } RETURN(rc); }
int target_quota_check(struct obd_device *obd, struct obd_export *exp, struct obd_quotactl *oqctl) { struct obd_device_target *obt = &obd->u.obt; struct quotacheck_thread_args *qta; int rc = 0; ENTRY; OBD_ALLOC_PTR(qta); if (!qta) RETURN(ENOMEM); cfs_down(&obt->obt_quotachecking); qta->qta_exp = exp; qta->qta_obd = obd; qta->qta_oqctl = *oqctl; qta->qta_oqctl.qc_id = obt->obt_qfmt; /* override qfmt version */ qta->qta_sb = obt->obt_sb; qta->qta_sem = &obt->obt_quotachecking; /* quotaoff firstly */ oqctl->qc_cmd = Q_QUOTAOFF; if (!strcmp(obd->obd_type->typ_name, LUSTRE_MDS_NAME)) { rc = do_mds_quota_off(obd, oqctl); if (rc && rc != -EALREADY) { CERROR("off quota on MDS failed: %d\n", rc); GOTO(out, rc); } /* quota master */ rc = init_admin_quotafiles(obd, &qta->qta_oqctl); if (rc) { CERROR("init_admin_quotafiles failed: %d\n", rc); GOTO(out, rc); } } else { struct lvfs_run_ctxt saved; struct lustre_quota_ctxt *qctxt = &obt->obt_qctxt; push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); rc = fsfilt_quotactl(obd, obt->obt_sb, oqctl); pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); if (!rc) { qctxt->lqc_flags &= ~UGQUOTA2LQC(oqctl->qc_type); } else if (!quota_is_off(qctxt, oqctl)) { CERROR("off quota on OSS failed: %d\n", rc); GOTO(out, rc); } } /* we get ref for exp because target_quotacheck_callback() will use this * export later b=18126 */ class_export_get(exp); rc = cfs_kernel_thread(target_quotacheck_thread, qta, CLONE_VM|CLONE_FILES); if (rc >= 0) { /* target_quotacheck_thread will drop the ref on exp and release * obt_quotachecking */ 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; } out: cfs_up(&obt->obt_quotachecking); OBD_FREE_PTR(qta); return rc; }