Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright (C) 2011 Red Hat, Inc.
0003  *
0004  * This file is released under the GPL.
0005  */
0006 
0007 #ifndef DM_SPACE_MAP_COMMON_H
0008 #define DM_SPACE_MAP_COMMON_H
0009 
0010 #include "dm-btree.h"
0011 
0012 /*----------------------------------------------------------------*/
0013 
0014 /*
0015  * Low level disk format
0016  *
0017  * Bitmap btree
0018  * ------------
0019  *
0020  * Each value stored in the btree is an index_entry.  This points to a
0021  * block that is used as a bitmap.  Within the bitmap hold 2 bits per
0022  * entry, which represent UNUSED = 0, REF_COUNT = 1, REF_COUNT = 2 and
0023  * REF_COUNT = many.
0024  *
0025  * Refcount btree
0026  * --------------
0027  *
0028  * Any entry that has a ref count higher than 2 gets entered in the ref
0029  * count tree.  The leaf values for this tree is the 32-bit ref count.
0030  */
0031 
0032 struct disk_index_entry {
0033     __le64 blocknr;
0034     __le32 nr_free;
0035     __le32 none_free_before;
0036 } __attribute__ ((packed, aligned(8)));
0037 
0038 
0039 #define MAX_METADATA_BITMAPS 255
0040 struct disk_metadata_index {
0041     __le32 csum;
0042     __le32 padding;
0043     __le64 blocknr;
0044 
0045     struct disk_index_entry index[MAX_METADATA_BITMAPS];
0046 } __attribute__ ((packed, aligned(8)));
0047 
0048 struct ll_disk;
0049 
0050 typedef int (*load_ie_fn)(struct ll_disk *ll, dm_block_t index, struct disk_index_entry *result);
0051 typedef int (*save_ie_fn)(struct ll_disk *ll, dm_block_t index, struct disk_index_entry *ie);
0052 typedef int (*init_index_fn)(struct ll_disk *ll);
0053 typedef int (*open_index_fn)(struct ll_disk *ll);
0054 typedef dm_block_t (*max_index_entries_fn)(struct ll_disk *ll);
0055 typedef int (*commit_fn)(struct ll_disk *ll);
0056 
0057 /*
0058  * A lot of time can be wasted reading and writing the same
0059  * index entry.  So we cache a few entries.
0060  */
0061 #define IE_CACHE_SIZE 64
0062 #define IE_CACHE_MASK (IE_CACHE_SIZE - 1)
0063 
0064 struct ie_cache {
0065     bool valid;
0066     bool dirty;
0067     dm_block_t index;
0068     struct disk_index_entry ie;
0069 };
0070 
0071 struct ll_disk {
0072     struct dm_transaction_manager *tm;
0073     struct dm_btree_info bitmap_info;
0074     struct dm_btree_info ref_count_info;
0075 
0076     uint32_t block_size;
0077     uint32_t entries_per_block;
0078     dm_block_t nr_blocks;
0079     dm_block_t nr_allocated;
0080 
0081     /*
0082      * bitmap_root may be a btree root or a simple index.
0083      */
0084     dm_block_t bitmap_root;
0085 
0086     dm_block_t ref_count_root;
0087 
0088     struct disk_metadata_index mi_le;
0089     load_ie_fn load_ie;
0090     save_ie_fn save_ie;
0091     init_index_fn init_index;
0092     open_index_fn open_index;
0093     max_index_entries_fn max_entries;
0094     commit_fn commit;
0095     bool bitmap_index_changed:1;
0096 
0097     struct ie_cache ie_cache[IE_CACHE_SIZE];
0098 };
0099 
0100 struct disk_sm_root {
0101     __le64 nr_blocks;
0102     __le64 nr_allocated;
0103     __le64 bitmap_root;
0104     __le64 ref_count_root;
0105 } __attribute__ ((packed, aligned(8)));
0106 
0107 #define ENTRIES_PER_BYTE 4
0108 
0109 struct disk_bitmap_header {
0110     __le32 csum;
0111     __le32 not_used;
0112     __le64 blocknr;
0113 } __attribute__ ((packed, aligned(8)));
0114 
0115 /*----------------------------------------------------------------*/
0116 
0117 int sm_ll_extend(struct ll_disk *ll, dm_block_t extra_blocks);
0118 int sm_ll_lookup_bitmap(struct ll_disk *ll, dm_block_t b, uint32_t *result);
0119 int sm_ll_lookup(struct ll_disk *ll, dm_block_t b, uint32_t *result);
0120 int sm_ll_find_free_block(struct ll_disk *ll, dm_block_t begin,
0121               dm_block_t end, dm_block_t *result);
0122 int sm_ll_find_common_free_block(struct ll_disk *old_ll, struct ll_disk *new_ll,
0123                              dm_block_t begin, dm_block_t end, dm_block_t *result);
0124 
0125 /*
0126  * The next three functions return (via nr_allocations) the net number of
0127  * allocations that were made.  This number may be negative if there were
0128  * more frees than allocs.
0129  */
0130 int sm_ll_insert(struct ll_disk *ll, dm_block_t b, uint32_t ref_count, int32_t *nr_allocations);
0131 int sm_ll_inc(struct ll_disk *ll, dm_block_t b, dm_block_t e, int32_t *nr_allocations);
0132 int sm_ll_dec(struct ll_disk *ll, dm_block_t b, dm_block_t e, int32_t *nr_allocations);
0133 int sm_ll_commit(struct ll_disk *ll);
0134 
0135 int sm_ll_new_metadata(struct ll_disk *ll, struct dm_transaction_manager *tm);
0136 int sm_ll_open_metadata(struct ll_disk *ll, struct dm_transaction_manager *tm,
0137             void *root_le, size_t len);
0138 
0139 int sm_ll_new_disk(struct ll_disk *ll, struct dm_transaction_manager *tm);
0140 int sm_ll_open_disk(struct ll_disk *ll, struct dm_transaction_manager *tm,
0141             void *root_le, size_t len);
0142 
0143 /*----------------------------------------------------------------*/
0144 
0145 #endif  /* DM_SPACE_MAP_COMMON_H */