err_t sys_pwritev(fd_t fd, const struct iovec* iov, int iovcnt, off_t seek_to_offset, ssize_t* num_written_out) { ssize_t got; ssize_t got_total; err_t err_out; int i; int niovs = IOV_MAX; STARTING_SLOW_SYSCALL; err_out = 0; got_total = 0; for( i = 0; i < iovcnt; i += niovs ) { niovs = iovcnt - i; if( niovs > IOV_MAX ) niovs = IOV_MAX; // Some systems pwritev doesn't take a const struct iovec*, hence the cast got = pwritev(fd, (struct iovec*) &iov[i], niovs, seek_to_offset + got_total); if( got != -1 ) { got_total += got; } else { err_out = errno; break; } if( got != sys_iov_total_bytes(&iov[i], niovs) ) { break; } } *num_written_out = got_total; DONE_SLOW_SYSCALL; return err_out; }
int lgfs2_sb_write(const struct gfs2_sb *sb, int fd, const unsigned bsize) { int i, err = -1; struct iovec *iov; const size_t sb_addr = GFS2_SB_ADDR * GFS2_BASIC_BLOCK / bsize; const size_t len = sb_addr + 1; /* We only need 2 blocks: one for zeroing and a second for the superblock */ char *buf = calloc(2, bsize); if (buf == NULL) return -1; iov = malloc(len * sizeof(*iov)); if (iov == NULL) goto out_buf; for (i = 0; i < len; i++) { iov[i].iov_base = buf; iov[i].iov_len = bsize; } gfs2_sb_out(sb, buf + bsize); iov[sb_addr].iov_base = buf + bsize; if (pwritev(fd, iov, len, 0) < (len * bsize)) goto out_iov; err = 0; out_iov: free(iov); out_buf: free(buf); return err; }
tb_long_t tb_file_pwritv(tb_file_ref_t file, tb_iovec_t const* list, tb_size_t size, tb_hize_t offset) { // check tb_assert_and_check_return_val(file && list && size, -1); // check iovec tb_assert_static(sizeof(tb_iovec_t) == sizeof(struct iovec)); tb_assert(tb_memberof_eq(tb_iovec_t, data, struct iovec, iov_base)); tb_assert(tb_memberof_eq(tb_iovec_t, size, struct iovec, iov_len)); // writ it #ifdef TB_CONFIG_POSIX_HAVE_PWRITEV return pwritev(tb_file2fd(file), (struct iovec const*)list, size, offset); #else // FIXME: lock it // save offset tb_hong_t current = tb_file_offset(file); tb_assert_and_check_return_val(current >= 0, -1); // seek it if (current != offset && tb_file_seek(file, offset, TB_FILE_SEEK_BEG) != offset) return -1; // writ it tb_long_t real = tb_file_writv(file, list, size); // restore offset if (current != offset && tb_file_seek(file, current, TB_FILE_SEEK_BEG) != current) return -1; // ok return real; #endif }
static void blockif_proc(struct blockif_ctxt *bc, struct blockif_elem *be) { struct blockif_req *br; int err; br = be->be_req; err = 0; switch (be->be_op) { case BOP_READ: if (preadv(bc->bc_fd, br->br_iov, br->br_iovcnt, br->br_offset) < 0) err = errno; break; case BOP_WRITE: if (bc->bc_rdonly) err = EROFS; else if (pwritev(bc->bc_fd, br->br_iov, br->br_iovcnt, br->br_offset) < 0) err = errno; break; case BOP_FLUSH: break; case BOP_CANCEL: err = EINTR; break; default: err = EINVAL; break; } (*br->br_callback)(br, err); }
void test_pwritev(char *path) { int fd; off_t off = 10; char *str0 = "Lind"; char *str1 = "pwritev () test \n"; struct iovec iov[2]; if ((fd = open(path, O_WRONLY)) < 0){ fprintf(stderr,"open64(%s) error \n", path); return; } iov[0].iov_base = str0; iov[0].iov_len = strlen(str0); iov[1].iov_base = str1; iov[1].iov_len = strlen(str1); ssize_t nwritten = pwritev(fd, iov, 2, off); fprintf(stdout, "nwritten = %d", (int) nwritten); if (close(fd)!= 0){ fprintf(stderr, "close() error \n"); return; } }
static ssize_t local_pwritev(FsContext *ctx, V9fsFidOpenState *fs, const struct iovec *iov, int iovcnt, off_t offset) { ssize_t ret ; #ifdef CONFIG_PREADV ret = pwritev(fs->fd, iov, iovcnt, offset); #else int err = lseek(fs->fd, offset, SEEK_SET); if (err == -1) { return err; } else { ret = writev(fs->fd, iov, iovcnt); } #endif #ifdef CONFIG_SYNC_FILE_RANGE if (ret > 0 && ctx->export_flags & V9FS_IMMEDIATE_WRITEOUT) { /* * Initiate a writeback. This is not a data integrity sync. * We want to ensure that we don't leave dirty pages in the cache * after write when writeout=immediate is sepcified. */ sync_file_range(fs->fd, offset, ret, SYNC_FILE_RANGE_WAIT_BEFORE | SYNC_FILE_RANGE_WRITE); } #endif return ret; }
int BufferList::write_fd(int fd, uint64_t offset){ ssize_t wrote; wrote = pwritev( fd, _buffers, _index, offset ); if (wrote < _total_bytes) { return errno; } }
static int do_pwritev( int fd, off64_t offset, ssize_t count, ssize_t buffer_size) { int vecs = 0; ssize_t oldlen = 0; ssize_t bytes = 0; /* trim the iovec if necessary */ if (count < buffersize) { size_t len = 0; while (len + iov[vecs].iov_len < count) { len += iov[vecs].iov_len; vecs++; } oldlen = iov[vecs].iov_len; iov[vecs].iov_len = count - len; vecs++; } else { vecs = vectors; } bytes = pwritev(fd, iov, vectors, offset); /* restore trimmed iov */ if (oldlen) iov[vecs - 1].iov_len = oldlen; return bytes; }
static ssize_t uv__fs_write(uv_fs_t* req) { #if defined(__linux__) static int no_pwritev; #endif ssize_t r; /* Serialize writes on OS X, concurrent write() and pwrite() calls result in * data loss. We can't use a per-file descriptor lock, the descriptor may be * a dup(). */ #if defined(__APPLE__) static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; if (pthread_mutex_lock(&lock)) abort(); #endif if (req->off < 0) { if (req->nbufs == 1) r = write(req->file, req->bufs[0].base, req->bufs[0].len); else r = writev(req->file, (struct iovec*) req->bufs, req->nbufs); } else { if (req->nbufs == 1) { r = pwrite(req->file, req->bufs[0].base, req->bufs[0].len, req->off); goto done; } #if HAVE_PREADV r = pwritev(req->file, (struct iovec*) req->bufs, req->nbufs, req->off); #else # if defined(__linux__) if (no_pwritev) retry: # endif { r = pwrite(req->file, req->bufs[0].base, req->bufs[0].len, req->off); } # if defined(__linux__) else { r = uv__pwritev(req->file, (struct iovec*) req->bufs, req->nbufs, req->off); if (r == -1 && errno == ENOSYS) { no_pwritev = 1; goto retry; } } # endif #endif } done: #if defined(__APPLE__) if (pthread_mutex_unlock(&lock)) abort(); #endif return r; }
static ssize_t pwritev_wrapper(int d, const void *buf, size_t nbytes) { struct iovec iov; iov.iov_base = (void *)buf; iov.iov_len = nbytes; return (pwritev(d, &iov, 1, 0)); }
Sint64 efile_pwritev(efile_data_t *d, Sint64 offset, SysIOVec *iov, int iovlen) { efile_unix_t *u = (efile_unix_t*)d; Sint64 bytes_written; ssize_t result; #if !defined(HAVE_PWRITEV) && !defined(HAVE_PWRITE) off_t original_position = lseek(u->fd, 0, SEEK_CUR); if(original_position < 0 || lseek(u->fd, offset, SEEK_SET) < 0) { u->common.posix_errno = errno; return -1; } #endif bytes_written = 0; do { if(iovlen < 1) { result = 0; break; } #if defined(HAVE_PWRITEV) result = pwritev(u->fd, iov, MIN(IOV_MAX, iovlen), offset); #elif defined(HAVE_PWRITE) result = pwrite(u->fd, iov->iov_base, iov->iov_len, offset); #else result = write(u->fd, iov->iov_base, iov->iov_len); #endif if(result > 0) { shift_iov(&iov, &iovlen, result); bytes_written += result; offset += result; } } while(result > 0 || (result < 0 && errno == EINTR)); u->common.posix_errno = errno; #if !defined(HAVE_PWRITEV) && !defined(HAVE_PWRITE) if(result >= 0) { if(lseek(u->fd, original_position, SEEK_SET) < 0) { u->common.posix_errno = errno; return -1; } } #endif if(result == 0 && bytes_written > 0) { return bytes_written; } return result; }
int bwrite(struct gfs2_buffer_head *bh) { struct gfs2_sbd *sdp = bh->sdp; if (pwritev(sdp->device_fd, &bh->iov, 1, bh->b_blocknr * sdp->bsize) != bh->iov.iov_len) return -1; sdp->writes++; bh->b_modified = 0; return 0; }
/* Same as pwritev(2) except that this function never returns EAGAIN or EINTR. */ ssize_t xpwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset) { ssize_t nr; restart: nr = pwritev(fd, iov, iovcnt, offset); if ((nr < 0) && ((errno == EAGAIN) || (errno == EINTR))) goto restart; return nr; }
int file_write(int fd, void *buf, size_t sz) { struct iovec iov[1]; ssize_t ret; iov[0].iov_base = buf; iov[0].iov_len = sz; ret = IGNORE_EINTR (pwritev (fd, iov, 1, 0)); if (ret != sz) { return -1; } return 0; }
static ssize_t local_pwritev(FsContext *ctx, int fd, const struct iovec *iov, int iovcnt, off_t offset) { #ifdef CONFIG_PREADV return pwritev(fd, iov, iovcnt, offset); #else int err = lseek(fd, offset, SEEK_SET); if (err == -1) { return err; } else { return writev(fd, iov, iovcnt); } #endif }
void verify_pwritev(struct test_case_t *tc) { TEST(pwritev(fd, tc->name, tc->count, tc->offset)); if (TEST_RETURN == 0) { tst_resm(TFAIL, "pwritev(2) succeed unexpectedly"); } else { if (TEST_ERRNO == EINVAL) { tst_resm(TPASS | TTERRNO, "pwritev(2) fails as expected"); } else { tst_resm(TFAIL | TTERRNO, "pwritev(2) fails unexpectedly," " expected errno is EINVAL"); } } }
int main(void) { tprintf("%s", ""); static char tmp[] = "preadv-pwritev-tmpfile"; if (open(tmp, O_CREAT|O_RDONLY|O_TRUNC, 0600) != 0) perror_msg_and_fail("creat: %s", tmp); if (open(tmp, O_WRONLY) != 1) perror_msg_and_fail("open: %s", tmp); if (unlink(tmp)) perror_msg_and_fail("unlink: %s", tmp); static const char w0_c[] = "012"; const char *w0_d = hexdump_strdup(w0_c); void *w0 = tail_memdup(w0_c, LENGTH_OF(w0_c)); const void *efault = w0 + LENGTH_OF(w0_c); static const char w1_c[] = "34567"; const char *w1_d = hexdump_strdup(w1_c); void *w1 = tail_memdup(w1_c, LENGTH_OF(w1_c)); static const char w2_c[] = "89abcde"; const char *w2_d = hexdump_strdup(w2_c); void *w2 = tail_memdup(w2_c, LENGTH_OF(w2_c)); long rc; rc = pwritev(1, efault, 42, 0); tprintf("pwritev(1, %p, 42, 0) = %ld %s (%m)\n", efault, rc, errno2name()); rc = preadv(0, efault, 42, 0); tprintf("preadv(0, %p, 42, 0) = %ld %s (%m)\n", efault, rc, errno2name()); static const char r0_c[] = "01234567"; const char *r0_d = hexdump_strdup(r0_c); static const char r1_c[] = "89abcde"; const char *r1_d = hexdump_strdup(r1_c); const struct iovec w_iov_[] = { { .iov_base = w0, .iov_len = LENGTH_OF(w0_c) }, { .iov_base = w1,
int main() { int fd = open("/tmp/x", O_CREAT | O_RDWR, 0666); assert(fd > 0); write(fd, "hello", 5); pwrite(fd, "world", 5, 4); struct iovec x[3]; x[0].iov_base = "aaa"; x[0].iov_len = 3; x[1].iov_base = "bbb"; x[1].iov_len = 3; x[2].iov_base = "ccc"; x[2].iov_len = 3; writev(fd, x, 3); x[0].iov_base = "xxx"; x[1].iov_base = "yyy"; x[2].iov_base = "zzz"; pwritev(fd, x, 3, 10); }
void pfl_odt_write(struct pfl_odt *t, const void *p, struct pfl_odt_slotftr *f, int64_t item) { ssize_t expect = 0; struct pfl_odt_hdr *h; struct iovec iov[3]; ssize_t rc, pad; int nio = 0; off_t off; memset(iov, 0, sizeof(iov)); h = t->odt_hdr; pad = h->odth_slotsz - h->odth_itemsz - sizeof(*f); pfl_assert(!pad); pfl_odt_zerobuf_ensurelen(pad); off = item * h->odth_slotsz + h->odth_start; if (p) PACK_IOV(p, h->odth_itemsz); else off += h->odth_itemsz; if (p && f) PACK_IOV(pfl_odt_zerobuf, pad); else off += pad; if (f) PACK_IOV(f, sizeof(*f)); rc = pwritev(t->odt_fd, iov, nio, off); pfl_assert(rc == expect); }
static void do_test(int (*opener)(int)) { pid_t child; int fd; int status; int pipe_fds[2]; struct iovec iov[2]; test_assert(0 == pipe(pipe_fds)); child = fork(); if (!child) { char ch; test_assert(1 == read(pipe_fds[0], &ch, 1)); test_assert(COOKIE == cookie1); test_assert(COOKIE == cookie2); test_assert(COOKIE == cookie3); exit(77); } fd = opener(child); test_assert(fd >= 0); test_assert(sizeof(COOKIE) == pwrite(fd, &COOKIE, sizeof(COOKIE), (off_t)&cookie1)); iov[0].iov_base = (char*)&COOKIE; iov[0].iov_len = 2; iov[1].iov_base = (char*)&COOKIE + 2; iov[1].iov_len = 2; test_assert(sizeof(COOKIE) == pwritev(fd, iov, 2, (off_t)&cookie2)); lseek(fd, (off_t)&cookie3, SEEK_SET); test_assert(sizeof(COOKIE) == write(fd, &COOKIE, sizeof(COOKIE))); test_assert(1 == write(pipe_fds[1], "x", 1)); test_assert(child == waitpid(child, &status, 0)); test_assert(WIFEXITED(status) && WEXITSTATUS(status) == 77); }
static int fio_pvsyncio_queue(struct thread_data *td, struct io_u *io_u) { struct syncio_data *sd = td->io_ops->data; struct iovec *iov = &sd->iovecs[0]; struct fio_file *f = io_u->file; int ret; fio_ro_check(td, io_u); iov->iov_base = io_u->xfer_buf; iov->iov_len = io_u->xfer_buflen; if (io_u->ddir == DDIR_READ) ret = preadv(f->fd, iov, 1, io_u->offset); else if (io_u->ddir == DDIR_WRITE) ret = pwritev(f->fd, iov, 1, io_u->offset); else if (io_u->ddir == DDIR_TRIM) { do_io_u_trim(td, io_u); return FIO_Q_COMPLETED; } else ret = do_io_u_sync(td, io_u); return fio_io_end(td, io_u, ret); }
static ssize_t uv__fs_write(uv_fs_t* req) { ssize_t r; /* Serialize writes on OS X, concurrent write() and pwrite() calls result in * data loss. We can't use a per-file descriptor lock, the descriptor may be * a dup(). */ #if defined(__APPLE__) static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_lock(&lock); #endif if (req->off < 0) { if (req->nbufs == 1) r = write(req->file, req->bufs[0].base, req->bufs[0].len); else r = writev(req->file, (struct iovec*) req->bufs, req->nbufs); } else { if (req->nbufs == 1) { r = pwrite(req->file, req->bufs[0].base, req->bufs[0].len, req->off); goto done; } #if HAVE_PREADV r = pwritev(req->file, (struct iovec*) req->bufs, req->nbufs, req->off); #else # if defined(__linux__) static int no_pwritev; if (no_pwritev) # endif { off_t written; size_t index; # if defined(__linux__) retry: # endif written = 0; index = 0; r = 0; do { if (req->bufs[index].len > 0) { r = pwrite(req->file, req->bufs[index].base, req->bufs[index].len, req->off + written); if (r > 0) written += r; } index++; } while (index < req->nbufs && r >= 0); if (written > 0) r = written; } # if defined(__linux__) else { r = uv__pwritev(req->file, (struct iovec*) req->bufs, req->nbufs, req->off); if (r == -1 && errno == ENOSYS) { no_pwritev = 1; goto retry; } } # endif #endif } done: #if defined(__APPLE__) pthread_mutex_unlock(&lock); #endif if (req->bufs != req->bufsml) free(req->bufs); return r; }
int main(void) { (void) close(0); if (open("/dev/null", O_WRONLY)) perror_msg_and_fail("open"); char *buf = tail_alloc(LEN); unsigned i; for (i = 0; i < LEN; ++i) buf[i] = i; struct iovec *iov = tail_alloc(sizeof(*iov) * LEN); for (i = 0; i < LEN; ++i) { buf[i] = i; iov[i].iov_base = &buf[i]; iov[i].iov_len = LEN - i; } const off_t offset = 0xdefaceddeadbeefLL; long rc; int written = 0; for (i = 0; i < LEN; ++i) { written += iov[i].iov_len; if (pwritev(0, iov, i + 1, offset + i) != written) perror_msg_and_fail("pwritev"); fputs("pwritev(0, ", stdout); print_iovec(iov, i + 1, LEN); printf(", %u, %lld) = %d\n", i + 1, (long long) offset + i, written); } for (i = 0; i <= LEN; ++i) { unsigned int n = LEN + 1 - i; fputs("pwritev(0, ", stdout); print_iovec(iov + i, n, LEN - i); rc = pwritev(0, iov + i, n, offset + LEN + i); printf(", %u, %lld) = %ld %s (%m)\n", n, (long long) offset + LEN + i, rc, errno2name()); } iov->iov_base = iov + LEN * 2; rc = pwritev(0, iov, 1, -1); printf("pwritev(0, [{%p, %d}], 1, -1) = %ld %s (%m)\n", iov->iov_base, LEN, rc, errno2name()); iov += LEN; rc = pwritev(0, iov, 42, -2); printf("pwritev(0, %p, 42, -2) = %ld %s (%m)\n", iov, rc, errno2name()); rc = pwritev(0, NULL, 1, -3); printf("pwritev(0, NULL, 1, -3) = %ld %s (%m)\n", rc, errno2name()); rc = pwritev(0, iov, 0, -4); printf("pwritev(0, [], 0, -4) = %ld %s (%m)\n", rc, errno2name()); puts("+++ exited with 0 +++"); return 0; }
ssize_t pwritev64(int fd, const struct iovec *iov, int iovcnt,off_t offset) { return pwritev(fd,iov,iovcnt,offset); }
static ssize_t qemu_pwritev(int fd, const struct iovec *iov, int nr_iov, off_t offset) { return pwritev(fd, iov, nr_iov, offset); }
static void pci_vtblk_proc(struct pci_vtblk_softc *sc, struct vqueue_info *vq) { struct virtio_blk_hdr *vbh; uint8_t *status; int i, n; int err; int iolen; int writeop, type; off_t offset; struct iovec iov[VTBLK_MAXSEGS + 2]; uint16_t flags[VTBLK_MAXSEGS + 2]; n = vq_getchain(vq, iov, VTBLK_MAXSEGS + 2, flags); /* * The first descriptor will be the read-only fixed header, * and the last is for status (hence +2 above and below). * The remaining iov's are the actual data I/O vectors. * * XXX - note - this fails on crash dump, which does a * VIRTIO_BLK_T_FLUSH with a zero transfer length */ assert(n >= 2 && n <= VTBLK_MAXSEGS + 2); assert((flags[0] & VRING_DESC_F_WRITE) == 0); assert(iov[0].iov_len == sizeof(struct virtio_blk_hdr)); vbh = iov[0].iov_base; status = iov[--n].iov_base; assert(iov[n].iov_len == 1); assert(flags[n] & VRING_DESC_F_WRITE); /* * XXX * The guest should not be setting the BARRIER flag because * we don't advertise the capability. */ type = vbh->vbh_type & ~VBH_FLAG_BARRIER; writeop = (type == VBH_OP_WRITE); offset = vbh->vbh_sector * DEV_BSIZE; iolen = 0; for (i = 1; i < n; i++) { /* * - write op implies read-only descriptor, * - read/ident op implies write-only descriptor, * therefore test the inverse of the descriptor bit * to the op. */ assert(((flags[i] & VRING_DESC_F_WRITE) == 0) == writeop); iolen += iov[i].iov_len; } DPRINTF(("virtio-block: %s op, %d bytes, %d segs, offset %ld\n\r", writeop ? "write" : "read/ident", iolen, i - 1, offset)); switch (type) { case VBH_OP_WRITE: err = pwritev(sc->vbsc_fd, iov + 1, i - 1, offset); break; case VBH_OP_READ: err = preadv(sc->vbsc_fd, iov + 1, i - 1, offset); break; case VBH_OP_IDENT: /* Assume a single buffer */ strlcpy(iov[1].iov_base, sc->vbsc_ident, MIN(iov[1].iov_len, sizeof(sc->vbsc_ident))); err = 0; break; case VBH_OP_FLUSH: case VBH_OP_FLUSH_OUT: err = fsync(sc->vbsc_fd); break; default: err = -ENOSYS; break; } /* convert errno into a virtio block error return */ if (err < 0) { if (err == -ENOSYS) *status = VTBLK_S_UNSUPP; else *status = VTBLK_S_IOERR; } else *status = VTBLK_S_OK; /* * Return the descriptor back to the host. * We wrote 1 byte (our status) to host. */ vq_relchain(vq, 1); }
const struct iovec w_iov_[] = { { .iov_base = w0, .iov_len = LENGTH_OF(w0_c) }, { .iov_base = w1, .iov_len = LENGTH_OF(w1_c) }, { .iov_base = w2, .iov_len = LENGTH_OF(w2_c) } }; const struct iovec *w_iov = tail_memdup(w_iov_, sizeof(w_iov_)); rc = pwritev(1, w_iov, 0, 0); if (rc) perror_msg_and_fail("pwritev: expected 0, returned %ld", rc); tprintf("pwritev(1, [], 0, 0) = 0\n"); rc = pwritev(1, w_iov + ARRAY_SIZE(w_iov_) - 1, 2, 0); tprintf("pwritev(1, [{\"%s\", %u}, %p], 2, 0) = %ld %s (%m)\n", w2_c, LENGTH_OF(w2_c), w_iov + ARRAY_SIZE(w_iov_), rc, errno2name()); const unsigned int w_len = LENGTH_OF(w0_c) + LENGTH_OF(w1_c) + LENGTH_OF(w2_c); rc = pwritev(1, w_iov, ARRAY_SIZE(w_iov_), 0); if (rc != (int) w_len) perror_msg_and_fail("pwritev: expected %u, returned %ld",
int main(int argc, char *argv[]) { sd_memfd *m; char *s, *name; uint64_t sz; int r, fd; FILE *f; char buf[3] = {}; struct iovec iov[3] = {}; char bufv[3][3] = {}; log_set_max_level(LOG_DEBUG); r = sd_memfd_new(NULL, &m); if (r == -ENOENT) return EXIT_TEST_SKIP; assert_se(r >= 0); assert_se(sd_memfd_get_name(m, &name) >= 0); log_info("name: %s", name); free(name); r = sd_memfd_map(m, 0, 12, (void**) &s); assert_se(r >= 0); strcpy(s, "----- world"); r = sd_memfd_set_sealed(m, 1); assert_se(r == -ETXTBSY); assert_se(write(sd_memfd_get_fd(m), "he", 2) == 2); assert_se(write(sd_memfd_get_fd(m), "XXX", 3) == 3); assert_se(streq(s, "heXXX world")); /* fix "hello" */ assert_se(lseek(sd_memfd_get_fd(m), 2, SEEK_SET) == 2); assert_se(write(sd_memfd_get_fd(m), "ll", 2) == 2); assert_se(sd_memfd_get_file(m, &f) >= 0); fputc('o', f); fflush(f); /* check content */ assert_se(streq(s, "hello world")); assert_se(munmap(s, 12) == 0); r = sd_memfd_get_sealed(m); assert_se(r == 0); r = sd_memfd_get_size(m, &sz); assert_se(r >= 0); assert_se(sz = page_size()); /* truncate it */ r = sd_memfd_set_size(m, 6); assert_se(r >= 0); /* get back new value */ r = sd_memfd_get_size(m, &sz); assert_se(r >= 0); assert_se(sz == 6); r = sd_memfd_set_sealed(m, 1); assert_se(r >= 0); r = sd_memfd_get_sealed(m); assert_se(r == 1); fd = sd_memfd_dup_fd(m); assert_se(fd >= 0); sd_memfd_free(m); /* new sd_memfd, same underlying memfd */ r = sd_memfd_make(fd, &m); assert_se(r >= 0); /* we did truncate it to 6 */ r = sd_memfd_get_size(m, &sz); assert_se(r >= 0 && sz == 6); /* map it, check content */ r = sd_memfd_map(m, 0, 12, (void **)&s); assert_se(r >= 0); /* we only see the truncated size */ assert_se(streq(s, "hello ")); /* it was already sealed */ r = sd_memfd_set_sealed(m, 1); assert_se(r == -EALREADY); /* we cannot break the seal, it is mapped */ r = sd_memfd_set_sealed(m, 0); assert_se(r == -ETXTBSY); /* unmap it; become the single owner */ assert_se(munmap(s, 12) == 0); /* now we can do flip the sealing */ r = sd_memfd_set_sealed(m, 0); assert_se(r == 0); r = sd_memfd_get_sealed(m); assert_se(r == 0); r = sd_memfd_set_sealed(m, 1); assert_se(r == 0); r = sd_memfd_get_sealed(m); assert_se(r == 1); r = sd_memfd_set_sealed(m, 0); assert_se(r == 0); r = sd_memfd_get_sealed(m); assert_se(r == 0); /* seek at 2, read() 2 bytes */ assert_se(lseek(fd, 2, SEEK_SET) == 2); assert_se(read(fd, buf, 2) == 2); /* check content */ assert_se(memcmp(buf, "ll", 2) == 0); /* writev it out*/ iov[0].iov_base = (char *)"ABC"; iov[0].iov_len = 3; iov[1].iov_base = (char *)"DEF"; iov[1].iov_len = 3; iov[2].iov_base = (char *)"GHI"; iov[2].iov_len = 3; assert_se(pwritev(fd, iov, 3, 0) == 9); /* readv it back */ iov[0].iov_base = bufv[0]; iov[0].iov_len = 3; iov[1].iov_base = bufv[1]; iov[1].iov_len = 3; iov[2].iov_base = bufv[2]; iov[2].iov_len = 3; assert_se(preadv(fd, iov, 3, 0) == 9); /* check content */ assert_se(memcmp(bufv[0], "ABC", 3) == 0); assert_se(memcmp(bufv[1], "DEF", 3) == 0); assert_se(memcmp(bufv[2], "GHI", 3) == 0); sd_memfd_free(m); return 0; }
static ssize_t ngx_writev_file(ngx_file_t *file, ngx_array_t *vec, size_t size, off_t offset) { ssize_t n; ngx_err_t err; ngx_log_debug3(NGX_LOG_DEBUG_CORE, file->log, 0, "writev: %d, %uz, %O", file->fd, size, offset); #if (NGX_HAVE_PWRITEV) eintr: n = pwritev(file->fd, vec->elts, vec->nelts, offset); if (n == -1) { err = ngx_errno; if (err == NGX_EINTR) { ngx_log_debug0(NGX_LOG_DEBUG_CORE, file->log, err, "pwritev() was interrupted"); goto eintr; } ngx_log_error(NGX_LOG_CRIT, file->log, err, "pwritev() \"%s\" failed", file->name.data); return NGX_ERROR; } if ((size_t) n != size) { ngx_log_error(NGX_LOG_CRIT, file->log, 0, "pwritev() \"%s\" has written only %z of %uz", file->name.data, n, size); return NGX_ERROR; } #else if (file->sys_offset != offset) { if (lseek(file->fd, offset, SEEK_SET) == -1) { ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "lseek() \"%s\" failed", file->name.data); return NGX_ERROR; } file->sys_offset = offset; } eintr: n = writev(file->fd, vec->elts, vec->nelts); if (n == -1) { err = ngx_errno; if (err == NGX_EINTR) { ngx_log_debug0(NGX_LOG_DEBUG_CORE, file->log, err, "writev() was interrupted"); goto eintr; } ngx_log_error(NGX_LOG_CRIT, file->log, err, "writev() \"%s\" failed", file->name.data); return NGX_ERROR; } if ((size_t) n != size) { ngx_log_error(NGX_LOG_CRIT, file->log, 0, "writev() \"%s\" has written only %z of %uz", file->name.data, n, size); return NGX_ERROR; } file->sys_offset += n; #endif file->offset += n; return n; }
ssize_t mca_fbtl_posix_pwritev(mca_io_ompio_file_t *fh ) { /*int *fp = NULL;*/ int i, block = 1, ret; struct iovec *iov = NULL; int iov_count = 0; OMPI_MPI_OFFSET_TYPE iov_offset = 0; ssize_t ret_code=0, bytes_written=0; struct flock lock; off_t total_length, end_offset=0; if (NULL == fh->f_io_array) { return OMPI_ERROR; } iov = (struct iovec *) malloc (OMPIO_IOVEC_INITIAL_SIZE * sizeof (struct iovec)); if (NULL == iov) { opal_output(1, "OUT OF MEMORY\n"); return OMPI_ERR_OUT_OF_RESOURCE; } for (i=0 ; i<fh->f_num_of_io_entries ; i++) { if (0 == iov_count) { iov[iov_count].iov_base = fh->f_io_array[i].memory_address; iov[iov_count].iov_len = fh->f_io_array[i].length; iov_offset = (OMPI_MPI_OFFSET_TYPE)(intptr_t)fh->f_io_array[i].offset; end_offset = (off_t)fh->f_io_array[i].offset + (off_t)fh->f_io_array[i].length; iov_count ++; } if (OMPIO_IOVEC_INITIAL_SIZE*block <= iov_count) { block ++; iov = (struct iovec *)realloc (iov, OMPIO_IOVEC_INITIAL_SIZE * block * sizeof(struct iovec)); if (NULL == iov) { opal_output(1, "OUT OF MEMORY\n"); return OMPI_ERR_OUT_OF_RESOURCE; } } if (fh->f_num_of_io_entries != i+1) { if ( (((OMPI_MPI_OFFSET_TYPE)(intptr_t)fh->f_io_array[i].offset + (ptrdiff_t)fh->f_io_array[i].length) == (OMPI_MPI_OFFSET_TYPE)(intptr_t)fh->f_io_array[i+1].offset) && (iov_count < IOV_MAX )) { iov[iov_count].iov_base = fh->f_io_array[i+1].memory_address; iov[iov_count].iov_len = fh->f_io_array[i+1].length; end_offset = (off_t)fh->f_io_array[i].offset + (off_t)fh->f_io_array[i].length; iov_count ++; continue; } } /* printf ("RANK: %d Entries: %d count: %d\n", fh->f_rank, fh->f_num_of_io_entries, iov_count); for (j=0 ; j<iov_count ; j++) { printf ("%p %lld\n", iov[j].iov_base, iov[j].iov_len); } */ total_length = (end_offset - (off_t)iov_offset); ret = mca_fbtl_posix_lock ( &lock, fh, F_WRLCK, iov_offset, total_length, OMPIO_LOCK_SELECTIVE ); if ( 0 < ret ) { opal_output(1, "mca_fbtl_posix_pwritev: error in mca_fbtl_posix_lock() error ret=%d %s", ret, strerror(errno)); free (iov); /* just in case some part of the lock worked */ mca_fbtl_posix_unlock ( &lock, fh ); return OMPI_ERROR; } #if defined (HAVE_PWRITEV) ret_code = pwritev (fh->fd, iov, iov_count, iov_offset); #else if (-1 == lseek (fh->fd, iov_offset, SEEK_SET)) { opal_output(1, "mca_fbtl_posix_pwritev: error in lseek:%s", strerror(errno)); free(iov); mca_fbtl_posix_unlock ( &lock, fh ); return OMPI_ERROR; } ret_code = writev (fh->fd, iov, iov_count); #endif mca_fbtl_posix_unlock ( &lock, fh ); if ( 0 < ret_code ) { bytes_written += ret_code; } else if (-1 == ret_code ) { opal_output(1, "mca_fbtl_posix_pwritev: error in writev:%s", strerror(errno)); free (iov); return OMPI_ERROR; } iov_count = 0; } free (iov); return bytes_written; }