![]() |
|
|||
0001 /* 0002 * Copyright (C) 2011 Red Hat, Inc. 0003 * 0004 * This file is released under the GPL. 0005 */ 0006 0007 #ifndef _LINUX_DM_TRANSACTION_MANAGER_H 0008 #define _LINUX_DM_TRANSACTION_MANAGER_H 0009 0010 #include "dm-block-manager.h" 0011 0012 struct dm_transaction_manager; 0013 struct dm_space_map; 0014 0015 /*----------------------------------------------------------------*/ 0016 0017 /* 0018 * This manages the scope of a transaction. It also enforces immutability 0019 * of the on-disk data structures by limiting access to writeable blocks. 0020 * 0021 * Clients should not fiddle with the block manager directly. 0022 */ 0023 0024 void dm_tm_destroy(struct dm_transaction_manager *tm); 0025 0026 /* 0027 * The non-blocking version of a transaction manager is intended for use in 0028 * fast path code that needs to do lookups e.g. a dm mapping function. 0029 * You create the non-blocking variant from a normal tm. The interface is 0030 * the same, except that most functions will just return -EWOULDBLOCK. 0031 * Methods that return void yet may block should not be called on a clone 0032 * viz. dm_tm_inc, dm_tm_dec. Call dm_tm_destroy() as you would with a normal 0033 * tm when you've finished with it. You may not destroy the original prior 0034 * to clones. 0035 */ 0036 struct dm_transaction_manager *dm_tm_create_non_blocking_clone(struct dm_transaction_manager *real); 0037 0038 /* 0039 * We use a 2-phase commit here. 0040 * 0041 * i) Make all changes for the transaction *except* for the superblock. 0042 * Then call dm_tm_pre_commit() to flush them to disk. 0043 * 0044 * ii) Lock your superblock. Update. Then call dm_tm_commit() which will 0045 * unlock the superblock and flush it. No other blocks should be updated 0046 * during this period. Care should be taken to never unlock a partially 0047 * updated superblock; perform any operations that could fail *before* you 0048 * take the superblock lock. 0049 */ 0050 int dm_tm_pre_commit(struct dm_transaction_manager *tm); 0051 int dm_tm_commit(struct dm_transaction_manager *tm, struct dm_block *superblock); 0052 0053 /* 0054 * These methods are the only way to get hold of a writeable block. 0055 */ 0056 0057 /* 0058 * dm_tm_new_block() is pretty self-explanatory. Make sure you do actually 0059 * write to the whole of @data before you unlock, otherwise you could get 0060 * a data leak. (The other option is for tm_new_block() to zero new blocks 0061 * before handing them out, which will be redundant in most, if not all, 0062 * cases). 0063 * Zeroes the new block and returns with write lock held. 0064 */ 0065 int dm_tm_new_block(struct dm_transaction_manager *tm, 0066 struct dm_block_validator *v, 0067 struct dm_block **result); 0068 0069 /* 0070 * dm_tm_shadow_block() allocates a new block and copies the data from @orig 0071 * to it. It then decrements the reference count on original block. Use 0072 * this to update the contents of a block in a data structure, don't 0073 * confuse this with a clone - you shouldn't access the orig block after 0074 * this operation. Because the tm knows the scope of the transaction it 0075 * can optimise requests for a shadow of a shadow to a no-op. Don't forget 0076 * to unlock when you've finished with the shadow. 0077 * 0078 * The @inc_children flag is used to tell the caller whether it needs to 0079 * adjust reference counts for children. (Data in the block may refer to 0080 * other blocks.) 0081 * 0082 * Shadowing implicitly drops a reference on @orig so you must not have 0083 * it locked when you call this. 0084 */ 0085 int dm_tm_shadow_block(struct dm_transaction_manager *tm, dm_block_t orig, 0086 struct dm_block_validator *v, 0087 struct dm_block **result, int *inc_children); 0088 0089 /* 0090 * Read access. You can lock any block you want. If there's a write lock 0091 * on it outstanding then it'll block. 0092 */ 0093 int dm_tm_read_lock(struct dm_transaction_manager *tm, dm_block_t b, 0094 struct dm_block_validator *v, 0095 struct dm_block **result); 0096 0097 void dm_tm_unlock(struct dm_transaction_manager *tm, struct dm_block *b); 0098 0099 /* 0100 * Functions for altering the reference count of a block directly. 0101 */ 0102 void dm_tm_inc(struct dm_transaction_manager *tm, dm_block_t b); 0103 void dm_tm_inc_range(struct dm_transaction_manager *tm, dm_block_t b, dm_block_t e); 0104 void dm_tm_dec(struct dm_transaction_manager *tm, dm_block_t b); 0105 void dm_tm_dec_range(struct dm_transaction_manager *tm, dm_block_t b, dm_block_t e); 0106 0107 /* 0108 * Builds up runs of adjacent blocks, and then calls the given fn 0109 * (typically dm_tm_inc/dec). Very useful when you have to perform 0110 * the same tm operation on all values in a btree leaf. 0111 */ 0112 typedef void (*dm_tm_run_fn)(struct dm_transaction_manager *, dm_block_t, dm_block_t); 0113 void dm_tm_with_runs(struct dm_transaction_manager *tm, 0114 const __le64 *value_le, unsigned count, dm_tm_run_fn fn); 0115 0116 int dm_tm_ref(struct dm_transaction_manager *tm, dm_block_t b, uint32_t *result); 0117 0118 /* 0119 * Finds out if a given block is shared (ie. has a reference count higher 0120 * than one). 0121 */ 0122 int dm_tm_block_is_shared(struct dm_transaction_manager *tm, dm_block_t b, 0123 int *result); 0124 0125 struct dm_block_manager *dm_tm_get_bm(struct dm_transaction_manager *tm); 0126 0127 /* 0128 * If you're using a non-blocking clone the tm will build up a list of 0129 * requested blocks that weren't in core. This call will request those 0130 * blocks to be prefetched. 0131 */ 0132 void dm_tm_issue_prefetches(struct dm_transaction_manager *tm); 0133 0134 /* 0135 * A little utility that ties the knot by producing a transaction manager 0136 * that has a space map managed by the transaction manager... 0137 * 0138 * Returns a tm that has an open transaction to write the new disk sm. 0139 * Caller should store the new sm root and commit. 0140 * 0141 * The superblock location is passed so the metadata space map knows it 0142 * shouldn't be used. 0143 */ 0144 int dm_tm_create_with_sm(struct dm_block_manager *bm, dm_block_t sb_location, 0145 struct dm_transaction_manager **tm, 0146 struct dm_space_map **sm); 0147 0148 int dm_tm_open_with_sm(struct dm_block_manager *bm, dm_block_t sb_location, 0149 void *sm_root, size_t root_len, 0150 struct dm_transaction_manager **tm, 0151 struct dm_space_map **sm); 0152 0153 #endif /* _LINUX_DM_TRANSACTION_MANAGER_H */
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.1.0 LXR engine. The LXR team |
![]() ![]() |