1 | /*
2 | block_dev.h
3 | -----------
4 | $Id: block_dev.h,v 1.13 2003/10/01 05:42:06 stewart Exp $
5 |
6 | Designed to be rather similar to the Linux Buffer Cache,
7 | i.e. with functions like bread() et al that function similarly.
8 | Should allow testing and development of filesystems purely in
9 | userspace and purely in an application.
10 | User Mode Linux could be used for this, but this suite is designed
11 | for even earlier in the design process.
12 |
13 | (C)2003 Stewart Smith
14 | Distributed under the GNU Public License.
15 |
16 | Some data structures have been constructed out of those
17 | present in the Linux Kernel (v2.5.69). They are copyright
18 | of their respective owners.
19 | */
20 |
21 | #ifndef __BLOCK_DEV_H__
22 | #define __BLOCK_DEV_H__
23 |
24 | #include "types.h"
25 | #include "bitops.h"
26 | #include <glib.h>
27 |
28 | /*
29 | struct block_device
30 | -------------------
31 | A really simple block_device structure.
32 | $Id: block_dev.h,v 1.13 2003/10/01 05:42:06 stewart Exp $
33 | */
34 | struct block_device {
35 | char* name;
36 | int file_on_disk;
37 | u64 block_size;
38 | u64 num_blocks;
39 |
40 | /* Internal */
41 | u64 cache_hit;
42 | u64 cache_hit_clear;
43 | u64 cache_miss;
44 | u64 cache_miss_clear;
45 | };
46 |
47 | struct super_block {
48 | //struct list_head s_list; /* Keep this first */
49 | //dev_t s_dev; /* search index; _not_ kdev_t */
50 | unsigned long s_blocksize;
51 | unsigned long s_old_blocksize;
52 | unsigned char s_blocksize_bits;
53 | unsigned char s_dirt;
54 | unsigned long long s_maxbytes; /* Max file size */
55 | //struct file_system_type *s_type;
56 | //struct super_operations *s_op;
57 | //struct dquot_operations *dq_op;
58 | //struct quotactl_ops *s_qcop;
59 | //struct export_operations *s_export_op;
60 | unsigned long s_flags;
61 | unsigned long s_magic;
62 | //struct dentry *s_root;
63 | //struct rw_semaphore s_umount;
64 | //struct semaphore s_lock;
65 | int s_count;
66 | int s_syncing;
67 | int s_need_sync_fs;
68 | //atomic_t s_active;
69 | void *s_security;
70 |
71 | //struct list_head s_dirty; /* dirty inodes */
72 | //struct list_head s_io; /* parked for writeback */
73 | //struct hlist_head s_anon; /* anonymous dentries for (nfs) exporting */
74 | //struct list_head s_files;
75 |
76 | struct block_device *s_bdev;
77 | //struct list_head s_instances;
78 | //struct quota_info s_dquot; /* Diskquota specific options */
79 |
80 | char s_id[32]; /* Informational name */
81 |
82 | //struct kobject kobj; /* anchor for sysfs */
83 | void *s_fs_info; /* Filesystem private info */
84 |
85 | /*
86 | * The next field is for VFS *only*. No filesystems have any business
87 | * even looking at it. You had been warned.
88 | */
89 | // struct semaphore s_vfs_rename_sem; /* Kludge */
90 | };
91 |
92 | /*
93 | bh_state-bits
94 | -------------
95 | straight from include/linux/buffer_head.h (kernel 2.5.69)
96 | */
97 | enum bh_state_bits {
98 | BH_Uptodate, /* Contains valid data */
99 | BH_Dirty, /* Is dirty */
100 | BH_Lock, /* Is locked */
101 | BH_Req, /* Has been submitted for I/O */
102 |
103 | BH_Mapped, /* Has a disk mapping */
104 | BH_New, /* Disk mapping was newly created by get_block */
105 | BH_Async_Read, /* Is under end_buffer_async_read I/O */
106 | BH_Async_Write, /* Is under end_buffer_async_write I/O */
107 | BH_Delay, /* Buffer is not yet allocated on disk */
108 |
109 | BH_Boundary, /* Block is followed by a discontiguity */
110 | BH_PrivateStart,/* not a state bit, but the first bit available
111 | * for private allocation by other entities
112 | */
113 | };
114 |
115 | /*
116 | buffer_head
117 | -----------
118 | straight from include/linux/buffer_head.h (kernel 2.5.69)
119 | We've comment out things we don't really care too much about.
120 | $Id: block_dev.h,v 1.13 2003/10/01 05:42:06 stewart Exp $
121 | */
122 | struct buffer_head {
123 |
124 | unsigned long b_state; /* buffer state bitmap (see above) */
125 | atomic_t b_count; /* users using this block */
126 | struct buffer_head *b_this_page;/* circular list of page's buffers */
127 | // struct page *b_page; /* the page this bh is mapped to */
128 |
129 | sector_t b_blocknr; /* block number */
130 | u32 b_size; /* block size */
131 | char *b_data; /* pointer to data block */
132 |
133 | struct block_device *b_bdev;
134 | // bh_end_io_t *b_end_io; /* I/O completion */
135 | // void *b_private; /* reserved for b_end_io */
136 | // struct list_head b_assoc_buffers; /* associated with another mapping */
137 | };
138 |
139 | /*
140 | Macro tricks to exapnd the set_buffer_foo(), clear_buffer_foo()
141 | and buffer_foo() functions
142 | */
143 | #define BUFFER_FNS(bit,name) \
144 | static inline void set_buffer_##name(struct buffer_head *bh) \
145 | { \
146 | set_bit(BH_##bit, &(bh)->b_state);\
147 | } \
148 | static inline void clear_buffer_##name(struct buffer_head *bh) \
149 | { \
150 | clear_bit(BH_##bit, &(bh)->b_state); \
151 | } \
152 | static inline int buffer_##name(struct buffer_head *bh) \
153 | { \
154 | return test_bit(BH_##bit, &(bh)->b_state); \
155 | }
156 |
157 | /*
158 | test_set_buffer_foo() and test_clear_buffer_foo()
159 | */
160 | #define TAS_BUFFER_FNS(bit, name) \
161 | static inline int test_set_buffer_##name(struct buffer_head *bh) \
162 | { \
163 | return test_and_set_bit(BH_##bit, &(bh)->b_state); \
164 | } \
165 | static inline int test_clear_buffer_##name(struct buffer_head *bh) \
166 | { \
167 | return test_and_clear_bit(BH_##bit, &(bh)->b_state); \
168 | }
169 |
170 | /*
171 | Emit the buffer bitops functions.
172 | */
173 | BUFFER_FNS(Uptodate,uptodate)
174 | BUFFER_FNS(Dirty,dirty)
175 | TAS_BUFFER_FNS(Dirty,dirty)
176 | BUFFER_FNS(Lock,locked)
177 | TAS_BUFFER_FNS(Lock,locked)
178 | BUFFER_FNS(Req,req)
179 | BUFFER_FNS(Mapped,mapped)
180 | BUFFER_FNS(New,new)
181 | BUFFER_FNS(Async_Read,async_read)
182 | BUFFER_FNS(Async_Write,async_write)
183 | BUFFER_FNS(Delay,delay)
184 | BUFFER_FNS(Boundary,boundary)
185 |
186 |
187 |
188 | /*
189 | for submit_bh
190 | */
191 | #define READ 1
192 | #define WRITE 2
193 |
194 | /*
195 | our function definitions. Mostly glue.
196 | */
197 | int block_dev_new(struct block_device* b, const char* file, u64 block_size, u64 num_blocks);
198 | int block_dev_close(struct block_device *b);
199 |
200 | struct buffer_head *bnew(struct block_device *b, sector_t block, int size);
201 |
202 | /*
203 | function definitions pretty much straight out of include/linux/block_head.h
204 | */
205 | struct buffer_head *bread(struct block_device *b, sector_t block, int size);
206 |
207 | /*
208 | reads block as per super block info
209 | */
210 | static inline struct buffer_head *
211 | sb_bread(struct super_block *sb, sector_t block)
212 | {
213 | return bread(sb->s_bdev, block, sb->s_blocksize);
214 | }
215 |
216 | void block_dev_init();
217 |
218 | void submit_bh(int rw,struct buffer_head * bh);
219 |
220 | #endif