xref: /OK3568_Linux_fs/kernel/drivers/md/persistent-data/dm-space-map-common.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright (C) 2011 Red Hat, Inc.
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * This file is released under the GPL.
5*4882a593Smuzhiyun  */
6*4882a593Smuzhiyun 
7*4882a593Smuzhiyun #ifndef DM_SPACE_MAP_COMMON_H
8*4882a593Smuzhiyun #define DM_SPACE_MAP_COMMON_H
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #include "dm-btree.h"
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun /*----------------------------------------------------------------*/
13*4882a593Smuzhiyun 
14*4882a593Smuzhiyun /*
15*4882a593Smuzhiyun  * Low level disk format
16*4882a593Smuzhiyun  *
17*4882a593Smuzhiyun  * Bitmap btree
18*4882a593Smuzhiyun  * ------------
19*4882a593Smuzhiyun  *
20*4882a593Smuzhiyun  * Each value stored in the btree is an index_entry.  This points to a
21*4882a593Smuzhiyun  * block that is used as a bitmap.  Within the bitmap hold 2 bits per
22*4882a593Smuzhiyun  * entry, which represent UNUSED = 0, REF_COUNT = 1, REF_COUNT = 2 and
23*4882a593Smuzhiyun  * REF_COUNT = many.
24*4882a593Smuzhiyun  *
25*4882a593Smuzhiyun  * Refcount btree
26*4882a593Smuzhiyun  * --------------
27*4882a593Smuzhiyun  *
28*4882a593Smuzhiyun  * Any entry that has a ref count higher than 2 gets entered in the ref
29*4882a593Smuzhiyun  * count tree.  The leaf values for this tree is the 32-bit ref count.
30*4882a593Smuzhiyun  */
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun struct disk_index_entry {
33*4882a593Smuzhiyun 	__le64 blocknr;
34*4882a593Smuzhiyun 	__le32 nr_free;
35*4882a593Smuzhiyun 	__le32 none_free_before;
36*4882a593Smuzhiyun } __attribute__ ((packed, aligned(8)));
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun #define MAX_METADATA_BITMAPS 255
40*4882a593Smuzhiyun struct disk_metadata_index {
41*4882a593Smuzhiyun 	__le32 csum;
42*4882a593Smuzhiyun 	__le32 padding;
43*4882a593Smuzhiyun 	__le64 blocknr;
44*4882a593Smuzhiyun 
45*4882a593Smuzhiyun 	struct disk_index_entry index[MAX_METADATA_BITMAPS];
46*4882a593Smuzhiyun } __attribute__ ((packed, aligned(8)));
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun struct ll_disk;
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun typedef int (*load_ie_fn)(struct ll_disk *ll, dm_block_t index, struct disk_index_entry *result);
51*4882a593Smuzhiyun typedef int (*save_ie_fn)(struct ll_disk *ll, dm_block_t index, struct disk_index_entry *ie);
52*4882a593Smuzhiyun typedef int (*init_index_fn)(struct ll_disk *ll);
53*4882a593Smuzhiyun typedef int (*open_index_fn)(struct ll_disk *ll);
54*4882a593Smuzhiyun typedef dm_block_t (*max_index_entries_fn)(struct ll_disk *ll);
55*4882a593Smuzhiyun typedef int (*commit_fn)(struct ll_disk *ll);
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun struct ll_disk {
58*4882a593Smuzhiyun 	struct dm_transaction_manager *tm;
59*4882a593Smuzhiyun 	struct dm_btree_info bitmap_info;
60*4882a593Smuzhiyun 	struct dm_btree_info ref_count_info;
61*4882a593Smuzhiyun 
62*4882a593Smuzhiyun 	uint32_t block_size;
63*4882a593Smuzhiyun 	uint32_t entries_per_block;
64*4882a593Smuzhiyun 	dm_block_t nr_blocks;
65*4882a593Smuzhiyun 	dm_block_t nr_allocated;
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun 	/*
68*4882a593Smuzhiyun 	 * bitmap_root may be a btree root or a simple index.
69*4882a593Smuzhiyun 	 */
70*4882a593Smuzhiyun 	dm_block_t bitmap_root;
71*4882a593Smuzhiyun 
72*4882a593Smuzhiyun 	dm_block_t ref_count_root;
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun 	struct disk_metadata_index mi_le;
75*4882a593Smuzhiyun 	load_ie_fn load_ie;
76*4882a593Smuzhiyun 	save_ie_fn save_ie;
77*4882a593Smuzhiyun 	init_index_fn init_index;
78*4882a593Smuzhiyun 	open_index_fn open_index;
79*4882a593Smuzhiyun 	max_index_entries_fn max_entries;
80*4882a593Smuzhiyun 	commit_fn commit;
81*4882a593Smuzhiyun 	bool bitmap_index_changed:1;
82*4882a593Smuzhiyun };
83*4882a593Smuzhiyun 
84*4882a593Smuzhiyun struct disk_sm_root {
85*4882a593Smuzhiyun 	__le64 nr_blocks;
86*4882a593Smuzhiyun 	__le64 nr_allocated;
87*4882a593Smuzhiyun 	__le64 bitmap_root;
88*4882a593Smuzhiyun 	__le64 ref_count_root;
89*4882a593Smuzhiyun } __attribute__ ((packed, aligned(8)));
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun #define ENTRIES_PER_BYTE 4
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun struct disk_bitmap_header {
94*4882a593Smuzhiyun 	__le32 csum;
95*4882a593Smuzhiyun 	__le32 not_used;
96*4882a593Smuzhiyun 	__le64 blocknr;
97*4882a593Smuzhiyun } __attribute__ ((packed, aligned(8)));
98*4882a593Smuzhiyun 
99*4882a593Smuzhiyun enum allocation_event {
100*4882a593Smuzhiyun 	SM_NONE,
101*4882a593Smuzhiyun 	SM_ALLOC,
102*4882a593Smuzhiyun 	SM_FREE,
103*4882a593Smuzhiyun };
104*4882a593Smuzhiyun 
105*4882a593Smuzhiyun /*----------------------------------------------------------------*/
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun int sm_ll_extend(struct ll_disk *ll, dm_block_t extra_blocks);
108*4882a593Smuzhiyun int sm_ll_lookup_bitmap(struct ll_disk *ll, dm_block_t b, uint32_t *result);
109*4882a593Smuzhiyun int sm_ll_lookup(struct ll_disk *ll, dm_block_t b, uint32_t *result);
110*4882a593Smuzhiyun int sm_ll_find_free_block(struct ll_disk *ll, dm_block_t begin,
111*4882a593Smuzhiyun 			  dm_block_t end, dm_block_t *result);
112*4882a593Smuzhiyun int sm_ll_find_common_free_block(struct ll_disk *old_ll, struct ll_disk *new_ll,
113*4882a593Smuzhiyun 	                         dm_block_t begin, dm_block_t end, dm_block_t *result);
114*4882a593Smuzhiyun int sm_ll_insert(struct ll_disk *ll, dm_block_t b, uint32_t ref_count, enum allocation_event *ev);
115*4882a593Smuzhiyun int sm_ll_inc(struct ll_disk *ll, dm_block_t b, enum allocation_event *ev);
116*4882a593Smuzhiyun int sm_ll_dec(struct ll_disk *ll, dm_block_t b, enum allocation_event *ev);
117*4882a593Smuzhiyun int sm_ll_commit(struct ll_disk *ll);
118*4882a593Smuzhiyun 
119*4882a593Smuzhiyun int sm_ll_new_metadata(struct ll_disk *ll, struct dm_transaction_manager *tm);
120*4882a593Smuzhiyun int sm_ll_open_metadata(struct ll_disk *ll, struct dm_transaction_manager *tm,
121*4882a593Smuzhiyun 			void *root_le, size_t len);
122*4882a593Smuzhiyun 
123*4882a593Smuzhiyun int sm_ll_new_disk(struct ll_disk *ll, struct dm_transaction_manager *tm);
124*4882a593Smuzhiyun int sm_ll_open_disk(struct ll_disk *ll, struct dm_transaction_manager *tm,
125*4882a593Smuzhiyun 		    void *root_le, size_t len);
126*4882a593Smuzhiyun 
127*4882a593Smuzhiyun /*----------------------------------------------------------------*/
128*4882a593Smuzhiyun 
129*4882a593Smuzhiyun #endif	/* DM_SPACE_MAP_COMMON_H */
130