1 |
/* ??? |
/* Copyright 2002 Johan Rydberg, jrydberg@rtmk.org. |
|
Copyright 2002 Johan Rydberg, jrydberg@rtmk.org. |
|
2 |
|
|
3 |
This program is free software; you can redistribute it and/or modify |
This program is free software; you can redistribute it and/or modify |
4 |
it under the terms of the GNU General Public License as published by |
it under the terms of the GNU General Public License as published by |
17 |
#ifndef _IO_BUF_H |
#ifndef _IO_BUF_H |
18 |
#define _IO_BUF_H 1 |
#define _IO_BUF_H 1 |
19 |
|
|
20 |
#include "proc.h" |
#include <stdio.h> |
|
#include "vfs.h" |
|
21 |
#include "queue.h" |
#include "queue.h" |
22 |
|
#include <pthread.h> |
23 |
|
#include "proc.h" |
24 |
|
|
25 |
/* The buffer header describes an I/O operation in the kernel. */ |
struct vnode; |
|
|
|
|
#define B_READ 1 |
|
|
#define B_WRITE 2 |
|
26 |
|
|
27 |
|
/* Block devices uses a block buffer cache. The buffer |
28 |
|
cache consists of a number of buffer headers (see below), |
29 |
|
each of which can point to a peice of memory, as well as |
30 |
|
to a device number and a block number on the device. |
31 |
|
|
32 |
|
The buffer header for blocks not currently in use are kept |
33 |
|
in several linked lists. */ |
34 |
struct io_buf |
struct io_buf |
35 |
{ |
{ |
36 |
struct queue_entry b_hashq; |
struct queue_entry hashq; |
37 |
struct queue_entry b_lruq; |
struct queue_entry listq; |
38 |
|
struct queue_entry nodeq; |
39 |
/* Associated proc if B_PHYS set. */ |
pthread_mutex_t mutex; |
40 |
struct proc *b_proc; |
pthread_cond_t cond; |
41 |
|
struct vnode *vp; |
42 |
/* Flags associated with the buffer. */ |
int flags; |
43 |
volatile unsigned int b_flags; |
void *data; |
44 |
|
size_t size; |
45 |
/* Error value (errno value). */ |
size_t bcount; |
46 |
int b_error; |
size_t resid; |
47 |
|
dev_t dev; |
48 |
/* Allocated buffer size (in any), valid bytes in buffer, |
void **loc; |
49 |
and remaining I/O. ??? should we use size_t? */ |
int error; |
50 |
size_t b_bufsize; |
void (*iodone) (struct io_buf *bp); |
51 |
size_t b_bcount; |
void *private; |
52 |
size_t b_resid; |
off_t lblkno; |
53 |
|
off_t blkno; |
54 |
/* Memory, superblocks, indirect etc. */ |
off_t rblkno; |
55 |
void *b_data; |
off_t dircookie; |
|
|
|
|
/* Device associated with buffer. */ |
|
|
dev_t b_dev; |
|
|
|
|
|
/* Logical block number, underlying physical block number |
|
|
(partition relative) and raw underlying phys block (not part rel). */ |
|
|
off_t b_lblkno; |
|
|
off_t b_blkno; |
|
|
off_t b_rblkno; |
|
|
|
|
|
/* Function to call unpon completion of I/O transaction. */ |
|
|
void (*b_iodone) (struct io_buf *); |
|
|
|
|
|
/* File vnode associated with buffer. */ |
|
|
struct vnode *b_vp; |
|
|
|
|
|
/* Private data for owner of buffer. */ |
|
|
void *b_private; |
|
|
|
|
|
/* Offset cookie for dir block. */ |
|
|
off_t b_dcookie; |
|
56 |
}; |
}; |
57 |
|
|
58 |
/* Grab a new buffer structure. SIZE is number of data bytes for |
/* FLAGS above are the following: */ |
59 |
buffer. If we fail to allocate, return NULL. */ |
#define B_FREE 0x00000001 |
60 |
extern struct io_buf *io_buf_get (size_t size); |
#define B_AGE 0x00000002 |
61 |
|
#define B_LRU 0x00000004 |
62 |
/* Create new buffer that holds DATA. SIZE is number of bytes |
#define B_READ 0x00000010 |
63 |
that can be put into DATA. Returns buf structure. */ |
#define B_ERROR 0x00000020 |
64 |
extern struct io_buf *io_buf_init (void *data, size_t size); |
#define B_BUSY 0x00000040 |
65 |
|
#define B_INVAL 0x00000080 |
66 |
extern int io_bread (struct vnode *vp, unsigned int blkno, size_t size, |
#define B_DATA 0x00000100 |
67 |
struct io_buf **bpp); |
#define B_WANTED 0x00000200 |
68 |
|
#define B_DELWRITE 0x00000400 |
69 |
/* Release reference to I/O buffer BP. If Reference counter |
#define B_EINTR 0x00000800 |
70 |
drops to zero - free resources held by buffer. */ |
#define B_NOCACHE 0x00001000 |
71 |
extern void io_brelease (struct io_buf *bp); |
#define B_VFLUSH 0x00002000 |
72 |
|
#define B_CACHE 0x00004000 |
73 |
|
#define B_ASYNC 0x00008000 |
74 |
|
#define B_DONE 0x00010000 |
75 |
|
#define B_VNCLEAN 0x10000000 /* buffer on vnode clean list. */ |
76 |
|
#define B_VNDIRTY 0x20000000 /* buffer on vnode dirty list. */ |
77 |
|
#define B_CACHEQ 0x40000000 /* buffer on cache list. */ |
78 |
|
|
79 |
|
/* Number of buffers initialized when the system is brought |
80 |
|
up (bootstrapped). This can not be increased while running. */ |
81 |
|
#define NBUFFERS 100 |
82 |
|
|
83 |
|
/* Maximum size of a buffer. Instead of adjusting this, adjust |
84 |
|
the NBUFFERS value. Total memory that the buffer system can |
85 |
|
allocate is NBUFFERS * MAXBUFSIZE bytes. */ |
86 |
|
#define MAXBUFSIZE (64 * 1024) |
87 |
|
|
88 |
|
/* Read disk block BLKNO (SIZE bytes) from VP. |
89 |
|
Return buffer in *BPP. Process's ucreds in UCRED. */ |
90 |
|
int io_buf_read (struct vnode *vp, off_t blkno, size_t size, |
91 |
|
struct ucred *ucred, struct io_buf **bpp); |
92 |
|
|
93 |
|
/* Mark buffer dirty, but do not release it. */ |
94 |
|
void io_buf_mark_dirty (struct io_buf *bp); |
95 |
|
|
96 |
|
/* Mark I/O complete on a buffer. If a callback has been |
97 |
|
requested, e.g. the pageout daemon, do so. Otherwise, |
98 |
|
awaken waiting processes. */ |
99 |
|
void io_buf_done (struct io_buf *bp); |
100 |
|
|
101 |
|
/* Release buffer BP on to the free lists. */ |
102 |
|
void io_buf_release (struct io_buf *bp); |
103 |
|
|
104 |
|
/* Wait for operations on buffer BP to complete. |
105 |
|
When they do, extract and return the I/O's error value. */ |
106 |
|
int io_buf_wait (struct io_buf *bp); |
107 |
|
|
108 |
|
/* Get a block of requested SIZE that is associated with |
109 |
|
given vnode VP and block offset BLKNO. If it is found |
110 |
|
in the block cache, mark it as having been found, |
111 |
|
make it busy and return it. Otherwise, return an empty |
112 |
|
block of the correct size. |
113 |
|
|
114 |
|
It is up to the caller to insure that the cached blocks |
115 |
|
be of the correct size. */ |
116 |
|
struct io_buf *io_buf_getblk (struct vnode *vp, off_t blkno, |
117 |
|
size_t size); |
118 |
|
|
119 |
|
|
120 |
|
/* Expand or contract the actual memory allocated to BP. |
121 |
|
|
122 |
|
If the buffer shrinks, data is lost, so it's up to the |
123 |
|
caller to have written it out *first*; this routine will not |
124 |
|
start a write. If the buffer grows, it's the callers |
125 |
|
responsibility to fill out the buffer's additional contents. */ |
126 |
|
void io_buf_adjust_size (struct io_buf *bp, size_t size); |
127 |
|
|
128 |
|
/* Read disk block BLKNO (SIZE bytes) from VP. |
129 |
|
Return buffer in *BPP. */ |
130 |
|
int io_buf_read (struct vnode *vp, off_t blkno, size_t size, |
131 |
|
struct ucred *ucred, struct io_buf **bpp); |
132 |
|
|
133 |
|
/* Read-ahead multiple disk blocks. |
134 |
|
The first, BLKNO, is sync, the rest async. Block offsets |
135 |
|
and buffer sizes listed in RABLKS and RASIZES. Number of |
136 |
|
read-ahead buffers in NRABLKS. */ |
137 |
|
int io_buf_read_ahead (struct vnode *vp, off_t blkno, size_t size, |
138 |
|
off_t rablks[], size_t rasizes[], int nrablks, |
139 |
|
struct ucred *ucred, struct io_buf **bpp); |
140 |
|
|
141 |
|
/* Associate buffer BP with vnode VP. The buffer |
142 |
|
will hold a reference to the vnode. */ |
143 |
|
void io_buf_associate (struct vnode *vp, struct io_buf *bp); |
144 |
|
|
145 |
|
/* Disassociate buffer BP from vnode VP. |
146 |
|
This removes the buffer for {clean|dirty} queue in vnode. */ |
147 |
|
void io_buf_disassociate (struct io_buf *bp); |
148 |
|
|
149 |
|
/* Reassign buffer BP from one vnode to new vnode NEWVP. |
150 |
|
Used to assign file specific control information |
151 |
|
(indirect blocks) to the vnode to which they belong. */ |
152 |
|
void io_buf_reassign (struct io_buf *bp, struct vnode *newvp); |
153 |
|
|
154 |
|
/* Initialize the I/O buffer system. */ |
155 |
|
void io_buf_init (void); |
156 |
|
|
157 |
#endif /* _IO_BUF_H */ |
#endif /* io-buf.h */ |