|
static struct ioq_qev * | ioq_queue_get (struct m0_stob_ioq *ioq) |
|
static void | ioq_queue_put (struct m0_stob_ioq *ioq, struct ioq_qev *qev) |
|
static void | ioq_queue_submit (struct m0_stob_ioq *ioq) |
|
static void | ioq_queue_lock (struct m0_stob_ioq *ioq) |
|
static void | ioq_queue_unlock (struct m0_stob_ioq *ioq) |
|
M0_INTERNAL int | m0_stob_linux_io_init (struct m0_stob *stob, struct m0_stob_io *io) |
|
static void | stob_linux_io_release (struct stob_linux_io *lio) |
|
static void | stob_linux_io_fini (struct m0_stob_io *io) |
|
static int | stob_linux_io_launch (struct m0_stob_io *io) |
|
static void | ioq_io_error (struct m0_stob_ioq *ioq, struct ioq_qev *qev) |
|
static void | ioq_complete (struct m0_stob_ioq *ioq, struct ioq_qev *qev, long res, long res2) |
|
static unsigned long | stob_ioq_timer_cb (unsigned long data) |
|
static int | stob_ioq_thread_init (struct m0_stob_ioq *ioq) |
|
static void | stob_ioq_thread (struct m0_stob_ioq *ioq) |
|
M0_INTERNAL int | m0_stob_ioq_init (struct m0_stob_ioq *ioq) |
|
M0_INTERNAL void | m0_stob_ioq_fini (struct m0_stob_ioq *ioq) |
|
M0_INTERNAL uint32_t | m0_stob_ioq_bshift (struct m0_stob_ioq *ioq) |
|
M0_INTERNAL m0_bcount_t | m0_stob_ioq_bsize (struct m0_stob_ioq *ioq) |
|
M0_INTERNAL m0_bcount_t | m0_stob_ioq_bmask (struct m0_stob_ioq *ioq) |
|
M0_INTERNAL bool | m0_stob_ioq_directio (struct m0_stob_ioq *ioq) |
|
M0_INTERNAL void | m0_stob_ioq_directio_setup (struct m0_stob_ioq *ioq, bool use_directio) |
|
static void | stob_linux_type_register (struct m0_stob_type *type) |
|
static void | stob_linux_type_deregister (struct m0_stob_type *type) |
|
M0_INTERNAL struct m0_stob_linux * | m0_stob_linux_container (struct m0_stob *stob) |
|
M0_INTERNAL struct m0_stob_linux_domain * | m0_stob_linux_domain_container (struct m0_stob_domain *dom) |
|
static char * | stob_linux_vsnprintf (const char *format,...) |
|
static char * | stob_linux_dir_domain (const char *path) |
|
static char * | stob_linux_dir_stob (const char *path) |
|
static char * | stob_linux_file_domain_id (const char *path) |
|
static char * | stob_linux_file_stob (const char *path, const struct m0_fid *stob_fid) |
|
static int | stob_linux_domain_key_get_set (const char *path, uint64_t *dom_key, bool get) |
|
static int | stob_linux_domain_cfg_init_parse (const char *str_cfg_init, void **cfg_init) |
|
static void | stob_linux_domain_cfg_init_free (void *cfg_init) |
|
static int | stob_linux_domain_cfg_create_parse (const char *str_cfg_create, void **cfg_create) |
|
static void | stob_linux_domain_cfg_create_free (void *cfg_create) |
|
static int | stob_linux_domain_init (struct m0_stob_type *type, const char *location_data, void *cfg_init, struct m0_stob_domain **out) |
|
static void | stob_linux_domain_fini (struct m0_stob_domain *dom) |
|
static int | stob_linux_domain_create_destroy (struct m0_stob_type *type, const char *path, uint64_t dom_key, void *cfg, bool create) |
|
static int | stob_linux_domain_create (struct m0_stob_type *type, const char *location_data, uint64_t dom_key, void *cfg_create) |
|
static int | stob_linux_domain_destroy (struct m0_stob_type *type, const char *location_data) |
|
static struct m0_stob * | stob_linux_alloc (struct m0_stob_domain *dom, const struct m0_fid *stob_fid) |
|
static void | stob_linux_free (struct m0_stob_domain *dom, struct m0_stob *stob) |
|
static int | stob_linux_cfg_parse (const char *str_cfg_create, void **cfg_create) |
|
static void | stob_linux_cfg_free (void *cfg_create) |
|
static int | stob_linux_stat (struct m0_stob_linux *lstob) |
|
static int | stob_linux_open (struct m0_stob *stob, struct m0_stob_domain *dom, const struct m0_fid *stob_fid, void *cfg, bool create) |
|
static int | stob_linux_init (struct m0_stob *stob, struct m0_stob_domain *dom, const struct m0_fid *stob_fid) |
|
static void | stob_linux_close (struct m0_stob_linux *lstob) |
|
static void | stob_linux_fini (struct m0_stob *stob) |
|
static void | stob_linux_create_credit (struct m0_stob_domain *dom, struct m0_be_tx_credit *accum) |
|
static int | stob_linux_create (struct m0_stob *stob, struct m0_stob_domain *dom, struct m0_dtx *dtx, const struct m0_fid *stob_fid, void *cfg) |
|
static void | stob_linux_destroy_credit (struct m0_stob *stob, struct m0_be_tx_credit *accum) |
|
static int | stob_linux_punch_credit (struct m0_stob *stob, struct m0_indexvec *want, struct m0_indexvec *got, struct m0_be_tx_credit *accum) |
|
static int | stob_linux_destroy (struct m0_stob *stob, struct m0_dtx *dtx) |
|
static int | stob_linux_punch (struct m0_stob *stob, struct m0_indexvec *range, struct m0_dtx *dtx) |
|
static void | stob_linux_write_credit (const struct m0_stob_domain *dom, const struct m0_stob_io *io, struct m0_be_tx_credit *accum) |
|
static uint32_t | stob_linux_block_shift (struct m0_stob *stob) |
|
static int | stob_linux_fd (struct m0_stob *stob) |
|
M0_INTERNAL int | m0_stob_linux_reopen (struct m0_stob_id *stob_id, const char *f_path) |
|
M0_INTERNAL void | m0_stob_linux_conf_sdev_associate (struct m0_stob *stob, const struct m0_fid *conf_sdev) |
|
M0_INTERNAL int | m0_stob_linux_domain_fd_get (struct m0_stob_domain *dom, int *fd) |
|
M0_INTERNAL int | m0_stob_linux_domain_fd_put (struct m0_stob_domain *dom, int fd) |
|
M0_INTERNAL bool | m0_stob_linux_domain_directio (struct m0_stob_domain *dom) |
|
and block device interfaces.
- See also
- stob
Linux stob adieu
adieu implementation for Linux stob is based on Linux specific asynchronous IO interfaces: io_{setup,destroy,submit,cancel,getevents}().
IO admission control and queueing in Linux stob adieu are implemented on a storage object domain level, that is, each domain has its own set of queues, threads and thresholds.
On a high level, adieu IO request is first split into fragments. A fragment is initially placed into a per-domain queue (admission queue, linux_domain::ioq_queue) where it is held until there is enough space in the AIO ring buffer (linux_domain::ioq_ctx). Placing a fragment into the ring buffer (ioq_queue_submit()) means that kernel AIO is launched for it. When IO completes, the kernel delivers an IO completion event via the ring buffer.
A number (M0_STOB_IOQ_NR_THREADS by default) of worker adieu threads is created for each storage object domain. These threads are implementing admission control and completion notification, they
- listen for the AIO completion events in the ring buffer. When an AIO is
completed, worker thread signals completion event to AIO users;
- when space becomes available in the ring buffer, a worker thread moves
some number of pending fragments from the admission queue to the ring
buffer.
Admission queue separate from the ring buffer is needed to
- be able to handle more pending fragments than a kernel can support and
- potentially do some pre-processing on the pending fragments (like
elevator does).
Concurrency control
Per-domain data structures (queue, thresholds, etc.) are protected by linux_domain::ioq_mutex.
Concurrency control for an individual adieu fragment is very simple: user is not allowed to touch it in SIS_BUSY state and io_getevents() exactly-once delivery semantics guarantee that there is no concurrency for busy->idle transition. This nice picture would break apart if IO cancellation were to be implemented, because it requires synchronization between user actions (cancellation) and ongoing IO in SIS_BUSY state.
- Todo:
- use explicit state machine instead of ioq threads
- See also
- http://www.kernel.org/doc/man-pages/online/pages/man2/io_setup.2.html
Implementation of m0_stob on top of Linux files.
A linux storage object is simply a file on a local file system. A linux storage object domain is a directory containing
- data-base tables mapping storage object identifiers to local
identifiers (not currently used) and
- a directory where files, corresponding to storage objects are stored
in. A name of a file is built from the corresponding storage object
local identifier (stob_ket).
A linux storage object domain is identified by the path to its directory.
When an in-memory representation for an object is created, no file system operations are performed. It is only when the object is "located" (m0_stob_locate()) or "created" (m0_stob_create()) when actual open(2) system call is made. If the call was successful, the file descriptor (m0_stob_linux::sl_fd) remains open until the object is destroyed.
Direct I/O
To enable directio for a stob domain you should specify "directio=true" somewhere in str_cfg_init for m0_stob_domain_init() or m0_stob_domain_create().
Symlinks
To make stob pointing to other file on the filesystem just pass filename as str_cfg to m0_stob_create() to create a symlink instead of a file.
◆ anonymous enum
Enumerator |
---|
STOB_IOQ_BSHIFT | |
STOB_IOQ_BSIZE | |
STOB_IOQ_BMASK | |
Definition at line 149 of file ioq.c.
◆ anonymous enum
Enumerator |
---|
M0_STOB_IOQ_NR_THREADS | Default number of threads to create in a storage object domain.
|
M0_STOB_IOQ_RING_SIZE | Default size of a ring buffer shared by adieu and the kernel.
|
M0_STOB_IOQ_BATCH_IN_SIZE | Size of a batch in which requests are moved from the admission queue to the ring buffer.
|
M0_STOB_IOQ_BATCH_OUT_SIZE | Size of a batch in which completion events are extracted from the ring buffer.
|
Definition at line 47 of file ioq.h.
◆ anonymous enum
Enumerator |
---|
STOB_TYPE_LINUX | |
Definition at line 82 of file linux.c.
◆ ioq_complete()
static void ioq_complete |
( |
struct m0_stob_ioq * |
ioq, |
|
|
struct ioq_qev * |
qev, |
|
|
long |
res, |
|
|
long |
res2 |
|
) |
| |
|
static |
Handles AIO completion event from the ring buffer.
When all fragments of a certain adieu request have completed, signals m0_stob_io::si_wait.
Definition at line 495 of file ioq.c.
◆ ioq_io_error()
Handles detection of drive IO error by signalling HA.
Definition at line 434 of file ioq.c.
◆ ioq_queue_get()
Removes an element from the (non-empty) admission queue and returns it.
Definition at line 351 of file ioq.c.
◆ ioq_queue_lock()
◆ ioq_queue_put()
Adds an element to the admission queue.
Definition at line 367 of file ioq.c.
◆ ioq_queue_submit()
static void ioq_queue_submit |
( |
struct m0_stob_ioq * |
ioq | ) |
|
|
static |
Transfers fragments from the admission queue to the ring buffer in batches until the ring buffer is full.
Definition at line 393 of file ioq.c.
◆ ioq_queue_unlock()
static void ioq_queue_unlock |
( |
struct m0_stob_ioq * |
ioq | ) |
|
|
static |
◆ m0_stob_ioq_bmask()
◆ m0_stob_ioq_bshift()
M0_INTERNAL uint32_t m0_stob_ioq_bshift |
( |
struct m0_stob_ioq * |
ioq | ) |
|
◆ m0_stob_ioq_bsize()
◆ m0_stob_ioq_directio()
M0_INTERNAL bool m0_stob_ioq_directio |
( |
struct m0_stob_ioq * |
ioq | ) |
|
◆ m0_stob_ioq_directio_setup()
M0_INTERNAL void m0_stob_ioq_directio_setup |
( |
struct m0_stob_ioq * |
ioq, |
|
|
bool |
use_directio |
|
) |
| |
◆ m0_stob_ioq_fini()
M0_INTERNAL void m0_stob_ioq_fini |
( |
struct m0_stob_ioq * |
ioq | ) |
|
◆ m0_stob_ioq_init()
M0_INTERNAL int m0_stob_ioq_init |
( |
struct m0_stob_ioq * |
ioq | ) |
|
◆ m0_stob_linux_conf_sdev_associate()
M0_INTERNAL void m0_stob_linux_conf_sdev_associate |
( |
struct m0_stob * |
stob, |
|
|
const struct m0_fid * |
conf_sdev |
|
) |
| |
Associates linux stob with fid of a m0_conf_sdev object. This fid is sent to HA when stob I/O error is reported.
Definition at line 594 of file linux.c.
◆ m0_stob_linux_container()
◆ m0_stob_linux_domain_container()
◆ m0_stob_linux_domain_directio()
M0_INTERNAL bool m0_stob_linux_domain_directio |
( |
struct m0_stob_domain * |
dom | ) |
|
◆ m0_stob_linux_domain_fd_get()
M0_INTERNAL int m0_stob_linux_domain_fd_get |
( |
struct m0_stob_domain * |
dom, |
|
|
int * |
fd |
|
) |
| |
Obtains file descriptor of a file which is stored on the same local filesystem where objects are.
Definition at line 604 of file linux.c.
◆ m0_stob_linux_domain_fd_put()
M0_INTERNAL int m0_stob_linux_domain_fd_put |
( |
struct m0_stob_domain * |
dom, |
|
|
int |
fd |
|
) |
| |
Closes previously obtained file descriptor.
Definition at line 621 of file linux.c.
◆ m0_stob_linux_io_init()
M0_INTERNAL int m0_stob_linux_io_init |
( |
struct m0_stob * |
stob, |
|
|
struct m0_stob_io * |
io |
|
) |
| |
◆ m0_stob_linux_reopen()
M0_INTERNAL int m0_stob_linux_reopen |
( |
struct m0_stob_id * |
stob_id, |
|
|
const char * |
f_path |
|
) |
| |
Reopen the stob to update it's file descriptor. Find the stob from the provided stob_id and destroy it to get rid of the stale fd. Create the stob with provided path to reopen the underlying device, create will also update the stob with new fd.
Definition at line 554 of file linux.c.
◆ stob_ioq_thread()
static void stob_ioq_thread |
( |
struct m0_stob_ioq * |
ioq | ) |
|
|
static |
Linux adieu worker thread.
Listens to the completion events from the ring buffer. Delivers completion events to the users. Moves fragments from the admission queue to the ring buffer.
Definition at line 637 of file ioq.c.
◆ stob_ioq_thread_init()
static int stob_ioq_thread_init |
( |
struct m0_stob_ioq * |
ioq | ) |
|
|
static |
◆ stob_ioq_timer_cb()
static unsigned long stob_ioq_timer_cb |
( |
unsigned long |
data | ) |
|
|
static |
◆ stob_linux_alloc()
◆ stob_linux_block_shift()
static uint32_t stob_linux_block_shift |
( |
struct m0_stob * |
stob | ) |
|
|
static |
◆ stob_linux_cfg_free()
static void stob_linux_cfg_free |
( |
void * |
cfg_create | ) |
|
|
static |
◆ stob_linux_cfg_parse()
static int stob_linux_cfg_parse |
( |
const char * |
str_cfg_create, |
|
|
void ** |
cfg_create |
|
) |
| |
|
static |
◆ stob_linux_close()
◆ stob_linux_create()
◆ stob_linux_create_credit()
◆ stob_linux_destroy()
static int stob_linux_destroy |
( |
struct m0_stob * |
stob, |
|
|
struct m0_dtx * |
dtx |
|
) |
| |
|
static |
◆ stob_linux_destroy_credit()
◆ stob_linux_dir_domain()
static char* stob_linux_dir_domain |
( |
const char * |
path | ) |
|
|
static |
◆ stob_linux_dir_stob()
static char* stob_linux_dir_stob |
( |
const char * |
path | ) |
|
|
static |
◆ stob_linux_domain_cfg_create_free()
static void stob_linux_domain_cfg_create_free |
( |
void * |
cfg_create | ) |
|
|
static |
◆ stob_linux_domain_cfg_create_parse()
static int stob_linux_domain_cfg_create_parse |
( |
const char * |
str_cfg_create, |
|
|
void ** |
cfg_create |
|
) |
| |
|
static |
◆ stob_linux_domain_cfg_init_free()
static void stob_linux_domain_cfg_init_free |
( |
void * |
cfg_init | ) |
|
|
static |
◆ stob_linux_domain_cfg_init_parse()
static int stob_linux_domain_cfg_init_parse |
( |
const char * |
str_cfg_init, |
|
|
void ** |
cfg_init |
|
) |
| |
|
static |
◆ stob_linux_domain_create()
static int stob_linux_domain_create |
( |
struct m0_stob_type * |
type, |
|
|
const char * |
location_data, |
|
|
uint64_t |
dom_key, |
|
|
void * |
cfg_create |
|
) |
| |
|
static |
◆ stob_linux_domain_create_destroy()
static int stob_linux_domain_create_destroy |
( |
struct m0_stob_type * |
type, |
|
|
const char * |
path, |
|
|
uint64_t |
dom_key, |
|
|
void * |
cfg, |
|
|
bool |
create |
|
) |
| |
|
static |
◆ stob_linux_domain_destroy()
static int stob_linux_domain_destroy |
( |
struct m0_stob_type * |
type, |
|
|
const char * |
location_data |
|
) |
| |
|
static |
◆ stob_linux_domain_fini()
◆ stob_linux_domain_init()
static int stob_linux_domain_init |
( |
struct m0_stob_type * |
type, |
|
|
const char * |
location_data, |
|
|
void * |
cfg_init, |
|
|
struct m0_stob_domain ** |
out |
|
) |
| |
|
static |
◆ stob_linux_domain_key_get_set()
static int stob_linux_domain_key_get_set |
( |
const char * |
path, |
|
|
uint64_t * |
dom_key, |
|
|
bool |
get |
|
) |
| |
|
static |
◆ stob_linux_fd()
static int stob_linux_fd |
( |
struct m0_stob * |
stob | ) |
|
|
static |
◆ stob_linux_file_domain_id()
static char* stob_linux_file_domain_id |
( |
const char * |
path | ) |
|
|
static |
◆ stob_linux_file_stob()
static char* stob_linux_file_stob |
( |
const char * |
path, |
|
|
const struct m0_fid * |
stob_fid |
|
) |
| |
|
static |
◆ stob_linux_fini()
static void stob_linux_fini |
( |
struct m0_stob * |
stob | ) |
|
|
static |
◆ stob_linux_free()
◆ stob_linux_init()
◆ stob_linux_io_fini()
static void stob_linux_io_fini |
( |
struct m0_stob_io * |
io | ) |
|
|
static |
◆ stob_linux_io_launch()
static int stob_linux_io_launch |
( |
struct m0_stob_io * |
io | ) |
|
|
static |
Launch asynchronous IO.
- calculate how many fragments IO operation has;
- allocate ioq_qev array and fill it with fragments;
- queue all fragments and submit as many as possible;
Definition at line 205 of file ioq.c.
◆ stob_linux_io_release()
◆ stob_linux_open()
static int stob_linux_open |
( |
struct m0_stob * |
stob, |
|
|
struct m0_stob_domain * |
dom, |
|
|
const struct m0_fid * |
stob_fid, |
|
|
void * |
cfg, |
|
|
bool |
create |
|
) |
| |
|
static |
◆ stob_linux_punch()
Punch holes in a stob.
- Parameters
-
range,specifies | the location to punch. |
Definition at line 479 of file linux.c.
◆ stob_linux_punch_credit()
◆ stob_linux_stat()
◆ stob_linux_type_deregister()
static void stob_linux_type_deregister |
( |
struct m0_stob_type * |
type | ) |
|
|
static |
◆ stob_linux_type_register()
static void stob_linux_type_register |
( |
struct m0_stob_type * |
type | ) |
|
|
static |
◆ stob_linux_vsnprintf()
static char* stob_linux_vsnprintf |
( |
const char * |
format, |
|
|
|
... |
|
) |
| |
|
static |
Call vsnprintf() for the given parameters.
- memory is allocated using m0_alloc() for the string returned;
- at most (MAXPATHLEN - 1) characters is in the string returned;
- NULL is returned in case of error (including too large string).
Definition at line 119 of file linux.c.
◆ stob_linux_write_credit()
◆ emulate_disk_errors_nr
int64_t emulate_disk_errors_nr = 0 |
◆ ioq_timeout_default
const struct timespec ioq_timeout_default |
|
static |
Initial value:= {
.tv_sec = 1,
.tv_nsec = 0
}
Definition at line 591 of file ioq.c.
◆ m0_stob_linux_type [1/2]
Initial value:= {
.st_fidt = {
.ft_name = "linuxstob",
},
}
static struct m0_stob_type_ops stob_linux_type_ops
Definition at line 86 of file linux.c.
◆ m0_stob_linux_type [2/2]
◆ M0_XCA_DOMAIN
enum { ... } M0_XCA_DOMAIN |
◆ stob_linux_domain_ops
Initial value:= {
}
static int stob_linux_create(struct m0_stob *stob, struct m0_stob_domain *dom, struct m0_dtx *dtx, const struct m0_fid *stob_fid, void *cfg)
static struct m0_stob * stob_linux_alloc(struct m0_stob_domain *dom, const struct m0_fid *stob_fid)
static void stob_linux_free(struct m0_stob_domain *dom, struct m0_stob *stob)
static void stob_linux_create_credit(struct m0_stob_domain *dom, struct m0_be_tx_credit *accum)
static void stob_linux_cfg_free(void *cfg_create)
static int stob_linux_cfg_parse(const char *str_cfg_create, void **cfg_create)
static int stob_linux_init(struct m0_stob *stob, struct m0_stob_domain *dom, const struct m0_fid *stob_fid)
static void stob_linux_write_credit(const struct m0_stob_domain *dom, const struct m0_stob_io *io, struct m0_be_tx_credit *accum)
static void stob_linux_domain_fini(struct m0_stob_domain *dom)
Definition at line 89 of file linux.c.
◆ stob_linux_io_op
Initial value:= {
}
static void stob_linux_io_fini(struct m0_stob_io *io)
static int stob_linux_io_launch(struct m0_stob_io *io)
Definition at line 147 of file ioq.c.
◆ stob_linux_ops
Initial value:= {
}
static void stob_linux_destroy_credit(struct m0_stob *stob, struct m0_be_tx_credit *accum)
static int stob_linux_fd(struct m0_stob *stob)
static int stob_linux_destroy(struct m0_stob *stob, struct m0_dtx *dtx)
static uint32_t stob_linux_block_shift(struct m0_stob *stob)
static void stob_linux_fini(struct m0_stob *stob)
M0_INTERNAL int m0_stob_linux_io_init(struct m0_stob *stob, struct m0_stob_io *io)
static int stob_linux_punch(struct m0_stob *stob, struct m0_indexvec *range, struct m0_dtx *dtx)
static int stob_linux_punch_credit(struct m0_stob *stob, struct m0_indexvec *want, struct m0_indexvec *got, struct m0_be_tx_credit *accum)
Definition at line 90 of file linux.c.
◆ stob_linux_type_ops
Initial value:= {
}
static void stob_linux_type_deregister(struct m0_stob_type *type)
static int stob_linux_domain_destroy(struct m0_stob_type *type, const char *location_data)
static void stob_linux_type_register(struct m0_stob_type *type)
static int stob_linux_domain_cfg_create_parse(const char *str_cfg_create, void **cfg_create)
static int stob_linux_domain_cfg_init_parse(const char *str_cfg_init, void **cfg_init)
static void stob_linux_domain_cfg_init_free(void *cfg_init)
static int stob_linux_domain_create(struct m0_stob_type *type, const char *location_data, uint64_t dom_key, void *cfg_create)
static void stob_linux_domain_cfg_create_free(void *cfg_create)
static int stob_linux_domain_init(struct m0_stob_type *type, const char *location_data, void *cfg_init, struct m0_stob_domain **out)
Definition at line 88 of file linux.c.