]> git.proxmox.com Git - ceph.git/blob - ceph/src/os/fs/aio.h
c4757158cc90aa076699a09fe2db627d0133eae5
[ceph.git] / ceph / src / os / fs / aio.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3
4 #pragma once
5
6 #include "acconfig.h"
7 #ifdef HAVE_LIBAIO
8 # include <libaio.h>
9
10 #include <boost/intrusive/list.hpp>
11 #include <boost/container/small_vector.hpp>
12
13 #include "include/buffer.h"
14
15 struct aio_t {
16 struct iocb iocb; // must be first element; see shenanigans in aio_queue_t
17 void *priv;
18 int fd;
19 boost::container::small_vector<iovec,4> iov;
20 uint64_t offset, length;
21 int rval;
22 bufferlist bl; ///< write payload (so that it remains stable for duration)
23
24 boost::intrusive::list_member_hook<> queue_item;
25
26 aio_t(void *p, int f) : priv(p), fd(f), offset(0), length(0), rval(-1000) {
27 }
28
29 void pwritev(uint64_t _offset, uint64_t len) {
30 offset = _offset;
31 length = len;
32 io_prep_pwritev(&iocb, fd, &iov[0], iov.size(), offset);
33 }
34 void pread(uint64_t _offset, uint64_t len) {
35 offset = _offset;
36 length = len;
37 bufferptr p = buffer::create_page_aligned(length);
38 io_prep_pread(&iocb, fd, p.c_str(), length, offset);
39 bl.append(std::move(p));
40 }
41
42 int get_return_value() {
43 return rval;
44 }
45 };
46
47 typedef boost::intrusive::list<
48 aio_t,
49 boost::intrusive::member_hook<
50 aio_t,
51 boost::intrusive::list_member_hook<>,
52 &aio_t::queue_item> > aio_list_t;
53
54 struct aio_queue_t {
55 int max_iodepth;
56 io_context_t ctx;
57
58 explicit aio_queue_t(unsigned max_iodepth)
59 : max_iodepth(max_iodepth),
60 ctx(0) {
61 }
62 ~aio_queue_t() {
63 assert(ctx == 0);
64 }
65
66 int init() {
67 assert(ctx == 0);
68 int r = io_setup(max_iodepth, &ctx);
69 if (r < 0) {
70 if (ctx) {
71 io_destroy(ctx);
72 ctx = 0;
73 }
74 }
75 return r;
76 }
77 void shutdown() {
78 if (ctx) {
79 int r = io_destroy(ctx);
80 assert(r == 0);
81 ctx = 0;
82 }
83 }
84
85 int submit(aio_t &aio, int *retries);
86 int get_next_completed(int timeout_ms, aio_t **paio, int max);
87 };
88
89 #endif