#ifndef __LUNAIX_BLKBUF_H #define __LUNAIX_BLKBUF_H #include #include #include #include struct blkbuf_cache { union { struct { unsigned int blksize; }; struct bcache cached; }; struct llist_header dirty; struct block_dev* blkdev; mutex_t lock; }; struct blk_buf { void* raw; bcobj_t cobj; struct llist_header dirty; struct blkio_req* breq; }; typedef void* bbuf_t; #define BLOCK_BUFFER(type, name) \ union { \ type* name; \ bbuf_t bb_##name; \ } #define INVL_BUFFER 0xdeadc0de #define bbuf_null ((bbuf_t)0) static inline bool blkbuf_errbuf(bbuf_t buf) { return (ptr_t)buf == INVL_BUFFER; } static inline bool blkbuf_nullbuf(bbuf_t buf) { return buf == bbuf_null; } static inline unsigned int blkbuf_id(bbuf_t buf) { return to_bcache_node(((struct blk_buf*)buf)->cobj)->tag; } static inline unsigned int blkbuf_refcounts(bbuf_t buf) { return to_bcache_node(((struct blk_buf*)buf)->cobj)->refs; } static inline bool blkbuf_not_shared(bbuf_t buf) { return blkbuf_refcounts(buf) == 1; } struct blkbuf_cache* blkbuf_create(struct block_dev* blkdev, unsigned int blk_size); bbuf_t blkbuf_take(struct blkbuf_cache* bc, unsigned int block_id); static inline bbuf_t blkbuf_refonce(bbuf_t buf) { if (likely(buf && !blkbuf_errbuf(buf))) { bcache_refonce(((struct blk_buf*)buf)->cobj); } return buf; } static inline void* blkbuf_data(bbuf_t buf) { assert(!blkbuf_errbuf(buf)); return ((struct blk_buf*)buf)->raw; } #define block_buffer(buf, type) \ ((type*)blkbuf_data(buf)) void blkbuf_dirty(bbuf_t buf); void blkbuf_schedule_sync(bbuf_t buf); void blkbuf_release(struct blkbuf_cache* bc); void blkbuf_put(bbuf_t buf); bool blkbuf_syncall(struct blkbuf_cache* bc, bool async); #endif /* __LUNAIX_BLKBUF_H */