slkern/diskio.h

84 lines
3.1 KiB
C
Raw Permalink Normal View History

// NEW CODE implementing a simple disk i/o multiplexing layer
#ifndef _DISKIO_H
#define _DISKIO_H
#include "sched.h"
// TODO: Replace BSIZE references in old code with this and/or make it flexible
#define DISKIO_BLOCK_SIZE 4096
typedef struct diskio_buffer diskio_buffer_t;
typedef struct diskio_cache diskio_cache_t;
// NOTE: This still resembles the old structure but will probably be changed
// as different options/backends/etc. are added.
struct diskio_buffer {
diskio_cache_t* owner;
unsigned int referencecount;
int padding;
int isvalid;
int isdisk; // Is this a buffer owned by the disk (rather than the fs code??)
unsigned int device;
unsigned int blocknumber;
sched_sleeplock_t lock;
// Least-recently-used list:
diskio_buffer_t* previous;
diskio_buffer_t* next;
// Block data
unsigned char* data; // TODO: Flexible buffers
};
// The diskio_cache structure should fit in a page, so it must be limited in
// to a few hundred buffer references for now:
#define DISKIO_CACHE_MAXBUFFERS 500
struct diskio_cache {
sched_spinlock_t spin;
diskio_buffer_t* leastrecentlist;
unsigned long long buffercount;
unsigned long long blocksize;
diskio_buffer_t* buffers[DISKIO_CACHE_MAXBUFFERS];
};
// These are the internal allocation functions, a cache pre-allocates a number
// of buffer structures (each representing 1 disk block) then re-allocates them
// on demand from it's internal list.
diskio_buffer_t* diskio_buffer_alloc(diskio_cache_t* owner, unsigned long long blocksize);
void diskio_buffer_free(diskio_buffer_t* buffer);
diskio_cache_t* diskio_cache_alloc(unsigned long long buffercount, unsigned long long blocksize);
void diskio_cache_free(diskio_cache_t* cache);
// These are the internal read/write functions which link to any I/O multiplexing
void diskio_performread(diskio_buffer_t* buffer);
void diskio_performwrite(diskio_buffer_t* buffer);
// Performs a logical write of a buffered block through it's associated cache,
// checks that the buffer is already locked and writes it to the disk.
void diskio_buffer_write(diskio_buffer_t* buffer);
// Performs a logical read of a buffered block through a cache, returning it in
// locked form with the given block.
diskio_buffer_t* diskio_buffer_read(diskio_cache_t* cache, unsigned int device, unsigned int blocknumber);
// (Re-)allocates a buffer from the cache for a given device and block number
// combination, but does NOT attempt to read the block from disk. Returns an
// existing or newly repurposed buffer from the cache in a locked state.
diskio_buffer_t* diskio_buffer_get_noread(diskio_cache_t* cache, unsigned int device, unsigned int blocknumber);
void diskio_buffer_release(diskio_buffer_t* buffer);
void diskio_buffer_reference(diskio_buffer_t* buffer);
void diskio_buffer_dereference(diskio_buffer_t* buffer);
// Used internally for reads/writes to ramdisk devices
void diskio_ramdisk_rw(diskio_buffer_t* buffer, int wr);
struct drives; // Defined properly in drives.h
// Called to mount any available ramdisk images on the given drives structure.
void diskio_mountallramdisks(struct drives* drives);
// From ifndef at top of file:
#endif