dev: implement reading from block devices
reading from block devices is done using the block cache (bcache). This cache stores sectors from a block device in pages of memory marked as 'cached', which will allow them to be reclaimed when memory pressure is high (TODO). while block device drivers implement callbacks allowing reading/writing at block-granularity, the device subsystem uses the block cache to implement reading/writing at byte-granularity in a driver-agnostic way. block drivers can disable the block cache for their devices, but this will require that any clients communicate with the devices at block-granularity. also added an offset parameter to device and object read/write functions/callbacks.
This commit is contained in:
@@ -5,6 +5,8 @@
|
||||
#include <socks/types.h>
|
||||
#include <socks/status.h>
|
||||
#include <socks/queue.h>
|
||||
#include <socks/btree.h>
|
||||
#include <socks/bitmap.h>
|
||||
#include <socks/locks.h>
|
||||
#include <socks/machine/vm.h>
|
||||
|
||||
@@ -12,6 +14,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct bcache;
|
||||
|
||||
/* maximum number of NUMA nodes */
|
||||
#define VM_MAX_NODES 64
|
||||
/* maximum number of memory zones per node */
|
||||
@@ -21,6 +25,11 @@ extern "C" {
|
||||
/* maximum number of sparse memory sectors */
|
||||
#define VM_MAX_SECTORS 1024
|
||||
|
||||
/* maximum number of disk sectors that can be stored in a single
|
||||
page. AKA the number of bits in the sector bitmap.
|
||||
used by the block cache */
|
||||
#define VM_MAX_SECTORS_PER_PAGE 32
|
||||
|
||||
#define VM_CHECK_ALIGN(p, mask) ((((p) & (mask)) == (p)) ? 1 : 0)
|
||||
|
||||
#define VM_CACHE_INITIALISED(c) ((c)->c_obj_count != 0)
|
||||
@@ -108,6 +117,8 @@ enum vm_page_flags {
|
||||
VM_PAGE_HEAD = 0x04u,
|
||||
/* page is part of a huge-page */
|
||||
VM_PAGE_HUGE = 0x08u,
|
||||
/* page is holding cached data from secondary storage, and can be freed if necessary (and not dirty). */
|
||||
VM_PAGE_CACHE = 0x10u,
|
||||
};
|
||||
|
||||
enum vm_memory_region_status {
|
||||
@@ -210,18 +221,40 @@ struct vm_page {
|
||||
|
||||
uint32_t p_flags;
|
||||
|
||||
/* multi-purpose list.
|
||||
/* owner-specific pointer */
|
||||
union {
|
||||
struct vm_slab *p_slab;
|
||||
struct bcache *p_bcache;
|
||||
void *p_priv0;
|
||||
};
|
||||
|
||||
/* multi-purpose list/tree entry.
|
||||
the owner of the page can decide what to do with this.
|
||||
some examples:
|
||||
- the buddy allocator uses this to maintain its per-zone free-page lists.
|
||||
- the block cache uses this to maintain a tree of pages keyed by block number.
|
||||
*/
|
||||
struct queue_entry p_list;
|
||||
|
||||
/* owner-specific data */
|
||||
union {
|
||||
struct vm_slab *p_slab;
|
||||
struct queue_entry p_list;
|
||||
struct btree_node p_bnode;
|
||||
|
||||
/* btree_node contains three pointers, so provide three pointer-sized integers for
|
||||
use if p_bnode isn't needed. */
|
||||
uintptr_t priv1[3];
|
||||
};
|
||||
|
||||
union {
|
||||
/* used by bcache when sector size is < page size. bitmap of present/missing sectors */
|
||||
DECLARE_BITMAP(p_blockbits, VM_MAX_SECTORS_PER_PAGE);
|
||||
uint32_t p_priv2;
|
||||
};
|
||||
|
||||
union {
|
||||
/* sector address, used by bcache */
|
||||
sectors_t p_blockid;
|
||||
|
||||
uint32_t p_priv3[2];
|
||||
};
|
||||
} __attribute__((aligned(2 * sizeof(unsigned long))));
|
||||
|
||||
/* represents a sector of memory, containing its own array of vm_pages.
|
||||
|
||||
Reference in New Issue
Block a user