diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-04 12:06:16 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-04 12:06:16 -0400 |
commit | 4a61f17378c2cdd9bd8f34ef8bd7422861d0c1f1 (patch) | |
tree | a2054556900af8c16fd9f5419f012dcf1ee2995a /fs/gfs2/rgrp.c | |
parent | d002ec481c24f325ed6cfcb7810d317c015dd1b5 (diff) | |
parent | 7ecdb70a0ea436c06540140242bfac6ac3babfc0 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6: (292 commits)
[GFS2] Fix endian bug for de_type
[GFS2] Initialize SELinux extended attributes at inode creation time.
[GFS2] Move logging code into log.c (mostly)
[GFS2] Mark nlink cleared so VFS sees it happen
[GFS2] Two redundant casts removed
[GFS2] Remove uneeded endian conversion
[GFS2] Remove duplicate sb reading code
[GFS2] Mark metadata reads for blktrace
[GFS2] Remove iflags.h, use FS_
[GFS2] Fix code style/indent in ops_file.c
[GFS2] streamline-generic_file_-interfaces-and-filemap gfs fix
[GFS2] Remove readv/writev methods and use aio_read/aio_write instead (gfs bits)
[GFS2] inode-diet: Eliminate i_blksize from the inode structure
[GFS2] inode_diet: Replace inode.u.generic_ip with inode.i_private (gfs)
[GFS2] Fix typo in last patch
[GFS2] Fix direct i/o logic in filemap.c
[GFS2] Fix bug in Makefiles for lock modules
[GFS2] Remove (extra) fs_subsys declaration
[GFS2/DLM] Fix trailing whitespace
[GFS2] Tidy up meta_io code
...
Diffstat (limited to 'fs/gfs2/rgrp.c')
-rw-r--r-- | fs/gfs2/rgrp.c | 1513 |
1 files changed, 1513 insertions, 0 deletions
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c new file mode 100644 index 000000000000..b261385c0065 --- /dev/null +++ b/fs/gfs2/rgrp.c | |||
@@ -0,0 +1,1513 @@ | |||
1 | /* | ||
2 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. | ||
3 | * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. | ||
4 | * | ||
5 | * This copyrighted material is made available to anyone wishing to use, | ||
6 | * modify, copy, or redistribute it subject to the terms and conditions | ||
7 | * of the GNU General Public License version 2. | ||
8 | */ | ||
9 | |||
10 | #include <linux/sched.h> | ||
11 | #include <linux/slab.h> | ||
12 | #include <linux/spinlock.h> | ||
13 | #include <linux/completion.h> | ||
14 | #include <linux/buffer_head.h> | ||
15 | #include <linux/fs.h> | ||
16 | #include <linux/gfs2_ondisk.h> | ||
17 | #include <linux/lm_interface.h> | ||
18 | |||
19 | #include "gfs2.h" | ||
20 | #include "incore.h" | ||
21 | #include "glock.h" | ||
22 | #include "glops.h" | ||
23 | #include "lops.h" | ||
24 | #include "meta_io.h" | ||
25 | #include "quota.h" | ||
26 | #include "rgrp.h" | ||
27 | #include "super.h" | ||
28 | #include "trans.h" | ||
29 | #include "ops_file.h" | ||
30 | #include "util.h" | ||
31 | |||
32 | #define BFITNOENT ((u32)~0) | ||
33 | |||
34 | /* | ||
35 | * These routines are used by the resource group routines (rgrp.c) | ||
36 | * to keep track of block allocation. Each block is represented by two | ||
37 | * bits. So, each byte represents GFS2_NBBY (i.e. 4) blocks. | ||
38 | * | ||
39 | * 0 = Free | ||
40 | * 1 = Used (not metadata) | ||
41 | * 2 = Unlinked (still in use) inode | ||
42 | * 3 = Used (metadata) | ||
43 | */ | ||
44 | |||
45 | static const char valid_change[16] = { | ||
46 | /* current */ | ||
47 | /* n */ 0, 1, 1, 1, | ||
48 | /* e */ 1, 0, 0, 0, | ||
49 | /* w */ 0, 0, 0, 1, | ||
50 | 1, 0, 0, 0 | ||
51 | }; | ||
52 | |||
53 | /** | ||
54 | * gfs2_setbit - Set a bit in the bitmaps | ||
55 | * @buffer: the buffer that holds the bitmaps | ||
56 | * @buflen: the length (in bytes) of the buffer | ||
57 | * @block: the block to set | ||
58 | * @new_state: the new state of the block | ||
59 | * | ||
60 | */ | ||
61 | |||
62 | static void gfs2_setbit(struct gfs2_rgrpd *rgd, unsigned char *buffer, | ||
63 | unsigned int buflen, u32 block, | ||
64 | unsigned char new_state) | ||
65 | { | ||
66 | unsigned char *byte, *end, cur_state; | ||
67 | unsigned int bit; | ||
68 | |||
69 | byte = buffer + (block / GFS2_NBBY); | ||
70 | bit = (block % GFS2_NBBY) * GFS2_BIT_SIZE; | ||
71 | end = buffer + buflen; | ||
72 | |||
73 | gfs2_assert(rgd->rd_sbd, byte < end); | ||
74 | |||
75 | cur_state = (*byte >> bit) & GFS2_BIT_MASK; | ||
76 | |||
77 | if (valid_change[new_state * 4 + cur_state]) { | ||
78 | *byte ^= cur_state << bit; | ||
79 | *byte |= new_state << bit; | ||
80 | } else | ||
81 | gfs2_consist_rgrpd(rgd); | ||
82 | } | ||
83 | |||
84 | /** | ||
85 | * gfs2_testbit - test a bit in the bitmaps | ||
86 | * @buffer: the buffer that holds the bitmaps | ||
87 | * @buflen: the length (in bytes) of the buffer | ||
88 | * @block: the block to read | ||
89 | * | ||
90 | */ | ||
91 | |||
92 | static unsigned char gfs2_testbit(struct gfs2_rgrpd *rgd, unsigned char *buffer, | ||
93 | unsigned int buflen, u32 block) | ||
94 | { | ||
95 | unsigned char *byte, *end, cur_state; | ||
96 | unsigned int bit; | ||
97 | |||
98 | byte = buffer + (block / GFS2_NBBY); | ||
99 | bit = (block % GFS2_NBBY) * GFS2_BIT_SIZE; | ||
100 | end = buffer + buflen; | ||
101 | |||
102 | gfs2_assert(rgd->rd_sbd, byte < end); | ||
103 | |||
104 | cur_state = (*byte >> bit) & GFS2_BIT_MASK; | ||
105 | |||
106 | return cur_state; | ||
107 | } | ||
108 | |||
109 | /** | ||
110 | * gfs2_bitfit - Search an rgrp's bitmap buffer to find a bit-pair representing | ||
111 | * a block in a given allocation state. | ||
112 | * @buffer: the buffer that holds the bitmaps | ||
113 | * @buflen: the length (in bytes) of the buffer | ||
114 | * @goal: start search at this block's bit-pair (within @buffer) | ||
115 | * @old_state: GFS2_BLKST_XXX the state of the block we're looking for; | ||
116 | * bit 0 = alloc(1)/free(0), bit 1 = meta(1)/data(0) | ||
117 | * | ||
118 | * Scope of @goal and returned block number is only within this bitmap buffer, | ||
119 | * not entire rgrp or filesystem. @buffer will be offset from the actual | ||
120 | * beginning of a bitmap block buffer, skipping any header structures. | ||
121 | * | ||
122 | * Return: the block number (bitmap buffer scope) that was found | ||
123 | */ | ||
124 | |||
125 | static u32 gfs2_bitfit(struct gfs2_rgrpd *rgd, unsigned char *buffer, | ||
126 | unsigned int buflen, u32 goal, | ||
127 | unsigned char old_state) | ||
128 | { | ||
129 | unsigned char *byte, *end, alloc; | ||
130 | u32 blk = goal; | ||
131 | unsigned int bit; | ||
132 | |||
133 | byte = buffer + (goal / GFS2_NBBY); | ||
134 | bit = (goal % GFS2_NBBY) * GFS2_BIT_SIZE; | ||
135 | end = buffer + buflen; | ||
136 | alloc = (old_state & 1) ? 0 : 0x55; | ||
137 | |||
138 | while (byte < end) { | ||
139 | if ((*byte & 0x55) == alloc) { | ||
140 | blk += (8 - bit) >> 1; | ||
141 | |||
142 | bit = 0; | ||
143 | byte++; | ||
144 | |||
145 | continue; | ||
146 | } | ||
147 | |||
148 | if (((*byte >> bit) & GFS2_BIT_MASK) == old_state) | ||
149 | return blk; | ||
150 | |||
151 | bit += GFS2_BIT_SIZE; | ||
152 | if (bit >= 8) { | ||
153 | bit = 0; | ||
154 | byte++; | ||
155 | } | ||
156 | |||
157 | blk++; | ||
158 | } | ||
159 | |||
160 | return BFITNOENT; | ||
161 | } | ||
162 | |||
163 | /** | ||
164 | * gfs2_bitcount - count the number of bits in a certain state | ||
165 | * @buffer: the buffer that holds the bitmaps | ||
166 | * @buflen: the length (in bytes) of the buffer | ||
167 | * @state: the state of the block we're looking for | ||
168 | * | ||
169 | * Returns: The number of bits | ||
170 | */ | ||
171 | |||
172 | static u32 gfs2_bitcount(struct gfs2_rgrpd *rgd, unsigned char *buffer, | ||
173 | unsigned int buflen, unsigned char state) | ||
174 | { | ||
175 | unsigned char *byte = buffer; | ||
176 | unsigned char *end = buffer + buflen; | ||
177 | unsigned char state1 = state << 2; | ||
178 | unsigned char state2 = state << 4; | ||
179 | unsigned char state3 = state << 6; | ||
180 | u32 count = 0; | ||
181 | |||
182 | for (; byte < end; byte++) { | ||
183 | if (((*byte) & 0x03) == state) | ||
184 | count++; | ||
185 | if (((*byte) & 0x0C) == state1) | ||
186 | count++; | ||
187 | if (((*byte) & 0x30) == state2) | ||
188 | count++; | ||
189 | if (((*byte) & 0xC0) == state3) | ||
190 | count++; | ||
191 | } | ||
192 | |||
193 | return count; | ||
194 | } | ||
195 | |||
196 | /** | ||
197 | * gfs2_rgrp_verify - Verify that a resource group is consistent | ||
198 | * @sdp: the filesystem | ||
199 | * @rgd: the rgrp | ||
200 | * | ||
201 | */ | ||
202 | |||
203 | void gfs2_rgrp_verify(struct gfs2_rgrpd *rgd) | ||
204 | { | ||
205 | struct gfs2_sbd *sdp = rgd->rd_sbd; | ||
206 | struct gfs2_bitmap *bi = NULL; | ||
207 | u32 length = rgd->rd_ri.ri_length; | ||
208 | u32 count[4], tmp; | ||
209 | int buf, x; | ||
210 | |||
211 | memset(count, 0, 4 * sizeof(u32)); | ||
212 | |||
213 | /* Count # blocks in each of 4 possible allocation states */ | ||
214 | for (buf = 0; buf < length; buf++) { | ||
215 | bi = rgd->rd_bits + buf; | ||
216 | for (x = 0; x < 4; x++) | ||
217 | count[x] += gfs2_bitcount(rgd, | ||
218 | bi->bi_bh->b_data + | ||
219 | bi->bi_offset, | ||
220 | bi->bi_len, x); | ||
221 | } | ||
222 | |||
223 | if (count[0] != rgd->rd_rg.rg_free) { | ||
224 | if (gfs2_consist_rgrpd(rgd)) | ||
225 | fs_err(sdp, "free data mismatch: %u != %u\n", | ||
226 | count[0], rgd->rd_rg.rg_free); | ||
227 | return; | ||
228 | } | ||
229 | |||
230 | tmp = rgd->rd_ri.ri_data - | ||
231 | rgd->rd_rg.rg_free - | ||
232 | rgd->rd_rg.rg_dinodes; | ||
233 | if (count[1] + count[2] != tmp) { | ||
234 | if (gfs2_consist_rgrpd(rgd)) | ||
235 | fs_err(sdp, "used data mismatch: %u != %u\n", | ||
236 | count[1], tmp); | ||
237 | return; | ||
238 | } | ||
239 | |||
240 | if (count[3] != rgd->rd_rg.rg_dinodes) { | ||
241 | if (gfs2_consist_rgrpd(rgd)) | ||
242 | fs_err(sdp, "used metadata mismatch: %u != %u\n", | ||
243 | count[3], rgd->rd_rg.rg_dinodes); | ||
244 | return; | ||
245 | } | ||
246 | |||
247 | if (count[2] > count[3]) { | ||
248 | if (gfs2_consist_rgrpd(rgd)) | ||
249 | fs_err(sdp, "unlinked inodes > inodes: %u\n", | ||
250 | count[2]); | ||
251 | return; | ||
252 | } | ||
253 | |||
254 | } | ||
255 | |||
256 | static inline int rgrp_contains_block(struct gfs2_rindex *ri, u64 block) | ||
257 | { | ||
258 | u64 first = ri->ri_data0; | ||
259 | u64 last = first + ri->ri_data; | ||
260 | return first <= block && block < last; | ||
261 | } | ||
262 | |||
263 | /** | ||
264 | * gfs2_blk2rgrpd - Find resource group for a given data/meta block number | ||
265 | * @sdp: The GFS2 superblock | ||
266 | * @n: The data block number | ||
267 | * | ||
268 | * Returns: The resource group, or NULL if not found | ||
269 | */ | ||
270 | |||
271 | struct gfs2_rgrpd *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, u64 blk) | ||
272 | { | ||
273 | struct gfs2_rgrpd *rgd; | ||
274 | |||
275 | spin_lock(&sdp->sd_rindex_spin); | ||
276 | |||
277 | list_for_each_entry(rgd, &sdp->sd_rindex_mru_list, rd_list_mru) { | ||
278 | if (rgrp_contains_block(&rgd->rd_ri, blk)) { | ||
279 | list_move(&rgd->rd_list_mru, &sdp->sd_rindex_mru_list); | ||
280 | spin_unlock(&sdp->sd_rindex_spin); | ||
281 | return rgd; | ||
282 | } | ||
283 | } | ||
284 | |||
285 | spin_unlock(&sdp->sd_rindex_spin); | ||
286 | |||
287 | return NULL; | ||
288 | } | ||
289 | |||
290 | /** | ||
291 | * gfs2_rgrpd_get_first - get the first Resource Group in the filesystem | ||
292 | * @sdp: The GFS2 superblock | ||
293 | * | ||
294 | * Returns: The first rgrp in the filesystem | ||
295 | */ | ||
296 | |||
297 | struct gfs2_rgrpd *gfs2_rgrpd_get_first(struct gfs2_sbd *sdp) | ||
298 | { | ||
299 | gfs2_assert(sdp, !list_empty(&sdp->sd_rindex_list)); | ||
300 | return list_entry(sdp->sd_rindex_list.next, struct gfs2_rgrpd, rd_list); | ||
301 | } | ||
302 | |||
303 | /** | ||
304 | * gfs2_rgrpd_get_next - get the next RG | ||
305 | * @rgd: A RG | ||
306 | * | ||
307 | * Returns: The next rgrp | ||
308 | */ | ||
309 | |||
310 | struct gfs2_rgrpd *gfs2_rgrpd_get_next(struct gfs2_rgrpd *rgd) | ||
311 | { | ||
312 | if (rgd->rd_list.next == &rgd->rd_sbd->sd_rindex_list) | ||
313 | return NULL; | ||
314 | return list_entry(rgd->rd_list.next, struct gfs2_rgrpd, rd_list); | ||
315 | } | ||
316 | |||
317 | static void clear_rgrpdi(struct gfs2_sbd *sdp) | ||
318 | { | ||
319 | struct list_head *head; | ||
320 | struct gfs2_rgrpd *rgd; | ||
321 | struct gfs2_glock *gl; | ||
322 | |||
323 | spin_lock(&sdp->sd_rindex_spin); | ||
324 | sdp->sd_rindex_forward = NULL; | ||
325 | head = &sdp->sd_rindex_recent_list; | ||
326 | while (!list_empty(head)) { | ||
327 | rgd = list_entry(head->next, struct gfs2_rgrpd, rd_recent); | ||
328 | list_del(&rgd->rd_recent); | ||
329 | } | ||
330 | spin_unlock(&sdp->sd_rindex_spin); | ||
331 | |||
332 | head = &sdp->sd_rindex_list; | ||
333 | while (!list_empty(head)) { | ||
334 | rgd = list_entry(head->next, struct gfs2_rgrpd, rd_list); | ||
335 | gl = rgd->rd_gl; | ||
336 | |||
337 | list_del(&rgd->rd_list); | ||
338 | list_del(&rgd->rd_list_mru); | ||
339 | |||
340 | if (gl) { | ||
341 | gl->gl_object = NULL; | ||
342 | gfs2_glock_put(gl); | ||
343 | } | ||
344 | |||
345 | kfree(rgd->rd_bits); | ||
346 | kfree(rgd); | ||
347 | } | ||
348 | } | ||
349 | |||
350 | void gfs2_clear_rgrpd(struct gfs2_sbd *sdp) | ||
351 | { | ||
352 | mutex_lock(&sdp->sd_rindex_mutex); | ||
353 | clear_rgrpdi(sdp); | ||
354 | mutex_unlock(&sdp->sd_rindex_mutex); | ||
355 | } | ||
356 | |||
357 | /** | ||
358 | * gfs2_compute_bitstructs - Compute the bitmap sizes | ||
359 | * @rgd: The resource group descriptor | ||
360 | * | ||
361 | * Calculates bitmap descriptors, one for each block that contains bitmap data | ||
362 | * | ||
363 | * Returns: errno | ||
364 | */ | ||
365 | |||
366 | static int compute_bitstructs(struct gfs2_rgrpd *rgd) | ||
367 | { | ||
368 | struct gfs2_sbd *sdp = rgd->rd_sbd; | ||
369 | struct gfs2_bitmap *bi; | ||
370 | u32 length = rgd->rd_ri.ri_length; /* # blocks in hdr & bitmap */ | ||
371 | u32 bytes_left, bytes; | ||
372 | int x; | ||
373 | |||
374 | if (!length) | ||
375 | return -EINVAL; | ||
376 | |||
377 | rgd->rd_bits = kcalloc(length, sizeof(struct gfs2_bitmap), GFP_NOFS); | ||
378 | if (!rgd->rd_bits) | ||
379 | return -ENOMEM; | ||
380 | |||
381 | bytes_left = rgd->rd_ri.ri_bitbytes; | ||
382 | |||
383 | for (x = 0; x < length; x++) { | ||
384 | bi = rgd->rd_bits + x; | ||
385 | |||
386 | /* small rgrp; bitmap stored completely in header block */ | ||
387 | if (length == 1) { | ||
388 | bytes = bytes_left; | ||
389 | bi->bi_offset = sizeof(struct gfs2_rgrp); | ||
390 | bi->bi_start = 0; | ||
391 | bi->bi_len = bytes; | ||
392 | /* header block */ | ||
393 | } else if (x == 0) { | ||
394 | bytes = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_rgrp); | ||
395 | bi->bi_offset = sizeof(struct gfs2_rgrp); | ||
396 | bi->bi_start = 0; | ||
397 | bi->bi_len = bytes; | ||
398 | /* last block */ | ||
399 | } else if (x + 1 == length) { | ||
400 | bytes = bytes_left; | ||
401 | bi->bi_offset = sizeof(struct gfs2_meta_header); | ||
402 | bi->bi_start = rgd->rd_ri.ri_bitbytes - bytes_left; | ||
403 | bi->bi_len = bytes; | ||
404 | /* other blocks */ | ||
405 | } else { | ||
406 | bytes = sdp->sd_sb.sb_bsize - | ||
407 | sizeof(struct gfs2_meta_header); | ||
408 | bi->bi_offset = sizeof(struct gfs2_meta_header); | ||
409 | bi->bi_start = rgd->rd_ri.ri_bitbytes - bytes_left; | ||
410 | bi->bi_len = bytes; | ||
411 | } | ||
412 | |||
413 | bytes_left -= bytes; | ||
414 | } | ||
415 | |||
416 | if (bytes_left) { | ||
417 | gfs2_consist_rgrpd(rgd); | ||
418 | return -EIO; | ||
419 | } | ||
420 | bi = rgd->rd_bits + (length - 1); | ||
421 | if ((bi->bi_start + bi->bi_len) * GFS2_NBBY != rgd->rd_ri.ri_data) { | ||
422 | if (gfs2_consist_rgrpd(rgd)) { | ||
423 | gfs2_rindex_print(&rgd->rd_ri); | ||
424 | fs_err(sdp, "start=%u len=%u offset=%u\n", | ||
425 | bi->bi_start, bi->bi_len, bi->bi_offset); | ||
426 | } | ||
427 | return -EIO; | ||
428 | } | ||
429 | |||
430 | return 0; | ||
431 | } | ||
432 | |||
433 | /** | ||
434 | * gfs2_ri_update - Pull in a new resource index from the disk | ||
435 | * @gl: The glock covering the rindex inode | ||
436 | * | ||
437 | * Returns: 0 on successful update, error code otherwise | ||
438 | */ | ||
439 | |||
440 | static int gfs2_ri_update(struct gfs2_inode *ip) | ||
441 | { | ||
442 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | ||
443 | struct inode *inode = &ip->i_inode; | ||
444 | struct gfs2_rgrpd *rgd; | ||
445 | char buf[sizeof(struct gfs2_rindex)]; | ||
446 | struct file_ra_state ra_state; | ||
447 | u64 junk = ip->i_di.di_size; | ||
448 | int error; | ||
449 | |||
450 | if (do_div(junk, sizeof(struct gfs2_rindex))) { | ||
451 | gfs2_consist_inode(ip); | ||
452 | return -EIO; | ||
453 | } | ||
454 | |||
455 | clear_rgrpdi(sdp); | ||
456 | |||
457 | file_ra_state_init(&ra_state, inode->i_mapping); | ||
458 | for (sdp->sd_rgrps = 0;; sdp->sd_rgrps++) { | ||
459 | loff_t pos = sdp->sd_rgrps * sizeof(struct gfs2_rindex); | ||
460 | error = gfs2_internal_read(ip, &ra_state, buf, &pos, | ||
461 | sizeof(struct gfs2_rindex)); | ||
462 | if (!error) | ||
463 | break; | ||
464 | if (error != sizeof(struct gfs2_rindex)) { | ||
465 | if (error > 0) | ||
466 | error = -EIO; | ||
467 | goto fail; | ||
468 | } | ||
469 | |||
470 | rgd = kzalloc(sizeof(struct gfs2_rgrpd), GFP_NOFS); | ||
471 | error = -ENOMEM; | ||
472 | if (!rgd) | ||
473 | goto fail; | ||
474 | |||
475 | mutex_init(&rgd->rd_mutex); | ||
476 | lops_init_le(&rgd->rd_le, &gfs2_rg_lops); | ||
477 | rgd->rd_sbd = sdp; | ||
478 | |||
479 | list_add_tail(&rgd->rd_list, &sdp->sd_rindex_list); | ||
480 | list_add_tail(&rgd->rd_list_mru, &sdp->sd_rindex_mru_list); | ||
481 | |||
482 | gfs2_rindex_in(&rgd->rd_ri, buf); | ||
483 | error = compute_bitstructs(rgd); | ||
484 | if (error) | ||
485 | goto fail; | ||
486 | |||
487 | error = gfs2_glock_get(sdp, rgd->rd_ri.ri_addr, | ||
488 | &gfs2_rgrp_glops, CREATE, &rgd->rd_gl); | ||
489 | if (error) | ||
490 | goto fail; | ||
491 | |||
492 | rgd->rd_gl->gl_object = rgd; | ||
493 | rgd->rd_rg_vn = rgd->rd_gl->gl_vn - 1; | ||
494 | } | ||
495 | |||
496 | sdp->sd_rindex_vn = ip->i_gl->gl_vn; | ||
497 | return 0; | ||
498 | |||
499 | fail: | ||
500 | clear_rgrpdi(sdp); | ||
501 | return error; | ||
502 | } | ||
503 | |||
504 | /** | ||
505 | * gfs2_rindex_hold - Grab a lock on the rindex | ||
506 | * @sdp: The GFS2 superblock | ||
507 | * @ri_gh: the glock holder | ||
508 | * | ||
509 | * We grab a lock on the rindex inode to make sure that it doesn't | ||
510 | * change whilst we are performing an operation. We keep this lock | ||
511 | * for quite long periods of time compared to other locks. This | ||
512 | * doesn't matter, since it is shared and it is very, very rarely | ||
513 | * accessed in the exclusive mode (i.e. only when expanding the filesystem). | ||
514 | * | ||
515 | * This makes sure that we're using the latest copy of the resource index | ||
516 | * special file, which might have been updated if someone expanded the | ||
517 | * filesystem (via gfs2_grow utility), which adds new resource groups. | ||
518 | * | ||
519 | * Returns: 0 on success, error code otherwise | ||
520 | */ | ||
521 | |||
522 | int gfs2_rindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ri_gh) | ||
523 | { | ||
524 | struct gfs2_inode *ip = GFS2_I(sdp->sd_rindex); | ||
525 | struct gfs2_glock *gl = ip->i_gl; | ||
526 | int error; | ||
527 | |||
528 | error = gfs2_glock_nq_init(gl, LM_ST_SHARED, 0, ri_gh); | ||
529 | if (error) | ||
530 | return error; | ||
531 | |||
532 | /* Read new copy from disk if we don't have the latest */ | ||
533 | if (sdp->sd_rindex_vn != gl->gl_vn) { | ||
534 | mutex_lock(&sdp->sd_rindex_mutex); | ||
535 | if (sdp->sd_rindex_vn != gl->gl_vn) { | ||
536 | error = gfs2_ri_update(ip); | ||
537 | if (error) | ||
538 | gfs2_glock_dq_uninit(ri_gh); | ||
539 | } | ||
540 | mutex_unlock(&sdp->sd_rindex_mutex); | ||
541 | } | ||
542 | |||
543 | return error; | ||
544 | } | ||
545 | |||
546 | /** | ||
547 | * gfs2_rgrp_bh_get - Read in a RG's header and bitmaps | ||
548 | * @rgd: the struct gfs2_rgrpd describing the RG to read in | ||
549 | * | ||
550 | * Read in all of a Resource Group's header and bitmap blocks. | ||
551 | * Caller must eventually call gfs2_rgrp_relse() to free the bitmaps. | ||
552 | * | ||
553 | * Returns: errno | ||
554 | */ | ||
555 | |||
556 | int gfs2_rgrp_bh_get(struct gfs2_rgrpd *rgd) | ||
557 | { | ||
558 | struct gfs2_sbd *sdp = rgd->rd_sbd; | ||
559 | struct gfs2_glock *gl = rgd->rd_gl; | ||
560 | unsigned int length = rgd->rd_ri.ri_length; | ||
561 | struct gfs2_bitmap *bi; | ||
562 | unsigned int x, y; | ||
563 | int error; | ||
564 | |||
565 | mutex_lock(&rgd->rd_mutex); | ||
566 | |||
567 | spin_lock(&sdp->sd_rindex_spin); | ||
568 | if (rgd->rd_bh_count) { | ||
569 | rgd->rd_bh_count++; | ||
570 | spin_unlock(&sdp->sd_rindex_spin); | ||
571 | mutex_unlock(&rgd->rd_mutex); | ||
572 | return 0; | ||
573 | } | ||
574 | spin_unlock(&sdp->sd_rindex_spin); | ||
575 | |||
576 | for (x = 0; x < length; x++) { | ||
577 | bi = rgd->rd_bits + x; | ||
578 | error = gfs2_meta_read(gl, rgd->rd_ri.ri_addr + x, 0, &bi->bi_bh); | ||
579 | if (error) | ||
580 | goto fail; | ||
581 | } | ||
582 | |||
583 | for (y = length; y--;) { | ||
584 | bi = rgd->rd_bits + y; | ||
585 | error = gfs2_meta_wait(sdp, bi->bi_bh); | ||
586 | if (error) | ||
587 | goto fail; | ||
588 | if (gfs2_metatype_check(sdp, bi->bi_bh, y ? GFS2_METATYPE_RB : | ||
589 | GFS2_METATYPE_RG)) { | ||
590 | error = -EIO; | ||
591 | goto fail; | ||
592 | } | ||
593 | } | ||
594 | |||
595 | if (rgd->rd_rg_vn != gl->gl_vn) { | ||
596 | gfs2_rgrp_in(&rgd->rd_rg, (rgd->rd_bits[0].bi_bh)->b_data); | ||
597 | rgd->rd_rg_vn = gl->gl_vn; | ||
598 | } | ||
599 | |||
600 | spin_lock(&sdp->sd_rindex_spin); | ||
601 | rgd->rd_free_clone = rgd->rd_rg.rg_free; | ||
602 | rgd->rd_bh_count++; | ||
603 | spin_unlock(&sdp->sd_rindex_spin); | ||
604 | |||
605 | mutex_unlock(&rgd->rd_mutex); | ||
606 | |||
607 | return 0; | ||
608 | |||
609 | fail: | ||
610 | while (x--) { | ||
611 | bi = rgd->rd_bits + x; | ||
612 | brelse(bi->bi_bh); | ||
613 | bi->bi_bh = NULL; | ||
614 | gfs2_assert_warn(sdp, !bi->bi_clone); | ||
615 | } | ||
616 | mutex_unlock(&rgd->rd_mutex); | ||
617 | |||
618 | return error; | ||
619 | } | ||
620 | |||
621 | void gfs2_rgrp_bh_hold(struct gfs2_rgrpd *rgd) | ||
622 | { | ||
623 | struct gfs2_sbd *sdp = rgd->rd_sbd; | ||
624 | |||
625 | spin_lock(&sdp->sd_rindex_spin); | ||
626 | gfs2_assert_warn(rgd->rd_sbd, rgd->rd_bh_count); | ||
627 | rgd->rd_bh_count++; | ||
628 | spin_unlock(&sdp->sd_rindex_spin); | ||
629 | } | ||
630 | |||
631 | /** | ||
632 | * gfs2_rgrp_bh_put - Release RG bitmaps read in with gfs2_rgrp_bh_get() | ||
633 | * @rgd: the struct gfs2_rgrpd describing the RG to read in | ||
634 | * | ||
635 | */ | ||
636 | |||
637 | void gfs2_rgrp_bh_put(struct gfs2_rgrpd *rgd) | ||
638 | { | ||
639 | struct gfs2_sbd *sdp = rgd->rd_sbd; | ||
640 | int x, length = rgd->rd_ri.ri_length; | ||
641 | |||
642 | spin_lock(&sdp->sd_rindex_spin); | ||
643 | gfs2_assert_warn(rgd->rd_sbd, rgd->rd_bh_count); | ||
644 | if (--rgd->rd_bh_count) { | ||
645 | spin_unlock(&sdp->sd_rindex_spin); | ||
646 | return; | ||
647 | } | ||
648 | |||
649 | for (x = 0; x < length; x++) { | ||
650 | struct gfs2_bitmap *bi = rgd->rd_bits + x; | ||
651 | kfree(bi->bi_clone); | ||
652 | bi->bi_clone = NULL; | ||
653 | brelse(bi->bi_bh); | ||
654 | bi->bi_bh = NULL; | ||
655 | } | ||
656 | |||
657 | spin_unlock(&sdp->sd_rindex_spin); | ||
658 | } | ||
659 | |||
660 | void gfs2_rgrp_repolish_clones(struct gfs2_rgrpd *rgd) | ||
661 | { | ||
662 | struct gfs2_sbd *sdp = rgd->rd_sbd; | ||
663 | unsigned int length = rgd->rd_ri.ri_length; | ||
664 | unsigned int x; | ||
665 | |||
666 | for (x = 0; x < length; x++) { | ||
667 | struct gfs2_bitmap *bi = rgd->rd_bits + x; | ||
668 | if (!bi->bi_clone) | ||
669 | continue; | ||
670 | memcpy(bi->bi_clone + bi->bi_offset, | ||
671 | bi->bi_bh->b_data + bi->bi_offset, bi->bi_len); | ||
672 | } | ||
673 | |||
674 | spin_lock(&sdp->sd_rindex_spin); | ||
675 | rgd->rd_free_clone = rgd->rd_rg.rg_free; | ||
676 | spin_unlock(&sdp->sd_rindex_spin); | ||
677 | } | ||
678 | |||
679 | /** | ||
680 | * gfs2_alloc_get - get the struct gfs2_alloc structure for an inode | ||
681 | * @ip: the incore GFS2 inode structure | ||
682 | * | ||
683 | * Returns: the struct gfs2_alloc | ||
684 | */ | ||
685 | |||
686 | struct gfs2_alloc *gfs2_alloc_get(struct gfs2_inode *ip) | ||
687 | { | ||
688 | struct gfs2_alloc *al = &ip->i_alloc; | ||
689 | |||
690 | /* FIXME: Should assert that the correct locks are held here... */ | ||
691 | memset(al, 0, sizeof(*al)); | ||
692 | return al; | ||
693 | } | ||
694 | |||
695 | /** | ||
696 | * try_rgrp_fit - See if a given reservation will fit in a given RG | ||
697 | * @rgd: the RG data | ||
698 | * @al: the struct gfs2_alloc structure describing the reservation | ||
699 | * | ||
700 | * If there's room for the requested blocks to be allocated from the RG: | ||
701 | * Sets the $al_reserved_data field in @al. | ||
702 | * Sets the $al_reserved_meta field in @al. | ||
703 | * Sets the $al_rgd field in @al. | ||
704 | * | ||
705 | * Returns: 1 on success (it fits), 0 on failure (it doesn't fit) | ||
706 | */ | ||
707 | |||
708 | static int try_rgrp_fit(struct gfs2_rgrpd *rgd, struct gfs2_alloc *al) | ||
709 | { | ||
710 | struct gfs2_sbd *sdp = rgd->rd_sbd; | ||
711 | int ret = 0; | ||
712 | |||
713 | spin_lock(&sdp->sd_rindex_spin); | ||
714 | if (rgd->rd_free_clone >= al->al_requested) { | ||
715 | al->al_rgd = rgd; | ||
716 | ret = 1; | ||
717 | } | ||
718 | spin_unlock(&sdp->sd_rindex_spin); | ||
719 | |||
720 | return ret; | ||
721 | } | ||
722 | |||
723 | /** | ||
724 | * recent_rgrp_first - get first RG from "recent" list | ||
725 | * @sdp: The GFS2 superblock | ||
726 | * @rglast: address of the rgrp used last | ||
727 | * | ||
728 | * Returns: The first rgrp in the recent list | ||
729 | */ | ||
730 | |||
731 | static struct gfs2_rgrpd *recent_rgrp_first(struct gfs2_sbd *sdp, | ||
732 | u64 rglast) | ||
733 | { | ||
734 | struct gfs2_rgrpd *rgd = NULL; | ||
735 | |||
736 | spin_lock(&sdp->sd_rindex_spin); | ||
737 | |||
738 | if (list_empty(&sdp->sd_rindex_recent_list)) | ||
739 | goto out; | ||
740 | |||
741 | if (!rglast) | ||
742 | goto first; | ||
743 | |||
744 | list_for_each_entry(rgd, &sdp->sd_rindex_recent_list, rd_recent) { | ||
745 | if (rgd->rd_ri.ri_addr == rglast) | ||
746 | goto out; | ||
747 | } | ||
748 | |||
749 | first: | ||
750 | rgd = list_entry(sdp->sd_rindex_recent_list.next, struct gfs2_rgrpd, | ||
751 | rd_recent); | ||
752 | out: | ||
753 | spin_unlock(&sdp->sd_rindex_spin); | ||
754 | return rgd; | ||
755 | } | ||
756 | |||
757 | /** | ||
758 | * recent_rgrp_next - get next RG from "recent" list | ||
759 | * @cur_rgd: current rgrp | ||
760 | * @remove: | ||
761 | * | ||
762 | * Returns: The next rgrp in the recent list | ||
763 | */ | ||
764 | |||
765 | static struct gfs2_rgrpd *recent_rgrp_next(struct gfs2_rgrpd *cur_rgd, | ||
766 | int remove) | ||
767 | { | ||
768 | struct gfs2_sbd *sdp = cur_rgd->rd_sbd; | ||
769 | struct list_head *head; | ||
770 | struct gfs2_rgrpd *rgd; | ||
771 | |||
772 | spin_lock(&sdp->sd_rindex_spin); | ||
773 | |||
774 | head = &sdp->sd_rindex_recent_list; | ||
775 | |||
776 | list_for_each_entry(rgd, head, rd_recent) { | ||
777 | if (rgd == cur_rgd) { | ||
778 | if (cur_rgd->rd_recent.next != head) | ||
779 | rgd = list_entry(cur_rgd->rd_recent.next, | ||
780 | struct gfs2_rgrpd, rd_recent); | ||
781 | else | ||
782 | rgd = NULL; | ||
783 | |||
784 | if (remove) | ||
785 | list_del(&cur_rgd->rd_recent); | ||
786 | |||
787 | goto out; | ||
788 | } | ||
789 | } | ||
790 | |||
791 | rgd = NULL; | ||
792 | if (!list_empty(head)) | ||
793 | rgd = list_entry(head->next, struct gfs2_rgrpd, rd_recent); | ||
794 | |||
795 | out: | ||
796 | spin_unlock(&sdp->sd_rindex_spin); | ||
797 | return rgd; | ||
798 | } | ||
799 | |||
800 | /** | ||
801 | * recent_rgrp_add - add an RG to tail of "recent" list | ||
802 | * @new_rgd: The rgrp to add | ||
803 | * | ||
804 | */ | ||
805 | |||
806 | static void recent_rgrp_add(struct gfs2_rgrpd *new_rgd) | ||
807 | { | ||
808 | struct gfs2_sbd *sdp = new_rgd->rd_sbd; | ||
809 | struct gfs2_rgrpd *rgd; | ||
810 | unsigned int count = 0; | ||
811 | unsigned int max = sdp->sd_rgrps / gfs2_jindex_size(sdp); | ||
812 | |||
813 | spin_lock(&sdp->sd_rindex_spin); | ||
814 | |||
815 | list_for_each_entry(rgd, &sdp->sd_rindex_recent_list, rd_recent) { | ||
816 | if (rgd == new_rgd) | ||
817 | goto out; | ||
818 | |||
819 | if (++count >= max) | ||
820 | goto out; | ||
821 | } | ||
822 | list_add_tail(&new_rgd->rd_recent, &sdp->sd_rindex_recent_list); | ||
823 | |||
824 | out: | ||
825 | spin_unlock(&sdp->sd_rindex_spin); | ||
826 | } | ||
827 | |||
828 | /** | ||
829 | * forward_rgrp_get - get an rgrp to try next from full list | ||
830 | * @sdp: The GFS2 superblock | ||
831 | * | ||
832 | * Returns: The rgrp to try next | ||
833 | */ | ||
834 | |||
835 | static struct gfs2_rgrpd *forward_rgrp_get(struct gfs2_sbd *sdp) | ||
836 | { | ||
837 | struct gfs2_rgrpd *rgd; | ||
838 | unsigned int journals = gfs2_jindex_size(sdp); | ||
839 | unsigned int rg = 0, x; | ||
840 | |||
841 | spin_lock(&sdp->sd_rindex_spin); | ||
842 | |||
843 | rgd = sdp->sd_rindex_forward; | ||
844 | if (!rgd) { | ||
845 | if (sdp->sd_rgrps >= journals) | ||
846 | rg = sdp->sd_rgrps * sdp->sd_jdesc->jd_jid / journals; | ||
847 | |||
848 | for (x = 0, rgd = gfs2_rgrpd_get_first(sdp); x < rg; | ||
849 | x++, rgd = gfs2_rgrpd_get_next(rgd)) | ||
850 | /* Do Nothing */; | ||
851 | |||
852 | sdp->sd_rindex_forward = rgd; | ||
853 | } | ||
854 | |||
855 | spin_unlock(&sdp->sd_rindex_spin); | ||
856 | |||
857 | return rgd; | ||
858 | } | ||
859 | |||
860 | /** | ||
861 | * forward_rgrp_set - set the forward rgrp pointer | ||
862 | * @sdp: the filesystem | ||
863 | * @rgd: The new forward rgrp | ||
864 | * | ||
865 | */ | ||
866 | |||
867 | static void forward_rgrp_set(struct gfs2_sbd *sdp, struct gfs2_rgrpd *rgd) | ||
868 | { | ||
869 | spin_lock(&sdp->sd_rindex_spin); | ||
870 | sdp->sd_rindex_forward = rgd; | ||
871 | spin_unlock(&sdp->sd_rindex_spin); | ||
872 | } | ||
873 | |||
874 | /** | ||
875 | * get_local_rgrp - Choose and lock a rgrp for allocation | ||
876 | * @ip: the inode to reserve space for | ||
877 | * @rgp: the chosen and locked rgrp | ||
878 | * | ||
879 | * Try to acquire rgrp in way which avoids contending with others. | ||
880 | * | ||
881 | * Returns: errno | ||
882 | */ | ||
883 | |||
884 | static int get_local_rgrp(struct gfs2_inode *ip) | ||
885 | { | ||
886 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | ||
887 | struct gfs2_rgrpd *rgd, *begin = NULL; | ||
888 | struct gfs2_alloc *al = &ip->i_alloc; | ||
889 | int flags = LM_FLAG_TRY; | ||
890 | int skipped = 0; | ||
891 | int loops = 0; | ||
892 | int error; | ||
893 | |||
894 | /* Try recently successful rgrps */ | ||
895 | |||
896 | rgd = recent_rgrp_first(sdp, ip->i_last_rg_alloc); | ||
897 | |||
898 | while (rgd) { | ||
899 | error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, | ||
900 | LM_FLAG_TRY, &al->al_rgd_gh); | ||
901 | switch (error) { | ||
902 | case 0: | ||
903 | if (try_rgrp_fit(rgd, al)) | ||
904 | goto out; | ||
905 | gfs2_glock_dq_uninit(&al->al_rgd_gh); | ||
906 | rgd = recent_rgrp_next(rgd, 1); | ||
907 | break; | ||
908 | |||
909 | case GLR_TRYFAILED: | ||
910 | rgd = recent_rgrp_next(rgd, 0); | ||
911 | break; | ||
912 | |||
913 | default: | ||
914 | return error; | ||
915 | } | ||
916 | } | ||
917 | |||
918 | /* Go through full list of rgrps */ | ||
919 | |||
920 | begin = rgd = forward_rgrp_get(sdp); | ||
921 | |||
922 | for (;;) { | ||
923 | error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, flags, | ||
924 | &al->al_rgd_gh); | ||
925 | switch (error) { | ||
926 | case 0: | ||
927 | if (try_rgrp_fit(rgd, al)) | ||
928 | goto out; | ||
929 | gfs2_glock_dq_uninit(&al->al_rgd_gh); | ||
930 | break; | ||
931 | |||
932 | case GLR_TRYFAILED: | ||
933 | skipped++; | ||
934 | break; | ||
935 | |||
936 | default: | ||
937 | return error; | ||
938 | } | ||
939 | |||
940 | rgd = gfs2_rgrpd_get_next(rgd); | ||
941 | if (!rgd) | ||
942 | rgd = gfs2_rgrpd_get_first(sdp); | ||
943 | |||
944 | if (rgd == begin) { | ||
945 | if (++loops >= 2 || !skipped) | ||
946 | return -ENOSPC; | ||
947 | flags = 0; | ||
948 | } | ||
949 | } | ||
950 | |||
951 | out: | ||
952 | ip->i_last_rg_alloc = rgd->rd_ri.ri_addr; | ||
953 | |||
954 | if (begin) { | ||
955 | recent_rgrp_add(rgd); | ||
956 | rgd = gfs2_rgrpd_get_next(rgd); | ||
957 | if (!rgd) | ||
958 | rgd = gfs2_rgrpd_get_first(sdp); | ||
959 | forward_rgrp_set(sdp, rgd); | ||
960 | } | ||
961 | |||
962 | return 0; | ||
963 | } | ||
964 | |||
965 | /** | ||
966 | * gfs2_inplace_reserve_i - Reserve space in the filesystem | ||
967 | * @ip: the inode to reserve space for | ||
968 | * | ||
969 | * Returns: errno | ||
970 | */ | ||
971 | |||
972 | int gfs2_inplace_reserve_i(struct gfs2_inode *ip, char *file, unsigned int line) | ||
973 | { | ||
974 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | ||
975 | struct gfs2_alloc *al = &ip->i_alloc; | ||
976 | int error; | ||
977 | |||
978 | if (gfs2_assert_warn(sdp, al->al_requested)) | ||
979 | return -EINVAL; | ||
980 | |||
981 | error = gfs2_rindex_hold(sdp, &al->al_ri_gh); | ||
982 | if (error) | ||
983 | return error; | ||
984 | |||
985 | error = get_local_rgrp(ip); | ||
986 | if (error) { | ||
987 | gfs2_glock_dq_uninit(&al->al_ri_gh); | ||
988 | return error; | ||
989 | } | ||
990 | |||
991 | al->al_file = file; | ||
992 | al->al_line = line; | ||
993 | |||
994 | return 0; | ||
995 | } | ||
996 | |||
997 | /** | ||
998 | * gfs2_inplace_release - release an inplace reservation | ||
999 | * @ip: the inode the reservation was taken out on | ||
1000 | * | ||
1001 | * Release a reservation made by gfs2_inplace_reserve(). | ||
1002 | */ | ||
1003 | |||
1004 | void gfs2_inplace_release(struct gfs2_inode *ip) | ||
1005 | { | ||
1006 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | ||
1007 | struct gfs2_alloc *al = &ip->i_alloc; | ||
1008 | |||
1009 | if (gfs2_assert_warn(sdp, al->al_alloced <= al->al_requested) == -1) | ||
1010 | fs_warn(sdp, "al_alloced = %u, al_requested = %u " | ||
1011 | "al_file = %s, al_line = %u\n", | ||
1012 | al->al_alloced, al->al_requested, al->al_file, | ||
1013 | al->al_line); | ||
1014 | |||
1015 | al->al_rgd = NULL; | ||
1016 | gfs2_glock_dq_uninit(&al->al_rgd_gh); | ||
1017 | gfs2_glock_dq_uninit(&al->al_ri_gh); | ||
1018 | } | ||
1019 | |||
1020 | /** | ||
1021 | * gfs2_get_block_type - Check a block in a RG is of given type | ||
1022 | * @rgd: the resource group holding the block | ||
1023 | * @block: the block number | ||
1024 | * | ||
1025 | * Returns: The block type (GFS2_BLKST_*) | ||
1026 | */ | ||
1027 | |||
1028 | unsigned char gfs2_get_block_type(struct gfs2_rgrpd *rgd, u64 block) | ||
1029 | { | ||
1030 | struct gfs2_bitmap *bi = NULL; | ||
1031 | u32 length, rgrp_block, buf_block; | ||
1032 | unsigned int buf; | ||
1033 | unsigned char type; | ||
1034 | |||
1035 | length = rgd->rd_ri.ri_length; | ||
1036 | rgrp_block = block - rgd->rd_ri.ri_data0; | ||
1037 | |||
1038 | for (buf = 0; buf < length; buf++) { | ||
1039 | bi = rgd->rd_bits + buf; | ||
1040 | if (rgrp_block < (bi->bi_start + bi->bi_len) * GFS2_NBBY) | ||
1041 | break; | ||
1042 | } | ||
1043 | |||
1044 | gfs2_assert(rgd->rd_sbd, buf < length); | ||
1045 | buf_block = rgrp_block - bi->bi_start * GFS2_NBBY; | ||
1046 | |||
1047 | type = gfs2_testbit(rgd, bi->bi_bh->b_data + bi->bi_offset, | ||
1048 | bi->bi_len, buf_block); | ||
1049 | |||
1050 | return type; | ||
1051 | } | ||
1052 | |||
1053 | /** | ||
1054 | * rgblk_search - find a block in @old_state, change allocation | ||
1055 | * state to @new_state | ||
1056 | * @rgd: the resource group descriptor | ||
1057 | * @goal: the goal block within the RG (start here to search for avail block) | ||
1058 | * @old_state: GFS2_BLKST_XXX the before-allocation state to find | ||
1059 | * @new_state: GFS2_BLKST_XXX the after-allocation block state | ||
1060 | * | ||
1061 | * Walk rgrp's bitmap to find bits that represent a block in @old_state. | ||
1062 | * Add the found bitmap buffer to the transaction. | ||
1063 | * Set the found bits to @new_state to change block's allocation state. | ||
1064 | * | ||
1065 | * This function never fails, because we wouldn't call it unless we | ||
1066 | * know (from reservation results, etc.) that a block is available. | ||
1067 | * | ||
1068 | * Scope of @goal and returned block is just within rgrp, not the whole | ||
1069 | * filesystem. | ||
1070 | * | ||
1071 | * Returns: the block number allocated | ||
1072 | */ | ||
1073 | |||
1074 | static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal, | ||
1075 | unsigned char old_state, unsigned char new_state) | ||
1076 | { | ||
1077 | struct gfs2_bitmap *bi = NULL; | ||
1078 | u32 length = rgd->rd_ri.ri_length; | ||
1079 | u32 blk = 0; | ||
1080 | unsigned int buf, x; | ||
1081 | |||
1082 | /* Find bitmap block that contains bits for goal block */ | ||
1083 | for (buf = 0; buf < length; buf++) { | ||
1084 | bi = rgd->rd_bits + buf; | ||
1085 | if (goal < (bi->bi_start + bi->bi_len) * GFS2_NBBY) | ||
1086 | break; | ||
1087 | } | ||
1088 | |||
1089 | gfs2_assert(rgd->rd_sbd, buf < length); | ||
1090 | |||
1091 | /* Convert scope of "goal" from rgrp-wide to within found bit block */ | ||
1092 | goal -= bi->bi_start * GFS2_NBBY; | ||
1093 | |||
1094 | /* Search (up to entire) bitmap in this rgrp for allocatable block. | ||
1095 | "x <= length", instead of "x < length", because we typically start | ||
1096 | the search in the middle of a bit block, but if we can't find an | ||
1097 | allocatable block anywhere else, we want to be able wrap around and | ||
1098 | search in the first part of our first-searched bit block. */ | ||
1099 | for (x = 0; x <= length; x++) { | ||
1100 | if (bi->bi_clone) | ||
1101 | blk = gfs2_bitfit(rgd, bi->bi_clone + bi->bi_offset, | ||
1102 | bi->bi_len, goal, old_state); | ||
1103 | else | ||
1104 | blk = gfs2_bitfit(rgd, | ||
1105 | bi->bi_bh->b_data + bi->bi_offset, | ||
1106 | bi->bi_len, goal, old_state); | ||
1107 | if (blk != BFITNOENT) | ||
1108 | break; | ||
1109 | |||
1110 | /* Try next bitmap block (wrap back to rgrp header if at end) */ | ||
1111 | buf = (buf + 1) % length; | ||
1112 | bi = rgd->rd_bits + buf; | ||
1113 | goal = 0; | ||
1114 | } | ||
1115 | |||
1116 | if (gfs2_assert_withdraw(rgd->rd_sbd, x <= length)) | ||
1117 | blk = 0; | ||
1118 | |||
1119 | gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1); | ||
1120 | gfs2_setbit(rgd, bi->bi_bh->b_data + bi->bi_offset, | ||
1121 | bi->bi_len, blk, new_state); | ||
1122 | if (bi->bi_clone) | ||
1123 | gfs2_setbit(rgd, bi->bi_clone + bi->bi_offset, | ||
1124 | bi->bi_len, blk, new_state); | ||
1125 | |||
1126 | return bi->bi_start * GFS2_NBBY + blk; | ||
1127 | } | ||
1128 | |||
1129 | /** | ||
1130 | * rgblk_free - Change alloc state of given block(s) | ||
1131 | * @sdp: the filesystem | ||
1132 | * @bstart: the start of a run of blocks to free | ||
1133 | * @blen: the length of the block run (all must lie within ONE RG!) | ||
1134 | * @new_state: GFS2_BLKST_XXX the after-allocation block state | ||
1135 | * | ||
1136 | * Returns: Resource group containing the block(s) | ||
1137 | */ | ||
1138 | |||
1139 | static struct gfs2_rgrpd *rgblk_free(struct gfs2_sbd *sdp, u64 bstart, | ||
1140 | u32 blen, unsigned char new_state) | ||
1141 | { | ||
1142 | struct gfs2_rgrpd *rgd; | ||
1143 | struct gfs2_bitmap *bi = NULL; | ||
1144 | u32 length, rgrp_blk, buf_blk; | ||
1145 | unsigned int buf; | ||
1146 | |||
1147 | rgd = gfs2_blk2rgrpd(sdp, bstart); | ||
1148 | if (!rgd) { | ||
1149 | if (gfs2_consist(sdp)) | ||
1150 | fs_err(sdp, "block = %llu\n", (unsigned long long)bstart); | ||
1151 | return NULL; | ||
1152 | } | ||
1153 | |||
1154 | length = rgd->rd_ri.ri_length; | ||
1155 | |||
1156 | rgrp_blk = bstart - rgd->rd_ri.ri_data0; | ||
1157 | |||
1158 | while (blen--) { | ||
1159 | for (buf = 0; buf < length; buf++) { | ||
1160 | bi = rgd->rd_bits + buf; | ||
1161 | if (rgrp_blk < (bi->bi_start + bi->bi_len) * GFS2_NBBY) | ||
1162 | break; | ||
1163 | } | ||
1164 | |||
1165 | gfs2_assert(rgd->rd_sbd, buf < length); | ||
1166 | |||
1167 | buf_blk = rgrp_blk - bi->bi_start * GFS2_NBBY; | ||
1168 | rgrp_blk++; | ||
1169 | |||
1170 | if (!bi->bi_clone) { | ||
1171 | bi->bi_clone = kmalloc(bi->bi_bh->b_size, | ||
1172 | GFP_NOFS | __GFP_NOFAIL); | ||
1173 | memcpy(bi->bi_clone + bi->bi_offset, | ||
1174 | bi->bi_bh->b_data + bi->bi_offset, | ||
1175 | bi->bi_len); | ||
1176 | } | ||
1177 | gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1); | ||
1178 | gfs2_setbit(rgd, bi->bi_bh->b_data + bi->bi_offset, | ||
1179 | bi->bi_len, buf_blk, new_state); | ||
1180 | } | ||
1181 | |||
1182 | return rgd; | ||
1183 | } | ||
1184 | |||
1185 | /** | ||
1186 | * gfs2_alloc_data - Allocate a data block | ||
1187 | * @ip: the inode to allocate the data block for | ||
1188 | * | ||
1189 | * Returns: the allocated block | ||
1190 | */ | ||
1191 | |||
1192 | u64 gfs2_alloc_data(struct gfs2_inode *ip) | ||
1193 | { | ||
1194 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | ||
1195 | struct gfs2_alloc *al = &ip->i_alloc; | ||
1196 | struct gfs2_rgrpd *rgd = al->al_rgd; | ||
1197 | u32 goal, blk; | ||
1198 | u64 block; | ||
1199 | |||
1200 | if (rgrp_contains_block(&rgd->rd_ri, ip->i_di.di_goal_data)) | ||
1201 | goal = ip->i_di.di_goal_data - rgd->rd_ri.ri_data0; | ||
1202 | else | ||
1203 | goal = rgd->rd_last_alloc_data; | ||
1204 | |||
1205 | blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, GFS2_BLKST_USED); | ||
1206 | rgd->rd_last_alloc_data = blk; | ||
1207 | |||
1208 | block = rgd->rd_ri.ri_data0 + blk; | ||
1209 | ip->i_di.di_goal_data = block; | ||
1210 | |||
1211 | gfs2_assert_withdraw(sdp, rgd->rd_rg.rg_free); | ||
1212 | rgd->rd_rg.rg_free--; | ||
1213 | |||
1214 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); | ||
1215 | gfs2_rgrp_out(&rgd->rd_rg, rgd->rd_bits[0].bi_bh->b_data); | ||
1216 | |||
1217 | al->al_alloced++; | ||
1218 | |||
1219 | gfs2_statfs_change(sdp, 0, -1, 0); | ||
1220 | gfs2_quota_change(ip, +1, ip->i_di.di_uid, ip->i_di.di_gid); | ||
1221 | |||
1222 | spin_lock(&sdp->sd_rindex_spin); | ||
1223 | rgd->rd_free_clone--; | ||
1224 | spin_unlock(&sdp->sd_rindex_spin); | ||
1225 | |||
1226 | return block; | ||
1227 | } | ||
1228 | |||
1229 | /** | ||
1230 | * gfs2_alloc_meta - Allocate a metadata block | ||
1231 | * @ip: the inode to allocate the metadata block for | ||
1232 | * | ||
1233 | * Returns: the allocated block | ||
1234 | */ | ||
1235 | |||
1236 | u64 gfs2_alloc_meta(struct gfs2_inode *ip) | ||
1237 | { | ||
1238 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | ||
1239 | struct gfs2_alloc *al = &ip->i_alloc; | ||
1240 | struct gfs2_rgrpd *rgd = al->al_rgd; | ||
1241 | u32 goal, blk; | ||
1242 | u64 block; | ||
1243 | |||
1244 | if (rgrp_contains_block(&rgd->rd_ri, ip->i_di.di_goal_meta)) | ||
1245 | goal = ip->i_di.di_goal_meta - rgd->rd_ri.ri_data0; | ||
1246 | else | ||
1247 | goal = rgd->rd_last_alloc_meta; | ||
1248 | |||
1249 | blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, GFS2_BLKST_USED); | ||
1250 | rgd->rd_last_alloc_meta = blk; | ||
1251 | |||
1252 | block = rgd->rd_ri.ri_data0 + blk; | ||
1253 | ip->i_di.di_goal_meta = block; | ||
1254 | |||
1255 | gfs2_assert_withdraw(sdp, rgd->rd_rg.rg_free); | ||
1256 | rgd->rd_rg.rg_free--; | ||
1257 | |||
1258 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); | ||
1259 | gfs2_rgrp_out(&rgd->rd_rg, rgd->rd_bits[0].bi_bh->b_data); | ||
1260 | |||
1261 | al->al_alloced++; | ||
1262 | |||
1263 | gfs2_statfs_change(sdp, 0, -1, 0); | ||
1264 | gfs2_quota_change(ip, +1, ip->i_di.di_uid, ip->i_di.di_gid); | ||
1265 | gfs2_trans_add_unrevoke(sdp, block); | ||
1266 | |||
1267 | spin_lock(&sdp->sd_rindex_spin); | ||
1268 | rgd->rd_free_clone--; | ||
1269 | spin_unlock(&sdp->sd_rindex_spin); | ||
1270 | |||
1271 | return block; | ||
1272 | } | ||
1273 | |||
1274 | /** | ||
1275 | * gfs2_alloc_di - Allocate a dinode | ||
1276 | * @dip: the directory that the inode is going in | ||
1277 | * | ||
1278 | * Returns: the block allocated | ||
1279 | */ | ||
1280 | |||
1281 | u64 gfs2_alloc_di(struct gfs2_inode *dip, u64 *generation) | ||
1282 | { | ||
1283 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | ||
1284 | struct gfs2_alloc *al = &dip->i_alloc; | ||
1285 | struct gfs2_rgrpd *rgd = al->al_rgd; | ||
1286 | u32 blk; | ||
1287 | u64 block; | ||
1288 | |||
1289 | blk = rgblk_search(rgd, rgd->rd_last_alloc_meta, | ||
1290 | GFS2_BLKST_FREE, GFS2_BLKST_DINODE); | ||
1291 | |||
1292 | rgd->rd_last_alloc_meta = blk; | ||
1293 | |||
1294 | block = rgd->rd_ri.ri_data0 + blk; | ||
1295 | |||
1296 | gfs2_assert_withdraw(sdp, rgd->rd_rg.rg_free); | ||
1297 | rgd->rd_rg.rg_free--; | ||
1298 | rgd->rd_rg.rg_dinodes++; | ||
1299 | *generation = rgd->rd_rg.rg_igeneration++; | ||
1300 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); | ||
1301 | gfs2_rgrp_out(&rgd->rd_rg, rgd->rd_bits[0].bi_bh->b_data); | ||
1302 | |||
1303 | al->al_alloced++; | ||
1304 | |||
1305 | gfs2_statfs_change(sdp, 0, -1, +1); | ||
1306 | gfs2_trans_add_unrevoke(sdp, block); | ||
1307 | |||
1308 | spin_lock(&sdp->sd_rindex_spin); | ||
1309 | rgd->rd_free_clone--; | ||
1310 | spin_unlock(&sdp->sd_rindex_spin); | ||
1311 | |||
1312 | return block; | ||
1313 | } | ||
1314 | |||
1315 | /** | ||
1316 | * gfs2_free_data - free a contiguous run of data block(s) | ||
1317 | * @ip: the inode these blocks are being freed from | ||
1318 | * @bstart: first block of a run of contiguous blocks | ||
1319 | * @blen: the length of the block run | ||
1320 | * | ||
1321 | */ | ||
1322 | |||
1323 | void gfs2_free_data(struct gfs2_inode *ip, u64 bstart, u32 blen) | ||
1324 | { | ||
1325 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | ||
1326 | struct gfs2_rgrpd *rgd; | ||
1327 | |||
1328 | rgd = rgblk_free(sdp, bstart, blen, GFS2_BLKST_FREE); | ||
1329 | if (!rgd) | ||
1330 | return; | ||
1331 | |||
1332 | rgd->rd_rg.rg_free += blen; | ||
1333 | |||
1334 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); | ||
1335 | gfs2_rgrp_out(&rgd->rd_rg, rgd->rd_bits[0].bi_bh->b_data); | ||
1336 | |||
1337 | gfs2_trans_add_rg(rgd); | ||
1338 | |||
1339 | gfs2_statfs_change(sdp, 0, +blen, 0); | ||
1340 | gfs2_quota_change(ip, -(s64)blen, | ||
1341 | ip->i_di.di_uid, ip->i_di.di_gid); | ||
1342 | } | ||
1343 | |||
1344 | /** | ||
1345 | * gfs2_free_meta - free a contiguous run of data block(s) | ||
1346 | * @ip: the inode these blocks are being freed from | ||
1347 | * @bstart: first block of a run of contiguous blocks | ||
1348 | * @blen: the length of the block run | ||
1349 | * | ||
1350 | */ | ||
1351 | |||
1352 | void gfs2_free_meta(struct gfs2_inode *ip, u64 bstart, u32 blen) | ||
1353 | { | ||
1354 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | ||
1355 | struct gfs2_rgrpd *rgd; | ||
1356 | |||
1357 | rgd = rgblk_free(sdp, bstart, blen, GFS2_BLKST_FREE); | ||
1358 | if (!rgd) | ||
1359 | return; | ||
1360 | |||
1361 | rgd->rd_rg.rg_free += blen; | ||
1362 | |||
1363 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); | ||
1364 | gfs2_rgrp_out(&rgd->rd_rg, rgd->rd_bits[0].bi_bh->b_data); | ||
1365 | |||
1366 | gfs2_trans_add_rg(rgd); | ||
1367 | |||
1368 | gfs2_statfs_change(sdp, 0, +blen, 0); | ||
1369 | gfs2_quota_change(ip, -(s64)blen, ip->i_di.di_uid, ip->i_di.di_gid); | ||
1370 | gfs2_meta_wipe(ip, bstart, blen); | ||
1371 | } | ||
1372 | |||
1373 | void gfs2_unlink_di(struct inode *inode) | ||
1374 | { | ||
1375 | struct gfs2_inode *ip = GFS2_I(inode); | ||
1376 | struct gfs2_sbd *sdp = GFS2_SB(inode); | ||
1377 | struct gfs2_rgrpd *rgd; | ||
1378 | u64 blkno = ip->i_num.no_addr; | ||
1379 | |||
1380 | rgd = rgblk_free(sdp, blkno, 1, GFS2_BLKST_UNLINKED); | ||
1381 | if (!rgd) | ||
1382 | return; | ||
1383 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); | ||
1384 | gfs2_rgrp_out(&rgd->rd_rg, rgd->rd_bits[0].bi_bh->b_data); | ||
1385 | gfs2_trans_add_rg(rgd); | ||
1386 | } | ||
1387 | |||
1388 | static void gfs2_free_uninit_di(struct gfs2_rgrpd *rgd, u64 blkno) | ||
1389 | { | ||
1390 | struct gfs2_sbd *sdp = rgd->rd_sbd; | ||
1391 | struct gfs2_rgrpd *tmp_rgd; | ||
1392 | |||
1393 | tmp_rgd = rgblk_free(sdp, blkno, 1, GFS2_BLKST_FREE); | ||
1394 | if (!tmp_rgd) | ||
1395 | return; | ||
1396 | gfs2_assert_withdraw(sdp, rgd == tmp_rgd); | ||
1397 | |||
1398 | if (!rgd->rd_rg.rg_dinodes) | ||
1399 | gfs2_consist_rgrpd(rgd); | ||
1400 | rgd->rd_rg.rg_dinodes--; | ||
1401 | rgd->rd_rg.rg_free++; | ||
1402 | |||
1403 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); | ||
1404 | gfs2_rgrp_out(&rgd->rd_rg, rgd->rd_bits[0].bi_bh->b_data); | ||
1405 | |||
1406 | gfs2_statfs_change(sdp, 0, +1, -1); | ||
1407 | gfs2_trans_add_rg(rgd); | ||
1408 | } | ||
1409 | |||
1410 | |||
1411 | void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip) | ||
1412 | { | ||
1413 | gfs2_free_uninit_di(rgd, ip->i_num.no_addr); | ||
1414 | gfs2_quota_change(ip, -1, ip->i_di.di_uid, ip->i_di.di_gid); | ||
1415 | gfs2_meta_wipe(ip, ip->i_num.no_addr, 1); | ||
1416 | } | ||
1417 | |||
1418 | /** | ||
1419 | * gfs2_rlist_add - add a RG to a list of RGs | ||
1420 | * @sdp: the filesystem | ||
1421 | * @rlist: the list of resource groups | ||
1422 | * @block: the block | ||
1423 | * | ||
1424 | * Figure out what RG a block belongs to and add that RG to the list | ||
1425 | * | ||
1426 | * FIXME: Don't use NOFAIL | ||
1427 | * | ||
1428 | */ | ||
1429 | |||
1430 | void gfs2_rlist_add(struct gfs2_sbd *sdp, struct gfs2_rgrp_list *rlist, | ||
1431 | u64 block) | ||
1432 | { | ||
1433 | struct gfs2_rgrpd *rgd; | ||
1434 | struct gfs2_rgrpd **tmp; | ||
1435 | unsigned int new_space; | ||
1436 | unsigned int x; | ||
1437 | |||
1438 | if (gfs2_assert_warn(sdp, !rlist->rl_ghs)) | ||
1439 | return; | ||
1440 | |||
1441 | rgd = gfs2_blk2rgrpd(sdp, block); | ||
1442 | if (!rgd) { | ||
1443 | if (gfs2_consist(sdp)) | ||
1444 | fs_err(sdp, "block = %llu\n", (unsigned long long)block); | ||
1445 | return; | ||
1446 | } | ||
1447 | |||
1448 | for (x = 0; x < rlist->rl_rgrps; x++) | ||
1449 | if (rlist->rl_rgd[x] == rgd) | ||
1450 | return; | ||
1451 | |||
1452 | if (rlist->rl_rgrps == rlist->rl_space) { | ||
1453 | new_space = rlist->rl_space + 10; | ||
1454 | |||
1455 | tmp = kcalloc(new_space, sizeof(struct gfs2_rgrpd *), | ||
1456 | GFP_NOFS | __GFP_NOFAIL); | ||
1457 | |||
1458 | if (rlist->rl_rgd) { | ||
1459 | memcpy(tmp, rlist->rl_rgd, | ||
1460 | rlist->rl_space * sizeof(struct gfs2_rgrpd *)); | ||
1461 | kfree(rlist->rl_rgd); | ||
1462 | } | ||
1463 | |||
1464 | rlist->rl_space = new_space; | ||
1465 | rlist->rl_rgd = tmp; | ||
1466 | } | ||
1467 | |||
1468 | rlist->rl_rgd[rlist->rl_rgrps++] = rgd; | ||
1469 | } | ||
1470 | |||
1471 | /** | ||
1472 | * gfs2_rlist_alloc - all RGs have been added to the rlist, now allocate | ||
1473 | * and initialize an array of glock holders for them | ||
1474 | * @rlist: the list of resource groups | ||
1475 | * @state: the lock state to acquire the RG lock in | ||
1476 | * @flags: the modifier flags for the holder structures | ||
1477 | * | ||
1478 | * FIXME: Don't use NOFAIL | ||
1479 | * | ||
1480 | */ | ||
1481 | |||
1482 | void gfs2_rlist_alloc(struct gfs2_rgrp_list *rlist, unsigned int state, | ||
1483 | int flags) | ||
1484 | { | ||
1485 | unsigned int x; | ||
1486 | |||
1487 | rlist->rl_ghs = kcalloc(rlist->rl_rgrps, sizeof(struct gfs2_holder), | ||
1488 | GFP_NOFS | __GFP_NOFAIL); | ||
1489 | for (x = 0; x < rlist->rl_rgrps; x++) | ||
1490 | gfs2_holder_init(rlist->rl_rgd[x]->rd_gl, | ||
1491 | state, flags, | ||
1492 | &rlist->rl_ghs[x]); | ||
1493 | } | ||
1494 | |||
1495 | /** | ||
1496 | * gfs2_rlist_free - free a resource group list | ||
1497 | * @list: the list of resource groups | ||
1498 | * | ||
1499 | */ | ||
1500 | |||
1501 | void gfs2_rlist_free(struct gfs2_rgrp_list *rlist) | ||
1502 | { | ||
1503 | unsigned int x; | ||
1504 | |||
1505 | kfree(rlist->rl_rgd); | ||
1506 | |||
1507 | if (rlist->rl_ghs) { | ||
1508 | for (x = 0; x < rlist->rl_rgrps; x++) | ||
1509 | gfs2_holder_uninit(&rlist->rl_ghs[x]); | ||
1510 | kfree(rlist->rl_ghs); | ||
1511 | } | ||
1512 | } | ||
1513 | |||