]>
git.proxmox.com Git - ceph.git/blob - ceph/src/os/bluestore/aio.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
7 std::ostream
& operator<<(std::ostream
& os
, const aio_t
& aio
)
11 for (auto& iov
: aio
.iov
) {
12 os
<< "\n [" << i
++ << "] 0x"
13 << std::hex
<< iov
.iov_base
<< "~" << iov
.iov_len
<< std::dec
;
18 int aio_queue_t::submit_batch(aio_iter begin
, aio_iter end
,
19 uint16_t aios_size
, void *priv
,
22 // 2^16 * 125us = ~8 seconds, so max sleep is ~16 seconds
28 struct aio_t
*piocb
[aios_size
];
32 *(piocb
+left
) = &(*cur
);
36 ceph_assert(aios_size
>= left
);
39 #if defined(HAVE_LIBAIO)
40 r
= io_submit(ctx
, std::min(left
, max_iodepth
), (struct iocb
**)(piocb
+ done
));
41 #elif defined(HAVE_POSIXAIO)
42 if (piocb
[done
]->n_aiocb
== 1) {
43 // TODO: consider batching multiple reads together with lio_listio
44 piocb
[done
]->aio
.aiocb
.aio_sigevent
.sigev_notify
= SIGEV_KEVENT
;
45 piocb
[done
]->aio
.aiocb
.aio_sigevent
.sigev_notify_kqueue
= ctx
;
46 piocb
[done
]->aio
.aiocb
.aio_sigevent
.sigev_value
.sival_ptr
= piocb
[done
];
47 r
= aio_read(&piocb
[done
]->aio
.aiocb
);
50 sev
.sigev_notify
= SIGEV_KEVENT
;
51 sev
.sigev_notify_kqueue
= ctx
;
52 sev
.sigev_value
.sival_ptr
= piocb
[done
];
53 r
= lio_listio(LIO_NOWAIT
, &piocb
[done
]->aio
.aiocbp
, piocb
[done
]->n_aiocb
, &sev
);
57 if (r
== -EAGAIN
&& attempts
-- > 0) {
74 int aio_queue_t::get_next_completed(int timeout_ms
, aio_t
**paio
, int max
)
76 #if defined(HAVE_LIBAIO)
78 #elif defined(HAVE_POSIXAIO)
79 struct kevent events
[max
];
83 (timeout_ms
% 1000) * 1000 * 1000
88 #if defined(HAVE_LIBAIO)
89 r
= io_getevents(ctx
, 1, max
, events
, &t
);
90 #elif defined(HAVE_POSIXAIO)
91 r
= kevent(ctx
, NULL
, 0, events
, max
, &t
);
95 } while (r
== -EINTR
);
97 for (int i
=0; i
<r
; ++i
) {
98 #if defined(HAVE_LIBAIO)
99 paio
[i
] = (aio_t
*)events
[i
].obj
;
100 paio
[i
]->rval
= events
[i
].res
;
102 paio
[i
] = (aio_t
*)events
[i
].udata
;
103 if (paio
[i
]->n_aiocb
== 1) {
104 paio
[i
]->rval
= aio_return(&paio
[i
]->aio
.aiocb
);
106 // Emulate the return value of pwritev. I can't find any documentation
107 // for what the value of io_event.res is supposed to be. I'm going to
108 // assume that it's just like pwritev/preadv/pwrite/pread.
110 for (int j
= 0; j
< paio
[i
]->n_aiocb
; j
++) {
111 int res
= aio_return(&paio
[i
]->aio
.aiocbp
[j
]);
116 paio
[i
]->rval
+= res
;
119 free(paio
[i
]->aio
.aiocbp
);