Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Split cfiscsi_datamove() in two; no functional changes.

Approved by:	re (glebius)
Sponsored by:	FreeBSD Foundation
  • Loading branch information...
commit e19bd878747b3ea1bf8f279f885d5a6d20a6c396 1 parent 26b6c94
Edward Tomasz Napierała trasz authored

Showing 1 changed file with 203 additions and 182 deletions. Show diff stats Hide diff stats

  1. +203 182 sys/cam/ctl/ctl_frontend_iscsi.c
385 sys/cam/ctl/ctl_frontend_iscsi.c
@@ -2239,20 +2239,16 @@ cfiscsi_lun_disable(void *arg, struct ctl_id target_id, int lun_id)
2239 2239 }
2240 2240
2241 2241 static void
2242   -cfiscsi_datamove(union ctl_io *io)
  2242 +cfiscsi_datamove_in(union ctl_io *io)
2243 2243 {
2244 2244 struct cfiscsi_session *cs;
2245 2245 struct icl_pdu *request, *response;
2246 2246 const struct iscsi_bhs_scsi_command *bhssc;
2247 2247 struct iscsi_bhs_data_in *bhsdi;
2248   - struct iscsi_bhs_r2t *bhsr2t;
2249   - struct cfiscsi_data_wait *cdw;
2250 2248 struct ctl_sg_entry ctl_sg_entry, *ctl_sglist;
2251 2249 size_t copy_len, len, off;
2252 2250 const char *addr;
2253 2251 int ctl_sg_count, error, i;
2254   - uint32_t target_transfer_tag;
2255   - bool done;
2256 2252
2257 2253 request = io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr;
2258 2254 cs = PDU_SESSION(request);
@@ -2278,215 +2274,240 @@ cfiscsi_datamove(union ctl_io *io)
2278 2274 */
2279 2275 PDU_TOTAL_TRANSFER_LEN(request) = io->scsiio.kern_total_len;
2280 2276
2281   - if ((io->io_hdr.flags & CTL_FLAG_DATA_MASK) == CTL_FLAG_DATA_IN) {
2282 2277 #if 0
2283   - if (ctl_sg_count > 1)
2284   - CFISCSI_SESSION_DEBUG(cs, "ctl_sg_count = %d", ctl_sg_count);
  2278 + if (ctl_sg_count > 1)
  2279 + CFISCSI_SESSION_DEBUG(cs, "ctl_sg_count = %d", ctl_sg_count);
2285 2280 #endif
2286 2281
2287   - /*
2288   - * This is the offset within the current SCSI command;
2289   - * i.e. for the first call of datamove(), it will be 0,
2290   - * and for subsequent ones it will be the sum of lengths
2291   - * of previous ones.
2292   - */
2293   - off = htonl(io->scsiio.kern_rel_offset);
2294   - if (off > 1)
2295   - CFISCSI_SESSION_DEBUG(cs, "off = %zd", off);
2296   -
2297   - i = 0;
2298   - addr = NULL;
2299   - len = 0;
2300   - response = NULL;
2301   - bhsdi = NULL;
2302   - for (;;) {
2303   - KASSERT(i < ctl_sg_count, ("i >= ctl_sg_count"));
  2282 + /*
  2283 + * This is the offset within the current SCSI command;
  2284 + * i.e. for the first call of datamove(), it will be 0,
  2285 + * and for subsequent ones it will be the sum of lengths
  2286 + * of previous ones.
  2287 + */
  2288 + off = htonl(io->scsiio.kern_rel_offset);
  2289 + if (off > 1)
  2290 + CFISCSI_SESSION_DEBUG(cs, "off = %zd", off);
  2291 +
  2292 + i = 0;
  2293 + addr = NULL;
  2294 + len = 0;
  2295 + response = NULL;
  2296 + bhsdi = NULL;
  2297 + for (;;) {
  2298 + KASSERT(i < ctl_sg_count, ("i >= ctl_sg_count"));
  2299 + if (response == NULL) {
  2300 + response = cfiscsi_pdu_new_response(request, M_NOWAIT);
2304 2301 if (response == NULL) {
2305   - response =
2306   - cfiscsi_pdu_new_response(request, M_NOWAIT);
2307   - if (response == NULL) {
2308   - CFISCSI_SESSION_WARN(cs, "failed to "
2309   - "allocate memory; dropping connection");
2310   - icl_pdu_free(request);
2311   - cfiscsi_session_terminate(cs);
2312   - return;
2313   - }
2314   - bhsdi = (struct iscsi_bhs_data_in *)
2315   - response->ip_bhs;
2316   - bhsdi->bhsdi_opcode =
2317   - ISCSI_BHS_OPCODE_SCSI_DATA_IN;
2318   - bhsdi->bhsdi_initiator_task_tag =
2319   - bhssc->bhssc_initiator_task_tag;
2320   - bhsdi->bhsdi_datasn =
2321   - htonl(PDU_EXPDATASN(request));
2322   - PDU_EXPDATASN(request)++;
2323   - bhsdi->bhsdi_buffer_offset = htonl(off);
2324   - }
2325   -
2326   - if (len == 0) {
2327   - addr = ctl_sglist[i].addr;
2328   - len = ctl_sglist[i].len;
2329   - KASSERT(len > 0, ("len <= 0"));
2330   - }
2331   -
2332   - copy_len = len;
2333   - if (response->ip_data_len + copy_len >
2334   - cs->cs_max_data_segment_length)
2335   - copy_len = cs->cs_max_data_segment_length -
2336   - response->ip_data_len;
2337   - KASSERT(copy_len <= len, ("copy_len > len"));
2338   - error = icl_pdu_append_data(response, addr, copy_len, M_NOWAIT);
2339   - if (error != 0) {
2340 2302 CFISCSI_SESSION_WARN(cs, "failed to "
2341 2303 "allocate memory; dropping connection");
2342 2304 icl_pdu_free(request);
2343   - icl_pdu_free(response);
2344 2305 cfiscsi_session_terminate(cs);
2345 2306 return;
2346 2307 }
2347   - addr += copy_len;
2348   - len -= copy_len;
2349   - off += copy_len;
2350   - io->scsiio.ext_data_filled += copy_len;
  2308 + bhsdi = (struct iscsi_bhs_data_in *)response->ip_bhs;
  2309 + bhsdi->bhsdi_opcode = ISCSI_BHS_OPCODE_SCSI_DATA_IN;
  2310 + bhsdi->bhsdi_initiator_task_tag =
  2311 + bhssc->bhssc_initiator_task_tag;
  2312 + bhsdi->bhsdi_datasn = htonl(PDU_EXPDATASN(request));
  2313 + PDU_EXPDATASN(request)++;
  2314 + bhsdi->bhsdi_buffer_offset = htonl(off);
  2315 + }
2351 2316
2352   - if (len == 0) {
2353   - /*
2354   - * End of scatter-gather segment;
2355   - * proceed to the next one...
2356   - */
2357   - if (i == ctl_sg_count - 1) {
2358   - /*
2359   - * ... unless this was the last one.
2360   - */
2361   - break;
2362   - }
2363   - i++;
2364   - }
  2317 + if (len == 0) {
  2318 + addr = ctl_sglist[i].addr;
  2319 + len = ctl_sglist[i].len;
  2320 + KASSERT(len > 0, ("len <= 0"));
  2321 + }
2365 2322
2366   - if (response->ip_data_len ==
2367   - cs->cs_max_data_segment_length) {
  2323 + copy_len = len;
  2324 + if (response->ip_data_len + copy_len >
  2325 + cs->cs_max_data_segment_length)
  2326 + copy_len = cs->cs_max_data_segment_length -
  2327 + response->ip_data_len;
  2328 + KASSERT(copy_len <= len, ("copy_len > len"));
  2329 + error = icl_pdu_append_data(response, addr, copy_len, M_NOWAIT);
  2330 + if (error != 0) {
  2331 + CFISCSI_SESSION_WARN(cs, "failed to "
  2332 + "allocate memory; dropping connection");
  2333 + icl_pdu_free(request);
  2334 + icl_pdu_free(response);
  2335 + cfiscsi_session_terminate(cs);
  2336 + return;
  2337 + }
  2338 + addr += copy_len;
  2339 + len -= copy_len;
  2340 + off += copy_len;
  2341 + io->scsiio.ext_data_filled += copy_len;
  2342 +
  2343 + if (len == 0) {
  2344 + /*
  2345 + * End of scatter-gather segment;
  2346 + * proceed to the next one...
  2347 + */
  2348 + if (i == ctl_sg_count - 1) {
2368 2349 /*
2369   - * Can't stuff more data into the current PDU;
2370   - * queue it. Note that's not enough to check
2371   - * for kern_data_resid == 0 instead; there
2372   - * may be several Data-In PDUs for the final
2373   - * call to cfiscsi_datamove(), and we want
2374   - * to set the F flag only on the last of them.
  2350 + * ... unless this was the last one.
2375 2351 */
2376   - if (off == io->scsiio.kern_total_len)
2377   - bhsdi->bhsdi_flags |= BHSDI_FLAGS_F;
2378   - KASSERT(response->ip_data_len > 0,
2379   - ("sending empty Data-In"));
2380   - cfiscsi_pdu_queue(response);
2381   - response = NULL;
2382   - bhsdi = NULL;
  2352 + break;
2383 2353 }
  2354 + i++;
2384 2355 }
2385   - KASSERT(i == ctl_sg_count - 1, ("missed SG segment"));
2386   - KASSERT(len == 0, ("missed data from SG segment"));
2387   - if (response != NULL) {
2388   - if (off == io->scsiio.kern_total_len) {
  2356 +
  2357 + if (response->ip_data_len == cs->cs_max_data_segment_length) {
  2358 + /*
  2359 + * Can't stuff more data into the current PDU;
  2360 + * queue it. Note that's not enough to check
  2361 + * for kern_data_resid == 0 instead; there
  2362 + * may be several Data-In PDUs for the final
  2363 + * call to cfiscsi_datamove(), and we want
  2364 + * to set the F flag only on the last of them.
  2365 + */
  2366 + if (off == io->scsiio.kern_total_len)
2389 2367 bhsdi->bhsdi_flags |= BHSDI_FLAGS_F;
2390   - } else {
2391   - CFISCSI_SESSION_DEBUG(cs, "not setting the F flag; "
2392   - "have %zd, need %zd", off,
2393   - (size_t)io->scsiio.kern_total_len);
2394   - }
2395 2368 KASSERT(response->ip_data_len > 0,
2396 2369 ("sending empty Data-In"));
2397 2370 cfiscsi_pdu_queue(response);
  2371 + response = NULL;
  2372 + bhsdi = NULL;
  2373 + }
  2374 + }
  2375 + KASSERT(i == ctl_sg_count - 1, ("missed SG segment"));
  2376 + KASSERT(len == 0, ("missed data from SG segment"));
  2377 + if (response != NULL) {
  2378 + if (off == io->scsiio.kern_total_len) {
  2379 + bhsdi->bhsdi_flags |= BHSDI_FLAGS_F;
  2380 + } else {
  2381 + CFISCSI_SESSION_DEBUG(cs, "not setting the F flag; "
  2382 + "have %zd, need %zd", off,
  2383 + (size_t)io->scsiio.kern_total_len);
2398 2384 }
  2385 + KASSERT(response->ip_data_len > 0, ("sending empty Data-In"));
  2386 + cfiscsi_pdu_queue(response);
  2387 + }
2399 2388
2400   - io->scsiio.be_move_done(io);
2401   - } else {
2402   - CFISCSI_SESSION_LOCK(cs);
2403   - target_transfer_tag = cs->cs_target_transfer_tag;
2404   - cs->cs_target_transfer_tag++;
2405   - CFISCSI_SESSION_UNLOCK(cs);
  2389 + io->scsiio.be_move_done(io);
  2390 +}
  2391 +
  2392 +static void
  2393 +cfiscsi_datamove_out(union ctl_io *io)
  2394 +{
  2395 + struct cfiscsi_session *cs;
  2396 + struct icl_pdu *request, *response;
  2397 + const struct iscsi_bhs_scsi_command *bhssc;
  2398 + struct iscsi_bhs_r2t *bhsr2t;
  2399 + struct cfiscsi_data_wait *cdw;
  2400 + uint32_t target_transfer_tag;
  2401 + bool done;
  2402 +
  2403 + request = io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr;
  2404 + cs = PDU_SESSION(request);
  2405 +
  2406 + bhssc = (const struct iscsi_bhs_scsi_command *)request->ip_bhs;
  2407 + KASSERT((bhssc->bhssc_opcode & ~ISCSI_BHS_OPCODE_IMMEDIATE) ==
  2408 + ISCSI_BHS_OPCODE_SCSI_COMMAND,
  2409 + ("bhssc->bhssc_opcode != ISCSI_BHS_OPCODE_SCSI_COMMAND"));
  2410 +
  2411 + /*
  2412 + * We need to record it so that we can properly report
  2413 + * underflow/underflow.
  2414 + */
  2415 + PDU_TOTAL_TRANSFER_LEN(request) = io->scsiio.kern_total_len;
  2416 +
  2417 + CFISCSI_SESSION_LOCK(cs);
  2418 + target_transfer_tag = cs->cs_target_transfer_tag;
  2419 + cs->cs_target_transfer_tag++;
  2420 + CFISCSI_SESSION_UNLOCK(cs);
2406 2421
2407 2422 #if 0
2408   - CFISCSI_SESSION_DEBUG(cs, "expecting Data-Out with initiator "
2409   - "task tag 0x%x, target transfer tag 0x%x",
2410   - bhssc->bhssc_initiator_task_tag, target_transfer_tag);
  2423 + CFISCSI_SESSION_DEBUG(cs, "expecting Data-Out with initiator "
  2424 + "task tag 0x%x, target transfer tag 0x%x",
  2425 + bhssc->bhssc_initiator_task_tag, target_transfer_tag);
2411 2426 #endif
2412   - cdw = uma_zalloc(cfiscsi_data_wait_zone, M_NOWAIT | M_ZERO);
2413   - if (cdw == NULL) {
2414   - CFISCSI_SESSION_WARN(cs, "failed to "
2415   - "allocate memory; dropping connection");
2416   - icl_pdu_free(request);
2417   - cfiscsi_session_terminate(cs);
  2427 + cdw = uma_zalloc(cfiscsi_data_wait_zone, M_NOWAIT | M_ZERO);
  2428 + if (cdw == NULL) {
  2429 + CFISCSI_SESSION_WARN(cs, "failed to "
  2430 + "allocate memory; dropping connection");
  2431 + icl_pdu_free(request);
  2432 + cfiscsi_session_terminate(cs);
  2433 + }
  2434 + cdw->cdw_ctl_io = io;
  2435 + cdw->cdw_target_transfer_tag = htonl(target_transfer_tag);
  2436 + cdw->cdw_initiator_task_tag = bhssc->bhssc_initiator_task_tag;
  2437 +
  2438 + if (cs->cs_immediate_data && icl_pdu_data_segment_length(request) > 0) {
  2439 + done = cfiscsi_handle_data_segment(request, cdw);
  2440 + if (done) {
  2441 + uma_zfree(cfiscsi_data_wait_zone, cdw);
  2442 + io->scsiio.be_move_done(io);
  2443 + return;
2418 2444 }
2419   - cdw->cdw_ctl_io = io;
2420   - cdw->cdw_target_transfer_tag = htonl(target_transfer_tag);
2421   - cdw->cdw_initiator_task_tag = bhssc->bhssc_initiator_task_tag;
2422   -
2423   - if (cs->cs_immediate_data &&
2424   - icl_pdu_data_segment_length(request) > 0) {
2425   - done = cfiscsi_handle_data_segment(request, cdw);
2426   - if (done) {
2427   - uma_zfree(cfiscsi_data_wait_zone, cdw);
2428   - io->scsiio.be_move_done(io);
2429   - return;
2430   - }
2431 2445
2432 2446 #if 0
2433   - if (io->scsiio.ext_data_filled != 0)
2434   - CFISCSI_SESSION_DEBUG(cs, "got %zd bytes of immediate data, need %zd",
2435   - io->scsiio.ext_data_filled, io->scsiio.kern_data_len);
  2447 + if (io->scsiio.ext_data_filled != 0)
  2448 + CFISCSI_SESSION_DEBUG(cs, "got %zd bytes of immediate data, need %zd",
  2449 + io->scsiio.ext_data_filled, io->scsiio.kern_data_len);
2436 2450 #endif
2437   - }
  2451 + }
2438 2452
2439   - CFISCSI_SESSION_LOCK(cs);
2440   - TAILQ_INSERT_TAIL(&cs->cs_waiting_for_data_out, cdw, cdw_next);
2441   - CFISCSI_SESSION_UNLOCK(cs);
  2453 + CFISCSI_SESSION_LOCK(cs);
  2454 + TAILQ_INSERT_TAIL(&cs->cs_waiting_for_data_out, cdw, cdw_next);
  2455 + CFISCSI_SESSION_UNLOCK(cs);
2442 2456
2443   - /*
2444   - * XXX: We should limit the number of outstanding R2T PDUs
2445   - * per task to MaxOutstandingR2T.
2446   - */
2447   - response = cfiscsi_pdu_new_response(request, M_NOWAIT);
2448   - if (response == NULL) {
2449   - CFISCSI_SESSION_WARN(cs, "failed to "
2450   - "allocate memory; dropping connection");
2451   - icl_pdu_free(request);
2452   - cfiscsi_session_terminate(cs);
2453   - }
2454   - bhsr2t = (struct iscsi_bhs_r2t *)response->ip_bhs;
2455   - bhsr2t->bhsr2t_opcode = ISCSI_BHS_OPCODE_R2T;
2456   - bhsr2t->bhsr2t_flags = 0x80;
2457   - bhsr2t->bhsr2t_lun = bhssc->bhssc_lun;
2458   - bhsr2t->bhsr2t_initiator_task_tag =
2459   - bhssc->bhssc_initiator_task_tag;
2460   - bhsr2t->bhsr2t_target_transfer_tag =
2461   - htonl(target_transfer_tag);
2462   - /*
2463   - * XXX: Here we assume that cfiscsi_datamove() won't ever
2464   - * be running concurrently on several CPUs for a given
2465   - * command.
2466   - */
2467   - bhsr2t->bhsr2t_r2tsn = htonl(PDU_R2TSN(request));
2468   - PDU_R2TSN(request)++;
2469   - /*
2470   - * This is the offset within the current SCSI command;
2471   - * i.e. for the first call of datamove(), it will be 0,
2472   - * and for subsequent ones it will be the sum of lengths
2473   - * of previous ones.
2474   - *
2475   - * The ext_data_filled is to account for unsolicited
2476   - * (immediate) data that might have already arrived.
2477   - */
2478   - bhsr2t->bhsr2t_buffer_offset =
2479   - htonl(io->scsiio.kern_rel_offset + io->scsiio.ext_data_filled);
2480   - /*
2481   - * This is the total length (sum of S/G lengths) this call
2482   - * to cfiscsi_datamove() is supposed to handle.
2483   - *
2484   - * XXX: Limit it to MaxBurstLength.
2485   - */
2486   - bhsr2t->bhsr2t_desired_data_transfer_length =
2487   - htonl(io->scsiio.kern_data_len - io->scsiio.ext_data_filled);
2488   - cfiscsi_pdu_queue(response);
  2457 + /*
  2458 + * XXX: We should limit the number of outstanding R2T PDUs
  2459 + * per task to MaxOutstandingR2T.
  2460 + */
  2461 + response = cfiscsi_pdu_new_response(request, M_NOWAIT);
  2462 + if (response == NULL) {
  2463 + CFISCSI_SESSION_WARN(cs, "failed to "
  2464 + "allocate memory; dropping connection");
  2465 + icl_pdu_free(request);
  2466 + cfiscsi_session_terminate(cs);
2489 2467 }
  2468 + bhsr2t = (struct iscsi_bhs_r2t *)response->ip_bhs;
  2469 + bhsr2t->bhsr2t_opcode = ISCSI_BHS_OPCODE_R2T;
  2470 + bhsr2t->bhsr2t_flags = 0x80;
  2471 + bhsr2t->bhsr2t_lun = bhssc->bhssc_lun;
  2472 + bhsr2t->bhsr2t_initiator_task_tag = bhssc->bhssc_initiator_task_tag;
  2473 + bhsr2t->bhsr2t_target_transfer_tag = htonl(target_transfer_tag);
  2474 + /*
  2475 + * XXX: Here we assume that cfiscsi_datamove() won't ever
  2476 + * be running concurrently on several CPUs for a given
  2477 + * command.
  2478 + */
  2479 + bhsr2t->bhsr2t_r2tsn = htonl(PDU_R2TSN(request));
  2480 + PDU_R2TSN(request)++;
  2481 + /*
  2482 + * This is the offset within the current SCSI command;
  2483 + * i.e. for the first call of datamove(), it will be 0,
  2484 + * and for subsequent ones it will be the sum of lengths
  2485 + * of previous ones.
  2486 + *
  2487 + * The ext_data_filled is to account for unsolicited
  2488 + * (immediate) data that might have already arrived.
  2489 + */
  2490 + bhsr2t->bhsr2t_buffer_offset =
  2491 + htonl(io->scsiio.kern_rel_offset + io->scsiio.ext_data_filled);
  2492 + /*
  2493 + * This is the total length (sum of S/G lengths) this call
  2494 + * to cfiscsi_datamove() is supposed to handle.
  2495 + *
  2496 + * XXX: Limit it to MaxBurstLength.
  2497 + */
  2498 + bhsr2t->bhsr2t_desired_data_transfer_length =
  2499 + htonl(io->scsiio.kern_data_len - io->scsiio.ext_data_filled);
  2500 + cfiscsi_pdu_queue(response);
  2501 +}
  2502 +
  2503 +static void
  2504 +cfiscsi_datamove(union ctl_io *io)
  2505 +{
  2506 +
  2507 + if ((io->io_hdr.flags & CTL_FLAG_DATA_MASK) == CTL_FLAG_DATA_IN)
  2508 + cfiscsi_datamove_in(io);
  2509 + else
  2510 + cfiscsi_datamove_out(io);
2490 2511 }
2491 2512
2492 2513 static void

0 comments on commit e19bd87

Please sign in to comment.
Something went wrong with that request. Please try again.