Changeset View
Standalone View
usr.sbin/bhyve/block_backends.h
- This file was copied from usr.sbin/bhyve/block_if.h.
Show All 19 Lines | |||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||||
* SUCH DAMAGE. | * SUCH DAMAGE. | ||||
* | * | ||||
* $FreeBSD: head/usr.sbin/bhyve/block_if.h 347033 2019-05-02 22:46:37Z jhb $ | * $FreeBSD$ | ||||
*/ | */ | ||||
/* | /* | ||||
* The block API to be used by bhyve block-device emulations. The routines | * The block API to be used by bhyve block-device emulations. The routines | ||||
* are thread safe, with no assumptions about the context of the completion | * are thread safe, with no assumptions about the context of the completion | ||||
* callback - it may occur in the caller's context, or asynchronously in | * callback - it may occur in the caller's context, or asynchronously in | ||||
* another thread. | * another thread. | ||||
*/ | */ | ||||
#ifndef _BLOCK_IF_H_ | #ifndef _BLOCK_BACKENDS_H_ | ||||
#define _BLOCK_IF_H_ | #define _BLOCK_BACKENDS_H_ | ||||
#include <sys/queue.h> | |||||
#include <sys/uio.h> | #include <sys/uio.h> | ||||
#include <sys/unistd.h> | #include <sys/unistd.h> | ||||
/* Opaque type representing a block device backend. */ | |||||
typedef struct block_backend block_backend_t; | |||||
/* | /* | ||||
* BLOCKIF_IOV_MAX is the maximum number of scatter/gather entries in | * BLOCKIF_IOV_MAX is the maximum number of scatter/gather entries in | ||||
* a single request. BLOCKIF_RING_MAX is the maxmimum number of | * a single request. BLOCKIF_RING_MAX is the maxmimum number of | ||||
* pending requests that can be queued. | * pending requests that can be queued. | ||||
*/ | */ | ||||
#define BLOCKIF_IOV_MAX 128 /* not practical to be IOV_MAX */ | #define BLOCKIF_IOV_MAX 128 /* not practical to be IOV_MAX */ | ||||
#define BLOCKIF_RING_MAX 128 | #define BLOCKIF_RING_MAX 128 | ||||
#define BLOCKIF_SIG 0xb109b109 | |||||
#define BLOCKIF_NUMTHR 8 | |||||
#define BLOCKIF_MAXREQ (BLOCKIF_RING_MAX + BLOCKIF_NUMTHR) | |||||
enum blockop { | |||||
BOP_READ, | |||||
BOP_WRITE, | |||||
BOP_FLUSH, | |||||
BOP_DELETE | |||||
}; | |||||
enum blockstat { | |||||
BST_FREE, | |||||
BST_BLOCK, | |||||
BST_PEND, | |||||
BST_BUSY, | |||||
BST_DONE | |||||
}; | |||||
struct blockif_req { | struct blockif_req { | ||||
int br_iovcnt; | int br_iovcnt; | ||||
off_t br_offset; | off_t br_offset; | ||||
ssize_t br_resid; | ssize_t br_resid; | ||||
void (*br_callback)(struct blockif_req *req, int err); | void (*br_callback)(struct blockif_req *req, int err); | ||||
void *br_param; | void *br_param; | ||||
struct iovec br_iov[BLOCKIF_IOV_MAX]; | struct iovec br_iov[BLOCKIF_IOV_MAX]; | ||||
}; | }; | ||||
struct blockif_ctxt; | /* Interface between block device frontends and backends. */ | ||||
struct blockif_ctxt *blockif_open(const char *optstr, const char *ident); | int blockbe_open(block_backend_t **ret, const char *optstr, | ||||
off_t blockif_size(struct blockif_ctxt *bc); | const char *pci_ident); | ||||
void blockif_chs(struct blockif_ctxt *bc, uint16_t *c, uint8_t *h, | off_t blockbe_size(block_backend_t *be); | ||||
void blockbe_chs(block_backend_t *be, uint16_t *c, uint8_t *h, | |||||
uint8_t *s); | uint8_t *s); | ||||
int blockif_sectsz(struct blockif_ctxt *bc); | int blockbe_sectsz(block_backend_t *be); | ||||
void blockif_psectsz(struct blockif_ctxt *bc, int *size, int *off); | void blockbe_psectsz(block_backend_t *be, int *size, int *off); | ||||
int blockif_queuesz(struct blockif_ctxt *bc); | int blockbe_queuesz(block_backend_t *be); | ||||
int blockif_is_ro(struct blockif_ctxt *bc); | int blockbe_is_ro(block_backend_t *be); | ||||
int blockif_candelete(struct blockif_ctxt *bc); | int blockbe_candelete(block_backend_t *be); | ||||
int blockif_read(struct blockif_ctxt *bc, struct blockif_req *breq); | int blockbe_read(block_backend_t *be, struct blockif_req *breq); | ||||
int blockif_write(struct blockif_ctxt *bc, struct blockif_req *breq); | int blockbe_write(block_backend_t *be, struct blockif_req *breq); | ||||
int blockif_flush(struct blockif_ctxt *bc, struct blockif_req *breq); | int blockbe_flush(block_backend_t *be, struct blockif_req *breq); | ||||
int blockif_delete(struct blockif_ctxt *bc, struct blockif_req *breq); | int blockbe_delete(block_backend_t *be, struct blockif_req *breq); | ||||
int blockif_cancel(struct blockif_ctxt *bc, struct blockif_req *breq); | int blockbe_cancel(block_backend_t *be, struct blockif_req *breq); | ||||
int blockif_close(struct blockif_ctxt *bc); | int blockbe_close(block_backend_t *be); | ||||
freqlabs: Can you avoid changing the name? `blockif` still seems more appropriate. I think this could be… | |||||
Done Inline ActionsIt is a good question, which triggers quite a few ideas in my head. I did this rename on purpose, since I wanted to emphasize that there is quite a difference between the old blockif and the newer backend multiplexer. Also note that at first the backend mux and the locblk provider were in the same files, which made it even more confusing to keep the old name. But there is a difference between block_backend_t and blockif_ctxt_t. struct blockif_ctxt { int bc_magic; int bc_fd; int bc_ischr; int bc_isgeom; int bc_candelete; int bc_rdonly; off_t bc_size; int bc_sectsz; int bc_psectsz; int bc_psectoff; int bc_closing; pthread_t bc_btid[BLOCKIF_NUMTHR]; pthread_mutex_t bc_mtx; pthread_cond_t bc_cond; /* Request elements and free/pending/busy queues */ TAILQ_HEAD(, blockif_elem) bc_freeq; TAILQ_HEAD(, blockif_elem) bc_pendq; TAILQ_HEAD(, blockif_elem) bc_busyq; struct blockif_elem bc_reqs[BLOCKIF_MAXREQ]; }; Which is the original blockif_ctxt_t. And I feel uncomfortable to just glue this in the structure that describes the backend. wjw_digiware.nl: It is a good question, which triggers quite a few ideas in my head.
So I'm just going to answer… | |||||
#endif /* _BLOCK_IF_H_ */ | /* | ||||
* Each block device backend registers a set of function pointers that are | |||||
* used to implement the net backends API. | |||||
*/ | |||||
struct block_backend { | |||||
const char *prefix; /* prefix matching this backend */ | |||||
/* | |||||
* Routines used to initialize and cleanup the resources needed | |||||
* by a backend. The cleanup function is used internally, | |||||
* and should not be called by the frontend. | |||||
*/ | |||||
void (*init)(void); | |||||
void (*cleanup)(block_backend_t **be); | |||||
int (*open)(block_backend_t **be, const char *optstr, | |||||
const char *pci_ident); | |||||
off_t (*size)(block_backend_t *be); | |||||
void (*chs)(block_backend_t *be, uint16_t *c, uint8_t *h, | |||||
uint8_t *s); | |||||
int (*sectsz)(block_backend_t *be); | |||||
void (*psectsz)(block_backend_t *be, int *size, int *off); | |||||
int (*queuesz)(block_backend_t *be); | |||||
int (*is_ro)(block_backend_t *be); | |||||
int (*candelete)(block_backend_t *be); | |||||
int (*read)(block_backend_t *be, struct blockif_req *breq); | |||||
int (*write)(block_backend_t *be, struct blockif_req *breq); | |||||
int (*flush)(block_backend_t *be, struct blockif_req *breq); | |||||
int (*delete)(block_backend_t *be, struct blockif_req *breq); | |||||
int (*cancel)(block_backend_t *be, struct blockif_req *breq); | |||||
int (*close)(block_backend_t *be); | |||||
struct pci_vtblk_softc *sc; | |||||
struct blockif_ctxt *bc; | |||||
/* Size of backend-specific private data. */ | |||||
size_t priv_size; | |||||
/* Room for backend-specific data. */ | |||||
char opaque[0]; | |||||
}; | |||||
#endif /* _BLOCK_BACKENDS_H_ */ |
Can you avoid changing the name? blockif still seems more appropriate. I think this could be a much smaller diff.