libxtc 0.4.0
Async concurrency for C: Tokio + Seastar + BEAM, in one library
Loading...
Searching...
No Matches
xtc_bdev.h
1/*-
2 * Copyright (c) 2026, The XTC Project
3 * @stability stable
4 * Use of this source code is governed by the ISC License.
5 *
6 * src/inc/xtc_bdev.h
7 * Portable block-device I/O over the async xtc_aio path. A thin,
8 * uniform surface for reading and writing a raw block device (or a
9 * regular file treated as one) with sector-aligned positioned I/O
10 * that suspends the calling fiber and resumes it on completion --
11 * the same "write once, runs as AIO everywhere" model as
12 * xtc_aio(3), on top of which this layer is built.
13 *
14 * xtc_bdev_open probes the device for its logical and physical
15 * sector sizes and total capacity using the host's native query
16 * (BLKSSZGET / BLKGETSIZE64 on Linux, DIOCGSECTORSIZE on the BSDs
17 * and macOS, DKIOCGMEDIAINFO on illumos, the drive geometry IOCTL on
18 * Windows) and opens the descriptor with direct I/O (O_DIRECT) for a
19 * real device so transfers bypass the page cache. A regular file or
20 * an unqueryable target falls back to logical=512, physical=4096, and
21 * the capacity reported by fstat, with buffered I/O.
22 *
23 * xtc_bdev_pread / xtc_bdev_pwrite route through
24 * xtc_aio_pread / xtc_aio_pwrite: on a fiber loop the call parks the
25 * fiber and the loop keeps running other work. The offset and the
26 * length must both be multiples of the logical sector size, else the
27 * call returns XTC_E_INVAL. xtc_bdev_flush issues xtc_aio_fsync.
28 *
29 * See xtc_bdev(3).
30 */
31
32#ifndef XTC_BDEV_H
33#define XTC_BDEV_H
34
35#include "xtc_export.h"
36
37#include <stddef.h>
38#include <stdint.h>
39
40/* The pread/pwrite return values use the standard POSIX `ssize_t`. We
41 * provide it portably WITHOUT a namespace-polluting #define of the name
42 * and WITHOUT redefining it where the platform already has it:
43 * - POSIX: <sys/types.h> defines the real ssize_t; we just use it.
44 * - MinGW/Cygwin on Windows: same -- their <sys/types.h> defines
45 * ssize_t and sets _SSIZE_T_DEFINED.
46 * - MSVC: the CRT has no ssize_t, so we typedef it from SSIZE_T,
47 * guarded by _SSIZE_T_DEFINED (the de-facto sentinel) so a consumer
48 * header that already defined it wins, and a later include of ours
49 * cannot double-define. */
50#if defined(_WIN32) && defined(_MSC_VER)
51# ifndef _SSIZE_T_DEFINED
52# define _SSIZE_T_DEFINED
53# include <BaseTsd.h> /* SSIZE_T */
54typedef SSIZE_T ssize_t;
55# endif
56#else
57# include <sys/types.h> /* real ssize_t (POSIX, MinGW, Cygwin) */
58#endif
59
60/* Open flags for xtc_bdev_open (subset of xtc_fs flags that make sense
61 * for a block device; mapped to O_* per platform). */
62#define XTC_BDEV_READ 0x01u /* open for reading */
63#define XTC_BDEV_WRITE 0x02u /* open for writing (implies read too) */
64
65/* Opaque device handle. */
66typedef struct xtc_bdev xtc_bdev_t;
67
68/*
69 * PUBLIC: int xtc_bdev_open __P((const char *, int, xtc_bdev_t **));
70 *
71 * Open path as a block device, probing its geometry. flags is a mask of
72 * XTC_BDEV_READ / XTC_BDEV_WRITE. On success stores the handle in *out
73 * and returns XTC_OK; otherwise a negative XTC_E_* code.
74 */
75XTC_API int xtc_bdev_open(const char *path, int flags, xtc_bdev_t **out);
76
77/*
78 * PUBLIC: void xtc_bdev_close __P((xtc_bdev_t *));
79 *
80 * Close the device and free the handle. NULL is a no-op.
81 */
82XTC_API void xtc_bdev_close(xtc_bdev_t *b);
83
84/*
85 * PUBLIC: uint32_t xtc_bdev_logical_sector __P((const xtc_bdev_t *));
86 * PUBLIC: uint32_t xtc_bdev_physical_sector __P((const xtc_bdev_t *));
87 * PUBLIC: uint64_t xtc_bdev_capacity __P((const xtc_bdev_t *));
88 *
89 * Report the probed logical sector size, physical sector size, and total
90 * capacity in bytes. Offsets and lengths passed to pread/pwrite must be
91 * multiples of the logical sector size.
92 */
93XTC_API uint32_t xtc_bdev_logical_sector(const xtc_bdev_t *b);
94XTC_API uint32_t xtc_bdev_physical_sector(const xtc_bdev_t *b);
95XTC_API uint64_t xtc_bdev_capacity(const xtc_bdev_t *b);
96
97/*
98 * PUBLIC: ssize_t xtc_bdev_pread __P((xtc_bdev_t *, void *, size_t, uint64_t));
99 * PUBLIC: ssize_t xtc_bdev_pwrite __P((xtc_bdev_t *, const void *, size_t, uint64_t));
100 *
101 * Read n bytes into buf / write n bytes from buf at absolute byte offset
102 * off, routed through xtc_aio so the fiber parks and the loop stays live.
103 * off and n must each be a multiple of the logical sector size, else the
104 * call returns XTC_E_INVAL. On success returns the byte count
105 * transferred (>= 0); a short read at end of device returns the partial
106 * count. On failure returns a negative XTC_E_* code.
107 */
108XTC_API ssize_t xtc_bdev_pread(xtc_bdev_t *b, void *buf, size_t n, uint64_t off);
109XTC_API ssize_t xtc_bdev_pwrite(xtc_bdev_t *b, const void *buf, size_t n, uint64_t off);
110
111/*
112 * PUBLIC: int xtc_bdev_flush __P((xtc_bdev_t *));
113 *
114 * Flush the device's data and metadata durably via xtc_aio_fsync.
115 * Returns XTC_OK or a negative XTC_E_* code.
116 */
117XTC_API int xtc_bdev_flush(xtc_bdev_t *b);
118
119#endif /* XTC_BDEV_H */