static int lov_llog_origin_connect(struct llog_ctxt *ctxt, struct llog_logid *logid, struct llog_gen *gen, struct obd_uuid *uuid) { struct obd_device *obd = ctxt->loc_obd; struct lov_obd *lov = &obd->u.lov; int i, rc = 0, err = 0; ENTRY; obd_getref(obd); for (i = 0; i < lov->desc.ld_tgt_count; i++) { struct obd_device *child; struct llog_ctxt *cctxt; if (!lov->lov_tgts[i] || !lov->lov_tgts[i]->ltd_active) continue; if (uuid && !obd_uuid_equals(uuid, &lov->lov_tgts[i]->ltd_uuid)) continue; CDEBUG(D_CONFIG, "connect %d/%d\n", i, lov->desc.ld_tgt_count); child = lov->lov_tgts[i]->ltd_exp->exp_obd; cctxt = llog_get_context(child, ctxt->loc_idx); rc = llog_connect(cctxt, logid, gen, uuid); llog_ctxt_put(cctxt); if (rc) { CERROR("error osc_llog_connect tgt %d (%d)\n", i, rc); if (!err) err = rc; } } obd_putref(obd); RETURN(err); }
static inline int mgs_destroy_export(struct obd_export *exp) { ENTRY; target_destroy_export(exp); mgs_client_free(exp); if (unlikely(obd_uuid_equals(&exp->exp_obd->obd_uuid, &exp->exp_client_uuid))) RETURN(0); ldlm_destroy_export(exp); RETURN(0); }
static inline int mgs_init_export(struct obd_export *exp) { struct mgs_export_data *data = &exp->u.eu_mgs_data; /* init mgs_export_data for fsc */ cfs_spin_lock_init(&data->med_lock); CFS_INIT_LIST_HEAD(&data->med_clients); cfs_spin_lock(&exp->exp_lock); exp->exp_connecting = 1; cfs_spin_unlock(&exp->exp_lock); /* self-export doesn't need client data and ldlm initialization */ if (unlikely(obd_uuid_equals(&exp->exp_obd->obd_uuid, &exp->exp_client_uuid))) return 0; return ldlm_init_export(exp); }
/** * Initialize OFD per-export statistics. * * This function sets up procfs entries for various OFD export counters. These * counters are for per-client statistics tracked on the server. * * \param[in] ofd OFD device * \param[in] exp OBD export * \param[in] client_nid NID of client * * \retval 0 if successful * \retval negative value on error */ static int ofd_export_stats_init(struct ofd_device *ofd, struct obd_export *exp, lnet_nid_t *client_nid) { struct obd_device *obd = ofd_obd(ofd); struct nid_stat *stats; int rc; ENTRY; LASSERT(obd->obd_uses_nid_stats); if (obd_uuid_equals(&exp->exp_client_uuid, &obd->obd_uuid)) /* Self-export gets no proc entry */ RETURN(0); rc = lprocfs_exp_setup(exp, client_nid); if (rc != 0) /* Mask error for already created /proc entries */ RETURN(rc == -EALREADY ? 0 : rc); stats = exp->exp_nid_stats; stats->nid_stats = lprocfs_alloc_stats(NUM_OBD_STATS + LPROC_OFD_STATS_LAST, LPROCFS_STATS_FLAG_NOPERCPU); if (stats->nid_stats == NULL) RETURN(-ENOMEM); lprocfs_init_ops_stats(LPROC_OFD_STATS_LAST, stats->nid_stats); ofd_stats_counter_init(stats->nid_stats); rc = lprocfs_register_stats(stats->nid_proc, "stats", stats->nid_stats); if (rc != 0) { lprocfs_free_stats(&stats->nid_stats); GOTO(out, rc); } rc = lprocfs_nid_ldlm_stats_init(stats); if (rc != 0) GOTO(out, rc); out: RETURN(rc); }
/** * Implementation of obd_ops::o_destroy_export. * * This function is called from class_export_destroy() to cleanup * the OFD-specific data for export being destroyed. * * \param[in] exp OBD export * * \retval 0 if successful * \retval negative value on error */ static int ofd_destroy_export(struct obd_export *exp) { struct ofd_device *ofd = ofd_exp(exp); if (exp->exp_filter_data.fed_pending) CERROR("%s: cli %s/%p has %lu pending on destroyed export" "\n", exp->exp_obd->obd_name, exp->exp_client_uuid.uuid, exp, exp->exp_filter_data.fed_pending); target_destroy_export(exp); if (unlikely(obd_uuid_equals(&exp->exp_obd->obd_uuid, &exp->exp_client_uuid))) return 0; ldlm_destroy_export(exp); tgt_client_free(exp); ofd_fmd_cleanup(exp); /* * discard grants once we're sure no more * interaction with the client is possible */ ofd_grant_discard(exp); ofd_fmd_cleanup(exp); if (exp_connect_flags(exp) & OBD_CONNECT_GRANT_SHRINK) { if (ofd->ofd_tot_granted_clients > 0) ofd->ofd_tot_granted_clients --; } if (!(exp->exp_flags & OBD_OPT_FORCE)) ofd_grant_sanity_check(exp->exp_obd, __FUNCTION__); LASSERT(list_empty(&exp->exp_filter_data.fed_mod_list)); return 0; }
/** * Implementation of obd_ops::o_init_export. * * This function is called from class_new_export() and initializes * the OFD-specific data for new export. * * \param[in] exp OBD export * * \retval 0 if successful * \retval negative value on error */ static int ofd_init_export(struct obd_export *exp) { int rc; spin_lock_init(&exp->exp_filter_data.fed_lock); INIT_LIST_HEAD(&exp->exp_filter_data.fed_mod_list); atomic_set(&exp->exp_filter_data.fed_soft_sync_count, 0); spin_lock(&exp->exp_lock); exp->exp_connecting = 1; spin_unlock(&exp->exp_lock); /* self-export doesn't need client data and ldlm initialization */ if (unlikely(obd_uuid_equals(&exp->exp_obd->obd_uuid, &exp->exp_client_uuid))) return 0; rc = tgt_client_alloc(exp); if (rc == 0) ldlm_init_export(exp); if (rc) CERROR("%s: Can't initialize export: rc %d\n", exp->exp_obd->obd_name, rc); return rc; }
int llog_init_handle(const struct lu_env *env, struct llog_handle *handle, int flags, struct obd_uuid *uuid) { struct llog_log_hdr *llh; int rc; LASSERT(handle->lgh_hdr == NULL); OBD_ALLOC_PTR(llh); if (llh == NULL) return -ENOMEM; handle->lgh_hdr = llh; /* first assign flags to use llog_client_ops */ llh->llh_flags = flags; rc = llog_read_header(env, handle, uuid); if (rc == 0) { if (unlikely((llh->llh_flags & LLOG_F_IS_PLAIN && flags & LLOG_F_IS_CAT) || (llh->llh_flags & LLOG_F_IS_CAT && flags & LLOG_F_IS_PLAIN))) { CERROR("%s: llog type is %s but initializing %s\n", handle->lgh_ctxt->loc_obd->obd_name, llh->llh_flags & LLOG_F_IS_CAT ? "catalog" : "plain", flags & LLOG_F_IS_CAT ? "catalog" : "plain"); GOTO(out, rc = -EINVAL); } else if (llh->llh_flags & (LLOG_F_IS_PLAIN | LLOG_F_IS_CAT)) { /* * it is possible to open llog without specifying llog * type so it is taken from llh_flags */ flags = llh->llh_flags; } else { /* for some reason the llh_flags has no type set */ CERROR("llog type is not specified!\n"); GOTO(out, rc = -EINVAL); } if (unlikely(uuid && !obd_uuid_equals(uuid, &llh->llh_tgtuuid))) { CERROR("%s: llog uuid mismatch: %s/%s\n", handle->lgh_ctxt->loc_obd->obd_name, (char *)uuid->uuid, (char *)llh->llh_tgtuuid.uuid); GOTO(out, rc = -EEXIST); } } if (flags & LLOG_F_IS_CAT) { LASSERT(list_empty(&handle->u.chd.chd_head)); INIT_LIST_HEAD(&handle->u.chd.chd_head); llh->llh_size = sizeof(struct llog_logid_rec); } else if (!(flags & LLOG_F_IS_PLAIN)) { CERROR("%s: unknown flags: %#x (expected %#x or %#x)\n", handle->lgh_ctxt->loc_obd->obd_name, flags, LLOG_F_IS_CAT, LLOG_F_IS_PLAIN); rc = -EINVAL; } out: if (rc) { OBD_FREE_PTR(llh); handle->lgh_hdr = NULL; } return rc; }
int llog_init_handle(const struct lu_env *env, struct llog_handle *handle, int flags, struct obd_uuid *uuid) { int chunk_size = handle->lgh_ctxt->loc_chunk_size; enum llog_flag fmt = flags & LLOG_F_EXT_MASK; struct llog_log_hdr *llh; int rc; LASSERT(!handle->lgh_hdr); LASSERT(chunk_size >= LLOG_MIN_CHUNK_SIZE); llh = libcfs_kvzalloc(sizeof(*llh), GFP_NOFS); if (!llh) return -ENOMEM; handle->lgh_hdr = llh; handle->lgh_hdr_size = chunk_size; /* first assign flags to use llog_client_ops */ llh->llh_flags = flags; rc = llog_read_header(env, handle, uuid); if (rc == 0) { if (unlikely((llh->llh_flags & LLOG_F_IS_PLAIN && flags & LLOG_F_IS_CAT) || (llh->llh_flags & LLOG_F_IS_CAT && flags & LLOG_F_IS_PLAIN))) { CERROR("%s: llog type is %s but initializing %s\n", handle->lgh_ctxt->loc_obd->obd_name, llh->llh_flags & LLOG_F_IS_CAT ? "catalog" : "plain", flags & LLOG_F_IS_CAT ? "catalog" : "plain"); rc = -EINVAL; goto out; } else if (llh->llh_flags & (LLOG_F_IS_PLAIN | LLOG_F_IS_CAT)) { /* * it is possible to open llog without specifying llog * type so it is taken from llh_flags */ flags = llh->llh_flags; } else { /* for some reason the llh_flags has no type set */ CERROR("llog type is not specified!\n"); rc = -EINVAL; goto out; } if (unlikely(uuid && !obd_uuid_equals(uuid, &llh->llh_tgtuuid))) { CERROR("%s: llog uuid mismatch: %s/%s\n", handle->lgh_ctxt->loc_obd->obd_name, (char *)uuid->uuid, (char *)llh->llh_tgtuuid.uuid); rc = -EEXIST; goto out; } } if (flags & LLOG_F_IS_CAT) { LASSERT(list_empty(&handle->u.chd.chd_head)); INIT_LIST_HEAD(&handle->u.chd.chd_head); llh->llh_size = sizeof(struct llog_logid_rec); llh->llh_flags |= LLOG_F_IS_FIXSIZE; } else if (!(flags & LLOG_F_IS_PLAIN)) { CERROR("%s: unknown flags: %#x (expected %#x or %#x)\n", handle->lgh_ctxt->loc_obd->obd_name, flags, LLOG_F_IS_CAT, LLOG_F_IS_PLAIN); rc = -EINVAL; } llh->llh_flags |= fmt; out: if (rc) { kvfree(llh); handle->lgh_hdr = NULL; } return rc; }
/* * Handle quota request from slave. * * \param env - is the environment passed by the caller * \param ld - is the lu device associated with the qmt * \param req - is the quota acquire request */ static int qmt_dqacq(const struct lu_env *env, struct lu_device *ld, struct ptlrpc_request *req) { struct qmt_device *qmt = lu2qmt_dev(ld); struct quota_body *qbody, *repbody; struct obd_uuid *uuid; struct ldlm_lock *lock; struct lquota_entry *lqe; int pool_id, pool_type, qtype; int rc; ENTRY; qbody = req_capsule_client_get(&req->rq_pill, &RMF_QUOTA_BODY); if (qbody == NULL) RETURN(err_serious(-EPROTO)); repbody = req_capsule_server_get(&req->rq_pill, &RMF_QUOTA_BODY); if (repbody == NULL) RETURN(err_serious(-EFAULT)); /* verify if global lock is stale */ if (!lustre_handle_is_used(&qbody->qb_glb_lockh)) RETURN(-ENOLCK); lock = ldlm_handle2lock(&qbody->qb_glb_lockh); if (lock == NULL) RETURN(-ENOLCK); LDLM_LOCK_PUT(lock); uuid = &req->rq_export->exp_client_uuid; if (req_is_rel(qbody->qb_flags) + req_is_acq(qbody->qb_flags) + req_is_preacq(qbody->qb_flags) > 1) { CERROR("%s: malformed quota request with conflicting flags set " "(%x) from slave %s\n", qmt->qmt_svname, qbody->qb_flags, obd_uuid2str(uuid)); RETURN(-EPROTO); } if (req_is_acq(qbody->qb_flags) || req_is_preacq(qbody->qb_flags)) { /* acquire and pre-acquire should use a valid ID lock */ if (!lustre_handle_is_used(&qbody->qb_lockh)) RETURN(-ENOLCK); lock = ldlm_handle2lock(&qbody->qb_lockh); if (lock == NULL) /* no lock associated with this handle */ RETURN(-ENOLCK); LDLM_DEBUG(lock, "%sacquire request", req_is_preacq(qbody->qb_flags) ? "pre" : ""); if (!obd_uuid_equals(&lock->l_export->exp_client_uuid, uuid)) { /* sorry, no way to cheat ... */ LDLM_LOCK_PUT(lock); RETURN(-ENOLCK); } if ((lock->l_flags & LDLM_FL_AST_SENT) != 0) { struct ptlrpc_service_part *svc; unsigned int timeout; svc = req->rq_rqbd->rqbd_svcpt; timeout = at_est2timeout(at_get(&svc->scp_at_estimate)); timeout = max(timeout, ldlm_timeout); /* lock is being cancelled, prolong timeout */ ldlm_refresh_waiting_lock(lock, timeout); } LDLM_LOCK_PUT(lock); } /* extract pool & quota information from global index FID packed in the * request */ rc = lquota_extract_fid(&qbody->qb_fid, &pool_id, &pool_type, &qtype); if (rc) RETURN(-EINVAL); /* Find the quota entry associated with the quota id */ lqe = qmt_pool_lqe_lookup(env, qmt, pool_id, pool_type, qtype, &qbody->qb_id); if (IS_ERR(lqe)) RETURN(PTR_ERR(lqe)); /* process quota request */ rc = qmt_dqacq0(env, lqe, qmt, uuid, qbody->qb_flags, qbody->qb_count, qbody->qb_usage, repbody); if (lustre_handle_is_used(&qbody->qb_lockh)) /* return current qunit value only to slaves owning an per-ID * quota lock. For enqueue, the qunit value will be returned in * the LVB */ repbody->qb_qunit = lqe->lqe_qunit; lqe_putref(lqe); RETURN(rc); }