#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 */
// 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). */
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
* 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 */
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);
+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);
#endif /* ROS_KERN_BLOCKDEV_H */