Blame view

include/linux/buffer_head.h 11.7 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
  /*
   * include/linux/buffer_head.h
   *
   * Everything to do with buffer_heads.
   */
  
  #ifndef _LINUX_BUFFER_HEAD_H
  #define _LINUX_BUFFER_HEAD_H
  
  #include <linux/types.h>
  #include <linux/fs.h>
  #include <linux/linkage.h>
  #include <linux/pagemap.h>
  #include <linux/wait.h>
60063497a   Arun Sharma   atomic: use <linu...
15
  #include <linux/atomic.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
16

9361401eb   David Howells   [PATCH] BLOCK: Ma...
17
  #ifdef CONFIG_BLOCK
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
18
19
20
21
22
  enum bh_state_bits {
  	BH_Uptodate,	/* Contains valid data */
  	BH_Dirty,	/* Is dirty */
  	BH_Lock,	/* Is locked */
  	BH_Req,		/* Has been submitted for I/O */
a39722034   Nick Piggin   [PATCH] page_upto...
23
24
25
  	BH_Uptodate_Lock,/* Used by the first bh in a page, to serialise
  			  * IO completion of other buffers in the page
  			  */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
26
27
28
29
30
31
32
33
  
  	BH_Mapped,	/* Has a disk mapping */
  	BH_New,		/* Disk mapping was newly created by get_block */
  	BH_Async_Read,	/* Is under end_buffer_async_read I/O */
  	BH_Async_Write,	/* Is under end_buffer_async_write I/O */
  	BH_Delay,	/* Buffer is not yet allocated on disk */
  	BH_Boundary,	/* Block is followed by a discontiguity */
  	BH_Write_EIO,	/* I/O error on write */
33a266dda   David Chinner   [PATCH] Make BH_U...
34
  	BH_Unwritten,	/* Buffer is allocated on disk but not written */
08bafc034   Keith Mannthey   block: Supress Bu...
35
  	BH_Quiet,	/* Buffer Error Prinks to be quiet */
877f962c5   Theodore Ts'o   buffer: add BH_Pr...
36
37
  	BH_Meta,	/* Buffer contains metadata */
  	BH_Prio,	/* Buffer should be submitted with REQ_PRIO */
7b7a8665e   Christoph Hellwig   direct-io: Implem...
38
  	BH_Defer_Completion, /* Defer AIO completion to workqueue */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
39
40
41
42
43
44
45
46
47
48
49
50
51
52
  
  	BH_PrivateStart,/* not a state bit, but the first bit available
  			 * for private allocation by other entities
  			 */
  };
  
  #define MAX_BUF_PER_PAGE (PAGE_CACHE_SIZE / 512)
  
  struct page;
  struct buffer_head;
  struct address_space;
  typedef void (bh_end_io_t)(struct buffer_head *bh, int uptodate);
  
  /*
205f87f6b   Badari Pulavarty   [PATCH] change bu...
53
54
55
56
57
58
59
   * Historically, a buffer_head was used to map a single block
   * within a page, and of course as the unit of I/O through the
   * filesystem and block layers.  Nowadays the basic I/O unit
   * is the bio, and buffer_heads are used for extracting block
   * mappings (via a get_block_t call), for tracking state within
   * a page (via a page_mapping) and for wrapping bio submission
   * for backward compatibility reasons (e.g. submit_bh).
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
60
61
   */
  struct buffer_head {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
62
63
64
  	unsigned long b_state;		/* buffer state bitmap (see above) */
  	struct buffer_head *b_this_page;/* circular list of page's buffers */
  	struct page *b_page;		/* the page this bh is mapped to */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
65

205f87f6b   Badari Pulavarty   [PATCH] change bu...
66
67
68
  	sector_t b_blocknr;		/* start block number */
  	size_t b_size;			/* size of mapping */
  	char *b_data;			/* pointer to data within the page */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
69
70
71
72
73
  
  	struct block_device *b_bdev;
  	bh_end_io_t *b_end_io;		/* I/O completion */
   	void *b_private;		/* reserved for b_end_io */
  	struct list_head b_assoc_buffers; /* associated with another mapping */
58ff407be   Jan Kara   [PATCH] Fix IO er...
74
75
  	struct address_space *b_assoc_map;	/* mapping this buffer is
  						   associated with */
205f87f6b   Badari Pulavarty   [PATCH] change bu...
76
  	atomic_t b_count;		/* users using this buffer_head */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
  };
  
  /*
   * macro tricks to expand the set_buffer_foo(), clear_buffer_foo()
   * and buffer_foo() functions.
   */
  #define BUFFER_FNS(bit, name)						\
  static inline void set_buffer_##name(struct buffer_head *bh)		\
  {									\
  	set_bit(BH_##bit, &(bh)->b_state);				\
  }									\
  static inline void clear_buffer_##name(struct buffer_head *bh)		\
  {									\
  	clear_bit(BH_##bit, &(bh)->b_state);				\
  }									\
  static inline int buffer_##name(const struct buffer_head *bh)		\
  {									\
  	return test_bit(BH_##bit, &(bh)->b_state);			\
  }
  
  /*
   * test_set_buffer_foo() and test_clear_buffer_foo()
   */
  #define TAS_BUFFER_FNS(bit, name)					\
  static inline int test_set_buffer_##name(struct buffer_head *bh)	\
  {									\
  	return test_and_set_bit(BH_##bit, &(bh)->b_state);		\
  }									\
  static inline int test_clear_buffer_##name(struct buffer_head *bh)	\
  {									\
  	return test_and_clear_bit(BH_##bit, &(bh)->b_state);		\
  }									\
  
  /*
   * Emit the buffer bitops functions.   Note that there are also functions
   * of the form "mark_buffer_foo()".  These are higher-level functions which
   * do something in addition to setting a b_state bit.
   */
  BUFFER_FNS(Uptodate, uptodate)
  BUFFER_FNS(Dirty, dirty)
  TAS_BUFFER_FNS(Dirty, dirty)
  BUFFER_FNS(Lock, locked)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
119
120
121
122
123
124
125
126
127
  BUFFER_FNS(Req, req)
  TAS_BUFFER_FNS(Req, req)
  BUFFER_FNS(Mapped, mapped)
  BUFFER_FNS(New, new)
  BUFFER_FNS(Async_Read, async_read)
  BUFFER_FNS(Async_Write, async_write)
  BUFFER_FNS(Delay, delay)
  BUFFER_FNS(Boundary, boundary)
  BUFFER_FNS(Write_EIO, write_io_error)
33a266dda   David Chinner   [PATCH] Make BH_U...
128
  BUFFER_FNS(Unwritten, unwritten)
877f962c5   Theodore Ts'o   buffer: add BH_Pr...
129
130
  BUFFER_FNS(Meta, meta)
  BUFFER_FNS(Prio, prio)
7b7a8665e   Christoph Hellwig   direct-io: Implem...
131
  BUFFER_FNS(Defer_Completion, defer_completion)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
132
133
  
  #define bh_offset(bh)		((unsigned long)(bh)->b_data & ~PAGE_MASK)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
134
135
136
137
  
  /* If we *know* page->private refers to buffer_heads */
  #define page_buffers(page)					\
  	({							\
4c21e2f24   Hugh Dickins   [PATCH] mm: split...
138
139
  		BUG_ON(!PagePrivate(page));			\
  		((struct buffer_head *)page_private(page));	\
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
140
141
  	})
  #define page_has_buffers(page)	PagePrivate(page)
b45972265   Mel Gorman   mm: vmscan: take ...
142
143
  void buffer_check_dirty_writeback(struct page *page,
  				     bool *dirty, bool *writeback);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
144
145
146
  /*
   * Declarations
   */
b3c975286   Harvey Harrison   include/linux: Re...
147
  void mark_buffer_dirty(struct buffer_head *bh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
148
  void init_buffer(struct buffer_head *, bh_end_io_t *, void *);
f0059afd3   Tejun Heo   buffer: make touc...
149
  void touch_buffer(struct buffer_head *bh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
150
151
152
153
154
155
156
157
158
  void set_bh_page(struct buffer_head *bh,
  		struct page *page, unsigned long offset);
  int try_to_free_buffers(struct page *);
  struct buffer_head *alloc_page_buffers(struct page *page, unsigned long size,
  		int retry);
  void create_empty_buffers(struct page *, unsigned long,
  			unsigned long b_state);
  void end_buffer_read_sync(struct buffer_head *bh, int uptodate);
  void end_buffer_write_sync(struct buffer_head *bh, int uptodate);
35c80d5f4   Chris Mason   Add block_write_f...
159
  void end_buffer_async_write(struct buffer_head *bh, int uptodate);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
160
161
162
163
164
165
166
167
168
169
  
  /* Things to do with buffers at mapping->private_list */
  void mark_buffer_dirty_inode(struct buffer_head *bh, struct inode *inode);
  int inode_has_buffers(struct inode *);
  void invalidate_inode_buffers(struct inode *);
  int remove_inode_buffers(struct inode *inode);
  int sync_mapping_buffers(struct address_space *mapping);
  void unmap_underlying_metadata(struct block_device *bdev, sector_t block);
  
  void mark_buffer_async_write(struct buffer_head *bh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
170
171
  void __wait_on_buffer(struct buffer_head *);
  wait_queue_head_t *bh_waitq_head(struct buffer_head *bh);
3991d3bd1   Tomasz Kvarsin   [PATCH] warning f...
172
173
174
175
  struct buffer_head *__find_get_block(struct block_device *bdev, sector_t block,
  			unsigned size);
  struct buffer_head *__getblk(struct block_device *bdev, sector_t block,
  			unsigned size);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
176
177
  void __brelse(struct buffer_head *);
  void __bforget(struct buffer_head *);
3991d3bd1   Tomasz Kvarsin   [PATCH] warning f...
178
179
  void __breadahead(struct block_device *, sector_t block, unsigned int size);
  struct buffer_head *__bread(struct block_device *, sector_t block, unsigned size);
f9a14399a   Peter Zijlstra   mm: optimize kill...
180
  void invalidate_bh_lrus(void);
dd0fc66fb   Al Viro   [PATCH] gfp flags...
181
  struct buffer_head *alloc_buffer_head(gfp_t gfp_flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
182
  void free_buffer_head(struct buffer_head * bh);
b3c975286   Harvey Harrison   include/linux: Re...
183
184
  void unlock_buffer(struct buffer_head *bh);
  void __lock_buffer(struct buffer_head *bh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
185
186
  void ll_rw_block(int, int, struct buffer_head * bh[]);
  int sync_dirty_buffer(struct buffer_head *bh);
87e99511e   Christoph Hellwig   kill BH_Ordered flag
187
  int __sync_dirty_buffer(struct buffer_head *bh, int rw);
9cb569d60   Christoph Hellwig   remove SWRITE* I/...
188
  void write_dirty_buffer(struct buffer_head *bh, int rw);
713685111   Darrick J. Wong   mm: make snapshot...
189
  int _submit_bh(int rw, struct buffer_head *bh, unsigned long bio_flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
190
191
192
  int submit_bh(int, struct buffer_head *);
  void write_boundary_block(struct block_device *bdev,
  			sector_t bblock, unsigned blocksize);
389d1b083   Aneesh Kumar K.V   Add buffer head r...
193
194
  int bh_uptodate_or_lock(struct buffer_head *bh);
  int bh_submit_read(struct buffer_head *bh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
195
196
197
198
199
200
201
  
  extern int buffer_heads_over_limit;
  
  /*
   * Generic address_space_operations implementations for buffer_head-backed
   * address_spaces.
   */
d47992f86   Lukas Czerner   mm: change invali...
202
203
  void block_invalidatepage(struct page *page, unsigned int offset,
  			  unsigned int length);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
204
205
  int block_write_full_page(struct page *page, get_block_t *get_block,
  				struct writeback_control *wbc);
35c80d5f4   Chris Mason   Add block_write_f...
206
207
  int block_write_full_page_endio(struct page *page, get_block_t *get_block,
  			struct writeback_control *wbc, bh_end_io_t *handler);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
208
  int block_read_full_page(struct page*, get_block_t*);
c186afb4d   Al Viro   switch ->is_parti...
209
210
  int block_is_partially_uptodate(struct page *page, unsigned long from,
  				unsigned long count);
155130a4f   Christoph Hellwig   get rid of block_...
211
212
  int block_write_begin(struct address_space *mapping, loff_t pos, unsigned len,
  		unsigned flags, struct page **pagep, get_block_t *get_block);
6e1db88d5   Christoph Hellwig   introduce __block...
213
214
  int __block_write_begin(struct page *page, loff_t pos, unsigned len,
  		get_block_t *get_block);
afddba49d   Nick Piggin   fs: introduce wri...
215
216
217
218
219
220
221
  int block_write_end(struct file *, struct address_space *,
  				loff_t, unsigned, unsigned,
  				struct page *, void *);
  int generic_write_end(struct file *, struct address_space *,
  				loff_t, unsigned, unsigned,
  				struct page *, void *);
  void page_zero_new_buffers(struct page *page, unsigned from, unsigned to);
89e107877   Nick Piggin   fs: new cont helpers
222
223
224
  int cont_write_begin(struct file *, struct address_space *, loff_t,
  			unsigned, unsigned, struct page **, void **,
  			get_block_t *, loff_t *);
05eb0b51f   OGAWA Hirofumi   [PATCH] fat: supp...
225
  int generic_cont_expand_simple(struct inode *inode, loff_t size);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
226
  int block_commit_write(struct page *page, unsigned from, unsigned to);
24da4fab5   Jan Kara   vfs: Create __blo...
227
228
  int __block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
  				get_block_t get_block);
c2ec175c3   Nick Piggin   mm: page_mkwrite ...
229
  int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
541716902   David Chinner   [FS] Implement bl...
230
  				get_block_t get_block);
24da4fab5   Jan Kara   vfs: Create __blo...
231
232
233
234
235
236
237
238
239
  /* Convert errno to return value from ->page_mkwrite() call */
  static inline int block_page_mkwrite_return(int err)
  {
  	if (err == 0)
  		return VM_FAULT_LOCKED;
  	if (err == -EFAULT)
  		return VM_FAULT_NOPAGE;
  	if (err == -ENOMEM)
  		return VM_FAULT_OOM;
ea13a8646   Jan Kara   vfs: Block mmappe...
240
241
  	if (err == -EAGAIN)
  		return VM_FAULT_RETRY;
24da4fab5   Jan Kara   vfs: Create __blo...
242
243
244
  	/* -ENOSPC, -EDQUOT, -EIO ... */
  	return VM_FAULT_SIGBUS;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
245
  sector_t generic_block_bmap(struct address_space *, sector_t, get_block_t *);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
246
  int block_truncate_page(struct address_space *, loff_t, get_block_t *);
ea0f04e59   Christoph Hellwig   get rid of nobh_w...
247
  int nobh_write_begin(struct address_space *, loff_t, unsigned, unsigned,
03158cd7e   Nick Piggin   fs: restore nobh
248
249
250
251
252
  				struct page **, void **, get_block_t*);
  int nobh_write_end(struct file *, struct address_space *,
  				loff_t, unsigned, unsigned,
  				struct page *, void *);
  int nobh_truncate_page(struct address_space *, loff_t, get_block_t *);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
253
254
  int nobh_writepage(struct page *page, get_block_t *get_block,
                          struct writeback_control *wbc);
b6cd0b772   Adrian Bunk   [PATCH] fs/buffer...
255
  void buffer_init(void);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
256
257
258
259
260
261
262
263
264
265
  
  /*
   * inline definitions
   */
  
  static inline void attach_page_buffers(struct page *page,
  		struct buffer_head *head)
  {
  	page_cache_get(page);
  	SetPagePrivate(page);
4c21e2f24   Hugh Dickins   [PATCH] mm: split...
266
  	set_page_private(page, (unsigned long)head);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
  }
  
  static inline void get_bh(struct buffer_head *bh)
  {
          atomic_inc(&bh->b_count);
  }
  
  static inline void put_bh(struct buffer_head *bh)
  {
          smp_mb__before_atomic_dec();
          atomic_dec(&bh->b_count);
  }
  
  static inline void brelse(struct buffer_head *bh)
  {
  	if (bh)
  		__brelse(bh);
  }
  
  static inline void bforget(struct buffer_head *bh)
  {
  	if (bh)
  		__bforget(bh);
  }
  
  static inline struct buffer_head *
  sb_bread(struct super_block *sb, sector_t block)
  {
  	return __bread(sb->s_bdev, block, sb->s_blocksize);
  }
  
  static inline void
  sb_breadahead(struct super_block *sb, sector_t block)
  {
  	__breadahead(sb->s_bdev, block, sb->s_blocksize);
  }
  
  static inline struct buffer_head *
  sb_getblk(struct super_block *sb, sector_t block)
  {
  	return __getblk(sb->s_bdev, block, sb->s_blocksize);
  }
  
  static inline struct buffer_head *
  sb_find_get_block(struct super_block *sb, sector_t block)
  {
  	return __find_get_block(sb->s_bdev, block, sb->s_blocksize);
  }
  
  static inline void
  map_bh(struct buffer_head *bh, struct super_block *sb, sector_t block)
  {
  	set_buffer_mapped(bh);
  	bh->b_bdev = sb->s_bdev;
  	bh->b_blocknr = block;
b0cf2321c   Badari Pulavarty   [PATCH] pass b_si...
322
  	bh->b_size = sb->s_blocksize;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
323
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
324
325
326
  static inline void wait_on_buffer(struct buffer_head *bh)
  {
  	might_sleep();
a9877cc29   Richard Kennedy   buffer_head: remo...
327
  	if (buffer_locked(bh))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
328
329
  		__wait_on_buffer(bh);
  }
ca5de404f   Nick Piggin   fs: rename buffer...
330
331
  static inline int trylock_buffer(struct buffer_head *bh)
  {
51b07fc3c   Nick Piggin   fs: buffer lock u...
332
  	return likely(!test_and_set_bit_lock(BH_Lock, &bh->b_state));
ca5de404f   Nick Piggin   fs: rename buffer...
333
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
334
335
336
  static inline void lock_buffer(struct buffer_head *bh)
  {
  	might_sleep();
ca5de404f   Nick Piggin   fs: rename buffer...
337
  	if (!trylock_buffer(bh))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
338
339
  		__lock_buffer(bh);
  }
cf9a2ae8d   David Howells   [PATCH] BLOCK: Mo...
340
  extern int __set_page_dirty_buffers(struct page *page);
9361401eb   David Howells   [PATCH] BLOCK: Ma...
341
342
343
344
345
  
  #else /* CONFIG_BLOCK */
  
  static inline void buffer_init(void) {}
  static inline int try_to_free_buffers(struct page *page) { return 1; }
9361401eb   David Howells   [PATCH] BLOCK: Ma...
346
347
348
349
  static inline int inode_has_buffers(struct inode *inode) { return 0; }
  static inline void invalidate_inode_buffers(struct inode *inode) {}
  static inline int remove_inode_buffers(struct inode *inode) { return 1; }
  static inline int sync_mapping_buffers(struct address_space *mapping) { return 0; }
9361401eb   David Howells   [PATCH] BLOCK: Ma...
350
351
  
  #endif /* CONFIG_BLOCK */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
352
  #endif /* _LINUX_BUFFER_HEAD_H */