Example #1
0
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;
}
Example #2
0
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;
}
Example #3
0
File: file.c Project: ljx0305/tbox
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
}
Example #4
0
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;
   }
}
Example #6
0
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;
}
Example #7
0
int BufferList::write_fd(int fd, uint64_t offset){
  ssize_t wrote;
  wrote = pwritev( fd, _buffers, _index, offset );
  if (wrote < _total_bytes) {
    return errno;
  }
}
Example #8
0
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;
}
Example #9
0
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;
}
Example #10
0
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));
}
Example #11
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;
}
Example #12
0
File: buf.c Project: smintz/cluster
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;
}
Example #13
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;
}
Example #14
0
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
}
Example #16
0
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");
		}
	}
}
Example #17
0
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,
Example #18
0
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);
}
Example #19
0
File: odtable.c Project: pscedu/pfl
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);
}
Example #20
0
File: proc_mem.c Project: khuey/rr
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);
}
Example #21
0
File: sync.c Project: apexearth/fio
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);
}
Example #22
0
File: fs.c Project: 90lantran/node
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;
}
Example #23
0
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;
}
Example #24
0
ssize_t pwritev64(int fd, const struct iovec *iov, int iovcnt,off_t offset)
{
  return pwritev(fd,iov,iovcnt,offset);
}
Example #25
0
static ssize_t
qemu_pwritev(int fd, const struct iovec *iov, int nr_iov, off_t offset)
{
    return pwritev(fd, iov, nr_iov, offset);
}
Example #26
0
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);
}
Example #27
0
	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",
Example #28
0
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;
}
Example #29
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;
}
Example #30
0
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;
}