| 93 | } |
| 94 | |
| 95 | ssize_t ICacheStore::pwritev2(const struct iovec* iov, int iovcnt, off_t offset, int flags) |
| 96 | { |
| 97 | if ((open_flags_&(O_WRITE_THROUGH|O_CACHE_ONLY|O_WRITE_BACK)) || |
| 98 | (flags&(RW_V2_CACHE_ONLY|RW_V2_WRITE_BACK))) { |
| 99 | return pwritev2_extend(iov, iovcnt, offset, flags); |
| 100 | } |
| 101 | |
| 102 | iovector_view view(const_cast<struct iovec*>(iov), iovcnt); |
| 103 | size_t size = view.sum(); |
| 104 | if (offset >= actual_size_ || offset + static_cast<off_t>(size) > actual_size_) { |
| 105 | if (tryget_size() != 0) { |
| 106 | LOG_ERROR_RETURN(0, -1, |
| 107 | "try get size failed, actual_size_ : `, offset : `, count : `", |
| 108 | actual_size_, offset, size); |
| 109 | } |
| 110 | } |
| 111 | |
| 112 | off_t actual_size = actual_size_; |
| 113 | if (offset >= actual_size) return 0; |
| 114 | if (offset % page_size_ != 0 || (size % page_size_ != 0 && offset + static_cast<off_t>(size) < actual_size)) { |
| 115 | LOG_ERROR_RETURN(EINVAL, -1, |
| 116 | "size or offset is not aligned to `, size : `, offset : `", page_size_, size, offset); |
| 117 | } |
| 118 | |
| 119 | if (offset + static_cast<off_t>(size) <= actual_size) { |
| 120 | return do_pwritev2(iov, iovcnt, offset, flags); |
| 121 | } |
| 122 | |
| 123 | IOVector io_vector(iov, iovcnt); |
| 124 | if (offset + static_cast<off_t>(size) > actual_size) { |
| 125 | auto ret = io_vector.extract_back(size - (actual_size - offset)); |
| 126 | if (ret != size - (actual_size - offset)) |
| 127 | LOG_ERRNO_RETURN(EINVAL, -1, |
| 128 | "extract failed, extractSize : `, expected : ", ret, size - (actual_size - offset)) |
| 129 | } |
| 130 | |
| 131 | auto write = do_pwritev2(io_vector.iovec(), io_vector.iovcnt(), offset, flags); |
| 132 | if (write != static_cast<ssize_t>(io_vector.sum())) { |
| 133 | if (ENOSPC != errno) |
| 134 | LOG_ERROR("cache file write failed : `, error : `, actual_size : `, offset : `, sum : `", |
| 135 | write, ERRNO(errno), actual_size, offset, io_vector.sum()); |
| 136 | } |
| 137 | |
| 138 | return write; |
| 139 | } |
| 140 | |
| 141 | ssize_t ICacheStore::try_refill_range(off_t offset, size_t count) { |
| 142 | if (offset >= actual_size_ || offset + count > (size_t)actual_size_) { |
no test coverage detected