84 lines
3.1 KiB
C
84 lines
3.1 KiB
C
// 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
|
|
|