Merge branch 'akpm'
[linux-2.6/next.git] / drivers / md / persistent-data / dm-block-manager.h
blob38c49c797c84627ee741b3b6839858f8fdef4f5f
1 /*
2 * Copyright (C) 2011 Red Hat, Inc. All rights reserved.
4 * This file is released under the GPL.
5 */
7 #ifndef _LINUX_DM_BLOCK_MANAGER_H
8 #define _LINUX_DM_BLOCK_MANAGER_H
10 #include <linux/blkdev.h>
11 #include <linux/types.h>
12 #include <linux/crc32c.h>
14 /*----------------------------------------------------------------*/
17 * Block number.
19 typedef uint64_t dm_block_t;
22 * An opaque handle to a block of data.
24 struct dm_block;
26 dm_block_t dm_block_location(struct dm_block *b);
27 void *dm_block_data(struct dm_block *b);
30 * Use CRC32 checksumming on data blocks.
32 static inline uint32_t dm_block_csum_data(const void *data_le, unsigned length)
34 return crc32c(~(u32)0, data_le, length);
37 /*----------------------------------------------------------------*/
39 struct dm_block_manager;
42 * @max_held_per_thread should be the maximum number of locks, read or
43 * write, that an individual thread holds at any one time.
45 struct dm_block_manager *dm_block_manager_create(
46 struct block_device *bdev, unsigned block_size,
47 unsigned cache_size, unsigned max_held_per_thread);
48 void dm_block_manager_destroy(struct dm_block_manager *bm);
50 unsigned dm_bm_block_size(struct dm_block_manager *bm);
51 dm_block_t dm_bm_nr_blocks(struct dm_block_manager *bm);
53 /*----------------------------------------------------------------*/
56 * The validator allows the caller to verify newly-read data and modify
57 * the data just before writing, e.g. to calculate checksums. It's
58 * important to be consistent with your use of validators. The only time
59 * you can change validators is if you call dm_bm_write_lock_zero.
61 struct dm_block_validator {
62 const char *name;
63 void (*prepare_for_write)(struct dm_block_validator *v, struct dm_block *b, size_t block_size);
66 * Return 0 if the checksum is valid or < 0 on error.
68 int (*check)(struct dm_block_validator *v, struct dm_block *b, size_t block_size);
71 /*----------------------------------------------------------------*/
74 * You can have multiple concurrent readers or a single writer holding a
75 * block lock.
79 * dm_bm_lock() locks a block and returns through @result a pointer to
80 * memory that holds a copy of that block. If you have write-locked the
81 * block then any changes you make to memory pointed to by @result will be
82 * written back to the disk sometime after dm_bm_unlock is called.
84 int dm_bm_read_lock(struct dm_block_manager *bm, dm_block_t b,
85 struct dm_block_validator *v,
86 struct dm_block **result);
88 int dm_bm_write_lock(struct dm_block_manager *bm, dm_block_t b,
89 struct dm_block_validator *v,
90 struct dm_block **result);
93 * The *_try_lock variants return -EWOULDBLOCK if the block isn't
94 * available immediately.
96 int dm_bm_read_try_lock(struct dm_block_manager *bm, dm_block_t b,
97 struct dm_block_validator *v,
98 struct dm_block **result);
101 * Use dm_bm_write_lock_zero() when you know you're going to
102 * overwrite the block completely. It saves a disk read.
104 int dm_bm_write_lock_zero(struct dm_block_manager *bm, dm_block_t b,
105 struct dm_block_validator *v,
106 struct dm_block **result);
108 int dm_bm_unlock(struct dm_block *b);
111 * It's a common idiom to have a superblock that should be committed last.
113 * @superblock should be write-locked on entry. It will be unlocked during
114 * this function. All dirty blocks are guaranteed to be written and flushed
115 * before the superblock.
117 * This method always blocks.
119 int dm_bm_flush_and_unlock(struct dm_block_manager *bm,
120 struct dm_block *superblock);
123 * The client may wish to change the block device to which the block
124 * manager points. If you use this function then the cache remains intact,
125 * so the data must be identical on the both devices, e.g. a different
126 * path to the same disk, and it must be at least as big.
128 * This function guarantees that once it returns, no further IO will occur
129 * on the old device.
131 int dm_bm_rebind_block_device(struct dm_block_manager *bm,
132 struct block_device *bdev);
134 #endif /* _LINUX_DM_BLOCK_MANAGER_H */