static int smb_rq_enqueue(struct smb_rq *rqp) { struct smb_share *ssp = rqp->sr_share; int error; if (ssp == NULL || rqp->sr_cred == &rqp->sr_vc->vc_iod->iod_scred) { return smb_iod_addrq(rqp); } for (;;) { SMBS_ST_LOCK(ssp); if (ssp->ss_flags & SMBS_RECONNECTING) { msleep(&ssp->ss_vcgenid, SMBS_ST_LOCKPTR(ssp), PWAIT | PDROP, "90trcn", hz); if (smb_td_intr(rqp->sr_cred->scr_td)) return EINTR; continue; } if (smb_share_valid(ssp) || (ssp->ss_flags & SMBS_CONNECTED) == 0) { SMBS_ST_UNLOCK(ssp); } else { SMBS_ST_UNLOCK(ssp); error = smb_iod_request(rqp->sr_vc->vc_iod, SMBIOD_EV_TREECONNECT | SMBIOD_EV_SYNC, ssp); if (error) return error; } error = smb_iod_addrq(rqp); if (error != EXDEV) break; } return error; }
static int smb_rq_enqueue(struct smb_rq *rqp) { struct smb_vc *vcp = rqp->sr_vc; struct smb_share *ssp = rqp->sr_share; int error = 0; /* * Normal requests may initiate a reconnect, * and/or wait for state changes to finish. * Some requests set the NORECONNECT flag * to avoid all that (i.e. tree discon) */ if (rqp->sr_flags & SMBR_NORECONNECT) { if (vcp->vc_state != SMBIOD_ST_VCACTIVE) { SMBSDEBUG("bad vc_state=%d\n", vcp->vc_state); return (ENOTCONN); } if (ssp != NULL && ((ssp->ss_flags & SMBS_CONNECTED) == 0)) return (ENOTCONN); goto ok_out; } /* * If we're not connected, initiate a reconnect * and/or wait for an existing one to finish. */ if (vcp->vc_state != SMBIOD_ST_VCACTIVE) { error = smb_iod_reconnect(vcp); if (error != 0) return (error); } /* * If this request has a "share" object * that needs a tree connect, do it now. */ if (ssp != NULL && (ssp->ss_flags & SMBS_CONNECTED) == 0) { error = smb_share_tcon(ssp, rqp->sr_cred); if (error) return (error); } /* * We now know what UID + TID to use. * Store them in the request. */ ok_out: rqp->sr_rquid = vcp->vc_smbuid; rqp->sr_rqtid = ssp ? ssp->ss_tid : SMB_TID_UNKNOWN; error = smb_iod_addrq(rqp); return (error); }