Second Extended Filesystem (ext2) and other improvements (#33)
[lunaix-os.git] / lunaix-os / includes / lunaix / blkbuf.h
diff --git a/lunaix-os/includes/lunaix/blkbuf.h b/lunaix-os/includes/lunaix/blkbuf.h
new file mode 100644 (file)
index 0000000..decf92f
--- /dev/null
@@ -0,0 +1,110 @@
+#ifndef __LUNAIX_BLKBUF_H
+#define __LUNAIX_BLKBUF_H
+
+#include <lunaix/blkio.h>
+#include <lunaix/bcache.h>
+#include <lunaix/block.h>
+#include <lunaix/ds/mutex.h>
+
+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 */