MCPcopy Create free account
hub / github.com/alibaba/PhotonLibOS / pwritev2_mutable

Method pwritev2_mutable

fs/aligned-file.cpp:192–265  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

190 return this->pwritev2_mutable(iovec.iovec(), iovec.iovcnt(), offset, flags);
191 }
192 virtual ssize_t pwritev2_mutable(struct iovec *iov, int iovcnt, off_t offset, int flags) override {
193 struct iovec tmpiovec[MAX_TMP_IOVEC_SIZE];
194 iovector_view view(tmpiovec, MAX_TMP_IOVEC_SIZE);
195 iovector_view buf(iov, iovcnt);
196 auto count = buf.sum();
197 if (count == 0) return 0;
198 range_split_power2 rs(offset, count, m_alignment);
199 if (rs.is_aligned() && (!m_align_memory || iov_align_check(buf)))
200 return m_file->pwritev2_mutable(iov, iovcnt, offset, flags);
201
202 struct stat stat;
203 m_file->fstat(&stat);
204 ssize_t filesize = stat.st_size;
205 auto suppose_filesize = (offset + (ssize_t)count) > filesize ? offset + count: filesize;
206 IOVector wbuf(m_allocator);
207 auto ret = wbuf.push_back(rs.aligned_length());
208 if (ret < rs.aligned_length())
209 LOG_ERROR_RETURN(0, -1, "Failed to allocate memory");
210
211 if (rs.begin_remainder > 0)
212 {
213 view.iovcnt = MAX_TMP_IOVEC_SIZE;
214 ssize_t ret = wbuf.slice(m_alignment, 0, &view);
215 assert(ret == m_alignment);
216 ssize_t off = rs.aligned_begin_offset();
217 ret = m_file->preadv2(view.iov, view.iovcnt, off, flags);
218 if ((ret < 0) || ((off + ret < filesize) && (ret < (ssize_t)m_alignment)))
219 LOG_ERRNO_RETURN(0, -1, "failed to aligned [`]->preadv2(iov=`, iovcnt=`, offset=`, flags=`) and patch the first alignment block",
220 m_file, view.iov, view.iovcnt, off, flags);
221 if (ret < (ssize_t)m_alignment) {
222 view.extract_front(ret);
223 for (auto &p : view) {
224 memset(p.iov_base, 0, p.iov_len);
225 }
226 }
227 }
228 if (!rs.small_note && rs.end_remainder > 0)
229 {
230 ssize_t off = rs.aligned_end_offset() - m_alignment; // this should never be negative
231 if (filesize - off > (ssize_t)(rs.end_remainder)) {
232 // that means there is still parts of data after the rear end of pwrite block
233 view.iovcnt = MAX_TMP_IOVEC_SIZE;
234 ssize_t ret = wbuf.slice(m_alignment, wbuf.sum() - m_alignment, &view);
235 assert(ret == m_alignment);
236 ret = m_file->preadv2(view.iov, view.iovcnt, off, flags);
237 if (ret < 0)
238 LOG_ERRNO_RETURN(0, -1, "failed to aligned [`]->preadv2(ptr=`, count=`, offset=`, flags=`)",
239 m_file, view.iov, view.iovcnt, off, flags);
240 if ((ret + off < filesize) && (ret < (ssize_t)m_alignment)) // cannot fetch all data of file, and cannot fillup aligned block
241 LOG_ERRNO_RETURN(0, -1, "aligned [`]->preadv2(ptr=`, count=`, offset=`, flags=`) partial read",
242 m_file, view.iov, view.iovcnt, off, flags);
243 }
244 }
245 view.iovcnt = MAX_TMP_IOVEC_SIZE;
246 ret = wbuf.slice(count, rs.begin_remainder, &view);
247 assert(ret == count);
248 ret = view.memcpy_from(&buf, count);
249 assert(ret == count);

Callers 2

pwritev_mutableMethod · 0.95
pwritev2Method · 0.95

Calls 14

sumMethod · 0.45
is_alignedMethod · 0.45
fstatMethod · 0.45
push_backMethod · 0.45
aligned_lengthMethod · 0.45
sliceMethod · 0.45
aligned_begin_offsetMethod · 0.45
preadv2Method · 0.45
extract_frontMethod · 0.45
aligned_end_offsetMethod · 0.45
memcpy_fromMethod · 0.45
iovecMethod · 0.45

Tested by

no test coverage detected