* The following method implements most of what _read_sync does, but in a * way that works with the non-blocking read path. */
| 11460 | * way that works with the non-blocking read path. |
| 11461 | */ |
| 11462 | void Client::C_Read_Sync_NonBlocking::finish(int r) |
| 11463 | { |
| 11464 | clnt->client_lock.lock(); |
| 11465 | |
| 11466 | auto effective_size = in->effective_size(); |
| 11467 | |
| 11468 | #if defined(__linux__) |
| 11469 | auto target_len = std::min(len, effective_size - off); |
| 11470 | bufferlist encbl; |
| 11471 | bufferlist *pbl = (fscrypt_denc ? &encbl : bl); |
| 11472 | #else |
| 11473 | bufferlist *pbl = bl; |
| 11474 | #endif |
| 11475 | if (r == -ENOENT) { |
| 11476 | // if we get ENOENT from OSD, assume 0 bytes returned |
| 11477 | r = 0; |
| 11478 | } else if (r < 0) { |
| 11479 | // pass error to caller |
| 11480 | goto error; |
| 11481 | } |
| 11482 | |
| 11483 | if (tbl.length()) { |
| 11484 | r = tbl.length(); |
| 11485 | |
| 11486 | read += r; |
| 11487 | pos += r; |
| 11488 | left -= r; |
| 11489 | pbl->claim_append(tbl); |
| 11490 | } |
| 11491 | |
| 11492 | // short read? |
| 11493 | if (r >= 0 && r < wanted) { |
| 11494 | if (pos < effective_size) { |
| 11495 | // zero up to known EOF |
| 11496 | int64_t some = effective_size - pos; |
| 11497 | if (some > left) |
| 11498 | some = left; |
| 11499 | auto z = buffer::ptr_node::create(some); |
| 11500 | z->zero(); |
| 11501 | pbl->push_back(std::move(z)); |
| 11502 | read += some; |
| 11503 | pos += some; |
| 11504 | left -= some; |
| 11505 | if (left == 0) |
| 11506 | goto success; |
| 11507 | } |
| 11508 | |
| 11509 | // reverify size |
| 11510 | { |
| 11511 | r = clnt->_getattr(in, CEPH_STAT_CAP_SIZE, f->actor_perms); |
| 11512 | if (r < 0) |
| 11513 | goto error; |
| 11514 | } |
| 11515 | |
| 11516 | // eof? short read. |
| 11517 | if ((uint64_t)pos >= effective_size) |
| 11518 | goto success; |
| 11519 |
no test coverage detected