| 715 | } |
| 716 | |
| 717 | Errata |
| 718 | Span::loadDevice() |
| 719 | { |
| 720 | Errata zret; |
| 721 | int flags; |
| 722 | |
| 723 | flags = OPEN_RW_FLAG |
| 724 | #if defined(O_DIRECT) |
| 725 | | O_DIRECT |
| 726 | #endif |
| 727 | #if defined(O_DSYNC) |
| 728 | | O_DSYNC |
| 729 | #endif |
| 730 | ; |
| 731 | |
| 732 | ats_scoped_fd fd(!_path.empty() ? ::open(_path.c_str(), flags) : ats_scoped_fd()); |
| 733 | |
| 734 | if (fd.isValid()) { |
| 735 | if (ink_file_get_geometry(fd, _geometry)) { |
| 736 | off_t offset = ts::CacheSpan::OFFSET; |
| 737 | CacheStoreBlocks span_hdr_size(1); // default. |
| 738 | static const ssize_t BUFF_SIZE = CacheStoreBlocks::SCALE; // match default span_hdr_size |
| 739 | alignas(512) char buff[BUFF_SIZE]; |
| 740 | ssize_t n = pread(fd, buff, BUFF_SIZE, offset); |
| 741 | if (n >= BUFF_SIZE) { |
| 742 | ts::SpanHeader &span_hdr = reinterpret_cast<ts::SpanHeader &>(buff); |
| 743 | _base = round_up(offset); |
| 744 | // See if it looks valid |
| 745 | if (span_hdr.magic == ts::SpanHeader::MAGIC && span_hdr.num_diskvol_blks == span_hdr.num_used + span_hdr.num_free) { |
| 746 | int nspb = span_hdr.num_diskvol_blks; |
| 747 | span_hdr_size = round_up(sizeof(ts::SpanHeader) + (nspb - 1) * sizeof(ts::CacheStripeDescriptor)); |
| 748 | _header.reset(new (malloc(span_hdr_size)) ts::SpanHeader); |
| 749 | if (span_hdr_size <= BUFF_SIZE) { |
| 750 | memcpy(static_cast<void *>(_header.get()), buff, span_hdr_size); |
| 751 | } else { |
| 752 | // TODO - check the pread return |
| 753 | ssize_t n = pread(fd, _header.get(), span_hdr_size, offset); |
| 754 | if (n < span_hdr_size) { |
| 755 | std::cout << "Failed to read the Span Header" << std::endl; |
| 756 | } |
| 757 | } |
| 758 | _len = _header->num_blocks; |
| 759 | } else { |
| 760 | zret.note("{} header is uninitialized or invalid", _path); |
| 761 | std::cout << "Span: " << _path.string() << " header is uninitialized or invalid" << std::endl; |
| 762 | _len = round_down(_geometry.totalsz) - _base; |
| 763 | } |
| 764 | // valid FD means the device is accessible and has enough storage to be configured. |
| 765 | _fd = fd.release(); |
| 766 | _offset = _base + span_hdr_size; |
| 767 | } else { |
| 768 | zret = Errata(make_errno_code(), "Failed to read from {}", _path); |
| 769 | } |
| 770 | } else { |
| 771 | zret = Errata("Unable to get device geometry for {}", _path); |
| 772 | } |
| 773 | } else { |
| 774 | zret = Errata(make_errno_code(), "Unable to open {}", _path); |
no test coverage detected