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