Buffer heads to track page mappings -> block num
[akaros.git] / kern / include / blockdev.h
1 /* Copyright (c) 2010 The Regents of the University of California
2  * Barret Rhoden <brho@cs.berkeley.edu>
3  * See LICENSE for details.
4  *
5  * Block device interfaces and structures */
6
7 #ifndef ROS_KERN_BLOCKDEV_H
8 #define ROS_KERN_BLOCKDEV_H
9
10 #include <ros/common.h>
11 #include <kref.h>
12 #include <slab.h>
13
14 /* All block IO is done assuming a certain size sector, which is the smallest
15  * possible unit of transfer between the kernel and the block layer.  This can
16  * be bigger than what the underlying hardware can handle, but it shouldn't be
17  * smaller than any higher-level block (like an FS block, which are often 1 KB).
18  */
19 #define SECTOR_SZ_LOG 9
20 #define SECTOR_SZ (1 << SECTOR_SZ_LOG)
21
22 /* Every block device is represented by one of these, with custom methods, as
23  * applicable for the type of device.  Subject to massive changes. */
24 #define BDEV_INLINE_NAME 10
25 struct block_device {
26         int                                                     b_id;
27         unsigned int                            b_sector_size;          /* HW sector size */
28         unsigned long                           b_num_sectors;          /* Total sectors on dev */
29         struct kref                                     b_kref;
30         void                                            *b_data;                        /* dev-specific use */
31         char                                            b_name[BDEV_INLINE_NAME];
32         // TODO: list or something of buffer heads (?)
33         // list of outstanding requests
34         // io scheduler
35         // callbacks for completion
36 };
37
38 /* Not sure which of these we'll need, if any */
39 #define BH_LOCKED               0x001   /* involved in an IO op */
40 #define BH_UPTODATE             0x002   /* buffer is filled with file data */
41 #define BH_DIRTY                0x004   /* buffer is dirty */
42
43 /* This maps to and from a buffer within a page to a block(s) on a bdev.  Some
44  * of it might not be needed later, etc (page, numblock). */
45 struct buffer_head {
46         struct page                                     *bh_page;                       /* redundant with buffer */
47         void                                            *bh_buffer;
48         unsigned int                            bh_flags;
49         struct buffer_head                      *bh_next;                       /* circular LL of BHs */
50         struct block_device                     *bh_bdev;
51         unsigned long                           bh_blocknum;
52         unsigned int                            bh_numblock;            /* length (in blocks) */
53 };
54 struct kmem_cache *bh_kcache;
55
56 /* This encapsulates the work of a request (instead of having a variety of
57  * slightly-different functions for things like read/write and scatter-gather
58  * ops).  Reads and writes are essentially the same, so all we need is a flag to
59  * differentiate.  This struct also serves as a tool to track the progress of a
60  * block request throughout its servicing.  This is analagous to Linux's struct
61  * bio.
62  *
63  * For now, this just holds the stuff to do some simple sector reading. */
64 struct block_request {
65         int                                                     flags;
66         void                                            *buffer;
67         unsigned int                            first_sector;
68         unsigned int                            amount;
69 };
70 struct kmem_cache *breq_kcache; /* for the block requests */
71
72 /* Block request flags */
73 #define BREQ_READ                       0x001
74 #define BREQ_WRITE                      0x002
75
76 void block_init(void);
77 struct block_device *get_bdev(char *path);
78 void free_bhs(struct page *page);
79 /* This function will probably be the one that blocks */
80 int make_request(struct block_device *bdev, struct block_request *req);
81
82 #endif /* ROS_KERN_BLOCKDEV_H */