diff options
Diffstat (limited to 'fs/nilfs2/alloc.c')
-rw-r--r-- | fs/nilfs2/alloc.c | 154 |
1 files changed, 153 insertions, 1 deletions
diff --git a/fs/nilfs2/alloc.c b/fs/nilfs2/alloc.c index 7cfb87e692da..d7fd696e595c 100644 --- a/fs/nilfs2/alloc.c +++ b/fs/nilfs2/alloc.c | |||
@@ -31,6 +31,11 @@ | |||
31 | #include "alloc.h" | 31 | #include "alloc.h" |
32 | 32 | ||
33 | 33 | ||
34 | /** | ||
35 | * nilfs_palloc_groups_per_desc_block - get the number of groups that a group | ||
36 | * descriptor block can maintain | ||
37 | * @inode: inode of metadata file using this allocator | ||
38 | */ | ||
34 | static inline unsigned long | 39 | static inline unsigned long |
35 | nilfs_palloc_groups_per_desc_block(const struct inode *inode) | 40 | nilfs_palloc_groups_per_desc_block(const struct inode *inode) |
36 | { | 41 | { |
@@ -38,12 +43,21 @@ nilfs_palloc_groups_per_desc_block(const struct inode *inode) | |||
38 | sizeof(struct nilfs_palloc_group_desc); | 43 | sizeof(struct nilfs_palloc_group_desc); |
39 | } | 44 | } |
40 | 45 | ||
46 | /** | ||
47 | * nilfs_palloc_groups_count - get maximum number of groups | ||
48 | * @inode: inode of metadata file using this allocator | ||
49 | */ | ||
41 | static inline unsigned long | 50 | static inline unsigned long |
42 | nilfs_palloc_groups_count(const struct inode *inode) | 51 | nilfs_palloc_groups_count(const struct inode *inode) |
43 | { | 52 | { |
44 | return 1UL << (BITS_PER_LONG - (inode->i_blkbits + 3 /* log2(8) */)); | 53 | return 1UL << (BITS_PER_LONG - (inode->i_blkbits + 3 /* log2(8) */)); |
45 | } | 54 | } |
46 | 55 | ||
56 | /** | ||
57 | * nilfs_palloc_init_blockgroup - initialize private variables for allocator | ||
58 | * @inode: inode of metadata file using this allocator | ||
59 | * @entry_size: size of the persistent object | ||
60 | */ | ||
47 | int nilfs_palloc_init_blockgroup(struct inode *inode, unsigned entry_size) | 61 | int nilfs_palloc_init_blockgroup(struct inode *inode, unsigned entry_size) |
48 | { | 62 | { |
49 | struct nilfs_mdt_info *mi = NILFS_MDT(inode); | 63 | struct nilfs_mdt_info *mi = NILFS_MDT(inode); |
@@ -69,6 +83,12 @@ int nilfs_palloc_init_blockgroup(struct inode *inode, unsigned entry_size) | |||
69 | return 0; | 83 | return 0; |
70 | } | 84 | } |
71 | 85 | ||
86 | /** | ||
87 | * nilfs_palloc_group - get group number and offset from an entry number | ||
88 | * @inode: inode of metadata file using this allocator | ||
89 | * @nr: serial number of the entry (e.g. inode number) | ||
90 | * @offset: pointer to store offset number in the group | ||
91 | */ | ||
72 | static unsigned long nilfs_palloc_group(const struct inode *inode, __u64 nr, | 92 | static unsigned long nilfs_palloc_group(const struct inode *inode, __u64 nr, |
73 | unsigned long *offset) | 93 | unsigned long *offset) |
74 | { | 94 | { |
@@ -78,6 +98,14 @@ static unsigned long nilfs_palloc_group(const struct inode *inode, __u64 nr, | |||
78 | return group; | 98 | return group; |
79 | } | 99 | } |
80 | 100 | ||
101 | /** | ||
102 | * nilfs_palloc_desc_blkoff - get block offset of a group descriptor block | ||
103 | * @inode: inode of metadata file using this allocator | ||
104 | * @group: group number | ||
105 | * | ||
106 | * nilfs_palloc_desc_blkoff() returns block offset of the descriptor | ||
107 | * block which contains a descriptor of the specified group. | ||
108 | */ | ||
81 | static unsigned long | 109 | static unsigned long |
82 | nilfs_palloc_desc_blkoff(const struct inode *inode, unsigned long group) | 110 | nilfs_palloc_desc_blkoff(const struct inode *inode, unsigned long group) |
83 | { | 111 | { |
@@ -86,6 +114,14 @@ nilfs_palloc_desc_blkoff(const struct inode *inode, unsigned long group) | |||
86 | return desc_block * NILFS_MDT(inode)->mi_blocks_per_desc_block; | 114 | return desc_block * NILFS_MDT(inode)->mi_blocks_per_desc_block; |
87 | } | 115 | } |
88 | 116 | ||
117 | /** | ||
118 | * nilfs_palloc_bitmap_blkoff - get block offset of a bitmap block | ||
119 | * @inode: inode of metadata file using this allocator | ||
120 | * @group: group number | ||
121 | * | ||
122 | * nilfs_palloc_bitmap_blkoff() returns block offset of the bitmap | ||
123 | * block used to allocate/deallocate entries in the specified group. | ||
124 | */ | ||
89 | static unsigned long | 125 | static unsigned long |
90 | nilfs_palloc_bitmap_blkoff(const struct inode *inode, unsigned long group) | 126 | nilfs_palloc_bitmap_blkoff(const struct inode *inode, unsigned long group) |
91 | { | 127 | { |
@@ -95,6 +131,12 @@ nilfs_palloc_bitmap_blkoff(const struct inode *inode, unsigned long group) | |||
95 | desc_offset * NILFS_MDT(inode)->mi_blocks_per_group; | 131 | desc_offset * NILFS_MDT(inode)->mi_blocks_per_group; |
96 | } | 132 | } |
97 | 133 | ||
134 | /** | ||
135 | * nilfs_palloc_group_desc_nfrees - get the number of free entries in a group | ||
136 | * @inode: inode of metadata file using this allocator | ||
137 | * @group: group number | ||
138 | * @desc: pointer to descriptor structure for the group | ||
139 | */ | ||
98 | static unsigned long | 140 | static unsigned long |
99 | nilfs_palloc_group_desc_nfrees(struct inode *inode, unsigned long group, | 141 | nilfs_palloc_group_desc_nfrees(struct inode *inode, unsigned long group, |
100 | const struct nilfs_palloc_group_desc *desc) | 142 | const struct nilfs_palloc_group_desc *desc) |
@@ -107,6 +149,13 @@ nilfs_palloc_group_desc_nfrees(struct inode *inode, unsigned long group, | |||
107 | return nfree; | 149 | return nfree; |
108 | } | 150 | } |
109 | 151 | ||
152 | /** | ||
153 | * nilfs_palloc_group_desc_add_entries - adjust count of free entries | ||
154 | * @inode: inode of metadata file using this allocator | ||
155 | * @group: group number | ||
156 | * @desc: pointer to descriptor structure for the group | ||
157 | * @n: delta to be added | ||
158 | */ | ||
110 | static void | 159 | static void |
111 | nilfs_palloc_group_desc_add_entries(struct inode *inode, | 160 | nilfs_palloc_group_desc_add_entries(struct inode *inode, |
112 | unsigned long group, | 161 | unsigned long group, |
@@ -118,6 +167,11 @@ nilfs_palloc_group_desc_add_entries(struct inode *inode, | |||
118 | spin_unlock(nilfs_mdt_bgl_lock(inode, group)); | 167 | spin_unlock(nilfs_mdt_bgl_lock(inode, group)); |
119 | } | 168 | } |
120 | 169 | ||
170 | /** | ||
171 | * nilfs_palloc_entry_blkoff - get block offset of an entry block | ||
172 | * @inode: inode of metadata file using this allocator | ||
173 | * @nr: serial number of the entry (e.g. inode number) | ||
174 | */ | ||
121 | static unsigned long | 175 | static unsigned long |
122 | nilfs_palloc_entry_blkoff(const struct inode *inode, __u64 nr) | 176 | nilfs_palloc_entry_blkoff(const struct inode *inode, __u64 nr) |
123 | { | 177 | { |
@@ -129,6 +183,12 @@ nilfs_palloc_entry_blkoff(const struct inode *inode, __u64 nr) | |||
129 | group_offset / NILFS_MDT(inode)->mi_entries_per_block; | 183 | group_offset / NILFS_MDT(inode)->mi_entries_per_block; |
130 | } | 184 | } |
131 | 185 | ||
186 | /** | ||
187 | * nilfs_palloc_desc_block_init - initialize buffer of a group descriptor block | ||
188 | * @inode: inode of metadata file | ||
189 | * @bh: buffer head of the buffer to be initialized | ||
190 | * @kaddr: kernel address mapped for the page including the buffer | ||
191 | */ | ||
132 | static void nilfs_palloc_desc_block_init(struct inode *inode, | 192 | static void nilfs_palloc_desc_block_init(struct inode *inode, |
133 | struct buffer_head *bh, void *kaddr) | 193 | struct buffer_head *bh, void *kaddr) |
134 | { | 194 | { |
@@ -179,6 +239,13 @@ static int nilfs_palloc_get_block(struct inode *inode, unsigned long blkoff, | |||
179 | return ret; | 239 | return ret; |
180 | } | 240 | } |
181 | 241 | ||
242 | /** | ||
243 | * nilfs_palloc_get_desc_block - get buffer head of a group descriptor block | ||
244 | * @inode: inode of metadata file using this allocator | ||
245 | * @group: group number | ||
246 | * @create: create flag | ||
247 | * @bhp: pointer to store the resultant buffer head | ||
248 | */ | ||
182 | static int nilfs_palloc_get_desc_block(struct inode *inode, | 249 | static int nilfs_palloc_get_desc_block(struct inode *inode, |
183 | unsigned long group, | 250 | unsigned long group, |
184 | int create, struct buffer_head **bhp) | 251 | int create, struct buffer_head **bhp) |
@@ -191,6 +258,13 @@ static int nilfs_palloc_get_desc_block(struct inode *inode, | |||
191 | bhp, &cache->prev_desc, &cache->lock); | 258 | bhp, &cache->prev_desc, &cache->lock); |
192 | } | 259 | } |
193 | 260 | ||
261 | /** | ||
262 | * nilfs_palloc_get_bitmap_block - get buffer head of a bitmap block | ||
263 | * @inode: inode of metadata file using this allocator | ||
264 | * @group: group number | ||
265 | * @create: create flag | ||
266 | * @bhp: pointer to store the resultant buffer head | ||
267 | */ | ||
194 | static int nilfs_palloc_get_bitmap_block(struct inode *inode, | 268 | static int nilfs_palloc_get_bitmap_block(struct inode *inode, |
195 | unsigned long group, | 269 | unsigned long group, |
196 | int create, struct buffer_head **bhp) | 270 | int create, struct buffer_head **bhp) |
@@ -203,6 +277,13 @@ static int nilfs_palloc_get_bitmap_block(struct inode *inode, | |||
203 | &cache->prev_bitmap, &cache->lock); | 277 | &cache->prev_bitmap, &cache->lock); |
204 | } | 278 | } |
205 | 279 | ||
280 | /** | ||
281 | * nilfs_palloc_get_entry_block - get buffer head of an entry block | ||
282 | * @inode: inode of metadata file using this allocator | ||
283 | * @nr: serial number of the entry (e.g. inode number) | ||
284 | * @create: create flag | ||
285 | * @bhp: pointer to store the resultant buffer head | ||
286 | */ | ||
206 | int nilfs_palloc_get_entry_block(struct inode *inode, __u64 nr, | 287 | int nilfs_palloc_get_entry_block(struct inode *inode, __u64 nr, |
207 | int create, struct buffer_head **bhp) | 288 | int create, struct buffer_head **bhp) |
208 | { | 289 | { |
@@ -214,6 +295,13 @@ int nilfs_palloc_get_entry_block(struct inode *inode, __u64 nr, | |||
214 | &cache->prev_entry, &cache->lock); | 295 | &cache->prev_entry, &cache->lock); |
215 | } | 296 | } |
216 | 297 | ||
298 | /** | ||
299 | * nilfs_palloc_block_get_group_desc - get kernel address of a group descriptor | ||
300 | * @inode: inode of metadata file using this allocator | ||
301 | * @group: group number | ||
302 | * @bh: buffer head of the buffer storing the group descriptor block | ||
303 | * @kaddr: kernel address mapped for the page including the buffer | ||
304 | */ | ||
217 | static struct nilfs_palloc_group_desc * | 305 | static struct nilfs_palloc_group_desc * |
218 | nilfs_palloc_block_get_group_desc(const struct inode *inode, | 306 | nilfs_palloc_block_get_group_desc(const struct inode *inode, |
219 | unsigned long group, | 307 | unsigned long group, |
@@ -223,6 +311,13 @@ nilfs_palloc_block_get_group_desc(const struct inode *inode, | |||
223 | group % nilfs_palloc_groups_per_desc_block(inode); | 311 | group % nilfs_palloc_groups_per_desc_block(inode); |
224 | } | 312 | } |
225 | 313 | ||
314 | /** | ||
315 | * nilfs_palloc_block_get_entry - get kernel address of an entry | ||
316 | * @inode: inode of metadata file using this allocator | ||
317 | * @nr: serial number of the entry (e.g. inode number) | ||
318 | * @bh: buffer head of the buffer storing the entry block | ||
319 | * @kaddr: kernel address mapped for the page including the buffer | ||
320 | */ | ||
226 | void *nilfs_palloc_block_get_entry(const struct inode *inode, __u64 nr, | 321 | void *nilfs_palloc_block_get_entry(const struct inode *inode, __u64 nr, |
227 | const struct buffer_head *bh, void *kaddr) | 322 | const struct buffer_head *bh, void *kaddr) |
228 | { | 323 | { |
@@ -235,11 +330,19 @@ void *nilfs_palloc_block_get_entry(const struct inode *inode, __u64 nr, | |||
235 | entry_offset * NILFS_MDT(inode)->mi_entry_size; | 330 | entry_offset * NILFS_MDT(inode)->mi_entry_size; |
236 | } | 331 | } |
237 | 332 | ||
333 | /** | ||
334 | * nilfs_palloc_find_available_slot - find available slot in a group | ||
335 | * @inode: inode of metadata file using this allocator | ||
336 | * @group: group number | ||
337 | * @target: offset number of an entry in the group (start point) | ||
338 | * @bitmap: bitmap of the group | ||
339 | * @bsize: size in bits | ||
340 | */ | ||
238 | static int nilfs_palloc_find_available_slot(struct inode *inode, | 341 | static int nilfs_palloc_find_available_slot(struct inode *inode, |
239 | unsigned long group, | 342 | unsigned long group, |
240 | unsigned long target, | 343 | unsigned long target, |
241 | unsigned char *bitmap, | 344 | unsigned char *bitmap, |
242 | int bsize) /* size in bits */ | 345 | int bsize) |
243 | { | 346 | { |
244 | int curr, pos, end, i; | 347 | int curr, pos, end, i; |
245 | 348 | ||
@@ -277,6 +380,13 @@ static int nilfs_palloc_find_available_slot(struct inode *inode, | |||
277 | return -ENOSPC; | 380 | return -ENOSPC; |
278 | } | 381 | } |
279 | 382 | ||
383 | /** | ||
384 | * nilfs_palloc_rest_groups_in_desc_block - get the remaining number of groups | ||
385 | * in a group descriptor block | ||
386 | * @inode: inode of metadata file using this allocator | ||
387 | * @curr: current group number | ||
388 | * @max: maximum number of groups | ||
389 | */ | ||
280 | static unsigned long | 390 | static unsigned long |
281 | nilfs_palloc_rest_groups_in_desc_block(const struct inode *inode, | 391 | nilfs_palloc_rest_groups_in_desc_block(const struct inode *inode, |
282 | unsigned long curr, unsigned long max) | 392 | unsigned long curr, unsigned long max) |
@@ -287,6 +397,11 @@ nilfs_palloc_rest_groups_in_desc_block(const struct inode *inode, | |||
287 | max - curr + 1); | 397 | max - curr + 1); |
288 | } | 398 | } |
289 | 399 | ||
400 | /** | ||
401 | * nilfs_palloc_prepare_alloc_entry - prepare to allocate a persistent object | ||
402 | * @inode: inode of metadata file using this allocator | ||
403 | * @req: nilfs_palloc_req structure exchanged for the allocation | ||
404 | */ | ||
290 | int nilfs_palloc_prepare_alloc_entry(struct inode *inode, | 405 | int nilfs_palloc_prepare_alloc_entry(struct inode *inode, |
291 | struct nilfs_palloc_req *req) | 406 | struct nilfs_palloc_req *req) |
292 | { | 407 | { |
@@ -366,6 +481,11 @@ int nilfs_palloc_prepare_alloc_entry(struct inode *inode, | |||
366 | return ret; | 481 | return ret; |
367 | } | 482 | } |
368 | 483 | ||
484 | /** | ||
485 | * nilfs_palloc_commit_alloc_entry - finish allocation of a persistent object | ||
486 | * @inode: inode of metadata file using this allocator | ||
487 | * @req: nilfs_palloc_req structure exchanged for the allocation | ||
488 | */ | ||
369 | void nilfs_palloc_commit_alloc_entry(struct inode *inode, | 489 | void nilfs_palloc_commit_alloc_entry(struct inode *inode, |
370 | struct nilfs_palloc_req *req) | 490 | struct nilfs_palloc_req *req) |
371 | { | 491 | { |
@@ -377,6 +497,11 @@ void nilfs_palloc_commit_alloc_entry(struct inode *inode, | |||
377 | brelse(req->pr_desc_bh); | 497 | brelse(req->pr_desc_bh); |
378 | } | 498 | } |
379 | 499 | ||
500 | /** | ||
501 | * nilfs_palloc_commit_free_entry - finish deallocating a persistent object | ||
502 | * @inode: inode of metadata file using this allocator | ||
503 | * @req: nilfs_palloc_req structure exchanged for the removal | ||
504 | */ | ||
380 | void nilfs_palloc_commit_free_entry(struct inode *inode, | 505 | void nilfs_palloc_commit_free_entry(struct inode *inode, |
381 | struct nilfs_palloc_req *req) | 506 | struct nilfs_palloc_req *req) |
382 | { | 507 | { |
@@ -410,6 +535,11 @@ void nilfs_palloc_commit_free_entry(struct inode *inode, | |||
410 | brelse(req->pr_desc_bh); | 535 | brelse(req->pr_desc_bh); |
411 | } | 536 | } |
412 | 537 | ||
538 | /** | ||
539 | * nilfs_palloc_abort_alloc_entry - cancel allocation of a persistent object | ||
540 | * @inode: inode of metadata file using this allocator | ||
541 | * @req: nilfs_palloc_req structure exchanged for the allocation | ||
542 | */ | ||
413 | void nilfs_palloc_abort_alloc_entry(struct inode *inode, | 543 | void nilfs_palloc_abort_alloc_entry(struct inode *inode, |
414 | struct nilfs_palloc_req *req) | 544 | struct nilfs_palloc_req *req) |
415 | { | 545 | { |
@@ -442,6 +572,11 @@ void nilfs_palloc_abort_alloc_entry(struct inode *inode, | |||
442 | req->pr_desc_bh = NULL; | 572 | req->pr_desc_bh = NULL; |
443 | } | 573 | } |
444 | 574 | ||
575 | /** | ||
576 | * nilfs_palloc_prepare_free_entry - prepare to deallocate a persistent object | ||
577 | * @inode: inode of metadata file using this allocator | ||
578 | * @req: nilfs_palloc_req structure exchanged for the removal | ||
579 | */ | ||
445 | int nilfs_palloc_prepare_free_entry(struct inode *inode, | 580 | int nilfs_palloc_prepare_free_entry(struct inode *inode, |
446 | struct nilfs_palloc_req *req) | 581 | struct nilfs_palloc_req *req) |
447 | { | 582 | { |
@@ -464,6 +599,11 @@ int nilfs_palloc_prepare_free_entry(struct inode *inode, | |||
464 | return 0; | 599 | return 0; |
465 | } | 600 | } |
466 | 601 | ||
602 | /** | ||
603 | * nilfs_palloc_abort_free_entry - cancel deallocating a persistent object | ||
604 | * @inode: inode of metadata file using this allocator | ||
605 | * @req: nilfs_palloc_req structure exchanged for the removal | ||
606 | */ | ||
467 | void nilfs_palloc_abort_free_entry(struct inode *inode, | 607 | void nilfs_palloc_abort_free_entry(struct inode *inode, |
468 | struct nilfs_palloc_req *req) | 608 | struct nilfs_palloc_req *req) |
469 | { | 609 | { |
@@ -475,6 +615,12 @@ void nilfs_palloc_abort_free_entry(struct inode *inode, | |||
475 | req->pr_desc_bh = NULL; | 615 | req->pr_desc_bh = NULL; |
476 | } | 616 | } |
477 | 617 | ||
618 | /** | ||
619 | * nilfs_palloc_group_is_in - judge if an entry is in a group | ||
620 | * @inode: inode of metadata file using this allocator | ||
621 | * @group: group number | ||
622 | * @nr: serial number of the entry (e.g. inode number) | ||
623 | */ | ||
478 | static int | 624 | static int |
479 | nilfs_palloc_group_is_in(struct inode *inode, unsigned long group, __u64 nr) | 625 | nilfs_palloc_group_is_in(struct inode *inode, unsigned long group, __u64 nr) |
480 | { | 626 | { |
@@ -485,6 +631,12 @@ nilfs_palloc_group_is_in(struct inode *inode, unsigned long group, __u64 nr) | |||
485 | return (nr >= first) && (nr <= last); | 631 | return (nr >= first) && (nr <= last); |
486 | } | 632 | } |
487 | 633 | ||
634 | /** | ||
635 | * nilfs_palloc_freev - deallocate a set of persistent objects | ||
636 | * @inode: inode of metadata file using this allocator | ||
637 | * @entry_nrs: array of entry numbers to be deallocated | ||
638 | * @nitems: number of entries stored in @entry_nrs | ||
639 | */ | ||
488 | int nilfs_palloc_freev(struct inode *inode, __u64 *entry_nrs, size_t nitems) | 640 | int nilfs_palloc_freev(struct inode *inode, __u64 *entry_nrs, size_t nitems) |
489 | { | 641 | { |
490 | struct buffer_head *desc_bh, *bitmap_bh; | 642 | struct buffer_head *desc_bh, *bitmap_bh; |