Remove mon_gfp()
[akaros.git] / kern / include / blockdev.h
index 1742026..19ca8d9 100644 (file)
@@ -4,12 +4,13 @@
  *
  * Block device interfaces and structures */
 
-#ifndef ROS_KERN_BLOCKDEV_H
-#define ROS_KERN_BLOCKDEV_H
+#pragma once
 
 #include <ros/common.h>
 #include <kref.h>
 #include <slab.h>
+#include <pagemap.h>
+#include <kthread.h>
 
 /* All block IO is done assuming a certain size sector, which is the smallest
  * possible unit of transfer between the kernel and the block layer.  This can
 #define BDEV_INLINE_NAME 10
 struct block_device {
        int                                                     b_id;
-       unsigned int                            b_sector_size;          /* HW sector size */
-       unsigned long                           b_num_sectors;          /* Total sectors on dev */
+       unsigned int                            b_sector_sz;            /* HW sector size */
+       unsigned long                           b_nr_sector;            /* Total sectors on dev */
        struct kref                                     b_kref;
+       struct page_map                         b_pm;
        void                                            *b_data;                        /* dev-specific use */
        char                                            b_name[BDEV_INLINE_NAME];
        // TODO: list or something of buffer heads (?)
@@ -35,10 +37,11 @@ struct block_device {
        // callbacks for completion
 };
 
-/* Not sure which of these we'll need, if any */
+/* So far, only NEEDS_ZEROED is used */
 #define BH_LOCKED              0x001   /* involved in an IO op */
 #define BH_UPTODATE            0x002   /* buffer is filled with file data */
 #define BH_DIRTY               0x004   /* buffer is dirty */
+#define BH_NEEDS_ZEROED        0x008   /* buffer should be 0'd, not read in */
 
 /* This maps to and from a buffer within a page to a block(s) on a bdev.  Some
  * of it might not be needed later, etc (page, numblock). */
@@ -48,11 +51,18 @@ struct buffer_head {
        unsigned int                            bh_flags;
        struct buffer_head                      *bh_next;                       /* circular LL of BHs */
        struct block_device                     *bh_bdev;
-       unsigned long                           bh_blocknum;
-       unsigned int                            bh_numblock;            /* length (in blocks) */
+       unsigned long                           bh_sector;
+       unsigned int                            bh_nr_sector;           /* length (in sectors) */
 };
 struct kmem_cache *bh_kcache;
 
+/* Buffer Head Requests.  For now, just use these for dealing with non-file IO
+ * on a block device.  Tell it what size you think blocks are. */
+struct buffer_head *bdev_get_buffer(struct block_device *bdev,
+                                    unsigned long blk_num, unsigned int blk_sz);
+void bdev_dirty_buffer(struct buffer_head *bh);
+void bdev_put_buffer(struct buffer_head *bh);
+
 /* This encapsulates the work of a request (instead of having a variety of
  * slightly-different functions for things like read/write and scatter-gather
  * ops).  Reads and writes are essentially the same, so all we need is a flag to
@@ -60,12 +70,19 @@ struct kmem_cache *bh_kcache;
  * block request throughout its servicing.  This is analagous to Linux's struct
  * bio.
  *
- * For now, this just holds the stuff to do some simple sector reading. */
+ * bhs normally points to the inline version (enough for a page).  kmalloc
+ * another array of BH pointers if you want more.  The BHs do not need to be
+ * linked or otherwise associated with a page mapping. */
+#define NR_INLINE_BH (PGSIZE >> SECTOR_SZ_LOG)
+struct block_request;
 struct block_request {
-       int                                                     flags;
-       void                                            *buffer;
-       unsigned int                            first_sector;
-       unsigned int                            amount;
+       unsigned int                            flags;
+       void                                            (*callback)(struct block_request *breq);
+       void                                            *data;
+       struct semaphore                        sem;
+       struct buffer_head                      **bhs;                          /* BHs describing the IOs */
+       unsigned int                            nr_bhs;
+       struct buffer_head                      *local_bhs[NR_INLINE_BH];
 };
 struct kmem_cache *breq_kcache;        /* for the block requests */
 
@@ -76,7 +93,6 @@ struct kmem_cache *breq_kcache;       /* for the block requests */
 void block_init(void);
 struct block_device *get_bdev(char *path);
 void free_bhs(struct page *page);
-/* This function will probably be the one that blocks */
-int make_request(struct block_device *bdev, struct block_request *req);
-
-#endif /* ROS_KERN_BLOCKDEV_H */
+int bdev_submit_request(struct block_device *bdev, struct block_request *breq);
+void generic_breq_done(struct block_request *breq);
+void sleep_on_breq(struct block_request *breq);