/** * Initialize new client connection. * * This function handles new connection to the OFD. The new export is * created (in context of class_connect()) and persistent client data is * initialized on storage. * * \param[in] env execution environment * \param[out] _exp stores pointer to new export * \param[in] obd OFD device * \param[in] cluuid client UUID * \param[in] data connection data from request * \param[in] localdata client NID * * \retval 0 if successful * \retval negative value on error */ static int ofd_obd_connect(const struct lu_env *env, struct obd_export **_exp, struct obd_device *obd, struct obd_uuid *cluuid, struct obd_connect_data *data, void *localdata) { struct obd_export *exp; struct ofd_device *ofd; struct lustre_handle conn = { 0 }; int rc; ENTRY; if (_exp == NULL || obd == NULL || cluuid == NULL) RETURN(-EINVAL); ofd = ofd_dev(obd->obd_lu_dev); rc = class_connect(&conn, obd, cluuid); if (rc) RETURN(rc); exp = class_conn2export(&conn); LASSERT(exp != NULL); if (localdata != NULL) { rc = nodemap_add_member(*(lnet_nid_t *)localdata, exp); if (rc != 0 && rc != -EEXIST) GOTO(out, rc); } else { CDEBUG(D_HA, "%s: cannot find nodemap for client %s: " "nid is null\n", obd->obd_name, cluuid->uuid); } rc = ofd_parse_connect_data(env, exp, data, true); if (rc) GOTO(out, rc); if (obd->obd_replayable) { struct tg_export_data *ted = &exp->exp_target_data; memcpy(ted->ted_lcd->lcd_uuid, cluuid, sizeof(ted->ted_lcd->lcd_uuid)); rc = tgt_client_new(env, exp); if (rc != 0) GOTO(out, rc); ofd_export_stats_init(ofd, exp, localdata); } CDEBUG(D_HA, "%s: get connection from MDS %d\n", obd->obd_name, data ? data->ocd_group : -1); out: if (rc != 0) { class_disconnect(exp); nodemap_del_member(exp); *_exp = NULL; } else { *_exp = exp; } RETURN(rc); }
/* * obd_connect handler used by the MDT to connect to the master target. */ static int qmt_device_obd_connect(const struct lu_env *env, struct obd_export **exp, struct obd_device *obd, struct obd_uuid *cluuid, struct obd_connect_data *data, void *localdata) { struct lustre_handle conn; int rc; ENTRY; rc = class_connect(&conn, obd, cluuid); if (rc) RETURN(rc); *exp = class_conn2export(&conn); RETURN(0); }
/* Establish a connection to the MGS.*/ static int mgs_connect(const struct lu_env *env, struct obd_export **exp, struct obd_device *obd, struct obd_uuid *cluuid, struct obd_connect_data *data, void *localdata) { struct obd_export *lexp; struct lustre_handle conn = { 0 }; int rc; ENTRY; if (!exp || !obd || !cluuid) RETURN(-EINVAL); rc = class_connect(&conn, obd, cluuid); if (rc) RETURN(rc); lexp = class_conn2export(&conn); LASSERT(lexp); mgs_counter_incr(lexp, LPROC_MGS_CONNECT); if (data != NULL) { data->ocd_connect_flags &= MGS_CONNECT_SUPPORTED; lexp->exp_connect_flags = data->ocd_connect_flags; data->ocd_version = LUSTRE_VERSION_CODE; } rc = mgs_export_stats_init(obd, lexp, localdata); if (rc) { class_disconnect(lexp); } else { *exp = lexp; } RETURN(rc); }
/* * we use exports to track all mdd users */ static int mdd_obd_connect(const struct lu_env *env, struct obd_export **exp, struct obd_device *obd, struct obd_uuid *cluuid, struct obd_connect_data *data, void *localdata) { struct mdd_device *mdd = lu2mdd_dev(obd->obd_lu_dev); struct lustre_handle conn; int rc; ENTRY; CDEBUG(D_CONFIG, "connect #%d\n", mdd->mdd_connects); rc = class_connect(&conn, obd, cluuid); if (rc) RETURN(rc); *exp = class_conn2export(&conn); /* Why should there ever be more than 1 connect? */ LASSERT(mdd->mdd_connects == 0); mdd->mdd_connects++; RETURN(0); }