250
251 ASSERT(mutex_owned(&stmf_state.stmf_lock));
252 /*
253 * to avoid conflict with updating session's map,
254 * which only grab stmf_lock
255 */
256 sm = iss->iss_sm;
257 iss->iss_sm = NULL;
258 iss->iss_hg = NULL;
259 if (sm->lm_nentries) {
260 for (n = 0; n < sm->lm_nentries; n++) {
261 if ((ent = (stmf_lun_map_ent_t *)sm->lm_plus[n])
262 != NULL) {
263 if (ent->ent_itl_datap) {
264 stmf_do_itl_dereg(ent->ent_lu,
265 ent->ent_itl_datap,
266 STMF_ITL_REASON_IT_NEXUS_LOSS);
267 }
268 ilu = (stmf_i_lu_t *)
269 ent->ent_lu->lu_stmf_private;
270 atomic_add_32(&ilu->ilu_ref_cnt, -1);
271 kmem_free(sm->lm_plus[n],
272 sizeof (stmf_lun_map_ent_t));
273 }
274 }
275 kmem_free(sm->lm_plus,
276 sizeof (stmf_lun_map_ent_t *) * sm->lm_nentries);
277 }
278
279 kmem_free(sm, sizeof (*sm));
280 return (STMF_SUCCESS);
281 }
282
283 /*
284 * Expects the session lock to be held.
285 */
286 stmf_xfer_data_t *
287 stmf_session_prepare_report_lun_data(stmf_lun_map_t *sm)
288 {
289 stmf_xfer_data_t *xd;
290 uint16_t nluns, ent;
403 stmf_lun_map_ent_t *lun_map_ent;
404 uint32_t new_flags = 0;
405 uint16_t luNbr =
406 ((uint16_t)lu_nbr[1] | (((uint16_t)(lu_nbr[0] & 0x3F)) << 8));
407
408 ASSERT(mutex_owned(&stmf_state.stmf_lock));
409 ASSERT(!stmf_get_ent_from_map(sm, luNbr));
410
411 if ((sm->lm_nluns == 0) &&
412 ((iss->iss_flags & ISS_BEING_CREATED) == 0)) {
413 new_flags = ISS_GOT_INITIAL_LUNS;
414 atomic_or_32(&ilport->ilport_flags, ILPORT_SS_GOT_INITIAL_LUNS);
415 stmf_state.stmf_process_initial_luns = 1;
416 }
417
418 lun_map_ent = (stmf_lun_map_ent_t *)
419 kmem_zalloc(sizeof (stmf_lun_map_ent_t), KM_SLEEP);
420 lun_map_ent->ent_lu = lu;
421 ret = stmf_add_ent_to_map(sm, (void *)lun_map_ent, lu_nbr);
422 ASSERT(ret == STMF_SUCCESS);
423 atomic_add_32(&ilu->ilu_ref_cnt, 1);
424 /*
425 * do not set lun inventory flag for standby port
426 * as this would be handled from peer
427 */
428 if (ilport->ilport_standby == 0) {
429 new_flags |= ISS_LUN_INVENTORY_CHANGED;
430 }
431 atomic_or_32(&iss->iss_flags, new_flags);
432 return (STMF_SUCCESS);
433 }
434
435 /*
436 * remvoe lu from a session, stmf_lock is already held
437 */
438 /* ARGSUSED */
439 stmf_status_t
440 stmf_remove_lu_from_session(stmf_i_local_port_t *ilport,
441 stmf_i_scsi_session_t *iss,
442 stmf_lu_t *lu,
443 uint8_t *lu_nbr)
444 {
445 stmf_status_t ret;
446 stmf_i_lu_t *ilu;
447 stmf_lun_map_t *sm = iss->iss_sm;
448 stmf_lun_map_ent_t *lun_map_ent;
449 uint16_t luNbr =
450 ((uint16_t)lu_nbr[1] | (((uint16_t)(lu_nbr[0] & 0x3F)) << 8));
451
452 ASSERT(mutex_owned(&stmf_state.stmf_lock));
453 lun_map_ent = stmf_get_ent_from_map(sm, luNbr);
454 ASSERT(lun_map_ent && lun_map_ent->ent_lu == lu);
455
456 ilu = (stmf_i_lu_t *)lu->lu_stmf_private;
457
458 ret = stmf_remove_ent_from_map(sm, lu_nbr);
459 ASSERT(ret == STMF_SUCCESS);
460 atomic_add_32(&ilu->ilu_ref_cnt, -1);
461 iss->iss_flags |= ISS_LUN_INVENTORY_CHANGED;
462 if (lun_map_ent->ent_itl_datap) {
463 stmf_do_itl_dereg(lu, lun_map_ent->ent_itl_datap,
464 STMF_ITL_REASON_USER_REQUEST);
465 }
466 kmem_free((void *)lun_map_ent, sizeof (stmf_lun_map_ent_t));
467 return (STMF_SUCCESS);
468 }
469
470 /*
471 * add or remove lu from all related sessions based on view entry,
472 * action is 0 for delete, 1 for add
473 */
474 void
475 stmf_update_sessions_per_ve(stmf_view_entry_t *ve,
476 stmf_lu_t *lu, int action)
477 {
478 stmf_i_lu_t *ilu_tmp;
479 stmf_lu_t *lu_to_add;
480 stmf_i_local_port_t *ilport;
667 host = stmf_lookup_id(
668 (stmf_id_list_t *)hgid->id_impl_specific,
669 ident_size, ident);
670 if (host)
671 return (hgid);
672 }
673 return (NULL);
674 }
675
676 void
677 stmf_append_id(stmf_id_list_t *idlist, stmf_id_data_t *id)
678 {
679 id->id_next = NULL;
680
681 if ((id->id_prev = idlist->idl_tail) == NULL) {
682 idlist->idl_head = idlist->idl_tail = id;
683 } else {
684 idlist->idl_tail->id_next = id;
685 idlist->idl_tail = id;
686 }
687 atomic_add_32(&idlist->id_count, 1);
688 }
689
690 void
691 stmf_remove_id(stmf_id_list_t *idlist, stmf_id_data_t *id)
692 {
693 if (id->id_next) {
694 id->id_next->id_prev = id->id_prev;
695 } else {
696 idlist->idl_tail = id->id_prev;
697 }
698
699 if (id->id_prev) {
700 id->id_prev->id_next = id->id_next;
701 } else {
702 idlist->idl_head = id->id_next;
703 }
704 atomic_add_32(&idlist->id_count, -1);
705 }
706
707
708 /*
709 * The refcnts of objects in a view entry are updated when then entry
710 * is successfully added. ve_map is just another representation of the
711 * view enrtries in a LU. Duplicating or merging a ve map does not
712 * affect any refcnts.
713 */
714 stmf_lun_map_t *
715 stmf_duplicate_ve_map(stmf_lun_map_t *src)
716 {
717 stmf_lun_map_t *dst;
718 int i;
719
720 dst = (stmf_lun_map_t *)kmem_zalloc(sizeof (*dst), KM_SLEEP);
721
722 if (src == NULL)
723 return (dst);
724
|
250
251 ASSERT(mutex_owned(&stmf_state.stmf_lock));
252 /*
253 * to avoid conflict with updating session's map,
254 * which only grab stmf_lock
255 */
256 sm = iss->iss_sm;
257 iss->iss_sm = NULL;
258 iss->iss_hg = NULL;
259 if (sm->lm_nentries) {
260 for (n = 0; n < sm->lm_nentries; n++) {
261 if ((ent = (stmf_lun_map_ent_t *)sm->lm_plus[n])
262 != NULL) {
263 if (ent->ent_itl_datap) {
264 stmf_do_itl_dereg(ent->ent_lu,
265 ent->ent_itl_datap,
266 STMF_ITL_REASON_IT_NEXUS_LOSS);
267 }
268 ilu = (stmf_i_lu_t *)
269 ent->ent_lu->lu_stmf_private;
270 atomic_dec_32(&ilu->ilu_ref_cnt);
271 kmem_free(sm->lm_plus[n],
272 sizeof (stmf_lun_map_ent_t));
273 }
274 }
275 kmem_free(sm->lm_plus,
276 sizeof (stmf_lun_map_ent_t *) * sm->lm_nentries);
277 }
278
279 kmem_free(sm, sizeof (*sm));
280 return (STMF_SUCCESS);
281 }
282
283 /*
284 * Expects the session lock to be held.
285 */
286 stmf_xfer_data_t *
287 stmf_session_prepare_report_lun_data(stmf_lun_map_t *sm)
288 {
289 stmf_xfer_data_t *xd;
290 uint16_t nluns, ent;
403 stmf_lun_map_ent_t *lun_map_ent;
404 uint32_t new_flags = 0;
405 uint16_t luNbr =
406 ((uint16_t)lu_nbr[1] | (((uint16_t)(lu_nbr[0] & 0x3F)) << 8));
407
408 ASSERT(mutex_owned(&stmf_state.stmf_lock));
409 ASSERT(!stmf_get_ent_from_map(sm, luNbr));
410
411 if ((sm->lm_nluns == 0) &&
412 ((iss->iss_flags & ISS_BEING_CREATED) == 0)) {
413 new_flags = ISS_GOT_INITIAL_LUNS;
414 atomic_or_32(&ilport->ilport_flags, ILPORT_SS_GOT_INITIAL_LUNS);
415 stmf_state.stmf_process_initial_luns = 1;
416 }
417
418 lun_map_ent = (stmf_lun_map_ent_t *)
419 kmem_zalloc(sizeof (stmf_lun_map_ent_t), KM_SLEEP);
420 lun_map_ent->ent_lu = lu;
421 ret = stmf_add_ent_to_map(sm, (void *)lun_map_ent, lu_nbr);
422 ASSERT(ret == STMF_SUCCESS);
423 atomic_inc_32(&ilu->ilu_ref_cnt);
424 /*
425 * do not set lun inventory flag for standby port
426 * as this would be handled from peer
427 */
428 if (ilport->ilport_standby == 0) {
429 new_flags |= ISS_LUN_INVENTORY_CHANGED;
430 }
431 atomic_or_32(&iss->iss_flags, new_flags);
432 return (STMF_SUCCESS);
433 }
434
435 /*
436 * remvoe lu from a session, stmf_lock is already held
437 */
438 /* ARGSUSED */
439 stmf_status_t
440 stmf_remove_lu_from_session(stmf_i_local_port_t *ilport,
441 stmf_i_scsi_session_t *iss,
442 stmf_lu_t *lu,
443 uint8_t *lu_nbr)
444 {
445 stmf_status_t ret;
446 stmf_i_lu_t *ilu;
447 stmf_lun_map_t *sm = iss->iss_sm;
448 stmf_lun_map_ent_t *lun_map_ent;
449 uint16_t luNbr =
450 ((uint16_t)lu_nbr[1] | (((uint16_t)(lu_nbr[0] & 0x3F)) << 8));
451
452 ASSERT(mutex_owned(&stmf_state.stmf_lock));
453 lun_map_ent = stmf_get_ent_from_map(sm, luNbr);
454 ASSERT(lun_map_ent && lun_map_ent->ent_lu == lu);
455
456 ilu = (stmf_i_lu_t *)lu->lu_stmf_private;
457
458 ret = stmf_remove_ent_from_map(sm, lu_nbr);
459 ASSERT(ret == STMF_SUCCESS);
460 atomic_dec_32(&ilu->ilu_ref_cnt);
461 iss->iss_flags |= ISS_LUN_INVENTORY_CHANGED;
462 if (lun_map_ent->ent_itl_datap) {
463 stmf_do_itl_dereg(lu, lun_map_ent->ent_itl_datap,
464 STMF_ITL_REASON_USER_REQUEST);
465 }
466 kmem_free((void *)lun_map_ent, sizeof (stmf_lun_map_ent_t));
467 return (STMF_SUCCESS);
468 }
469
470 /*
471 * add or remove lu from all related sessions based on view entry,
472 * action is 0 for delete, 1 for add
473 */
474 void
475 stmf_update_sessions_per_ve(stmf_view_entry_t *ve,
476 stmf_lu_t *lu, int action)
477 {
478 stmf_i_lu_t *ilu_tmp;
479 stmf_lu_t *lu_to_add;
480 stmf_i_local_port_t *ilport;
667 host = stmf_lookup_id(
668 (stmf_id_list_t *)hgid->id_impl_specific,
669 ident_size, ident);
670 if (host)
671 return (hgid);
672 }
673 return (NULL);
674 }
675
676 void
677 stmf_append_id(stmf_id_list_t *idlist, stmf_id_data_t *id)
678 {
679 id->id_next = NULL;
680
681 if ((id->id_prev = idlist->idl_tail) == NULL) {
682 idlist->idl_head = idlist->idl_tail = id;
683 } else {
684 idlist->idl_tail->id_next = id;
685 idlist->idl_tail = id;
686 }
687 atomic_inc_32(&idlist->id_count);
688 }
689
690 void
691 stmf_remove_id(stmf_id_list_t *idlist, stmf_id_data_t *id)
692 {
693 if (id->id_next) {
694 id->id_next->id_prev = id->id_prev;
695 } else {
696 idlist->idl_tail = id->id_prev;
697 }
698
699 if (id->id_prev) {
700 id->id_prev->id_next = id->id_next;
701 } else {
702 idlist->idl_head = id->id_next;
703 }
704 atomic_dec_32(&idlist->id_count);
705 }
706
707
708 /*
709 * The refcnts of objects in a view entry are updated when then entry
710 * is successfully added. ve_map is just another representation of the
711 * view enrtries in a LU. Duplicating or merging a ve map does not
712 * affect any refcnts.
713 */
714 stmf_lun_map_t *
715 stmf_duplicate_ve_map(stmf_lun_map_t *src)
716 {
717 stmf_lun_map_t *dst;
718 int i;
719
720 dst = (stmf_lun_map_t *)kmem_zalloc(sizeof (*dst), KM_SLEEP);
721
722 if (src == NULL)
723 return (dst);
724
|