vmrunkernel: load the file using the ELF library
[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 #pragma once
8
9 #include <ros/common.h>
10 #include <kref.h>
11 #include <slab.h>
12 #include <pagemap.h>
13 #include <kthread.h>
14
15 /* All block IO is done assuming a certain size sector, which is the smallest
16  * possible unit of transfer between the kernel and the block layer.  This can
17  * be bigger than what the underlying hardware can handle, but it shouldn't be
18  * smaller than any higher-level block (like an FS block, which are often 1 KB).
19  */
20 #define SECTOR_SZ_LOG 9
21 #define SECTOR_SZ (1 << SECTOR_SZ_LOG)
22
23 /* Every block device is represented by one of these, with custom methods, as
24  * applicable for the type of device.  Subject to massive changes. */
25 #define BDEV_INLINE_NAME 10
26 struct block_device {
27         int                                                     b_id;
28         unsigned int                            b_sector_sz;            /* HW sector size */
29         unsigned long                           b_nr_sector;            /* Total sectors on dev */
30         struct kref                                     b_kref;
31         struct page_map                         b_pm;
32         void                                            *b_data;                        /* dev-specific use */
33         char                                            b_name[BDEV_INLINE_NAME];
34         // TODO: list or something of buffer heads (?)
35         // list of outstanding requests
36         // io scheduler
37         // callbacks for completion
38 };
39
40 /* So far, only NEEDS_ZEROED is used */
41 #define BH_LOCKED               0x001   /* involved in an IO op */
42 #define BH_UPTODATE             0x002   /* buffer is filled with file data */
43 #define BH_DIRTY                0x004   /* buffer is dirty */
44 #define BH_NEEDS_ZEROED 0x008   /* buffer should be 0'd, not read in */
45
46 /* This maps to and from a buffer within a page to a block(s) on a bdev.  Some
47  * of it might not be needed later, etc (page, numblock). */
48 struct buffer_head {
49         struct page                                     *bh_page;                       /* redundant with buffer */
50         void                                            *bh_buffer;
51         unsigned int                            bh_flags;
52         struct buffer_head                      *bh_next;                       /* circular LL of BHs */
53         struct block_device                     *bh_bdev;
54         unsigned long                           bh_sector;
55         unsigned int                            bh_nr_sector;           /* length (in sectors) */
56 };
57 struct kmem_cache *bh_kcache;
58
59 /* Buffer Head Requests.  For now, just use these for dealing with non-file IO
60  * on a block device.  Tell it what size you think blocks are. */
61 struct buffer_head *bdev_get_buffer(struct block_device *bdev,
62                                     unsigned long blk_num, unsigned int blk_sz);
63 void bdev_dirty_buffer(struct buffer_head *bh);
64 void bdev_put_buffer(struct buffer_head *bh);
65
66 /* This encapsulates the work of a request (instead of having a variety of
67  * slightly-different functions for things like read/write and scatter-gather
68  * ops).  Reads and writes are essentially the same, so all we need is a flag to
69  * differentiate.  This struct also serves as a tool to track the progress of a
70  * block request throughout its servicing.  This is analagous to Linux's struct
71  * bio.
72  *
73  * bhs normally points to the inline version (enough for a page).  kmalloc
74  * another array of BH pointers if you want more.  The BHs do not need to be
75  * linked or otherwise associated with a page mapping. */
76 #define NR_INLINE_BH (PGSIZE >> SECTOR_SZ_LOG)
77 struct block_request;
78 struct block_request {
79         unsigned int                            flags;
80         void                                            (*callback)(struct block_request *breq);
81         void                                            *data;
82         struct semaphore                        sem;
83         struct buffer_head                      **bhs;                          /* BHs describing the IOs */
84         unsigned int                            nr_bhs;
85         struct buffer_head                      *local_bhs[NR_INLINE_BH];
86 };
87 struct kmem_cache *breq_kcache; /* for the block requests */
88
89 /* Block request flags */
90 #define BREQ_READ                       0x001
91 #define BREQ_WRITE                      0x002
92
93 void block_init(void);
94 struct block_device *get_bdev(char *path);
95 void free_bhs(struct page *page);
96 int bdev_submit_request(struct block_device *bdev, struct block_request *breq);
97 void generic_breq_done(struct block_request *breq);
98 void sleep_on_breq(struct block_request *breq);