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