Merge branch 'master' into isa/arm64
[lunaix-os.git] / lunaix-os / includes / lunaix / blkbuf.h
1 #ifndef __LUNAIX_BLKBUF_H
2 #define __LUNAIX_BLKBUF_H
3
4 #include <lunaix/blkio.h>
5 #include <lunaix/bcache.h>
6 #include <lunaix/block.h>
7 #include <lunaix/ds/mutex.h>
8
9 struct blkbuf_cache
10 {
11     union {
12         struct {
13             unsigned int blksize;
14         };
15         struct bcache cached;
16     };
17     struct llist_header dirty;
18     struct block_dev* blkdev;
19     mutex_t lock;
20 };
21
22 struct blk_buf {
23     void* raw;
24     bcobj_t cobj;
25     struct llist_header dirty;
26     struct blkio_req* breq;
27 };
28
29 typedef void* bbuf_t;
30
31 #define BLOCK_BUFFER(type, name)    \
32     union {                         \
33         type* name;                 \
34         bbuf_t bb_##name;             \
35     }
36
37 #define INVL_BUFFER      0xdeadc0de
38
39 #define bbuf_null        ((bbuf_t)0)
40
41 static inline bool
42 blkbuf_errbuf(bbuf_t buf) {
43     return (ptr_t)buf == INVL_BUFFER;
44 }
45
46 static inline bool
47 blkbuf_nullbuf(bbuf_t buf) {
48     return buf == bbuf_null;
49 }
50
51 static inline unsigned int
52 blkbuf_id(bbuf_t buf) 
53 {
54     return to_bcache_node(((struct blk_buf*)buf)->cobj)->tag;
55 }
56
57 static inline unsigned int
58 blkbuf_refcounts(bbuf_t buf) 
59 {
60     return to_bcache_node(((struct blk_buf*)buf)->cobj)->refs;
61 }
62
63 static inline bool
64 blkbuf_not_shared(bbuf_t buf)
65 {
66     return blkbuf_refcounts(buf) == 1;
67 }
68
69
70 struct blkbuf_cache*
71 blkbuf_create(struct block_dev* blkdev, unsigned int blk_size);
72
73 bbuf_t
74 blkbuf_take(struct blkbuf_cache* bc, unsigned int block_id);
75
76 static inline bbuf_t
77 blkbuf_refonce(bbuf_t buf)
78 {
79     if (likely(buf && !blkbuf_errbuf(buf))) {
80         bcache_refonce(((struct blk_buf*)buf)->cobj);
81     }
82
83     return buf;
84 }
85
86 static inline void*
87 blkbuf_data(bbuf_t buf) 
88 {
89     assert(!blkbuf_errbuf(buf));
90     return ((struct blk_buf*)buf)->raw;
91 }
92 #define block_buffer(buf, type) \
93     ((type*)blkbuf_data(buf))
94
95 void
96 blkbuf_dirty(bbuf_t buf);
97
98 void
99 blkbuf_schedule_sync(bbuf_t buf);
100
101 void
102 blkbuf_release(struct blkbuf_cache* bc);
103
104 void
105 blkbuf_put(bbuf_t buf);
106
107 bool
108 blkbuf_syncall(struct blkbuf_cache* bc, bool async);
109
110 #endif /* __LUNAIX_BLKBUF_H */