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