diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /fs/gfs2/rgrp.c | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'fs/gfs2/rgrp.c')
-rw-r--r-- | fs/gfs2/rgrp.c | 2049 |
1 files changed, 730 insertions, 1319 deletions
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index b7eff078fe9..7f8af1eb02d 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c | |||
@@ -15,8 +15,6 @@ | |||
15 | #include <linux/gfs2_ondisk.h> | 15 | #include <linux/gfs2_ondisk.h> |
16 | #include <linux/prefetch.h> | 16 | #include <linux/prefetch.h> |
17 | #include <linux/blkdev.h> | 17 | #include <linux/blkdev.h> |
18 | #include <linux/rbtree.h> | ||
19 | #include <linux/random.h> | ||
20 | 18 | ||
21 | #include "gfs2.h" | 19 | #include "gfs2.h" |
22 | #include "incore.h" | 20 | #include "incore.h" |
@@ -65,48 +63,53 @@ static const char valid_change[16] = { | |||
65 | 1, 0, 0, 0 | 63 | 1, 0, 0, 0 |
66 | }; | 64 | }; |
67 | 65 | ||
68 | static int gfs2_rbm_find(struct gfs2_rbm *rbm, u8 state, u32 minext, | 66 | static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal, |
69 | const struct gfs2_inode *ip, bool nowrap); | 67 | unsigned char old_state, unsigned char new_state, |
70 | 68 | unsigned int *n); | |
71 | 69 | ||
72 | /** | 70 | /** |
73 | * gfs2_setbit - Set a bit in the bitmaps | 71 | * gfs2_setbit - Set a bit in the bitmaps |
74 | * @rbm: The position of the bit to set | 72 | * @buffer: the buffer that holds the bitmaps |
75 | * @do_clone: Also set the clone bitmap, if it exists | 73 | * @buflen: the length (in bytes) of the buffer |
74 | * @block: the block to set | ||
76 | * @new_state: the new state of the block | 75 | * @new_state: the new state of the block |
77 | * | 76 | * |
78 | */ | 77 | */ |
79 | 78 | ||
80 | static inline void gfs2_setbit(const struct gfs2_rbm *rbm, bool do_clone, | 79 | static inline void gfs2_setbit(struct gfs2_rgrpd *rgd, unsigned char *buf1, |
80 | unsigned char *buf2, unsigned int offset, | ||
81 | struct gfs2_bitmap *bi, u32 block, | ||
81 | unsigned char new_state) | 82 | unsigned char new_state) |
82 | { | 83 | { |
83 | unsigned char *byte1, *byte2, *end, cur_state; | 84 | unsigned char *byte1, *byte2, *end, cur_state; |
84 | unsigned int buflen = rbm->bi->bi_len; | 85 | unsigned int buflen = bi->bi_len; |
85 | const unsigned int bit = (rbm->offset % GFS2_NBBY) * GFS2_BIT_SIZE; | 86 | const unsigned int bit = (block % GFS2_NBBY) * GFS2_BIT_SIZE; |
86 | 87 | ||
87 | byte1 = rbm->bi->bi_bh->b_data + rbm->bi->bi_offset + (rbm->offset / GFS2_NBBY); | 88 | byte1 = buf1 + offset + (block / GFS2_NBBY); |
88 | end = rbm->bi->bi_bh->b_data + rbm->bi->bi_offset + buflen; | 89 | end = buf1 + offset + buflen; |
89 | 90 | ||
90 | BUG_ON(byte1 >= end); | 91 | BUG_ON(byte1 >= end); |
91 | 92 | ||
92 | cur_state = (*byte1 >> bit) & GFS2_BIT_MASK; | 93 | cur_state = (*byte1 >> bit) & GFS2_BIT_MASK; |
93 | 94 | ||
94 | if (unlikely(!valid_change[new_state * 4 + cur_state])) { | 95 | if (unlikely(!valid_change[new_state * 4 + cur_state])) { |
95 | printk(KERN_WARNING "GFS2: buf_blk = 0x%x old_state=%d, " | 96 | printk(KERN_WARNING "GFS2: buf_blk = 0x%llx old_state=%d, " |
96 | "new_state=%d\n", rbm->offset, cur_state, new_state); | 97 | "new_state=%d\n", |
97 | printk(KERN_WARNING "GFS2: rgrp=0x%llx bi_start=0x%x\n", | 98 | (unsigned long long)block, cur_state, new_state); |
98 | (unsigned long long)rbm->rgd->rd_addr, | 99 | printk(KERN_WARNING "GFS2: rgrp=0x%llx bi_start=0x%lx\n", |
99 | rbm->bi->bi_start); | 100 | (unsigned long long)rgd->rd_addr, |
100 | printk(KERN_WARNING "GFS2: bi_offset=0x%x bi_len=0x%x\n", | 101 | (unsigned long)bi->bi_start); |
101 | rbm->bi->bi_offset, rbm->bi->bi_len); | 102 | printk(KERN_WARNING "GFS2: bi_offset=0x%lx bi_len=0x%lx\n", |
103 | (unsigned long)bi->bi_offset, | ||
104 | (unsigned long)bi->bi_len); | ||
102 | dump_stack(); | 105 | dump_stack(); |
103 | gfs2_consist_rgrpd(rbm->rgd); | 106 | gfs2_consist_rgrpd(rgd); |
104 | return; | 107 | return; |
105 | } | 108 | } |
106 | *byte1 ^= (cur_state ^ new_state) << bit; | 109 | *byte1 ^= (cur_state ^ new_state) << bit; |
107 | 110 | ||
108 | if (do_clone && rbm->bi->bi_clone) { | 111 | if (buf2) { |
109 | byte2 = rbm->bi->bi_clone + rbm->bi->bi_offset + (rbm->offset / GFS2_NBBY); | 112 | byte2 = buf2 + offset + (block / GFS2_NBBY); |
110 | cur_state = (*byte2 >> bit) & GFS2_BIT_MASK; | 113 | cur_state = (*byte2 >> bit) & GFS2_BIT_MASK; |
111 | *byte2 ^= (cur_state ^ new_state) << bit; | 114 | *byte2 ^= (cur_state ^ new_state) << bit; |
112 | } | 115 | } |
@@ -114,21 +117,29 @@ static inline void gfs2_setbit(const struct gfs2_rbm *rbm, bool do_clone, | |||
114 | 117 | ||
115 | /** | 118 | /** |
116 | * gfs2_testbit - test a bit in the bitmaps | 119 | * gfs2_testbit - test a bit in the bitmaps |
117 | * @rbm: The bit to test | 120 | * @buffer: the buffer that holds the bitmaps |
121 | * @buflen: the length (in bytes) of the buffer | ||
122 | * @block: the block to read | ||
118 | * | 123 | * |
119 | * Returns: The two bit block state of the requested bit | ||
120 | */ | 124 | */ |
121 | 125 | ||
122 | static inline u8 gfs2_testbit(const struct gfs2_rbm *rbm) | 126 | static inline unsigned char gfs2_testbit(struct gfs2_rgrpd *rgd, |
127 | const unsigned char *buffer, | ||
128 | unsigned int buflen, u32 block) | ||
123 | { | 129 | { |
124 | const u8 *buffer = rbm->bi->bi_bh->b_data + rbm->bi->bi_offset; | 130 | const unsigned char *byte, *end; |
125 | const u8 *byte; | 131 | unsigned char cur_state; |
126 | unsigned int bit; | 132 | unsigned int bit; |
127 | 133 | ||
128 | byte = buffer + (rbm->offset / GFS2_NBBY); | 134 | byte = buffer + (block / GFS2_NBBY); |
129 | bit = (rbm->offset % GFS2_NBBY) * GFS2_BIT_SIZE; | 135 | bit = (block % GFS2_NBBY) * GFS2_BIT_SIZE; |
136 | end = buffer + buflen; | ||
137 | |||
138 | gfs2_assert(rgd->rd_sbd, byte < end); | ||
139 | |||
140 | cur_state = (*byte >> bit) & GFS2_BIT_MASK; | ||
130 | 141 | ||
131 | return (*byte >> bit) & GFS2_BIT_MASK; | 142 | return cur_state; |
132 | } | 143 | } |
133 | 144 | ||
134 | /** | 145 | /** |
@@ -165,30 +176,9 @@ static inline u64 gfs2_bit_search(const __le64 *ptr, u64 mask, u8 state) | |||
165 | } | 176 | } |
166 | 177 | ||
167 | /** | 178 | /** |
168 | * rs_cmp - multi-block reservation range compare | ||
169 | * @blk: absolute file system block number of the new reservation | ||
170 | * @len: number of blocks in the new reservation | ||
171 | * @rs: existing reservation to compare against | ||
172 | * | ||
173 | * returns: 1 if the block range is beyond the reach of the reservation | ||
174 | * -1 if the block range is before the start of the reservation | ||
175 | * 0 if the block range overlaps with the reservation | ||
176 | */ | ||
177 | static inline int rs_cmp(u64 blk, u32 len, struct gfs2_blkreserv *rs) | ||
178 | { | ||
179 | u64 startblk = gfs2_rbm_to_block(&rs->rs_rbm); | ||
180 | |||
181 | if (blk >= startblk + rs->rs_free) | ||
182 | return 1; | ||
183 | if (blk + len - 1 < startblk) | ||
184 | return -1; | ||
185 | return 0; | ||
186 | } | ||
187 | |||
188 | /** | ||
189 | * gfs2_bitfit - Search an rgrp's bitmap buffer to find a bit-pair representing | 179 | * gfs2_bitfit - Search an rgrp's bitmap buffer to find a bit-pair representing |
190 | * a block in a given allocation state. | 180 | * a block in a given allocation state. |
191 | * @buf: the buffer that holds the bitmaps | 181 | * @buffer: the buffer that holds the bitmaps |
192 | * @len: the length (in bytes) of the buffer | 182 | * @len: the length (in bytes) of the buffer |
193 | * @goal: start search at this block's bit-pair (within @buffer) | 183 | * @goal: start search at this block's bit-pair (within @buffer) |
194 | * @state: GFS2_BLKST_XXX the state of the block we're looking for. | 184 | * @state: GFS2_BLKST_XXX the state of the block we're looking for. |
@@ -216,6 +206,8 @@ static u32 gfs2_bitfit(const u8 *buf, const unsigned int len, | |||
216 | u64 mask = 0x5555555555555555ULL; | 206 | u64 mask = 0x5555555555555555ULL; |
217 | u32 bit; | 207 | u32 bit; |
218 | 208 | ||
209 | BUG_ON(state > 3); | ||
210 | |||
219 | /* Mask off bits we don't care about at the start of the search */ | 211 | /* Mask off bits we don't care about at the start of the search */ |
220 | mask <<= spoint; | 212 | mask <<= spoint; |
221 | tmp = gfs2_bit_search(ptr, mask, state); | 213 | tmp = gfs2_bit_search(ptr, mask, state); |
@@ -237,140 +229,7 @@ static u32 gfs2_bitfit(const u8 *buf, const unsigned int len, | |||
237 | } | 229 | } |
238 | 230 | ||
239 | /** | 231 | /** |
240 | * gfs2_rbm_from_block - Set the rbm based upon rgd and block number | ||
241 | * @rbm: The rbm with rgd already set correctly | ||
242 | * @block: The block number (filesystem relative) | ||
243 | * | ||
244 | * This sets the bi and offset members of an rbm based on a | ||
245 | * resource group and a filesystem relative block number. The | ||
246 | * resource group must be set in the rbm on entry, the bi and | ||
247 | * offset members will be set by this function. | ||
248 | * | ||
249 | * Returns: 0 on success, or an error code | ||
250 | */ | ||
251 | |||
252 | static int gfs2_rbm_from_block(struct gfs2_rbm *rbm, u64 block) | ||
253 | { | ||
254 | u64 rblock = block - rbm->rgd->rd_data0; | ||
255 | u32 x; | ||
256 | |||
257 | if (WARN_ON_ONCE(rblock > UINT_MAX)) | ||
258 | return -EINVAL; | ||
259 | if (block >= rbm->rgd->rd_data0 + rbm->rgd->rd_data) | ||
260 | return -E2BIG; | ||
261 | |||
262 | rbm->bi = rbm->rgd->rd_bits; | ||
263 | rbm->offset = (u32)(rblock); | ||
264 | /* Check if the block is within the first block */ | ||
265 | if (rbm->offset < (rbm->bi->bi_start + rbm->bi->bi_len) * GFS2_NBBY) | ||
266 | return 0; | ||
267 | |||
268 | /* Adjust for the size diff between gfs2_meta_header and gfs2_rgrp */ | ||
269 | rbm->offset += (sizeof(struct gfs2_rgrp) - | ||
270 | sizeof(struct gfs2_meta_header)) * GFS2_NBBY; | ||
271 | x = rbm->offset / rbm->rgd->rd_sbd->sd_blocks_per_bitmap; | ||
272 | rbm->offset -= x * rbm->rgd->rd_sbd->sd_blocks_per_bitmap; | ||
273 | rbm->bi += x; | ||
274 | return 0; | ||
275 | } | ||
276 | |||
277 | /** | ||
278 | * gfs2_unaligned_extlen - Look for free blocks which are not byte aligned | ||
279 | * @rbm: Position to search (value/result) | ||
280 | * @n_unaligned: Number of unaligned blocks to check | ||
281 | * @len: Decremented for each block found (terminate on zero) | ||
282 | * | ||
283 | * Returns: true if a non-free block is encountered | ||
284 | */ | ||
285 | |||
286 | static bool gfs2_unaligned_extlen(struct gfs2_rbm *rbm, u32 n_unaligned, u32 *len) | ||
287 | { | ||
288 | u64 block; | ||
289 | u32 n; | ||
290 | u8 res; | ||
291 | |||
292 | for (n = 0; n < n_unaligned; n++) { | ||
293 | res = gfs2_testbit(rbm); | ||
294 | if (res != GFS2_BLKST_FREE) | ||
295 | return true; | ||
296 | (*len)--; | ||
297 | if (*len == 0) | ||
298 | return true; | ||
299 | block = gfs2_rbm_to_block(rbm); | ||
300 | if (gfs2_rbm_from_block(rbm, block + 1)) | ||
301 | return true; | ||
302 | } | ||
303 | |||
304 | return false; | ||
305 | } | ||
306 | |||
307 | /** | ||
308 | * gfs2_free_extlen - Return extent length of free blocks | ||
309 | * @rbm: Starting position | ||
310 | * @len: Max length to check | ||
311 | * | ||
312 | * Starting at the block specified by the rbm, see how many free blocks | ||
313 | * there are, not reading more than len blocks ahead. This can be done | ||
314 | * using memchr_inv when the blocks are byte aligned, but has to be done | ||
315 | * on a block by block basis in case of unaligned blocks. Also this | ||
316 | * function can cope with bitmap boundaries (although it must stop on | ||
317 | * a resource group boundary) | ||
318 | * | ||
319 | * Returns: Number of free blocks in the extent | ||
320 | */ | ||
321 | |||
322 | static u32 gfs2_free_extlen(const struct gfs2_rbm *rrbm, u32 len) | ||
323 | { | ||
324 | struct gfs2_rbm rbm = *rrbm; | ||
325 | u32 n_unaligned = rbm.offset & 3; | ||
326 | u32 size = len; | ||
327 | u32 bytes; | ||
328 | u32 chunk_size; | ||
329 | u8 *ptr, *start, *end; | ||
330 | u64 block; | ||
331 | |||
332 | if (n_unaligned && | ||
333 | gfs2_unaligned_extlen(&rbm, 4 - n_unaligned, &len)) | ||
334 | goto out; | ||
335 | |||
336 | n_unaligned = len & 3; | ||
337 | /* Start is now byte aligned */ | ||
338 | while (len > 3) { | ||
339 | start = rbm.bi->bi_bh->b_data; | ||
340 | if (rbm.bi->bi_clone) | ||
341 | start = rbm.bi->bi_clone; | ||
342 | end = start + rbm.bi->bi_bh->b_size; | ||
343 | start += rbm.bi->bi_offset; | ||
344 | BUG_ON(rbm.offset & 3); | ||
345 | start += (rbm.offset / GFS2_NBBY); | ||
346 | bytes = min_t(u32, len / GFS2_NBBY, (end - start)); | ||
347 | ptr = memchr_inv(start, 0, bytes); | ||
348 | chunk_size = ((ptr == NULL) ? bytes : (ptr - start)); | ||
349 | chunk_size *= GFS2_NBBY; | ||
350 | BUG_ON(len < chunk_size); | ||
351 | len -= chunk_size; | ||
352 | block = gfs2_rbm_to_block(&rbm); | ||
353 | if (gfs2_rbm_from_block(&rbm, block + chunk_size)) { | ||
354 | n_unaligned = 0; | ||
355 | break; | ||
356 | } | ||
357 | if (ptr) { | ||
358 | n_unaligned = 3; | ||
359 | break; | ||
360 | } | ||
361 | n_unaligned = len & 3; | ||
362 | } | ||
363 | |||
364 | /* Deal with any bits left over at the end */ | ||
365 | if (n_unaligned) | ||
366 | gfs2_unaligned_extlen(&rbm, n_unaligned, &len); | ||
367 | out: | ||
368 | return size - len; | ||
369 | } | ||
370 | |||
371 | /** | ||
372 | * gfs2_bitcount - count the number of bits in a certain state | 232 | * gfs2_bitcount - count the number of bits in a certain state |
373 | * @rgd: the resource group descriptor | ||
374 | * @buffer: the buffer that holds the bitmaps | 233 | * @buffer: the buffer that holds the bitmaps |
375 | * @buflen: the length (in bytes) of the buffer | 234 | * @buflen: the length (in bytes) of the buffer |
376 | * @state: the state of the block we're looking for | 235 | * @state: the state of the block we're looking for |
@@ -404,6 +263,7 @@ static u32 gfs2_bitcount(struct gfs2_rgrpd *rgd, const u8 *buffer, | |||
404 | 263 | ||
405 | /** | 264 | /** |
406 | * gfs2_rgrp_verify - Verify that a resource group is consistent | 265 | * gfs2_rgrp_verify - Verify that a resource group is consistent |
266 | * @sdp: the filesystem | ||
407 | * @rgd: the rgrp | 267 | * @rgd: the rgrp |
408 | * | 268 | * |
409 | */ | 269 | */ |
@@ -461,38 +321,25 @@ static inline int rgrp_contains_block(struct gfs2_rgrpd *rgd, u64 block) | |||
461 | /** | 321 | /** |
462 | * gfs2_blk2rgrpd - Find resource group for a given data/meta block number | 322 | * gfs2_blk2rgrpd - Find resource group for a given data/meta block number |
463 | * @sdp: The GFS2 superblock | 323 | * @sdp: The GFS2 superblock |
464 | * @blk: The data block number | 324 | * @n: The data block number |
465 | * @exact: True if this needs to be an exact match | ||
466 | * | 325 | * |
467 | * Returns: The resource group, or NULL if not found | 326 | * Returns: The resource group, or NULL if not found |
468 | */ | 327 | */ |
469 | 328 | ||
470 | struct gfs2_rgrpd *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, u64 blk, bool exact) | 329 | struct gfs2_rgrpd *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, u64 blk) |
471 | { | 330 | { |
472 | struct rb_node *n, *next; | 331 | struct gfs2_rgrpd *rgd; |
473 | struct gfs2_rgrpd *cur; | ||
474 | 332 | ||
475 | spin_lock(&sdp->sd_rindex_spin); | 333 | spin_lock(&sdp->sd_rindex_spin); |
476 | n = sdp->sd_rindex_tree.rb_node; | 334 | |
477 | while (n) { | 335 | list_for_each_entry(rgd, &sdp->sd_rindex_mru_list, rd_list_mru) { |
478 | cur = rb_entry(n, struct gfs2_rgrpd, rd_node); | 336 | if (rgrp_contains_block(rgd, blk)) { |
479 | next = NULL; | 337 | list_move(&rgd->rd_list_mru, &sdp->sd_rindex_mru_list); |
480 | if (blk < cur->rd_addr) | ||
481 | next = n->rb_left; | ||
482 | else if (blk >= cur->rd_data0 + cur->rd_data) | ||
483 | next = n->rb_right; | ||
484 | if (next == NULL) { | ||
485 | spin_unlock(&sdp->sd_rindex_spin); | 338 | spin_unlock(&sdp->sd_rindex_spin); |
486 | if (exact) { | 339 | return rgd; |
487 | if (blk < cur->rd_addr) | ||
488 | return NULL; | ||
489 | if (blk >= cur->rd_data0 + cur->rd_data) | ||
490 | return NULL; | ||
491 | } | ||
492 | return cur; | ||
493 | } | 340 | } |
494 | n = next; | ||
495 | } | 341 | } |
342 | |||
496 | spin_unlock(&sdp->sd_rindex_spin); | 343 | spin_unlock(&sdp->sd_rindex_spin); |
497 | 344 | ||
498 | return NULL; | 345 | return NULL; |
@@ -507,195 +354,60 @@ struct gfs2_rgrpd *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, u64 blk, bool exact) | |||
507 | 354 | ||
508 | struct gfs2_rgrpd *gfs2_rgrpd_get_first(struct gfs2_sbd *sdp) | 355 | struct gfs2_rgrpd *gfs2_rgrpd_get_first(struct gfs2_sbd *sdp) |
509 | { | 356 | { |
510 | const struct rb_node *n; | 357 | gfs2_assert(sdp, !list_empty(&sdp->sd_rindex_list)); |
511 | struct gfs2_rgrpd *rgd; | 358 | return list_entry(sdp->sd_rindex_list.next, struct gfs2_rgrpd, rd_list); |
512 | |||
513 | spin_lock(&sdp->sd_rindex_spin); | ||
514 | n = rb_first(&sdp->sd_rindex_tree); | ||
515 | rgd = rb_entry(n, struct gfs2_rgrpd, rd_node); | ||
516 | spin_unlock(&sdp->sd_rindex_spin); | ||
517 | |||
518 | return rgd; | ||
519 | } | 359 | } |
520 | 360 | ||
521 | /** | 361 | /** |
522 | * gfs2_rgrpd_get_next - get the next RG | 362 | * gfs2_rgrpd_get_next - get the next RG |
523 | * @rgd: the resource group descriptor | 363 | * @rgd: A RG |
524 | * | 364 | * |
525 | * Returns: The next rgrp | 365 | * Returns: The next rgrp |
526 | */ | 366 | */ |
527 | 367 | ||
528 | struct gfs2_rgrpd *gfs2_rgrpd_get_next(struct gfs2_rgrpd *rgd) | 368 | struct gfs2_rgrpd *gfs2_rgrpd_get_next(struct gfs2_rgrpd *rgd) |
529 | { | 369 | { |
530 | struct gfs2_sbd *sdp = rgd->rd_sbd; | 370 | if (rgd->rd_list.next == &rgd->rd_sbd->sd_rindex_list) |
531 | const struct rb_node *n; | ||
532 | |||
533 | spin_lock(&sdp->sd_rindex_spin); | ||
534 | n = rb_next(&rgd->rd_node); | ||
535 | if (n == NULL) | ||
536 | n = rb_first(&sdp->sd_rindex_tree); | ||
537 | |||
538 | if (unlikely(&rgd->rd_node == n)) { | ||
539 | spin_unlock(&sdp->sd_rindex_spin); | ||
540 | return NULL; | 371 | return NULL; |
541 | } | 372 | return list_entry(rgd->rd_list.next, struct gfs2_rgrpd, rd_list); |
542 | rgd = rb_entry(n, struct gfs2_rgrpd, rd_node); | ||
543 | spin_unlock(&sdp->sd_rindex_spin); | ||
544 | return rgd; | ||
545 | } | ||
546 | |||
547 | void gfs2_free_clones(struct gfs2_rgrpd *rgd) | ||
548 | { | ||
549 | int x; | ||
550 | |||
551 | for (x = 0; x < rgd->rd_length; x++) { | ||
552 | struct gfs2_bitmap *bi = rgd->rd_bits + x; | ||
553 | kfree(bi->bi_clone); | ||
554 | bi->bi_clone = NULL; | ||
555 | } | ||
556 | } | ||
557 | |||
558 | /** | ||
559 | * gfs2_rs_alloc - make sure we have a reservation assigned to the inode | ||
560 | * @ip: the inode for this reservation | ||
561 | */ | ||
562 | int gfs2_rs_alloc(struct gfs2_inode *ip) | ||
563 | { | ||
564 | int error = 0; | ||
565 | |||
566 | down_write(&ip->i_rw_mutex); | ||
567 | if (ip->i_res) | ||
568 | goto out; | ||
569 | |||
570 | ip->i_res = kmem_cache_zalloc(gfs2_rsrv_cachep, GFP_NOFS); | ||
571 | if (!ip->i_res) { | ||
572 | error = -ENOMEM; | ||
573 | goto out; | ||
574 | } | ||
575 | |||
576 | RB_CLEAR_NODE(&ip->i_res->rs_node); | ||
577 | out: | ||
578 | up_write(&ip->i_rw_mutex); | ||
579 | return 0; | ||
580 | } | ||
581 | |||
582 | static void dump_rs(struct seq_file *seq, const struct gfs2_blkreserv *rs) | ||
583 | { | ||
584 | gfs2_print_dbg(seq, " B: n:%llu s:%llu b:%u f:%u\n", | ||
585 | (unsigned long long)rs->rs_inum, | ||
586 | (unsigned long long)gfs2_rbm_to_block(&rs->rs_rbm), | ||
587 | rs->rs_rbm.offset, rs->rs_free); | ||
588 | } | ||
589 | |||
590 | /** | ||
591 | * __rs_deltree - remove a multi-block reservation from the rgd tree | ||
592 | * @rs: The reservation to remove | ||
593 | * | ||
594 | */ | ||
595 | static void __rs_deltree(struct gfs2_inode *ip, struct gfs2_blkreserv *rs) | ||
596 | { | ||
597 | struct gfs2_rgrpd *rgd; | ||
598 | |||
599 | if (!gfs2_rs_active(rs)) | ||
600 | return; | ||
601 | |||
602 | rgd = rs->rs_rbm.rgd; | ||
603 | trace_gfs2_rs(rs, TRACE_RS_TREEDEL); | ||
604 | rb_erase(&rs->rs_node, &rgd->rd_rstree); | ||
605 | RB_CLEAR_NODE(&rs->rs_node); | ||
606 | |||
607 | if (rs->rs_free) { | ||
608 | /* return reserved blocks to the rgrp and the ip */ | ||
609 | BUG_ON(rs->rs_rbm.rgd->rd_reserved < rs->rs_free); | ||
610 | rs->rs_rbm.rgd->rd_reserved -= rs->rs_free; | ||
611 | rs->rs_free = 0; | ||
612 | clear_bit(GBF_FULL, &rs->rs_rbm.bi->bi_flags); | ||
613 | smp_mb__after_clear_bit(); | ||
614 | } | ||
615 | } | ||
616 | |||
617 | /** | ||
618 | * gfs2_rs_deltree - remove a multi-block reservation from the rgd tree | ||
619 | * @rs: The reservation to remove | ||
620 | * | ||
621 | */ | ||
622 | void gfs2_rs_deltree(struct gfs2_inode *ip, struct gfs2_blkreserv *rs) | ||
623 | { | ||
624 | struct gfs2_rgrpd *rgd; | ||
625 | |||
626 | rgd = rs->rs_rbm.rgd; | ||
627 | if (rgd) { | ||
628 | spin_lock(&rgd->rd_rsspin); | ||
629 | __rs_deltree(ip, rs); | ||
630 | spin_unlock(&rgd->rd_rsspin); | ||
631 | } | ||
632 | } | ||
633 | |||
634 | /** | ||
635 | * gfs2_rs_delete - delete a multi-block reservation | ||
636 | * @ip: The inode for this reservation | ||
637 | * | ||
638 | */ | ||
639 | void gfs2_rs_delete(struct gfs2_inode *ip) | ||
640 | { | ||
641 | down_write(&ip->i_rw_mutex); | ||
642 | if (ip->i_res) { | ||
643 | gfs2_rs_deltree(ip, ip->i_res); | ||
644 | BUG_ON(ip->i_res->rs_free); | ||
645 | kmem_cache_free(gfs2_rsrv_cachep, ip->i_res); | ||
646 | ip->i_res = NULL; | ||
647 | } | ||
648 | up_write(&ip->i_rw_mutex); | ||
649 | } | ||
650 | |||
651 | /** | ||
652 | * return_all_reservations - return all reserved blocks back to the rgrp. | ||
653 | * @rgd: the rgrp that needs its space back | ||
654 | * | ||
655 | * We previously reserved a bunch of blocks for allocation. Now we need to | ||
656 | * give them back. This leave the reservation structures in tact, but removes | ||
657 | * all of their corresponding "no-fly zones". | ||
658 | */ | ||
659 | static void return_all_reservations(struct gfs2_rgrpd *rgd) | ||
660 | { | ||
661 | struct rb_node *n; | ||
662 | struct gfs2_blkreserv *rs; | ||
663 | |||
664 | spin_lock(&rgd->rd_rsspin); | ||
665 | while ((n = rb_first(&rgd->rd_rstree))) { | ||
666 | rs = rb_entry(n, struct gfs2_blkreserv, rs_node); | ||
667 | __rs_deltree(NULL, rs); | ||
668 | } | ||
669 | spin_unlock(&rgd->rd_rsspin); | ||
670 | } | 373 | } |
671 | 374 | ||
672 | void gfs2_clear_rgrpd(struct gfs2_sbd *sdp) | 375 | static void clear_rgrpdi(struct gfs2_sbd *sdp) |
673 | { | 376 | { |
674 | struct rb_node *n; | 377 | struct list_head *head; |
675 | struct gfs2_rgrpd *rgd; | 378 | struct gfs2_rgrpd *rgd; |
676 | struct gfs2_glock *gl; | 379 | struct gfs2_glock *gl; |
677 | 380 | ||
678 | while ((n = rb_first(&sdp->sd_rindex_tree))) { | 381 | spin_lock(&sdp->sd_rindex_spin); |
679 | rgd = rb_entry(n, struct gfs2_rgrpd, rd_node); | 382 | sdp->sd_rindex_forward = NULL; |
383 | spin_unlock(&sdp->sd_rindex_spin); | ||
384 | |||
385 | head = &sdp->sd_rindex_list; | ||
386 | while (!list_empty(head)) { | ||
387 | rgd = list_entry(head->next, struct gfs2_rgrpd, rd_list); | ||
680 | gl = rgd->rd_gl; | 388 | gl = rgd->rd_gl; |
681 | 389 | ||
682 | rb_erase(n, &sdp->sd_rindex_tree); | 390 | list_del(&rgd->rd_list); |
391 | list_del(&rgd->rd_list_mru); | ||
683 | 392 | ||
684 | if (gl) { | 393 | if (gl) { |
685 | spin_lock(&gl->gl_spin); | ||
686 | gl->gl_object = NULL; | 394 | gl->gl_object = NULL; |
687 | spin_unlock(&gl->gl_spin); | ||
688 | gfs2_glock_add_to_lru(gl); | 395 | gfs2_glock_add_to_lru(gl); |
689 | gfs2_glock_put(gl); | 396 | gfs2_glock_put(gl); |
690 | } | 397 | } |
691 | 398 | ||
692 | gfs2_free_clones(rgd); | ||
693 | kfree(rgd->rd_bits); | 399 | kfree(rgd->rd_bits); |
694 | return_all_reservations(rgd); | ||
695 | kmem_cache_free(gfs2_rgrpd_cachep, rgd); | 400 | kmem_cache_free(gfs2_rgrpd_cachep, rgd); |
696 | } | 401 | } |
697 | } | 402 | } |
698 | 403 | ||
404 | void gfs2_clear_rgrpd(struct gfs2_sbd *sdp) | ||
405 | { | ||
406 | mutex_lock(&sdp->sd_rindex_mutex); | ||
407 | clear_rgrpdi(sdp); | ||
408 | mutex_unlock(&sdp->sd_rindex_mutex); | ||
409 | } | ||
410 | |||
699 | static void gfs2_rindex_print(const struct gfs2_rgrpd *rgd) | 411 | static void gfs2_rindex_print(const struct gfs2_rgrpd *rgd) |
700 | { | 412 | { |
701 | printk(KERN_INFO " ri_addr = %llu\n", (unsigned long long)rgd->rd_addr); | 413 | printk(KERN_INFO " ri_addr = %llu\n", (unsigned long long)rgd->rd_addr); |
@@ -784,7 +496,6 @@ static int compute_bitstructs(struct gfs2_rgrpd *rgd) | |||
784 | 496 | ||
785 | /** | 497 | /** |
786 | * gfs2_ri_total - Total up the file system space, according to the rindex. | 498 | * gfs2_ri_total - Total up the file system space, according to the rindex. |
787 | * @sdp: the filesystem | ||
788 | * | 499 | * |
789 | */ | 500 | */ |
790 | u64 gfs2_ri_total(struct gfs2_sbd *sdp) | 501 | u64 gfs2_ri_total(struct gfs2_sbd *sdp) |
@@ -793,110 +504,87 @@ u64 gfs2_ri_total(struct gfs2_sbd *sdp) | |||
793 | struct inode *inode = sdp->sd_rindex; | 504 | struct inode *inode = sdp->sd_rindex; |
794 | struct gfs2_inode *ip = GFS2_I(inode); | 505 | struct gfs2_inode *ip = GFS2_I(inode); |
795 | char buf[sizeof(struct gfs2_rindex)]; | 506 | char buf[sizeof(struct gfs2_rindex)]; |
507 | struct file_ra_state ra_state; | ||
796 | int error, rgrps; | 508 | int error, rgrps; |
797 | 509 | ||
510 | mutex_lock(&sdp->sd_rindex_mutex); | ||
511 | file_ra_state_init(&ra_state, inode->i_mapping); | ||
798 | for (rgrps = 0;; rgrps++) { | 512 | for (rgrps = 0;; rgrps++) { |
799 | loff_t pos = rgrps * sizeof(struct gfs2_rindex); | 513 | loff_t pos = rgrps * sizeof(struct gfs2_rindex); |
800 | 514 | ||
801 | if (pos + sizeof(struct gfs2_rindex) > i_size_read(inode)) | 515 | if (pos + sizeof(struct gfs2_rindex) > i_size_read(inode)) |
802 | break; | 516 | break; |
803 | error = gfs2_internal_read(ip, buf, &pos, | 517 | error = gfs2_internal_read(ip, &ra_state, buf, &pos, |
804 | sizeof(struct gfs2_rindex)); | 518 | sizeof(struct gfs2_rindex)); |
805 | if (error != sizeof(struct gfs2_rindex)) | 519 | if (error != sizeof(struct gfs2_rindex)) |
806 | break; | 520 | break; |
807 | total_data += be32_to_cpu(((struct gfs2_rindex *)buf)->ri_data); | 521 | total_data += be32_to_cpu(((struct gfs2_rindex *)buf)->ri_data); |
808 | } | 522 | } |
523 | mutex_unlock(&sdp->sd_rindex_mutex); | ||
809 | return total_data; | 524 | return total_data; |
810 | } | 525 | } |
811 | 526 | ||
812 | static int rgd_insert(struct gfs2_rgrpd *rgd) | 527 | static void gfs2_rindex_in(struct gfs2_rgrpd *rgd, const void *buf) |
813 | { | 528 | { |
814 | struct gfs2_sbd *sdp = rgd->rd_sbd; | 529 | const struct gfs2_rindex *str = buf; |
815 | struct rb_node **newn = &sdp->sd_rindex_tree.rb_node, *parent = NULL; | ||
816 | |||
817 | /* Figure out where to put new node */ | ||
818 | while (*newn) { | ||
819 | struct gfs2_rgrpd *cur = rb_entry(*newn, struct gfs2_rgrpd, | ||
820 | rd_node); | ||
821 | |||
822 | parent = *newn; | ||
823 | if (rgd->rd_addr < cur->rd_addr) | ||
824 | newn = &((*newn)->rb_left); | ||
825 | else if (rgd->rd_addr > cur->rd_addr) | ||
826 | newn = &((*newn)->rb_right); | ||
827 | else | ||
828 | return -EEXIST; | ||
829 | } | ||
830 | 530 | ||
831 | rb_link_node(&rgd->rd_node, parent, newn); | 531 | rgd->rd_addr = be64_to_cpu(str->ri_addr); |
832 | rb_insert_color(&rgd->rd_node, &sdp->sd_rindex_tree); | 532 | rgd->rd_length = be32_to_cpu(str->ri_length); |
833 | sdp->sd_rgrps++; | 533 | rgd->rd_data0 = be64_to_cpu(str->ri_data0); |
834 | return 0; | 534 | rgd->rd_data = be32_to_cpu(str->ri_data); |
535 | rgd->rd_bitbytes = be32_to_cpu(str->ri_bitbytes); | ||
835 | } | 536 | } |
836 | 537 | ||
837 | /** | 538 | /** |
838 | * read_rindex_entry - Pull in a new resource index entry from the disk | 539 | * read_rindex_entry - Pull in a new resource index entry from the disk |
839 | * @ip: Pointer to the rindex inode | 540 | * @gl: The glock covering the rindex inode |
840 | * | 541 | * |
841 | * Returns: 0 on success, > 0 on EOF, error code otherwise | 542 | * Returns: 0 on success, error code otherwise |
842 | */ | 543 | */ |
843 | 544 | ||
844 | static int read_rindex_entry(struct gfs2_inode *ip) | 545 | static int read_rindex_entry(struct gfs2_inode *ip, |
546 | struct file_ra_state *ra_state) | ||
845 | { | 547 | { |
846 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 548 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
847 | loff_t pos = sdp->sd_rgrps * sizeof(struct gfs2_rindex); | 549 | loff_t pos = sdp->sd_rgrps * sizeof(struct gfs2_rindex); |
848 | struct gfs2_rindex buf; | 550 | char buf[sizeof(struct gfs2_rindex)]; |
849 | int error; | 551 | int error; |
850 | struct gfs2_rgrpd *rgd; | 552 | struct gfs2_rgrpd *rgd; |
851 | 553 | ||
852 | if (pos >= i_size_read(&ip->i_inode)) | 554 | error = gfs2_internal_read(ip, ra_state, buf, &pos, |
853 | return 1; | ||
854 | |||
855 | error = gfs2_internal_read(ip, (char *)&buf, &pos, | ||
856 | sizeof(struct gfs2_rindex)); | 555 | sizeof(struct gfs2_rindex)); |
857 | 556 | if (!error) | |
858 | if (error != sizeof(struct gfs2_rindex)) | 557 | return 0; |
859 | return (error == 0) ? 1 : error; | 558 | if (error != sizeof(struct gfs2_rindex)) { |
559 | if (error > 0) | ||
560 | error = -EIO; | ||
561 | return error; | ||
562 | } | ||
860 | 563 | ||
861 | rgd = kmem_cache_zalloc(gfs2_rgrpd_cachep, GFP_NOFS); | 564 | rgd = kmem_cache_zalloc(gfs2_rgrpd_cachep, GFP_NOFS); |
862 | error = -ENOMEM; | 565 | error = -ENOMEM; |
863 | if (!rgd) | 566 | if (!rgd) |
864 | return error; | 567 | return error; |
865 | 568 | ||
569 | mutex_init(&rgd->rd_mutex); | ||
570 | lops_init_le(&rgd->rd_le, &gfs2_rg_lops); | ||
866 | rgd->rd_sbd = sdp; | 571 | rgd->rd_sbd = sdp; |
867 | rgd->rd_addr = be64_to_cpu(buf.ri_addr); | ||
868 | rgd->rd_length = be32_to_cpu(buf.ri_length); | ||
869 | rgd->rd_data0 = be64_to_cpu(buf.ri_data0); | ||
870 | rgd->rd_data = be32_to_cpu(buf.ri_data); | ||
871 | rgd->rd_bitbytes = be32_to_cpu(buf.ri_bitbytes); | ||
872 | spin_lock_init(&rgd->rd_rsspin); | ||
873 | 572 | ||
573 | list_add_tail(&rgd->rd_list, &sdp->sd_rindex_list); | ||
574 | list_add_tail(&rgd->rd_list_mru, &sdp->sd_rindex_mru_list); | ||
575 | |||
576 | gfs2_rindex_in(rgd, buf); | ||
874 | error = compute_bitstructs(rgd); | 577 | error = compute_bitstructs(rgd); |
875 | if (error) | 578 | if (error) |
876 | goto fail; | 579 | return error; |
877 | 580 | ||
878 | error = gfs2_glock_get(sdp, rgd->rd_addr, | 581 | error = gfs2_glock_get(sdp, rgd->rd_addr, |
879 | &gfs2_rgrp_glops, CREATE, &rgd->rd_gl); | 582 | &gfs2_rgrp_glops, CREATE, &rgd->rd_gl); |
880 | if (error) | 583 | if (error) |
881 | goto fail; | 584 | return error; |
882 | 585 | ||
883 | rgd->rd_gl->gl_object = rgd; | 586 | rgd->rd_gl->gl_object = rgd; |
884 | rgd->rd_rgl = (struct gfs2_rgrp_lvb *)rgd->rd_gl->gl_lksb.sb_lvbptr; | ||
885 | rgd->rd_flags &= ~GFS2_RDF_UPTODATE; | 587 | rgd->rd_flags &= ~GFS2_RDF_UPTODATE; |
886 | if (rgd->rd_data > sdp->sd_max_rg_data) | ||
887 | sdp->sd_max_rg_data = rgd->rd_data; | ||
888 | spin_lock(&sdp->sd_rindex_spin); | ||
889 | error = rgd_insert(rgd); | ||
890 | spin_unlock(&sdp->sd_rindex_spin); | ||
891 | if (!error) | ||
892 | return 0; | ||
893 | |||
894 | error = 0; /* someone else read in the rgrp; free it and ignore it */ | ||
895 | gfs2_glock_put(rgd->rd_gl); | ||
896 | |||
897 | fail: | ||
898 | kfree(rgd->rd_bits); | ||
899 | kmem_cache_free(gfs2_rgrpd_cachep, rgd); | ||
900 | return error; | 588 | return error; |
901 | } | 589 | } |
902 | 590 | ||
@@ -907,25 +595,40 @@ fail: | |||
907 | * Returns: 0 on successful update, error code otherwise | 595 | * Returns: 0 on successful update, error code otherwise |
908 | */ | 596 | */ |
909 | 597 | ||
910 | static int gfs2_ri_update(struct gfs2_inode *ip) | 598 | int gfs2_ri_update(struct gfs2_inode *ip) |
911 | { | 599 | { |
912 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 600 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
601 | struct inode *inode = &ip->i_inode; | ||
602 | struct file_ra_state ra_state; | ||
603 | u64 rgrp_count = i_size_read(inode); | ||
604 | struct gfs2_rgrpd *rgd; | ||
605 | unsigned int max_data = 0; | ||
913 | int error; | 606 | int error; |
914 | 607 | ||
915 | do { | 608 | do_div(rgrp_count, sizeof(struct gfs2_rindex)); |
916 | error = read_rindex_entry(ip); | 609 | clear_rgrpdi(sdp); |
917 | } while (error == 0); | ||
918 | 610 | ||
919 | if (error < 0) | 611 | file_ra_state_init(&ra_state, inode->i_mapping); |
920 | return error; | 612 | for (sdp->sd_rgrps = 0; sdp->sd_rgrps < rgrp_count; sdp->sd_rgrps++) { |
613 | error = read_rindex_entry(ip, &ra_state); | ||
614 | if (error) { | ||
615 | clear_rgrpdi(sdp); | ||
616 | return error; | ||
617 | } | ||
618 | } | ||
921 | 619 | ||
620 | list_for_each_entry(rgd, &sdp->sd_rindex_list, rd_list) | ||
621 | if (rgd->rd_data > max_data) | ||
622 | max_data = rgd->rd_data; | ||
623 | sdp->sd_max_rg_data = max_data; | ||
922 | sdp->sd_rindex_uptodate = 1; | 624 | sdp->sd_rindex_uptodate = 1; |
923 | return 0; | 625 | return 0; |
924 | } | 626 | } |
925 | 627 | ||
926 | /** | 628 | /** |
927 | * gfs2_rindex_update - Update the rindex if required | 629 | * gfs2_rindex_hold - Grab a lock on the rindex |
928 | * @sdp: The GFS2 superblock | 630 | * @sdp: The GFS2 superblock |
631 | * @ri_gh: the glock holder | ||
929 | * | 632 | * |
930 | * We grab a lock on the rindex inode to make sure that it doesn't | 633 | * We grab a lock on the rindex inode to make sure that it doesn't |
931 | * change whilst we are performing an operation. We keep this lock | 634 | * change whilst we are performing an operation. We keep this lock |
@@ -937,29 +640,28 @@ static int gfs2_ri_update(struct gfs2_inode *ip) | |||
937 | * special file, which might have been updated if someone expanded the | 640 | * special file, which might have been updated if someone expanded the |
938 | * filesystem (via gfs2_grow utility), which adds new resource groups. | 641 | * filesystem (via gfs2_grow utility), which adds new resource groups. |
939 | * | 642 | * |
940 | * Returns: 0 on succeess, error code otherwise | 643 | * Returns: 0 on success, error code otherwise |
941 | */ | 644 | */ |
942 | 645 | ||
943 | int gfs2_rindex_update(struct gfs2_sbd *sdp) | 646 | int gfs2_rindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ri_gh) |
944 | { | 647 | { |
945 | struct gfs2_inode *ip = GFS2_I(sdp->sd_rindex); | 648 | struct gfs2_inode *ip = GFS2_I(sdp->sd_rindex); |
946 | struct gfs2_glock *gl = ip->i_gl; | 649 | struct gfs2_glock *gl = ip->i_gl; |
947 | struct gfs2_holder ri_gh; | 650 | int error; |
948 | int error = 0; | 651 | |
949 | int unlock_required = 0; | 652 | error = gfs2_glock_nq_init(gl, LM_ST_SHARED, 0, ri_gh); |
653 | if (error) | ||
654 | return error; | ||
950 | 655 | ||
951 | /* Read new copy from disk if we don't have the latest */ | 656 | /* Read new copy from disk if we don't have the latest */ |
952 | if (!sdp->sd_rindex_uptodate) { | 657 | if (!sdp->sd_rindex_uptodate) { |
953 | if (!gfs2_glock_is_locked_by_me(gl)) { | 658 | mutex_lock(&sdp->sd_rindex_mutex); |
954 | error = gfs2_glock_nq_init(gl, LM_ST_SHARED, 0, &ri_gh); | 659 | if (!sdp->sd_rindex_uptodate) { |
660 | error = gfs2_ri_update(ip); | ||
955 | if (error) | 661 | if (error) |
956 | return error; | 662 | gfs2_glock_dq_uninit(ri_gh); |
957 | unlock_required = 1; | ||
958 | } | 663 | } |
959 | if (!sdp->sd_rindex_uptodate) | 664 | mutex_unlock(&sdp->sd_rindex_mutex); |
960 | error = gfs2_ri_update(ip); | ||
961 | if (unlock_required) | ||
962 | gfs2_glock_dq_uninit(&ri_gh); | ||
963 | } | 665 | } |
964 | 666 | ||
965 | return error; | 667 | return error; |
@@ -991,62 +693,6 @@ static void gfs2_rgrp_out(struct gfs2_rgrpd *rgd, void *buf) | |||
991 | memset(&str->rg_reserved, 0, sizeof(str->rg_reserved)); | 693 | memset(&str->rg_reserved, 0, sizeof(str->rg_reserved)); |
992 | } | 694 | } |
993 | 695 | ||
994 | static int gfs2_rgrp_lvb_valid(struct gfs2_rgrpd *rgd) | ||
995 | { | ||
996 | struct gfs2_rgrp_lvb *rgl = rgd->rd_rgl; | ||
997 | struct gfs2_rgrp *str = (struct gfs2_rgrp *)rgd->rd_bits[0].bi_bh->b_data; | ||
998 | |||
999 | if (rgl->rl_flags != str->rg_flags || rgl->rl_free != str->rg_free || | ||
1000 | rgl->rl_dinodes != str->rg_dinodes || | ||
1001 | rgl->rl_igeneration != str->rg_igeneration) | ||
1002 | return 0; | ||
1003 | return 1; | ||
1004 | } | ||
1005 | |||
1006 | static void gfs2_rgrp_ondisk2lvb(struct gfs2_rgrp_lvb *rgl, const void *buf) | ||
1007 | { | ||
1008 | const struct gfs2_rgrp *str = buf; | ||
1009 | |||
1010 | rgl->rl_magic = cpu_to_be32(GFS2_MAGIC); | ||
1011 | rgl->rl_flags = str->rg_flags; | ||
1012 | rgl->rl_free = str->rg_free; | ||
1013 | rgl->rl_dinodes = str->rg_dinodes; | ||
1014 | rgl->rl_igeneration = str->rg_igeneration; | ||
1015 | rgl->__pad = 0UL; | ||
1016 | } | ||
1017 | |||
1018 | static void update_rgrp_lvb_unlinked(struct gfs2_rgrpd *rgd, u32 change) | ||
1019 | { | ||
1020 | struct gfs2_rgrp_lvb *rgl = rgd->rd_rgl; | ||
1021 | u32 unlinked = be32_to_cpu(rgl->rl_unlinked) + change; | ||
1022 | rgl->rl_unlinked = cpu_to_be32(unlinked); | ||
1023 | } | ||
1024 | |||
1025 | static u32 count_unlinked(struct gfs2_rgrpd *rgd) | ||
1026 | { | ||
1027 | struct gfs2_bitmap *bi; | ||
1028 | const u32 length = rgd->rd_length; | ||
1029 | const u8 *buffer = NULL; | ||
1030 | u32 i, goal, count = 0; | ||
1031 | |||
1032 | for (i = 0, bi = rgd->rd_bits; i < length; i++, bi++) { | ||
1033 | goal = 0; | ||
1034 | buffer = bi->bi_bh->b_data + bi->bi_offset; | ||
1035 | WARN_ON(!buffer_uptodate(bi->bi_bh)); | ||
1036 | while (goal < bi->bi_len * GFS2_NBBY) { | ||
1037 | goal = gfs2_bitfit(buffer, bi->bi_len, goal, | ||
1038 | GFS2_BLKST_UNLINKED); | ||
1039 | if (goal == BFITNOENT) | ||
1040 | break; | ||
1041 | count++; | ||
1042 | goal++; | ||
1043 | } | ||
1044 | } | ||
1045 | |||
1046 | return count; | ||
1047 | } | ||
1048 | |||
1049 | |||
1050 | /** | 696 | /** |
1051 | * gfs2_rgrp_bh_get - Read in a RG's header and bitmaps | 697 | * gfs2_rgrp_bh_get - Read in a RG's header and bitmaps |
1052 | * @rgd: the struct gfs2_rgrpd describing the RG to read in | 698 | * @rgd: the struct gfs2_rgrpd describing the RG to read in |
@@ -1066,8 +712,16 @@ int gfs2_rgrp_bh_get(struct gfs2_rgrpd *rgd) | |||
1066 | unsigned int x, y; | 712 | unsigned int x, y; |
1067 | int error; | 713 | int error; |
1068 | 714 | ||
1069 | if (rgd->rd_bits[0].bi_bh != NULL) | 715 | mutex_lock(&rgd->rd_mutex); |
716 | |||
717 | spin_lock(&sdp->sd_rindex_spin); | ||
718 | if (rgd->rd_bh_count) { | ||
719 | rgd->rd_bh_count++; | ||
720 | spin_unlock(&sdp->sd_rindex_spin); | ||
721 | mutex_unlock(&rgd->rd_mutex); | ||
1070 | return 0; | 722 | return 0; |
723 | } | ||
724 | spin_unlock(&sdp->sd_rindex_spin); | ||
1071 | 725 | ||
1072 | for (x = 0; x < length; x++) { | 726 | for (x = 0; x < length; x++) { |
1073 | bi = rgd->rd_bits + x; | 727 | bi = rgd->rd_bits + x; |
@@ -1093,22 +747,15 @@ int gfs2_rgrp_bh_get(struct gfs2_rgrpd *rgd) | |||
1093 | clear_bit(GBF_FULL, &rgd->rd_bits[x].bi_flags); | 747 | clear_bit(GBF_FULL, &rgd->rd_bits[x].bi_flags); |
1094 | gfs2_rgrp_in(rgd, (rgd->rd_bits[0].bi_bh)->b_data); | 748 | gfs2_rgrp_in(rgd, (rgd->rd_bits[0].bi_bh)->b_data); |
1095 | rgd->rd_flags |= (GFS2_RDF_UPTODATE | GFS2_RDF_CHECK); | 749 | rgd->rd_flags |= (GFS2_RDF_UPTODATE | GFS2_RDF_CHECK); |
1096 | rgd->rd_free_clone = rgd->rd_free; | ||
1097 | } | ||
1098 | if (be32_to_cpu(GFS2_MAGIC) != rgd->rd_rgl->rl_magic) { | ||
1099 | rgd->rd_rgl->rl_unlinked = cpu_to_be32(count_unlinked(rgd)); | ||
1100 | gfs2_rgrp_ondisk2lvb(rgd->rd_rgl, | ||
1101 | rgd->rd_bits[0].bi_bh->b_data); | ||
1102 | } | ||
1103 | else if (sdp->sd_args.ar_rgrplvb) { | ||
1104 | if (!gfs2_rgrp_lvb_valid(rgd)){ | ||
1105 | gfs2_consist_rgrpd(rgd); | ||
1106 | error = -EIO; | ||
1107 | goto fail; | ||
1108 | } | ||
1109 | if (rgd->rd_rgl->rl_unlinked == 0) | ||
1110 | rgd->rd_flags &= ~GFS2_RDF_CHECK; | ||
1111 | } | 750 | } |
751 | |||
752 | spin_lock(&sdp->sd_rindex_spin); | ||
753 | rgd->rd_free_clone = rgd->rd_free; | ||
754 | rgd->rd_bh_count++; | ||
755 | spin_unlock(&sdp->sd_rindex_spin); | ||
756 | |||
757 | mutex_unlock(&rgd->rd_mutex); | ||
758 | |||
1112 | return 0; | 759 | return 0; |
1113 | 760 | ||
1114 | fail: | 761 | fail: |
@@ -1118,67 +765,52 @@ fail: | |||
1118 | bi->bi_bh = NULL; | 765 | bi->bi_bh = NULL; |
1119 | gfs2_assert_warn(sdp, !bi->bi_clone); | 766 | gfs2_assert_warn(sdp, !bi->bi_clone); |
1120 | } | 767 | } |
768 | mutex_unlock(&rgd->rd_mutex); | ||
1121 | 769 | ||
1122 | return error; | 770 | return error; |
1123 | } | 771 | } |
1124 | 772 | ||
1125 | int update_rgrp_lvb(struct gfs2_rgrpd *rgd) | 773 | void gfs2_rgrp_bh_hold(struct gfs2_rgrpd *rgd) |
1126 | { | ||
1127 | u32 rl_flags; | ||
1128 | |||
1129 | if (rgd->rd_flags & GFS2_RDF_UPTODATE) | ||
1130 | return 0; | ||
1131 | |||
1132 | if (be32_to_cpu(GFS2_MAGIC) != rgd->rd_rgl->rl_magic) | ||
1133 | return gfs2_rgrp_bh_get(rgd); | ||
1134 | |||
1135 | rl_flags = be32_to_cpu(rgd->rd_rgl->rl_flags); | ||
1136 | rl_flags &= ~GFS2_RDF_MASK; | ||
1137 | rgd->rd_flags &= GFS2_RDF_MASK; | ||
1138 | rgd->rd_flags |= (rl_flags | GFS2_RDF_UPTODATE | GFS2_RDF_CHECK); | ||
1139 | if (rgd->rd_rgl->rl_unlinked == 0) | ||
1140 | rgd->rd_flags &= ~GFS2_RDF_CHECK; | ||
1141 | rgd->rd_free = be32_to_cpu(rgd->rd_rgl->rl_free); | ||
1142 | rgd->rd_free_clone = rgd->rd_free; | ||
1143 | rgd->rd_dinodes = be32_to_cpu(rgd->rd_rgl->rl_dinodes); | ||
1144 | rgd->rd_igeneration = be64_to_cpu(rgd->rd_rgl->rl_igeneration); | ||
1145 | return 0; | ||
1146 | } | ||
1147 | |||
1148 | int gfs2_rgrp_go_lock(struct gfs2_holder *gh) | ||
1149 | { | 774 | { |
1150 | struct gfs2_rgrpd *rgd = gh->gh_gl->gl_object; | ||
1151 | struct gfs2_sbd *sdp = rgd->rd_sbd; | 775 | struct gfs2_sbd *sdp = rgd->rd_sbd; |
1152 | 776 | ||
1153 | if (gh->gh_flags & GL_SKIP && sdp->sd_args.ar_rgrplvb) | 777 | spin_lock(&sdp->sd_rindex_spin); |
1154 | return 0; | 778 | gfs2_assert_warn(rgd->rd_sbd, rgd->rd_bh_count); |
1155 | return gfs2_rgrp_bh_get((struct gfs2_rgrpd *)gh->gh_gl->gl_object); | 779 | rgd->rd_bh_count++; |
780 | spin_unlock(&sdp->sd_rindex_spin); | ||
1156 | } | 781 | } |
1157 | 782 | ||
1158 | /** | 783 | /** |
1159 | * gfs2_rgrp_go_unlock - Release RG bitmaps read in with gfs2_rgrp_bh_get() | 784 | * gfs2_rgrp_bh_put - Release RG bitmaps read in with gfs2_rgrp_bh_get() |
1160 | * @gh: The glock holder for the resource group | 785 | * @rgd: the struct gfs2_rgrpd describing the RG to read in |
1161 | * | 786 | * |
1162 | */ | 787 | */ |
1163 | 788 | ||
1164 | void gfs2_rgrp_go_unlock(struct gfs2_holder *gh) | 789 | void gfs2_rgrp_bh_put(struct gfs2_rgrpd *rgd) |
1165 | { | 790 | { |
1166 | struct gfs2_rgrpd *rgd = gh->gh_gl->gl_object; | 791 | struct gfs2_sbd *sdp = rgd->rd_sbd; |
1167 | int x, length = rgd->rd_length; | 792 | int x, length = rgd->rd_length; |
1168 | 793 | ||
794 | spin_lock(&sdp->sd_rindex_spin); | ||
795 | gfs2_assert_warn(rgd->rd_sbd, rgd->rd_bh_count); | ||
796 | if (--rgd->rd_bh_count) { | ||
797 | spin_unlock(&sdp->sd_rindex_spin); | ||
798 | return; | ||
799 | } | ||
800 | |||
1169 | for (x = 0; x < length; x++) { | 801 | for (x = 0; x < length; x++) { |
1170 | struct gfs2_bitmap *bi = rgd->rd_bits + x; | 802 | struct gfs2_bitmap *bi = rgd->rd_bits + x; |
1171 | if (bi->bi_bh) { | 803 | kfree(bi->bi_clone); |
1172 | brelse(bi->bi_bh); | 804 | bi->bi_clone = NULL; |
1173 | bi->bi_bh = NULL; | 805 | brelse(bi->bi_bh); |
1174 | } | 806 | bi->bi_bh = NULL; |
1175 | } | 807 | } |
1176 | 808 | ||
809 | spin_unlock(&sdp->sd_rindex_spin); | ||
1177 | } | 810 | } |
1178 | 811 | ||
1179 | int gfs2_rgrp_send_discards(struct gfs2_sbd *sdp, u64 offset, | 812 | static void gfs2_rgrp_send_discards(struct gfs2_sbd *sdp, u64 offset, |
1180 | struct buffer_head *bh, | 813 | const struct gfs2_bitmap *bi) |
1181 | const struct gfs2_bitmap *bi, unsigned minlen, u64 *ptrimmed) | ||
1182 | { | 814 | { |
1183 | struct super_block *sb = sdp->sd_vfs; | 815 | struct super_block *sb = sdp->sd_vfs; |
1184 | struct block_device *bdev = sb->s_bdev; | 816 | struct block_device *bdev = sb->s_bdev; |
@@ -1189,19 +821,11 @@ int gfs2_rgrp_send_discards(struct gfs2_sbd *sdp, u64 offset, | |||
1189 | sector_t nr_sects = 0; | 821 | sector_t nr_sects = 0; |
1190 | int rv; | 822 | int rv; |
1191 | unsigned int x; | 823 | unsigned int x; |
1192 | u32 trimmed = 0; | ||
1193 | u8 diff; | ||
1194 | 824 | ||
1195 | for (x = 0; x < bi->bi_len; x++) { | 825 | for (x = 0; x < bi->bi_len; x++) { |
1196 | const u8 *clone = bi->bi_clone ? bi->bi_clone : bi->bi_bh->b_data; | 826 | const u8 *orig = bi->bi_bh->b_data + bi->bi_offset + x; |
1197 | clone += bi->bi_offset; | 827 | const u8 *clone = bi->bi_clone + bi->bi_offset + x; |
1198 | clone += x; | 828 | u8 diff = ~(*orig | (*orig >> 1)) & (*clone | (*clone >> 1)); |
1199 | if (bh) { | ||
1200 | const u8 *orig = bh->b_data + bi->bi_offset + x; | ||
1201 | diff = ~(*orig | (*orig >> 1)) & (*clone | (*clone >> 1)); | ||
1202 | } else { | ||
1203 | diff = ~(*clone | (*clone >> 1)); | ||
1204 | } | ||
1205 | diff &= 0x55; | 829 | diff &= 0x55; |
1206 | if (diff == 0) | 830 | if (diff == 0) |
1207 | continue; | 831 | continue; |
@@ -1212,14 +836,11 @@ int gfs2_rgrp_send_discards(struct gfs2_sbd *sdp, u64 offset, | |||
1212 | if (nr_sects == 0) | 836 | if (nr_sects == 0) |
1213 | goto start_new_extent; | 837 | goto start_new_extent; |
1214 | if ((start + nr_sects) != blk) { | 838 | if ((start + nr_sects) != blk) { |
1215 | if (nr_sects >= minlen) { | 839 | rv = blkdev_issue_discard(bdev, start, |
1216 | rv = blkdev_issue_discard(bdev, | 840 | nr_sects, GFP_NOFS, |
1217 | start, nr_sects, | 841 | 0); |
1218 | GFP_NOFS, 0); | 842 | if (rv) |
1219 | if (rv) | 843 | goto fail; |
1220 | goto fail; | ||
1221 | trimmed += nr_sects; | ||
1222 | } | ||
1223 | nr_sects = 0; | 844 | nr_sects = 0; |
1224 | start_new_extent: | 845 | start_new_extent: |
1225 | start = blk; | 846 | start = blk; |
@@ -1230,403 +851,85 @@ start_new_extent: | |||
1230 | blk += sects_per_blk; | 851 | blk += sects_per_blk; |
1231 | } | 852 | } |
1232 | } | 853 | } |
1233 | if (nr_sects >= minlen) { | 854 | if (nr_sects) { |
1234 | rv = blkdev_issue_discard(bdev, start, nr_sects, GFP_NOFS, 0); | 855 | rv = blkdev_issue_discard(bdev, start, nr_sects, GFP_NOFS, 0); |
1235 | if (rv) | 856 | if (rv) |
1236 | goto fail; | 857 | goto fail; |
1237 | trimmed += nr_sects; | ||
1238 | } | 858 | } |
1239 | if (ptrimmed) | 859 | return; |
1240 | *ptrimmed = trimmed; | ||
1241 | return 0; | ||
1242 | |||
1243 | fail: | 860 | fail: |
1244 | if (sdp->sd_args.ar_discard) | 861 | fs_warn(sdp, "error %d on discard request, turning discards off for this filesystem", rv); |
1245 | fs_warn(sdp, "error %d on discard request, turning discards off for this filesystem", rv); | ||
1246 | sdp->sd_args.ar_discard = 0; | 862 | sdp->sd_args.ar_discard = 0; |
1247 | return -EIO; | ||
1248 | } | 863 | } |
1249 | 864 | ||
1250 | /** | 865 | void gfs2_rgrp_repolish_clones(struct gfs2_rgrpd *rgd) |
1251 | * gfs2_fitrim - Generate discard requests for unused bits of the filesystem | ||
1252 | * @filp: Any file on the filesystem | ||
1253 | * @argp: Pointer to the arguments (also used to pass result) | ||
1254 | * | ||
1255 | * Returns: 0 on success, otherwise error code | ||
1256 | */ | ||
1257 | |||
1258 | int gfs2_fitrim(struct file *filp, void __user *argp) | ||
1259 | { | 866 | { |
1260 | struct inode *inode = filp->f_dentry->d_inode; | 867 | struct gfs2_sbd *sdp = rgd->rd_sbd; |
1261 | struct gfs2_sbd *sdp = GFS2_SB(inode); | 868 | unsigned int length = rgd->rd_length; |
1262 | struct request_queue *q = bdev_get_queue(sdp->sd_vfs->s_bdev); | ||
1263 | struct buffer_head *bh; | ||
1264 | struct gfs2_rgrpd *rgd; | ||
1265 | struct gfs2_rgrpd *rgd_end; | ||
1266 | struct gfs2_holder gh; | ||
1267 | struct fstrim_range r; | ||
1268 | int ret = 0; | ||
1269 | u64 amt; | ||
1270 | u64 trimmed = 0; | ||
1271 | u64 start, end, minlen; | ||
1272 | unsigned int x; | 869 | unsigned int x; |
1273 | unsigned bs_shift = sdp->sd_sb.sb_bsize_shift; | ||
1274 | 870 | ||
1275 | if (!capable(CAP_SYS_ADMIN)) | 871 | for (x = 0; x < length; x++) { |
1276 | return -EPERM; | 872 | struct gfs2_bitmap *bi = rgd->rd_bits + x; |
1277 | 873 | if (!bi->bi_clone) | |
1278 | if (!blk_queue_discard(q)) | 874 | continue; |
1279 | return -EOPNOTSUPP; | 875 | if (sdp->sd_args.ar_discard) |
1280 | 876 | gfs2_rgrp_send_discards(sdp, rgd->rd_data0, bi); | |
1281 | if (copy_from_user(&r, argp, sizeof(r))) | 877 | clear_bit(GBF_FULL, &bi->bi_flags); |
1282 | return -EFAULT; | 878 | memcpy(bi->bi_clone + bi->bi_offset, |
1283 | 879 | bi->bi_bh->b_data + bi->bi_offset, bi->bi_len); | |
1284 | ret = gfs2_rindex_update(sdp); | ||
1285 | if (ret) | ||
1286 | return ret; | ||
1287 | |||
1288 | start = r.start >> bs_shift; | ||
1289 | end = start + (r.len >> bs_shift); | ||
1290 | minlen = max_t(u64, r.minlen, | ||
1291 | q->limits.discard_granularity) >> bs_shift; | ||
1292 | |||
1293 | rgd = gfs2_blk2rgrpd(sdp, start, 0); | ||
1294 | rgd_end = gfs2_blk2rgrpd(sdp, end - 1, 0); | ||
1295 | |||
1296 | if (end <= start || | ||
1297 | minlen > sdp->sd_max_rg_data || | ||
1298 | start > rgd_end->rd_data0 + rgd_end->rd_data) | ||
1299 | return -EINVAL; | ||
1300 | |||
1301 | while (1) { | ||
1302 | |||
1303 | ret = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, &gh); | ||
1304 | if (ret) | ||
1305 | goto out; | ||
1306 | |||
1307 | if (!(rgd->rd_flags & GFS2_RGF_TRIMMED)) { | ||
1308 | /* Trim each bitmap in the rgrp */ | ||
1309 | for (x = 0; x < rgd->rd_length; x++) { | ||
1310 | struct gfs2_bitmap *bi = rgd->rd_bits + x; | ||
1311 | ret = gfs2_rgrp_send_discards(sdp, | ||
1312 | rgd->rd_data0, NULL, bi, minlen, | ||
1313 | &amt); | ||
1314 | if (ret) { | ||
1315 | gfs2_glock_dq_uninit(&gh); | ||
1316 | goto out; | ||
1317 | } | ||
1318 | trimmed += amt; | ||
1319 | } | ||
1320 | |||
1321 | /* Mark rgrp as having been trimmed */ | ||
1322 | ret = gfs2_trans_begin(sdp, RES_RG_HDR, 0); | ||
1323 | if (ret == 0) { | ||
1324 | bh = rgd->rd_bits[0].bi_bh; | ||
1325 | rgd->rd_flags |= GFS2_RGF_TRIMMED; | ||
1326 | gfs2_trans_add_bh(rgd->rd_gl, bh, 1); | ||
1327 | gfs2_rgrp_out(rgd, bh->b_data); | ||
1328 | gfs2_rgrp_ondisk2lvb(rgd->rd_rgl, bh->b_data); | ||
1329 | gfs2_trans_end(sdp); | ||
1330 | } | ||
1331 | } | ||
1332 | gfs2_glock_dq_uninit(&gh); | ||
1333 | |||
1334 | if (rgd == rgd_end) | ||
1335 | break; | ||
1336 | |||
1337 | rgd = gfs2_rgrpd_get_next(rgd); | ||
1338 | } | ||
1339 | |||
1340 | out: | ||
1341 | r.len = trimmed << 9; | ||
1342 | if (copy_to_user(argp, &r, sizeof(r))) | ||
1343 | return -EFAULT; | ||
1344 | |||
1345 | return ret; | ||
1346 | } | ||
1347 | |||
1348 | /** | ||
1349 | * rs_insert - insert a new multi-block reservation into the rgrp's rb_tree | ||
1350 | * @ip: the inode structure | ||
1351 | * | ||
1352 | */ | ||
1353 | static void rs_insert(struct gfs2_inode *ip) | ||
1354 | { | ||
1355 | struct rb_node **newn, *parent = NULL; | ||
1356 | int rc; | ||
1357 | struct gfs2_blkreserv *rs = ip->i_res; | ||
1358 | struct gfs2_rgrpd *rgd = rs->rs_rbm.rgd; | ||
1359 | u64 fsblock = gfs2_rbm_to_block(&rs->rs_rbm); | ||
1360 | |||
1361 | BUG_ON(gfs2_rs_active(rs)); | ||
1362 | |||
1363 | spin_lock(&rgd->rd_rsspin); | ||
1364 | newn = &rgd->rd_rstree.rb_node; | ||
1365 | while (*newn) { | ||
1366 | struct gfs2_blkreserv *cur = | ||
1367 | rb_entry(*newn, struct gfs2_blkreserv, rs_node); | ||
1368 | |||
1369 | parent = *newn; | ||
1370 | rc = rs_cmp(fsblock, rs->rs_free, cur); | ||
1371 | if (rc > 0) | ||
1372 | newn = &((*newn)->rb_right); | ||
1373 | else if (rc < 0) | ||
1374 | newn = &((*newn)->rb_left); | ||
1375 | else { | ||
1376 | spin_unlock(&rgd->rd_rsspin); | ||
1377 | WARN_ON(1); | ||
1378 | return; | ||
1379 | } | ||
1380 | } | 880 | } |
1381 | 881 | ||
1382 | rb_link_node(&rs->rs_node, parent, newn); | 882 | spin_lock(&sdp->sd_rindex_spin); |
1383 | rb_insert_color(&rs->rs_node, &rgd->rd_rstree); | 883 | rgd->rd_free_clone = rgd->rd_free; |
1384 | 884 | spin_unlock(&sdp->sd_rindex_spin); | |
1385 | /* Do our rgrp accounting for the reservation */ | ||
1386 | rgd->rd_reserved += rs->rs_free; /* blocks reserved */ | ||
1387 | spin_unlock(&rgd->rd_rsspin); | ||
1388 | trace_gfs2_rs(rs, TRACE_RS_INSERT); | ||
1389 | } | 885 | } |
1390 | 886 | ||
1391 | /** | 887 | /** |
1392 | * rg_mblk_search - find a group of multiple free blocks to form a reservation | 888 | * gfs2_alloc_get - get the struct gfs2_alloc structure for an inode |
1393 | * @rgd: the resource group descriptor | 889 | * @ip: the incore GFS2 inode structure |
1394 | * @ip: pointer to the inode for which we're reserving blocks | ||
1395 | * @requested: number of blocks required for this allocation | ||
1396 | * | 890 | * |
891 | * Returns: the struct gfs2_alloc | ||
1397 | */ | 892 | */ |
1398 | 893 | ||
1399 | static void rg_mblk_search(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip, | 894 | struct gfs2_alloc *gfs2_alloc_get(struct gfs2_inode *ip) |
1400 | unsigned requested) | ||
1401 | { | 895 | { |
1402 | struct gfs2_rbm rbm = { .rgd = rgd, }; | 896 | BUG_ON(ip->i_alloc != NULL); |
1403 | u64 goal; | 897 | ip->i_alloc = kzalloc(sizeof(struct gfs2_alloc), GFP_NOFS); |
1404 | struct gfs2_blkreserv *rs = ip->i_res; | 898 | return ip->i_alloc; |
1405 | u32 extlen; | ||
1406 | u32 free_blocks = rgd->rd_free_clone - rgd->rd_reserved; | ||
1407 | int ret; | ||
1408 | |||
1409 | extlen = max_t(u32, atomic_read(&rs->rs_sizehint), requested); | ||
1410 | extlen = clamp(extlen, RGRP_RSRV_MINBLKS, free_blocks); | ||
1411 | if ((rgd->rd_free_clone < rgd->rd_reserved) || (free_blocks < extlen)) | ||
1412 | return; | ||
1413 | |||
1414 | /* Find bitmap block that contains bits for goal block */ | ||
1415 | if (rgrp_contains_block(rgd, ip->i_goal)) | ||
1416 | goal = ip->i_goal; | ||
1417 | else | ||
1418 | goal = rgd->rd_last_alloc + rgd->rd_data0; | ||
1419 | |||
1420 | if (WARN_ON(gfs2_rbm_from_block(&rbm, goal))) | ||
1421 | return; | ||
1422 | |||
1423 | ret = gfs2_rbm_find(&rbm, GFS2_BLKST_FREE, extlen, ip, true); | ||
1424 | if (ret == 0) { | ||
1425 | rs->rs_rbm = rbm; | ||
1426 | rs->rs_free = extlen; | ||
1427 | rs->rs_inum = ip->i_no_addr; | ||
1428 | rs_insert(ip); | ||
1429 | } else { | ||
1430 | if (goal == rgd->rd_last_alloc + rgd->rd_data0) | ||
1431 | rgd->rd_last_alloc = 0; | ||
1432 | } | ||
1433 | } | 899 | } |
1434 | 900 | ||
1435 | /** | 901 | /** |
1436 | * gfs2_next_unreserved_block - Return next block that is not reserved | 902 | * try_rgrp_fit - See if a given reservation will fit in a given RG |
1437 | * @rgd: The resource group | 903 | * @rgd: the RG data |
1438 | * @block: The starting block | 904 | * @al: the struct gfs2_alloc structure describing the reservation |
1439 | * @length: The required length | ||
1440 | * @ip: Ignore any reservations for this inode | ||
1441 | * | 905 | * |
1442 | * If the block does not appear in any reservation, then return the | 906 | * If there's room for the requested blocks to be allocated from the RG: |
1443 | * block number unchanged. If it does appear in the reservation, then | 907 | * Sets the $al_rgd field in @al. |
1444 | * keep looking through the tree of reservations in order to find the | ||
1445 | * first block number which is not reserved. | ||
1446 | */ | ||
1447 | |||
1448 | static u64 gfs2_next_unreserved_block(struct gfs2_rgrpd *rgd, u64 block, | ||
1449 | u32 length, | ||
1450 | const struct gfs2_inode *ip) | ||
1451 | { | ||
1452 | struct gfs2_blkreserv *rs; | ||
1453 | struct rb_node *n; | ||
1454 | int rc; | ||
1455 | |||
1456 | spin_lock(&rgd->rd_rsspin); | ||
1457 | n = rgd->rd_rstree.rb_node; | ||
1458 | while (n) { | ||
1459 | rs = rb_entry(n, struct gfs2_blkreserv, rs_node); | ||
1460 | rc = rs_cmp(block, length, rs); | ||
1461 | if (rc < 0) | ||
1462 | n = n->rb_left; | ||
1463 | else if (rc > 0) | ||
1464 | n = n->rb_right; | ||
1465 | else | ||
1466 | break; | ||
1467 | } | ||
1468 | |||
1469 | if (n) { | ||
1470 | while ((rs_cmp(block, length, rs) == 0) && (ip->i_res != rs)) { | ||
1471 | block = gfs2_rbm_to_block(&rs->rs_rbm) + rs->rs_free; | ||
1472 | n = n->rb_right; | ||
1473 | if (n == NULL) | ||
1474 | break; | ||
1475 | rs = rb_entry(n, struct gfs2_blkreserv, rs_node); | ||
1476 | } | ||
1477 | } | ||
1478 | |||
1479 | spin_unlock(&rgd->rd_rsspin); | ||
1480 | return block; | ||
1481 | } | ||
1482 | |||
1483 | /** | ||
1484 | * gfs2_reservation_check_and_update - Check for reservations during block alloc | ||
1485 | * @rbm: The current position in the resource group | ||
1486 | * @ip: The inode for which we are searching for blocks | ||
1487 | * @minext: The minimum extent length | ||
1488 | * | ||
1489 | * This checks the current position in the rgrp to see whether there is | ||
1490 | * a reservation covering this block. If not then this function is a | ||
1491 | * no-op. If there is, then the position is moved to the end of the | ||
1492 | * contiguous reservation(s) so that we are pointing at the first | ||
1493 | * non-reserved block. | ||
1494 | * | 908 | * |
1495 | * Returns: 0 if no reservation, 1 if @rbm has changed, otherwise an error | 909 | * Returns: 1 on success (it fits), 0 on failure (it doesn't fit) |
1496 | */ | 910 | */ |
1497 | 911 | ||
1498 | static int gfs2_reservation_check_and_update(struct gfs2_rbm *rbm, | 912 | static int try_rgrp_fit(struct gfs2_rgrpd *rgd, struct gfs2_alloc *al) |
1499 | const struct gfs2_inode *ip, | ||
1500 | u32 minext) | ||
1501 | { | 913 | { |
1502 | u64 block = gfs2_rbm_to_block(rbm); | 914 | struct gfs2_sbd *sdp = rgd->rd_sbd; |
1503 | u32 extlen = 1; | 915 | int ret = 0; |
1504 | u64 nblock; | ||
1505 | int ret; | ||
1506 | |||
1507 | /* | ||
1508 | * If we have a minimum extent length, then skip over any extent | ||
1509 | * which is less than the min extent length in size. | ||
1510 | */ | ||
1511 | if (minext) { | ||
1512 | extlen = gfs2_free_extlen(rbm, minext); | ||
1513 | nblock = block + extlen; | ||
1514 | if (extlen < minext) | ||
1515 | goto fail; | ||
1516 | } | ||
1517 | 916 | ||
1518 | /* | 917 | if (rgd->rd_flags & (GFS2_RGF_NOALLOC | GFS2_RDF_ERROR)) |
1519 | * Check the extent which has been found against the reservations | ||
1520 | * and skip if parts of it are already reserved | ||
1521 | */ | ||
1522 | nblock = gfs2_next_unreserved_block(rbm->rgd, block, extlen, ip); | ||
1523 | if (nblock == block) | ||
1524 | return 0; | 918 | return 0; |
1525 | fail: | ||
1526 | ret = gfs2_rbm_from_block(rbm, nblock); | ||
1527 | if (ret < 0) | ||
1528 | return ret; | ||
1529 | return 1; | ||
1530 | } | ||
1531 | |||
1532 | /** | ||
1533 | * gfs2_rbm_find - Look for blocks of a particular state | ||
1534 | * @rbm: Value/result starting position and final position | ||
1535 | * @state: The state which we want to find | ||
1536 | * @minext: The requested extent length (0 for a single block) | ||
1537 | * @ip: If set, check for reservations | ||
1538 | * @nowrap: Stop looking at the end of the rgrp, rather than wrapping | ||
1539 | * around until we've reached the starting point. | ||
1540 | * | ||
1541 | * Side effects: | ||
1542 | * - If looking for free blocks, we set GBF_FULL on each bitmap which | ||
1543 | * has no free blocks in it. | ||
1544 | * | ||
1545 | * Returns: 0 on success, -ENOSPC if there is no block of the requested state | ||
1546 | */ | ||
1547 | 919 | ||
1548 | static int gfs2_rbm_find(struct gfs2_rbm *rbm, u8 state, u32 minext, | 920 | spin_lock(&sdp->sd_rindex_spin); |
1549 | const struct gfs2_inode *ip, bool nowrap) | 921 | if (rgd->rd_free_clone >= al->al_requested) { |
1550 | { | 922 | al->al_rgd = rgd; |
1551 | struct buffer_head *bh; | 923 | ret = 1; |
1552 | struct gfs2_bitmap *initial_bi; | ||
1553 | u32 initial_offset; | ||
1554 | u32 offset; | ||
1555 | u8 *buffer; | ||
1556 | int index; | ||
1557 | int n = 0; | ||
1558 | int iters = rbm->rgd->rd_length; | ||
1559 | int ret; | ||
1560 | |||
1561 | /* If we are not starting at the beginning of a bitmap, then we | ||
1562 | * need to add one to the bitmap count to ensure that we search | ||
1563 | * the starting bitmap twice. | ||
1564 | */ | ||
1565 | if (rbm->offset != 0) | ||
1566 | iters++; | ||
1567 | |||
1568 | while(1) { | ||
1569 | if (test_bit(GBF_FULL, &rbm->bi->bi_flags) && | ||
1570 | (state == GFS2_BLKST_FREE)) | ||
1571 | goto next_bitmap; | ||
1572 | |||
1573 | bh = rbm->bi->bi_bh; | ||
1574 | buffer = bh->b_data + rbm->bi->bi_offset; | ||
1575 | WARN_ON(!buffer_uptodate(bh)); | ||
1576 | if (state != GFS2_BLKST_UNLINKED && rbm->bi->bi_clone) | ||
1577 | buffer = rbm->bi->bi_clone + rbm->bi->bi_offset; | ||
1578 | initial_offset = rbm->offset; | ||
1579 | offset = gfs2_bitfit(buffer, rbm->bi->bi_len, rbm->offset, state); | ||
1580 | if (offset == BFITNOENT) | ||
1581 | goto bitmap_full; | ||
1582 | rbm->offset = offset; | ||
1583 | if (ip == NULL) | ||
1584 | return 0; | ||
1585 | |||
1586 | initial_bi = rbm->bi; | ||
1587 | ret = gfs2_reservation_check_and_update(rbm, ip, minext); | ||
1588 | if (ret == 0) | ||
1589 | return 0; | ||
1590 | if (ret > 0) { | ||
1591 | n += (rbm->bi - initial_bi); | ||
1592 | goto next_iter; | ||
1593 | } | ||
1594 | if (ret == -E2BIG) { | ||
1595 | index = 0; | ||
1596 | rbm->offset = 0; | ||
1597 | n += (rbm->bi - initial_bi); | ||
1598 | goto res_covered_end_of_rgrp; | ||
1599 | } | ||
1600 | return ret; | ||
1601 | |||
1602 | bitmap_full: /* Mark bitmap as full and fall through */ | ||
1603 | if ((state == GFS2_BLKST_FREE) && initial_offset == 0) | ||
1604 | set_bit(GBF_FULL, &rbm->bi->bi_flags); | ||
1605 | |||
1606 | next_bitmap: /* Find next bitmap in the rgrp */ | ||
1607 | rbm->offset = 0; | ||
1608 | index = rbm->bi - rbm->rgd->rd_bits; | ||
1609 | index++; | ||
1610 | if (index == rbm->rgd->rd_length) | ||
1611 | index = 0; | ||
1612 | res_covered_end_of_rgrp: | ||
1613 | rbm->bi = &rbm->rgd->rd_bits[index]; | ||
1614 | if ((index == 0) && nowrap) | ||
1615 | break; | ||
1616 | n++; | ||
1617 | next_iter: | ||
1618 | if (n >= iters) | ||
1619 | break; | ||
1620 | } | 924 | } |
925 | spin_unlock(&sdp->sd_rindex_spin); | ||
1621 | 926 | ||
1622 | return -ENOSPC; | 927 | return ret; |
1623 | } | 928 | } |
1624 | 929 | ||
1625 | /** | 930 | /** |
1626 | * try_rgrp_unlink - Look for any unlinked, allocated, but unused inodes | 931 | * try_rgrp_unlink - Look for any unlinked, allocated, but unused inodes |
1627 | * @rgd: The rgrp | 932 | * @rgd: The rgrp |
1628 | * @last_unlinked: block address of the last dinode we unlinked | ||
1629 | * @skip: block address we should explicitly not unlink | ||
1630 | * | 933 | * |
1631 | * Returns: 0 if no error | 934 | * Returns: 0 if no error |
1632 | * The inode, if one has been found, in inode. | 935 | * The inode, if one has been found, in inode. |
@@ -1634,33 +937,34 @@ next_iter: | |||
1634 | 937 | ||
1635 | static void try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked, u64 skip) | 938 | static void try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked, u64 skip) |
1636 | { | 939 | { |
1637 | u64 block; | 940 | u32 goal = 0, block; |
941 | u64 no_addr; | ||
1638 | struct gfs2_sbd *sdp = rgd->rd_sbd; | 942 | struct gfs2_sbd *sdp = rgd->rd_sbd; |
943 | unsigned int n; | ||
1639 | struct gfs2_glock *gl; | 944 | struct gfs2_glock *gl; |
1640 | struct gfs2_inode *ip; | 945 | struct gfs2_inode *ip; |
1641 | int error; | 946 | int error; |
1642 | int found = 0; | 947 | int found = 0; |
1643 | struct gfs2_rbm rbm = { .rgd = rgd, .bi = rgd->rd_bits, .offset = 0 }; | ||
1644 | 948 | ||
1645 | while (1) { | 949 | while (goal < rgd->rd_data) { |
1646 | down_write(&sdp->sd_log_flush_lock); | 950 | down_write(&sdp->sd_log_flush_lock); |
1647 | error = gfs2_rbm_find(&rbm, GFS2_BLKST_UNLINKED, 0, NULL, true); | 951 | n = 1; |
952 | block = rgblk_search(rgd, goal, GFS2_BLKST_UNLINKED, | ||
953 | GFS2_BLKST_UNLINKED, &n); | ||
1648 | up_write(&sdp->sd_log_flush_lock); | 954 | up_write(&sdp->sd_log_flush_lock); |
1649 | if (error == -ENOSPC) | 955 | if (block == BFITNOENT) |
1650 | break; | 956 | break; |
1651 | if (WARN_ON_ONCE(error)) | 957 | /* rgblk_search can return a block < goal, so we need to |
1652 | break; | 958 | keep it marching forward. */ |
1653 | 959 | no_addr = block + rgd->rd_data0; | |
1654 | block = gfs2_rbm_to_block(&rbm); | 960 | goal = max(block + 1, goal + 1); |
1655 | if (gfs2_rbm_from_block(&rbm, block + 1)) | 961 | if (*last_unlinked != NO_BLOCK && no_addr <= *last_unlinked) |
1656 | break; | ||
1657 | if (*last_unlinked != NO_BLOCK && block <= *last_unlinked) | ||
1658 | continue; | 962 | continue; |
1659 | if (block == skip) | 963 | if (no_addr == skip) |
1660 | continue; | 964 | continue; |
1661 | *last_unlinked = block; | 965 | *last_unlinked = no_addr; |
1662 | 966 | ||
1663 | error = gfs2_glock_get(sdp, block, &gfs2_inode_glops, CREATE, &gl); | 967 | error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &gl); |
1664 | if (error) | 968 | if (error) |
1665 | continue; | 969 | continue; |
1666 | 970 | ||
@@ -1688,230 +992,244 @@ static void try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked, u64 skip | |||
1688 | } | 992 | } |
1689 | 993 | ||
1690 | /** | 994 | /** |
1691 | * gfs2_rgrp_congested - Use stats to figure out whether an rgrp is congested | 995 | * recent_rgrp_next - get next RG from "recent" list |
1692 | * @rgd: The rgrp in question | 996 | * @cur_rgd: current rgrp |
1693 | * @loops: An indication of how picky we can be (0=very, 1=less so) | ||
1694 | * | ||
1695 | * This function uses the recently added glock statistics in order to | ||
1696 | * figure out whether a parciular resource group is suffering from | ||
1697 | * contention from multiple nodes. This is done purely on the basis | ||
1698 | * of timings, since this is the only data we have to work with and | ||
1699 | * our aim here is to reject a resource group which is highly contended | ||
1700 | * but (very important) not to do this too often in order to ensure that | ||
1701 | * we do not land up introducing fragmentation by changing resource | ||
1702 | * groups when not actually required. | ||
1703 | * | 997 | * |
1704 | * The calculation is fairly simple, we want to know whether the SRTTB | 998 | * Returns: The next rgrp in the recent list |
1705 | * (i.e. smoothed round trip time for blocking operations) to acquire | ||
1706 | * the lock for this rgrp's glock is significantly greater than the | ||
1707 | * time taken for resource groups on average. We introduce a margin in | ||
1708 | * the form of the variable @var which is computed as the sum of the two | ||
1709 | * respective variences, and multiplied by a factor depending on @loops | ||
1710 | * and whether we have a lot of data to base the decision on. This is | ||
1711 | * then tested against the square difference of the means in order to | ||
1712 | * decide whether the result is statistically significant or not. | ||
1713 | * | ||
1714 | * Returns: A boolean verdict on the congestion status | ||
1715 | */ | 999 | */ |
1716 | 1000 | ||
1717 | static bool gfs2_rgrp_congested(const struct gfs2_rgrpd *rgd, int loops) | 1001 | static struct gfs2_rgrpd *recent_rgrp_next(struct gfs2_rgrpd *cur_rgd) |
1718 | { | 1002 | { |
1719 | const struct gfs2_glock *gl = rgd->rd_gl; | 1003 | struct gfs2_sbd *sdp = cur_rgd->rd_sbd; |
1720 | const struct gfs2_sbd *sdp = gl->gl_sbd; | 1004 | struct list_head *head; |
1721 | struct gfs2_lkstats *st; | 1005 | struct gfs2_rgrpd *rgd; |
1722 | s64 r_dcount, l_dcount; | 1006 | |
1723 | s64 r_srttb, l_srttb; | 1007 | spin_lock(&sdp->sd_rindex_spin); |
1724 | s64 srttb_diff; | 1008 | head = &sdp->sd_rindex_mru_list; |
1725 | s64 sqr_diff; | 1009 | if (unlikely(cur_rgd->rd_list_mru.next == head)) { |
1726 | s64 var; | 1010 | spin_unlock(&sdp->sd_rindex_spin); |
1727 | 1011 | return NULL; | |
1728 | preempt_disable(); | 1012 | } |
1729 | st = &this_cpu_ptr(sdp->sd_lkstats)->lkstats[LM_TYPE_RGRP]; | 1013 | rgd = list_entry(cur_rgd->rd_list_mru.next, struct gfs2_rgrpd, rd_list_mru); |
1730 | r_srttb = st->stats[GFS2_LKS_SRTTB]; | 1014 | spin_unlock(&sdp->sd_rindex_spin); |
1731 | r_dcount = st->stats[GFS2_LKS_DCOUNT]; | 1015 | return rgd; |
1732 | var = st->stats[GFS2_LKS_SRTTVARB] + | ||
1733 | gl->gl_stats.stats[GFS2_LKS_SRTTVARB]; | ||
1734 | preempt_enable(); | ||
1735 | |||
1736 | l_srttb = gl->gl_stats.stats[GFS2_LKS_SRTTB]; | ||
1737 | l_dcount = gl->gl_stats.stats[GFS2_LKS_DCOUNT]; | ||
1738 | |||
1739 | if ((l_dcount < 1) || (r_dcount < 1) || (r_srttb == 0)) | ||
1740 | return false; | ||
1741 | |||
1742 | srttb_diff = r_srttb - l_srttb; | ||
1743 | sqr_diff = srttb_diff * srttb_diff; | ||
1744 | |||
1745 | var *= 2; | ||
1746 | if (l_dcount < 8 || r_dcount < 8) | ||
1747 | var *= 2; | ||
1748 | if (loops == 1) | ||
1749 | var *= 2; | ||
1750 | |||
1751 | return ((srttb_diff < 0) && (sqr_diff > var)); | ||
1752 | } | 1016 | } |
1753 | 1017 | ||
1754 | /** | 1018 | /** |
1755 | * gfs2_rgrp_used_recently | 1019 | * forward_rgrp_get - get an rgrp to try next from full list |
1756 | * @rs: The block reservation with the rgrp to test | 1020 | * @sdp: The GFS2 superblock |
1757 | * @msecs: The time limit in milliseconds | ||
1758 | * | 1021 | * |
1759 | * Returns: True if the rgrp glock has been used within the time limit | 1022 | * Returns: The rgrp to try next |
1760 | */ | 1023 | */ |
1761 | static bool gfs2_rgrp_used_recently(const struct gfs2_blkreserv *rs, | 1024 | |
1762 | u64 msecs) | 1025 | static struct gfs2_rgrpd *forward_rgrp_get(struct gfs2_sbd *sdp) |
1763 | { | 1026 | { |
1764 | u64 tdiff; | 1027 | struct gfs2_rgrpd *rgd; |
1028 | unsigned int journals = gfs2_jindex_size(sdp); | ||
1029 | unsigned int rg = 0, x; | ||
1765 | 1030 | ||
1766 | tdiff = ktime_to_ns(ktime_sub(ktime_get_real(), | 1031 | spin_lock(&sdp->sd_rindex_spin); |
1767 | rs->rs_rbm.rgd->rd_gl->gl_dstamp)); | ||
1768 | 1032 | ||
1769 | return tdiff > (msecs * 1000 * 1000); | 1033 | rgd = sdp->sd_rindex_forward; |
1770 | } | 1034 | if (!rgd) { |
1035 | if (sdp->sd_rgrps >= journals) | ||
1036 | rg = sdp->sd_rgrps * sdp->sd_jdesc->jd_jid / journals; | ||
1771 | 1037 | ||
1772 | static u32 gfs2_orlov_skip(const struct gfs2_inode *ip) | 1038 | for (x = 0, rgd = gfs2_rgrpd_get_first(sdp); x < rg; |
1773 | { | 1039 | x++, rgd = gfs2_rgrpd_get_next(rgd)) |
1774 | const struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 1040 | /* Do Nothing */; |
1775 | u32 skip; | 1041 | |
1042 | sdp->sd_rindex_forward = rgd; | ||
1043 | } | ||
1044 | |||
1045 | spin_unlock(&sdp->sd_rindex_spin); | ||
1776 | 1046 | ||
1777 | get_random_bytes(&skip, sizeof(skip)); | 1047 | return rgd; |
1778 | return skip % sdp->sd_rgrps; | ||
1779 | } | 1048 | } |
1780 | 1049 | ||
1781 | static bool gfs2_select_rgrp(struct gfs2_rgrpd **pos, const struct gfs2_rgrpd *begin) | 1050 | /** |
1782 | { | 1051 | * forward_rgrp_set - set the forward rgrp pointer |
1783 | struct gfs2_rgrpd *rgd = *pos; | 1052 | * @sdp: the filesystem |
1784 | struct gfs2_sbd *sdp = rgd->rd_sbd; | 1053 | * @rgd: The new forward rgrp |
1054 | * | ||
1055 | */ | ||
1785 | 1056 | ||
1786 | rgd = gfs2_rgrpd_get_next(rgd); | 1057 | static void forward_rgrp_set(struct gfs2_sbd *sdp, struct gfs2_rgrpd *rgd) |
1787 | if (rgd == NULL) | 1058 | { |
1788 | rgd = gfs2_rgrpd_get_first(sdp); | 1059 | spin_lock(&sdp->sd_rindex_spin); |
1789 | *pos = rgd; | 1060 | sdp->sd_rindex_forward = rgd; |
1790 | if (rgd != begin) /* If we didn't wrap */ | 1061 | spin_unlock(&sdp->sd_rindex_spin); |
1791 | return true; | ||
1792 | return false; | ||
1793 | } | 1062 | } |
1794 | 1063 | ||
1795 | /** | 1064 | /** |
1796 | * gfs2_inplace_reserve - Reserve space in the filesystem | 1065 | * get_local_rgrp - Choose and lock a rgrp for allocation |
1797 | * @ip: the inode to reserve space for | 1066 | * @ip: the inode to reserve space for |
1798 | * @requested: the number of blocks to be reserved | 1067 | * @rgp: the chosen and locked rgrp |
1068 | * | ||
1069 | * Try to acquire rgrp in way which avoids contending with others. | ||
1799 | * | 1070 | * |
1800 | * Returns: errno | 1071 | * Returns: errno |
1801 | */ | 1072 | */ |
1802 | 1073 | ||
1803 | int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested, u32 aflags) | 1074 | static int get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked) |
1804 | { | 1075 | { |
1805 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 1076 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
1806 | struct gfs2_rgrpd *begin = NULL; | 1077 | struct gfs2_rgrpd *rgd, *begin = NULL; |
1807 | struct gfs2_blkreserv *rs = ip->i_res; | 1078 | struct gfs2_alloc *al = ip->i_alloc; |
1808 | int error = 0, rg_locked, flags = 0; | 1079 | int flags = LM_FLAG_TRY; |
1809 | u64 last_unlinked = NO_BLOCK; | 1080 | int skipped = 0; |
1810 | int loops = 0; | 1081 | int loops = 0; |
1811 | u32 skip = 0; | 1082 | int error, rg_locked; |
1812 | 1083 | ||
1813 | if (sdp->sd_args.ar_rgrplvb) | 1084 | rgd = gfs2_blk2rgrpd(sdp, ip->i_goal); |
1814 | flags |= GL_SKIP; | 1085 | |
1815 | if (gfs2_assert_warn(sdp, requested)) | 1086 | while (rgd) { |
1816 | return -EINVAL; | 1087 | rg_locked = 0; |
1817 | if (gfs2_rs_active(rs)) { | 1088 | |
1818 | begin = rs->rs_rbm.rgd; | 1089 | if (gfs2_glock_is_locked_by_me(rgd->rd_gl)) { |
1819 | flags = 0; /* Yoda: Do or do not. There is no try */ | 1090 | rg_locked = 1; |
1820 | } else if (ip->i_rgd && rgrp_contains_block(ip->i_rgd, ip->i_goal)) { | 1091 | error = 0; |
1821 | rs->rs_rbm.rgd = begin = ip->i_rgd; | 1092 | } else { |
1822 | } else { | 1093 | error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, |
1823 | rs->rs_rbm.rgd = begin = gfs2_blk2rgrpd(sdp, ip->i_goal, 1); | 1094 | LM_FLAG_TRY, &al->al_rgd_gh); |
1824 | } | ||
1825 | if (S_ISDIR(ip->i_inode.i_mode) && (aflags & GFS2_AF_ORLOV)) | ||
1826 | skip = gfs2_orlov_skip(ip); | ||
1827 | if (rs->rs_rbm.rgd == NULL) | ||
1828 | return -EBADSLT; | ||
1829 | |||
1830 | while (loops < 3) { | ||
1831 | rg_locked = 1; | ||
1832 | |||
1833 | if (!gfs2_glock_is_locked_by_me(rs->rs_rbm.rgd->rd_gl)) { | ||
1834 | rg_locked = 0; | ||
1835 | if (skip && skip--) | ||
1836 | goto next_rgrp; | ||
1837 | if (!gfs2_rs_active(rs) && (loops < 2) && | ||
1838 | gfs2_rgrp_used_recently(rs, 1000) && | ||
1839 | gfs2_rgrp_congested(rs->rs_rbm.rgd, loops)) | ||
1840 | goto next_rgrp; | ||
1841 | error = gfs2_glock_nq_init(rs->rs_rbm.rgd->rd_gl, | ||
1842 | LM_ST_EXCLUSIVE, flags, | ||
1843 | &rs->rs_rgd_gh); | ||
1844 | if (unlikely(error)) | ||
1845 | return error; | ||
1846 | if (!gfs2_rs_active(rs) && (loops < 2) && | ||
1847 | gfs2_rgrp_congested(rs->rs_rbm.rgd, loops)) | ||
1848 | goto skip_rgrp; | ||
1849 | if (sdp->sd_args.ar_rgrplvb) { | ||
1850 | error = update_rgrp_lvb(rs->rs_rbm.rgd); | ||
1851 | if (unlikely(error)) { | ||
1852 | gfs2_glock_dq_uninit(&rs->rs_rgd_gh); | ||
1853 | return error; | ||
1854 | } | ||
1855 | } | ||
1856 | } | 1095 | } |
1096 | switch (error) { | ||
1097 | case 0: | ||
1098 | if (try_rgrp_fit(rgd, al)) | ||
1099 | goto out; | ||
1100 | if (rgd->rd_flags & GFS2_RDF_CHECK) | ||
1101 | try_rgrp_unlink(rgd, last_unlinked, ip->i_no_addr); | ||
1102 | if (!rg_locked) | ||
1103 | gfs2_glock_dq_uninit(&al->al_rgd_gh); | ||
1104 | /* fall through */ | ||
1105 | case GLR_TRYFAILED: | ||
1106 | rgd = recent_rgrp_next(rgd); | ||
1107 | break; | ||
1857 | 1108 | ||
1858 | /* Skip unuseable resource groups */ | 1109 | default: |
1859 | if (rs->rs_rbm.rgd->rd_flags & (GFS2_RGF_NOALLOC | GFS2_RDF_ERROR)) | 1110 | return error; |
1860 | goto skip_rgrp; | 1111 | } |
1112 | } | ||
1861 | 1113 | ||
1862 | if (sdp->sd_args.ar_rgrplvb) | 1114 | /* Go through full list of rgrps */ |
1863 | gfs2_rgrp_bh_get(rs->rs_rbm.rgd); | ||
1864 | 1115 | ||
1865 | /* Get a reservation if we don't already have one */ | 1116 | begin = rgd = forward_rgrp_get(sdp); |
1866 | if (!gfs2_rs_active(rs)) | ||
1867 | rg_mblk_search(rs->rs_rbm.rgd, ip, requested); | ||
1868 | 1117 | ||
1869 | /* Skip rgrps when we can't get a reservation on first pass */ | 1118 | for (;;) { |
1870 | if (!gfs2_rs_active(rs) && (loops < 1)) | 1119 | rg_locked = 0; |
1871 | goto check_rgrp; | ||
1872 | 1120 | ||
1873 | /* If rgrp has enough free space, use it */ | 1121 | if (gfs2_glock_is_locked_by_me(rgd->rd_gl)) { |
1874 | if (rs->rs_rbm.rgd->rd_free_clone >= requested) { | 1122 | rg_locked = 1; |
1875 | ip->i_rgd = rs->rs_rbm.rgd; | 1123 | error = 0; |
1876 | return 0; | 1124 | } else { |
1125 | error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, flags, | ||
1126 | &al->al_rgd_gh); | ||
1877 | } | 1127 | } |
1128 | switch (error) { | ||
1129 | case 0: | ||
1130 | if (try_rgrp_fit(rgd, al)) | ||
1131 | goto out; | ||
1132 | if (rgd->rd_flags & GFS2_RDF_CHECK) | ||
1133 | try_rgrp_unlink(rgd, last_unlinked, ip->i_no_addr); | ||
1134 | if (!rg_locked) | ||
1135 | gfs2_glock_dq_uninit(&al->al_rgd_gh); | ||
1136 | break; | ||
1878 | 1137 | ||
1879 | /* Drop reservation, if we couldn't use reserved rgrp */ | 1138 | case GLR_TRYFAILED: |
1880 | if (gfs2_rs_active(rs)) | 1139 | skipped++; |
1881 | gfs2_rs_deltree(ip, rs); | 1140 | break; |
1882 | check_rgrp: | ||
1883 | /* Check for unlinked inodes which can be reclaimed */ | ||
1884 | if (rs->rs_rbm.rgd->rd_flags & GFS2_RDF_CHECK) | ||
1885 | try_rgrp_unlink(rs->rs_rbm.rgd, &last_unlinked, | ||
1886 | ip->i_no_addr); | ||
1887 | skip_rgrp: | ||
1888 | /* Unlock rgrp if required */ | ||
1889 | if (!rg_locked) | ||
1890 | gfs2_glock_dq_uninit(&rs->rs_rgd_gh); | ||
1891 | next_rgrp: | ||
1892 | /* Find the next rgrp, and continue looking */ | ||
1893 | if (gfs2_select_rgrp(&rs->rs_rbm.rgd, begin)) | ||
1894 | continue; | ||
1895 | if (skip) | ||
1896 | continue; | ||
1897 | 1141 | ||
1898 | /* If we've scanned all the rgrps, but found no free blocks | 1142 | default: |
1899 | * then this checks for some less likely conditions before | 1143 | return error; |
1900 | * trying again. | 1144 | } |
1901 | */ | 1145 | |
1902 | loops++; | 1146 | rgd = gfs2_rgrpd_get_next(rgd); |
1903 | /* Check that fs hasn't grown if writing to rindex */ | 1147 | if (!rgd) |
1904 | if (ip == GFS2_I(sdp->sd_rindex) && !sdp->sd_rindex_uptodate) { | 1148 | rgd = gfs2_rgrpd_get_first(sdp); |
1905 | error = gfs2_ri_update(ip); | 1149 | |
1906 | if (error) | 1150 | if (rgd == begin) { |
1907 | return error; | 1151 | if (++loops >= 3) |
1152 | return -ENOSPC; | ||
1153 | if (!skipped) | ||
1154 | loops++; | ||
1155 | flags = 0; | ||
1156 | if (loops == 2) | ||
1157 | gfs2_log_flush(sdp, NULL); | ||
1908 | } | 1158 | } |
1909 | /* Flushing the log may release space */ | 1159 | } |
1910 | if (loops == 2) | 1160 | |
1161 | out: | ||
1162 | if (begin) { | ||
1163 | spin_lock(&sdp->sd_rindex_spin); | ||
1164 | list_move(&rgd->rd_list_mru, &sdp->sd_rindex_mru_list); | ||
1165 | spin_unlock(&sdp->sd_rindex_spin); | ||
1166 | rgd = gfs2_rgrpd_get_next(rgd); | ||
1167 | if (!rgd) | ||
1168 | rgd = gfs2_rgrpd_get_first(sdp); | ||
1169 | forward_rgrp_set(sdp, rgd); | ||
1170 | } | ||
1171 | |||
1172 | return 0; | ||
1173 | } | ||
1174 | |||
1175 | /** | ||
1176 | * gfs2_inplace_reserve_i - Reserve space in the filesystem | ||
1177 | * @ip: the inode to reserve space for | ||
1178 | * | ||
1179 | * Returns: errno | ||
1180 | */ | ||
1181 | |||
1182 | int gfs2_inplace_reserve_i(struct gfs2_inode *ip, int hold_rindex, | ||
1183 | char *file, unsigned int line) | ||
1184 | { | ||
1185 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | ||
1186 | struct gfs2_alloc *al = ip->i_alloc; | ||
1187 | int error = 0; | ||
1188 | u64 last_unlinked = NO_BLOCK; | ||
1189 | int tries = 0; | ||
1190 | |||
1191 | if (gfs2_assert_warn(sdp, al->al_requested)) | ||
1192 | return -EINVAL; | ||
1193 | |||
1194 | if (hold_rindex) { | ||
1195 | /* We need to hold the rindex unless the inode we're using is | ||
1196 | the rindex itself, in which case it's already held. */ | ||
1197 | if (ip != GFS2_I(sdp->sd_rindex)) | ||
1198 | error = gfs2_rindex_hold(sdp, &al->al_ri_gh); | ||
1199 | else if (!sdp->sd_rgrps) /* We may not have the rindex read | ||
1200 | in, so: */ | ||
1201 | error = gfs2_ri_update(ip); | ||
1202 | if (error) | ||
1203 | return error; | ||
1204 | } | ||
1205 | |||
1206 | try_again: | ||
1207 | do { | ||
1208 | error = get_local_rgrp(ip, &last_unlinked); | ||
1209 | /* If there is no space, flushing the log may release some */ | ||
1210 | if (error) { | ||
1211 | if (ip == GFS2_I(sdp->sd_rindex) && | ||
1212 | !sdp->sd_rindex_uptodate) { | ||
1213 | error = gfs2_ri_update(ip); | ||
1214 | if (error) | ||
1215 | return error; | ||
1216 | goto try_again; | ||
1217 | } | ||
1911 | gfs2_log_flush(sdp, NULL); | 1218 | gfs2_log_flush(sdp, NULL); |
1219 | } | ||
1220 | } while (error && tries++ < 3); | ||
1221 | |||
1222 | if (error) { | ||
1223 | if (hold_rindex && ip != GFS2_I(sdp->sd_rindex)) | ||
1224 | gfs2_glock_dq_uninit(&al->al_ri_gh); | ||
1225 | return error; | ||
1912 | } | 1226 | } |
1913 | 1227 | ||
1914 | return -ENOSPC; | 1228 | /* no error, so we have the rgrp set in the inode's allocation. */ |
1229 | al->al_file = file; | ||
1230 | al->al_line = line; | ||
1231 | |||
1232 | return 0; | ||
1915 | } | 1233 | } |
1916 | 1234 | ||
1917 | /** | 1235 | /** |
@@ -1923,10 +1241,20 @@ next_rgrp: | |||
1923 | 1241 | ||
1924 | void gfs2_inplace_release(struct gfs2_inode *ip) | 1242 | void gfs2_inplace_release(struct gfs2_inode *ip) |
1925 | { | 1243 | { |
1926 | struct gfs2_blkreserv *rs = ip->i_res; | 1244 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
1245 | struct gfs2_alloc *al = ip->i_alloc; | ||
1246 | |||
1247 | if (gfs2_assert_warn(sdp, al->al_alloced <= al->al_requested) == -1) | ||
1248 | fs_warn(sdp, "al_alloced = %u, al_requested = %u " | ||
1249 | "al_file = %s, al_line = %u\n", | ||
1250 | al->al_alloced, al->al_requested, al->al_file, | ||
1251 | al->al_line); | ||
1927 | 1252 | ||
1928 | if (rs->rs_rgd_gh.gh_gl) | 1253 | al->al_rgd = NULL; |
1929 | gfs2_glock_dq_uninit(&rs->rs_rgd_gh); | 1254 | if (al->al_rgd_gh.gh_gl) |
1255 | gfs2_glock_dq_uninit(&al->al_rgd_gh); | ||
1256 | if (ip != GFS2_I(sdp->sd_rindex) && al->al_ri_gh.gh_gl) | ||
1257 | gfs2_glock_dq_uninit(&al->al_ri_gh); | ||
1930 | } | 1258 | } |
1931 | 1259 | ||
1932 | /** | 1260 | /** |
@@ -1939,47 +1267,131 @@ void gfs2_inplace_release(struct gfs2_inode *ip) | |||
1939 | 1267 | ||
1940 | static unsigned char gfs2_get_block_type(struct gfs2_rgrpd *rgd, u64 block) | 1268 | static unsigned char gfs2_get_block_type(struct gfs2_rgrpd *rgd, u64 block) |
1941 | { | 1269 | { |
1942 | struct gfs2_rbm rbm = { .rgd = rgd, }; | 1270 | struct gfs2_bitmap *bi = NULL; |
1943 | int ret; | 1271 | u32 length, rgrp_block, buf_block; |
1272 | unsigned int buf; | ||
1273 | unsigned char type; | ||
1944 | 1274 | ||
1945 | ret = gfs2_rbm_from_block(&rbm, block); | 1275 | length = rgd->rd_length; |
1946 | WARN_ON_ONCE(ret != 0); | 1276 | rgrp_block = block - rgd->rd_data0; |
1947 | 1277 | ||
1948 | return gfs2_testbit(&rbm); | 1278 | for (buf = 0; buf < length; buf++) { |
1949 | } | 1279 | bi = rgd->rd_bits + buf; |
1280 | if (rgrp_block < (bi->bi_start + bi->bi_len) * GFS2_NBBY) | ||
1281 | break; | ||
1282 | } | ||
1950 | 1283 | ||
1284 | gfs2_assert(rgd->rd_sbd, buf < length); | ||
1285 | buf_block = rgrp_block - bi->bi_start * GFS2_NBBY; | ||
1286 | |||
1287 | type = gfs2_testbit(rgd, bi->bi_bh->b_data + bi->bi_offset, | ||
1288 | bi->bi_len, buf_block); | ||
1289 | |||
1290 | return type; | ||
1291 | } | ||
1951 | 1292 | ||
1952 | /** | 1293 | /** |
1953 | * gfs2_alloc_extent - allocate an extent from a given bitmap | 1294 | * rgblk_search - find a block in @old_state, change allocation |
1954 | * @rbm: the resource group information | 1295 | * state to @new_state |
1955 | * @dinode: TRUE if the first block we allocate is for a dinode | 1296 | * @rgd: the resource group descriptor |
1956 | * @n: The extent length (value/result) | 1297 | * @goal: the goal block within the RG (start here to search for avail block) |
1298 | * @old_state: GFS2_BLKST_XXX the before-allocation state to find | ||
1299 | * @new_state: GFS2_BLKST_XXX the after-allocation block state | ||
1300 | * @n: The extent length | ||
1957 | * | 1301 | * |
1958 | * Add the bitmap buffer to the transaction. | 1302 | * Walk rgrp's bitmap to find bits that represent a block in @old_state. |
1303 | * Add the found bitmap buffer to the transaction. | ||
1959 | * Set the found bits to @new_state to change block's allocation state. | 1304 | * Set the found bits to @new_state to change block's allocation state. |
1305 | * | ||
1306 | * This function never fails, because we wouldn't call it unless we | ||
1307 | * know (from reservation results, etc.) that a block is available. | ||
1308 | * | ||
1309 | * Scope of @goal and returned block is just within rgrp, not the whole | ||
1310 | * filesystem. | ||
1311 | * | ||
1312 | * Returns: the block number allocated | ||
1960 | */ | 1313 | */ |
1961 | static void gfs2_alloc_extent(const struct gfs2_rbm *rbm, bool dinode, | 1314 | |
1962 | unsigned int *n) | 1315 | static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal, |
1316 | unsigned char old_state, unsigned char new_state, | ||
1317 | unsigned int *n) | ||
1963 | { | 1318 | { |
1964 | struct gfs2_rbm pos = { .rgd = rbm->rgd, }; | 1319 | struct gfs2_bitmap *bi = NULL; |
1320 | const u32 length = rgd->rd_length; | ||
1321 | u32 blk = BFITNOENT; | ||
1322 | unsigned int buf, x; | ||
1965 | const unsigned int elen = *n; | 1323 | const unsigned int elen = *n; |
1966 | u64 block; | 1324 | const u8 *buffer = NULL; |
1967 | int ret; | 1325 | |
1326 | *n = 0; | ||
1327 | /* Find bitmap block that contains bits for goal block */ | ||
1328 | for (buf = 0; buf < length; buf++) { | ||
1329 | bi = rgd->rd_bits + buf; | ||
1330 | /* Convert scope of "goal" from rgrp-wide to within found bit block */ | ||
1331 | if (goal < (bi->bi_start + bi->bi_len) * GFS2_NBBY) { | ||
1332 | goal -= bi->bi_start * GFS2_NBBY; | ||
1333 | goto do_search; | ||
1334 | } | ||
1335 | } | ||
1336 | buf = 0; | ||
1337 | goal = 0; | ||
1338 | |||
1339 | do_search: | ||
1340 | /* Search (up to entire) bitmap in this rgrp for allocatable block. | ||
1341 | "x <= length", instead of "x < length", because we typically start | ||
1342 | the search in the middle of a bit block, but if we can't find an | ||
1343 | allocatable block anywhere else, we want to be able wrap around and | ||
1344 | search in the first part of our first-searched bit block. */ | ||
1345 | for (x = 0; x <= length; x++) { | ||
1346 | bi = rgd->rd_bits + buf; | ||
1347 | |||
1348 | if (test_bit(GBF_FULL, &bi->bi_flags) && | ||
1349 | (old_state == GFS2_BLKST_FREE)) | ||
1350 | goto skip; | ||
1351 | |||
1352 | /* The GFS2_BLKST_UNLINKED state doesn't apply to the clone | ||
1353 | bitmaps, so we must search the originals for that. */ | ||
1354 | buffer = bi->bi_bh->b_data + bi->bi_offset; | ||
1355 | if (old_state != GFS2_BLKST_UNLINKED && bi->bi_clone) | ||
1356 | buffer = bi->bi_clone + bi->bi_offset; | ||
1357 | |||
1358 | blk = gfs2_bitfit(buffer, bi->bi_len, goal, old_state); | ||
1359 | if (blk != BFITNOENT) | ||
1360 | break; | ||
1361 | |||
1362 | if ((goal == 0) && (old_state == GFS2_BLKST_FREE)) | ||
1363 | set_bit(GBF_FULL, &bi->bi_flags); | ||
1364 | |||
1365 | /* Try next bitmap block (wrap back to rgrp header if at end) */ | ||
1366 | skip: | ||
1367 | buf++; | ||
1368 | buf %= length; | ||
1369 | goal = 0; | ||
1370 | } | ||
1968 | 1371 | ||
1372 | if (blk == BFITNOENT) | ||
1373 | return blk; | ||
1969 | *n = 1; | 1374 | *n = 1; |
1970 | block = gfs2_rbm_to_block(rbm); | 1375 | if (old_state == new_state) |
1971 | gfs2_trans_add_bh(rbm->rgd->rd_gl, rbm->bi->bi_bh, 1); | 1376 | goto out; |
1972 | gfs2_setbit(rbm, true, dinode ? GFS2_BLKST_DINODE : GFS2_BLKST_USED); | 1377 | |
1973 | block++; | 1378 | gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1); |
1379 | gfs2_setbit(rgd, bi->bi_bh->b_data, bi->bi_clone, bi->bi_offset, | ||
1380 | bi, blk, new_state); | ||
1381 | goal = blk; | ||
1974 | while (*n < elen) { | 1382 | while (*n < elen) { |
1975 | ret = gfs2_rbm_from_block(&pos, block); | 1383 | goal++; |
1976 | if (ret || gfs2_testbit(&pos) != GFS2_BLKST_FREE) | 1384 | if (goal >= (bi->bi_len * GFS2_NBBY)) |
1385 | break; | ||
1386 | if (gfs2_testbit(rgd, buffer, bi->bi_len, goal) != | ||
1387 | GFS2_BLKST_FREE) | ||
1977 | break; | 1388 | break; |
1978 | gfs2_trans_add_bh(pos.rgd->rd_gl, pos.bi->bi_bh, 1); | 1389 | gfs2_setbit(rgd, bi->bi_bh->b_data, bi->bi_clone, bi->bi_offset, |
1979 | gfs2_setbit(&pos, true, GFS2_BLKST_USED); | 1390 | bi, goal, new_state); |
1980 | (*n)++; | 1391 | (*n)++; |
1981 | block++; | ||
1982 | } | 1392 | } |
1393 | out: | ||
1394 | return (bi->bi_start * GFS2_NBBY) + blk; | ||
1983 | } | 1395 | } |
1984 | 1396 | ||
1985 | /** | 1397 | /** |
@@ -1995,30 +1407,47 @@ static void gfs2_alloc_extent(const struct gfs2_rbm *rbm, bool dinode, | |||
1995 | static struct gfs2_rgrpd *rgblk_free(struct gfs2_sbd *sdp, u64 bstart, | 1407 | static struct gfs2_rgrpd *rgblk_free(struct gfs2_sbd *sdp, u64 bstart, |
1996 | u32 blen, unsigned char new_state) | 1408 | u32 blen, unsigned char new_state) |
1997 | { | 1409 | { |
1998 | struct gfs2_rbm rbm; | 1410 | struct gfs2_rgrpd *rgd; |
1411 | struct gfs2_bitmap *bi = NULL; | ||
1412 | u32 length, rgrp_blk, buf_blk; | ||
1413 | unsigned int buf; | ||
1999 | 1414 | ||
2000 | rbm.rgd = gfs2_blk2rgrpd(sdp, bstart, 1); | 1415 | rgd = gfs2_blk2rgrpd(sdp, bstart); |
2001 | if (!rbm.rgd) { | 1416 | if (!rgd) { |
2002 | if (gfs2_consist(sdp)) | 1417 | if (gfs2_consist(sdp)) |
2003 | fs_err(sdp, "block = %llu\n", (unsigned long long)bstart); | 1418 | fs_err(sdp, "block = %llu\n", (unsigned long long)bstart); |
2004 | return NULL; | 1419 | return NULL; |
2005 | } | 1420 | } |
2006 | 1421 | ||
1422 | length = rgd->rd_length; | ||
1423 | |||
1424 | rgrp_blk = bstart - rgd->rd_data0; | ||
1425 | |||
2007 | while (blen--) { | 1426 | while (blen--) { |
2008 | gfs2_rbm_from_block(&rbm, bstart); | 1427 | for (buf = 0; buf < length; buf++) { |
2009 | bstart++; | 1428 | bi = rgd->rd_bits + buf; |
2010 | if (!rbm.bi->bi_clone) { | 1429 | if (rgrp_blk < (bi->bi_start + bi->bi_len) * GFS2_NBBY) |
2011 | rbm.bi->bi_clone = kmalloc(rbm.bi->bi_bh->b_size, | 1430 | break; |
2012 | GFP_NOFS | __GFP_NOFAIL); | ||
2013 | memcpy(rbm.bi->bi_clone + rbm.bi->bi_offset, | ||
2014 | rbm.bi->bi_bh->b_data + rbm.bi->bi_offset, | ||
2015 | rbm.bi->bi_len); | ||
2016 | } | 1431 | } |
2017 | gfs2_trans_add_bh(rbm.rgd->rd_gl, rbm.bi->bi_bh, 1); | 1432 | |
2018 | gfs2_setbit(&rbm, false, new_state); | 1433 | gfs2_assert(rgd->rd_sbd, buf < length); |
1434 | |||
1435 | buf_blk = rgrp_blk - bi->bi_start * GFS2_NBBY; | ||
1436 | rgrp_blk++; | ||
1437 | |||
1438 | if (!bi->bi_clone) { | ||
1439 | bi->bi_clone = kmalloc(bi->bi_bh->b_size, | ||
1440 | GFP_NOFS | __GFP_NOFAIL); | ||
1441 | memcpy(bi->bi_clone + bi->bi_offset, | ||
1442 | bi->bi_bh->b_data + bi->bi_offset, | ||
1443 | bi->bi_len); | ||
1444 | } | ||
1445 | gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1); | ||
1446 | gfs2_setbit(rgd, bi->bi_bh->b_data, NULL, bi->bi_offset, | ||
1447 | bi, buf_blk, new_state); | ||
2019 | } | 1448 | } |
2020 | 1449 | ||
2021 | return rbm.rgd; | 1450 | return rgd; |
2022 | } | 1451 | } |
2023 | 1452 | ||
2024 | /** | 1453 | /** |
@@ -2030,22 +1459,12 @@ static struct gfs2_rgrpd *rgblk_free(struct gfs2_sbd *sdp, u64 bstart, | |||
2030 | 1459 | ||
2031 | int gfs2_rgrp_dump(struct seq_file *seq, const struct gfs2_glock *gl) | 1460 | int gfs2_rgrp_dump(struct seq_file *seq, const struct gfs2_glock *gl) |
2032 | { | 1461 | { |
2033 | struct gfs2_rgrpd *rgd = gl->gl_object; | 1462 | const struct gfs2_rgrpd *rgd = gl->gl_object; |
2034 | struct gfs2_blkreserv *trs; | ||
2035 | const struct rb_node *n; | ||
2036 | |||
2037 | if (rgd == NULL) | 1463 | if (rgd == NULL) |
2038 | return 0; | 1464 | return 0; |
2039 | gfs2_print_dbg(seq, " R: n:%llu f:%02x b:%u/%u i:%u r:%u\n", | 1465 | gfs2_print_dbg(seq, " R: n:%llu f:%02x b:%u/%u i:%u\n", |
2040 | (unsigned long long)rgd->rd_addr, rgd->rd_flags, | 1466 | (unsigned long long)rgd->rd_addr, rgd->rd_flags, |
2041 | rgd->rd_free, rgd->rd_free_clone, rgd->rd_dinodes, | 1467 | rgd->rd_free, rgd->rd_free_clone, rgd->rd_dinodes); |
2042 | rgd->rd_reserved); | ||
2043 | spin_lock(&rgd->rd_rsspin); | ||
2044 | for (n = rb_first(&rgd->rd_rstree); n; n = rb_next(&trs->rs_node)) { | ||
2045 | trs = rb_entry(n, struct gfs2_blkreserv, rs_node); | ||
2046 | dump_rs(seq, trs); | ||
2047 | } | ||
2048 | spin_unlock(&rgd->rd_rsspin); | ||
2049 | return 0; | 1468 | return 0; |
2050 | } | 1469 | } |
2051 | 1470 | ||
@@ -2060,146 +1479,130 @@ static void gfs2_rgrp_error(struct gfs2_rgrpd *rgd) | |||
2060 | } | 1479 | } |
2061 | 1480 | ||
2062 | /** | 1481 | /** |
2063 | * gfs2_adjust_reservation - Adjust (or remove) a reservation after allocation | 1482 | * gfs2_alloc_block - Allocate one or more blocks |
2064 | * @ip: The inode we have just allocated blocks for | ||
2065 | * @rbm: The start of the allocated blocks | ||
2066 | * @len: The extent length | ||
2067 | * | ||
2068 | * Adjusts a reservation after an allocation has taken place. If the | ||
2069 | * reservation does not match the allocation, or if it is now empty | ||
2070 | * then it is removed. | ||
2071 | */ | ||
2072 | |||
2073 | static void gfs2_adjust_reservation(struct gfs2_inode *ip, | ||
2074 | const struct gfs2_rbm *rbm, unsigned len) | ||
2075 | { | ||
2076 | struct gfs2_blkreserv *rs = ip->i_res; | ||
2077 | struct gfs2_rgrpd *rgd = rbm->rgd; | ||
2078 | unsigned rlen; | ||
2079 | u64 block; | ||
2080 | int ret; | ||
2081 | |||
2082 | spin_lock(&rgd->rd_rsspin); | ||
2083 | if (gfs2_rs_active(rs)) { | ||
2084 | if (gfs2_rbm_eq(&rs->rs_rbm, rbm)) { | ||
2085 | block = gfs2_rbm_to_block(rbm); | ||
2086 | ret = gfs2_rbm_from_block(&rs->rs_rbm, block + len); | ||
2087 | rlen = min(rs->rs_free, len); | ||
2088 | rs->rs_free -= rlen; | ||
2089 | rgd->rd_reserved -= rlen; | ||
2090 | trace_gfs2_rs(rs, TRACE_RS_CLAIM); | ||
2091 | if (rs->rs_free && !ret) | ||
2092 | goto out; | ||
2093 | } | ||
2094 | __rs_deltree(ip, rs); | ||
2095 | } | ||
2096 | out: | ||
2097 | spin_unlock(&rgd->rd_rsspin); | ||
2098 | } | ||
2099 | |||
2100 | /** | ||
2101 | * gfs2_alloc_blocks - Allocate one or more blocks of data and/or a dinode | ||
2102 | * @ip: the inode to allocate the block for | 1483 | * @ip: the inode to allocate the block for |
2103 | * @bn: Used to return the starting block number | 1484 | * @bn: Used to return the starting block number |
2104 | * @nblocks: requested number of blocks/extent length (value/result) | 1485 | * @n: requested number of blocks/extent length (value/result) |
2105 | * @dinode: 1 if we're allocating a dinode block, else 0 | ||
2106 | * @generation: the generation number of the inode | ||
2107 | * | 1486 | * |
2108 | * Returns: 0 or error | 1487 | * Returns: 0 or error |
2109 | */ | 1488 | */ |
2110 | 1489 | ||
2111 | int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *nblocks, | 1490 | int gfs2_alloc_block(struct gfs2_inode *ip, u64 *bn, unsigned int *n) |
2112 | bool dinode, u64 *generation) | ||
2113 | { | 1491 | { |
2114 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 1492 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
2115 | struct buffer_head *dibh; | 1493 | struct buffer_head *dibh; |
2116 | struct gfs2_rbm rbm = { .rgd = ip->i_rgd, }; | 1494 | struct gfs2_alloc *al = ip->i_alloc; |
2117 | unsigned int ndata; | 1495 | struct gfs2_rgrpd *rgd; |
2118 | u64 goal; | 1496 | u32 goal, blk; |
2119 | u64 block; /* block, within the file system scope */ | 1497 | u64 block; |
2120 | int error; | 1498 | int error; |
2121 | 1499 | ||
2122 | if (gfs2_rs_active(ip->i_res)) | 1500 | /* Only happens if there is a bug in gfs2, return something distinctive |
2123 | goal = gfs2_rbm_to_block(&ip->i_res->rs_rbm); | 1501 | * to ensure that it is noticed. |
2124 | else if (!dinode && rgrp_contains_block(rbm.rgd, ip->i_goal)) | 1502 | */ |
2125 | goal = ip->i_goal; | 1503 | if (al == NULL) |
2126 | else | 1504 | return -ECANCELED; |
2127 | goal = rbm.rgd->rd_last_alloc + rbm.rgd->rd_data0; | ||
2128 | 1505 | ||
2129 | gfs2_rbm_from_block(&rbm, goal); | 1506 | rgd = al->al_rgd; |
2130 | error = gfs2_rbm_find(&rbm, GFS2_BLKST_FREE, 0, ip, false); | ||
2131 | 1507 | ||
2132 | if (error == -ENOSPC) { | 1508 | if (rgrp_contains_block(rgd, ip->i_goal)) |
2133 | gfs2_rbm_from_block(&rbm, goal); | 1509 | goal = ip->i_goal - rgd->rd_data0; |
2134 | error = gfs2_rbm_find(&rbm, GFS2_BLKST_FREE, 0, NULL, false); | 1510 | else |
2135 | } | 1511 | goal = rgd->rd_last_alloc; |
1512 | |||
1513 | blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, GFS2_BLKST_USED, n); | ||
2136 | 1514 | ||
2137 | /* Since all blocks are reserved in advance, this shouldn't happen */ | 1515 | /* Since all blocks are reserved in advance, this shouldn't happen */ |
2138 | if (error) { | 1516 | if (blk == BFITNOENT) |
2139 | fs_warn(sdp, "inum=%llu error=%d, nblocks=%u, full=%d\n", | ||
2140 | (unsigned long long)ip->i_no_addr, error, *nblocks, | ||
2141 | test_bit(GBF_FULL, &rbm.rgd->rd_bits->bi_flags)); | ||
2142 | goto rgrp_error; | 1517 | goto rgrp_error; |
2143 | } | ||
2144 | 1518 | ||
2145 | gfs2_alloc_extent(&rbm, dinode, nblocks); | 1519 | rgd->rd_last_alloc = blk; |
2146 | block = gfs2_rbm_to_block(&rbm); | 1520 | block = rgd->rd_data0 + blk; |
2147 | rbm.rgd->rd_last_alloc = block - rbm.rgd->rd_data0; | 1521 | ip->i_goal = block; |
2148 | if (gfs2_rs_active(ip->i_res)) | 1522 | error = gfs2_meta_inode_buffer(ip, &dibh); |
2149 | gfs2_adjust_reservation(ip, &rbm, *nblocks); | 1523 | if (error == 0) { |
2150 | ndata = *nblocks; | 1524 | struct gfs2_dinode *di = (struct gfs2_dinode *)dibh->b_data; |
2151 | if (dinode) | 1525 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
2152 | ndata--; | 1526 | di->di_goal_meta = di->di_goal_data = cpu_to_be64(ip->i_goal); |
2153 | 1527 | brelse(dibh); | |
2154 | if (!dinode) { | ||
2155 | ip->i_goal = block + ndata - 1; | ||
2156 | error = gfs2_meta_inode_buffer(ip, &dibh); | ||
2157 | if (error == 0) { | ||
2158 | struct gfs2_dinode *di = | ||
2159 | (struct gfs2_dinode *)dibh->b_data; | ||
2160 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | ||
2161 | di->di_goal_meta = di->di_goal_data = | ||
2162 | cpu_to_be64(ip->i_goal); | ||
2163 | brelse(dibh); | ||
2164 | } | ||
2165 | } | 1528 | } |
2166 | if (rbm.rgd->rd_free < *nblocks) { | 1529 | if (rgd->rd_free < *n) |
2167 | printk(KERN_WARNING "nblocks=%u\n", *nblocks); | ||
2168 | goto rgrp_error; | 1530 | goto rgrp_error; |
2169 | } | ||
2170 | 1531 | ||
2171 | rbm.rgd->rd_free -= *nblocks; | 1532 | rgd->rd_free -= *n; |
2172 | if (dinode) { | ||
2173 | rbm.rgd->rd_dinodes++; | ||
2174 | *generation = rbm.rgd->rd_igeneration++; | ||
2175 | if (*generation == 0) | ||
2176 | *generation = rbm.rgd->rd_igeneration++; | ||
2177 | } | ||
2178 | 1533 | ||
2179 | gfs2_trans_add_bh(rbm.rgd->rd_gl, rbm.rgd->rd_bits[0].bi_bh, 1); | 1534 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); |
2180 | gfs2_rgrp_out(rbm.rgd, rbm.rgd->rd_bits[0].bi_bh->b_data); | 1535 | gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data); |
2181 | gfs2_rgrp_ondisk2lvb(rbm.rgd->rd_rgl, rbm.rgd->rd_bits[0].bi_bh->b_data); | ||
2182 | 1536 | ||
2183 | gfs2_statfs_change(sdp, 0, -(s64)*nblocks, dinode ? 1 : 0); | 1537 | al->al_alloced += *n; |
2184 | if (dinode) | ||
2185 | gfs2_trans_add_unrevoke(sdp, block, 1); | ||
2186 | 1538 | ||
2187 | /* | 1539 | gfs2_statfs_change(sdp, 0, -(s64)*n, 0); |
2188 | * This needs reviewing to see why we cannot do the quota change | 1540 | gfs2_quota_change(ip, *n, ip->i_inode.i_uid, ip->i_inode.i_gid); |
2189 | * at this point in the dinode case. | 1541 | |
2190 | */ | 1542 | spin_lock(&sdp->sd_rindex_spin); |
2191 | if (ndata) | 1543 | rgd->rd_free_clone -= *n; |
2192 | gfs2_quota_change(ip, ndata, ip->i_inode.i_uid, | 1544 | spin_unlock(&sdp->sd_rindex_spin); |
2193 | ip->i_inode.i_gid); | 1545 | trace_gfs2_block_alloc(ip, block, *n, GFS2_BLKST_USED); |
1546 | *bn = block; | ||
1547 | return 0; | ||
1548 | |||
1549 | rgrp_error: | ||
1550 | gfs2_rgrp_error(rgd); | ||
1551 | return -EIO; | ||
1552 | } | ||
1553 | |||
1554 | /** | ||
1555 | * gfs2_alloc_di - Allocate a dinode | ||
1556 | * @dip: the directory that the inode is going in | ||
1557 | * @bn: the block number which is allocated | ||
1558 | * @generation: the generation number of the inode | ||
1559 | * | ||
1560 | * Returns: 0 on success or error | ||
1561 | */ | ||
1562 | |||
1563 | int gfs2_alloc_di(struct gfs2_inode *dip, u64 *bn, u64 *generation) | ||
1564 | { | ||
1565 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | ||
1566 | struct gfs2_alloc *al = dip->i_alloc; | ||
1567 | struct gfs2_rgrpd *rgd = al->al_rgd; | ||
1568 | u32 blk; | ||
1569 | u64 block; | ||
1570 | unsigned int n = 1; | ||
1571 | |||
1572 | blk = rgblk_search(rgd, rgd->rd_last_alloc, | ||
1573 | GFS2_BLKST_FREE, GFS2_BLKST_DINODE, &n); | ||
1574 | |||
1575 | /* Since all blocks are reserved in advance, this shouldn't happen */ | ||
1576 | if (blk == BFITNOENT) | ||
1577 | goto rgrp_error; | ||
1578 | |||
1579 | rgd->rd_last_alloc = blk; | ||
1580 | block = rgd->rd_data0 + blk; | ||
1581 | if (rgd->rd_free == 0) | ||
1582 | goto rgrp_error; | ||
1583 | |||
1584 | rgd->rd_free--; | ||
1585 | rgd->rd_dinodes++; | ||
1586 | *generation = rgd->rd_igeneration++; | ||
1587 | if (*generation == 0) | ||
1588 | *generation = rgd->rd_igeneration++; | ||
1589 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); | ||
1590 | gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data); | ||
1591 | |||
1592 | al->al_alloced++; | ||
2194 | 1593 | ||
2195 | rbm.rgd->rd_free_clone -= *nblocks; | 1594 | gfs2_statfs_change(sdp, 0, -1, +1); |
2196 | trace_gfs2_block_alloc(ip, rbm.rgd, block, *nblocks, | 1595 | gfs2_trans_add_unrevoke(sdp, block, 1); |
2197 | dinode ? GFS2_BLKST_DINODE : GFS2_BLKST_USED); | 1596 | |
1597 | spin_lock(&sdp->sd_rindex_spin); | ||
1598 | rgd->rd_free_clone--; | ||
1599 | spin_unlock(&sdp->sd_rindex_spin); | ||
1600 | trace_gfs2_block_alloc(dip, block, 1, GFS2_BLKST_DINODE); | ||
2198 | *bn = block; | 1601 | *bn = block; |
2199 | return 0; | 1602 | return 0; |
2200 | 1603 | ||
2201 | rgrp_error: | 1604 | rgrp_error: |
2202 | gfs2_rgrp_error(rbm.rgd); | 1605 | gfs2_rgrp_error(rgd); |
2203 | return -EIO; | 1606 | return -EIO; |
2204 | } | 1607 | } |
2205 | 1608 | ||
@@ -2220,12 +1623,13 @@ void __gfs2_free_blocks(struct gfs2_inode *ip, u64 bstart, u32 blen, int meta) | |||
2220 | rgd = rgblk_free(sdp, bstart, blen, GFS2_BLKST_FREE); | 1623 | rgd = rgblk_free(sdp, bstart, blen, GFS2_BLKST_FREE); |
2221 | if (!rgd) | 1624 | if (!rgd) |
2222 | return; | 1625 | return; |
2223 | trace_gfs2_block_alloc(ip, rgd, bstart, blen, GFS2_BLKST_FREE); | 1626 | trace_gfs2_block_alloc(ip, bstart, blen, GFS2_BLKST_FREE); |
2224 | rgd->rd_free += blen; | 1627 | rgd->rd_free += blen; |
2225 | rgd->rd_flags &= ~GFS2_RGF_TRIMMED; | 1628 | |
2226 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); | 1629 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); |
2227 | gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data); | 1630 | gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data); |
2228 | gfs2_rgrp_ondisk2lvb(rgd->rd_rgl, rgd->rd_bits[0].bi_bh->b_data); | 1631 | |
1632 | gfs2_trans_add_rg(rgd); | ||
2229 | 1633 | ||
2230 | /* Directories keep their data in the metadata address space */ | 1634 | /* Directories keep their data in the metadata address space */ |
2231 | if (meta || ip->i_depth) | 1635 | if (meta || ip->i_depth) |
@@ -2259,11 +1663,10 @@ void gfs2_unlink_di(struct inode *inode) | |||
2259 | rgd = rgblk_free(sdp, blkno, 1, GFS2_BLKST_UNLINKED); | 1663 | rgd = rgblk_free(sdp, blkno, 1, GFS2_BLKST_UNLINKED); |
2260 | if (!rgd) | 1664 | if (!rgd) |
2261 | return; | 1665 | return; |
2262 | trace_gfs2_block_alloc(ip, rgd, blkno, 1, GFS2_BLKST_UNLINKED); | 1666 | trace_gfs2_block_alloc(ip, blkno, 1, GFS2_BLKST_UNLINKED); |
2263 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); | 1667 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); |
2264 | gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data); | 1668 | gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data); |
2265 | gfs2_rgrp_ondisk2lvb(rgd->rd_rgl, rgd->rd_bits[0].bi_bh->b_data); | 1669 | gfs2_trans_add_rg(rgd); |
2266 | update_rgrp_lvb_unlinked(rgd, 1); | ||
2267 | } | 1670 | } |
2268 | 1671 | ||
2269 | static void gfs2_free_uninit_di(struct gfs2_rgrpd *rgd, u64 blkno) | 1672 | static void gfs2_free_uninit_di(struct gfs2_rgrpd *rgd, u64 blkno) |
@@ -2283,17 +1686,16 @@ static void gfs2_free_uninit_di(struct gfs2_rgrpd *rgd, u64 blkno) | |||
2283 | 1686 | ||
2284 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); | 1687 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); |
2285 | gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data); | 1688 | gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data); |
2286 | gfs2_rgrp_ondisk2lvb(rgd->rd_rgl, rgd->rd_bits[0].bi_bh->b_data); | ||
2287 | update_rgrp_lvb_unlinked(rgd, -1); | ||
2288 | 1689 | ||
2289 | gfs2_statfs_change(sdp, 0, +1, -1); | 1690 | gfs2_statfs_change(sdp, 0, +1, -1); |
1691 | gfs2_trans_add_rg(rgd); | ||
2290 | } | 1692 | } |
2291 | 1693 | ||
2292 | 1694 | ||
2293 | void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip) | 1695 | void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip) |
2294 | { | 1696 | { |
2295 | gfs2_free_uninit_di(rgd, ip->i_no_addr); | 1697 | gfs2_free_uninit_di(rgd, ip->i_no_addr); |
2296 | trace_gfs2_block_alloc(ip, rgd, ip->i_no_addr, 1, GFS2_BLKST_FREE); | 1698 | trace_gfs2_block_alloc(ip, ip->i_no_addr, 1, GFS2_BLKST_FREE); |
2297 | gfs2_quota_change(ip, -1, ip->i_inode.i_uid, ip->i_inode.i_gid); | 1699 | gfs2_quota_change(ip, -1, ip->i_inode.i_uid, ip->i_inode.i_gid); |
2298 | gfs2_meta_wipe(ip, ip->i_no_addr, 1); | 1700 | gfs2_meta_wipe(ip, ip->i_no_addr, 1); |
2299 | } | 1701 | } |
@@ -2312,28 +1714,41 @@ void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip) | |||
2312 | int gfs2_check_blk_type(struct gfs2_sbd *sdp, u64 no_addr, unsigned int type) | 1714 | int gfs2_check_blk_type(struct gfs2_sbd *sdp, u64 no_addr, unsigned int type) |
2313 | { | 1715 | { |
2314 | struct gfs2_rgrpd *rgd; | 1716 | struct gfs2_rgrpd *rgd; |
2315 | struct gfs2_holder rgd_gh; | 1717 | struct gfs2_holder ri_gh, rgd_gh; |
2316 | int error = -EINVAL; | 1718 | struct gfs2_inode *ip = GFS2_I(sdp->sd_rindex); |
1719 | int ri_locked = 0; | ||
1720 | int error; | ||
1721 | |||
1722 | if (!gfs2_glock_is_locked_by_me(ip->i_gl)) { | ||
1723 | error = gfs2_rindex_hold(sdp, &ri_gh); | ||
1724 | if (error) | ||
1725 | goto fail; | ||
1726 | ri_locked = 1; | ||
1727 | } | ||
2317 | 1728 | ||
2318 | rgd = gfs2_blk2rgrpd(sdp, no_addr, 1); | 1729 | error = -EINVAL; |
1730 | rgd = gfs2_blk2rgrpd(sdp, no_addr); | ||
2319 | if (!rgd) | 1731 | if (!rgd) |
2320 | goto fail; | 1732 | goto fail_rindex; |
2321 | 1733 | ||
2322 | error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_SHARED, 0, &rgd_gh); | 1734 | error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_SHARED, 0, &rgd_gh); |
2323 | if (error) | 1735 | if (error) |
2324 | goto fail; | 1736 | goto fail_rindex; |
2325 | 1737 | ||
2326 | if (gfs2_get_block_type(rgd, no_addr) != type) | 1738 | if (gfs2_get_block_type(rgd, no_addr) != type) |
2327 | error = -ESTALE; | 1739 | error = -ESTALE; |
2328 | 1740 | ||
2329 | gfs2_glock_dq_uninit(&rgd_gh); | 1741 | gfs2_glock_dq_uninit(&rgd_gh); |
1742 | fail_rindex: | ||
1743 | if (ri_locked) | ||
1744 | gfs2_glock_dq_uninit(&ri_gh); | ||
2330 | fail: | 1745 | fail: |
2331 | return error; | 1746 | return error; |
2332 | } | 1747 | } |
2333 | 1748 | ||
2334 | /** | 1749 | /** |
2335 | * gfs2_rlist_add - add a RG to a list of RGs | 1750 | * gfs2_rlist_add - add a RG to a list of RGs |
2336 | * @ip: the inode | 1751 | * @sdp: the filesystem |
2337 | * @rlist: the list of resource groups | 1752 | * @rlist: the list of resource groups |
2338 | * @block: the block | 1753 | * @block: the block |
2339 | * | 1754 | * |
@@ -2343,10 +1758,9 @@ fail: | |||
2343 | * | 1758 | * |
2344 | */ | 1759 | */ |
2345 | 1760 | ||
2346 | void gfs2_rlist_add(struct gfs2_inode *ip, struct gfs2_rgrp_list *rlist, | 1761 | void gfs2_rlist_add(struct gfs2_sbd *sdp, struct gfs2_rgrp_list *rlist, |
2347 | u64 block) | 1762 | u64 block) |
2348 | { | 1763 | { |
2349 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | ||
2350 | struct gfs2_rgrpd *rgd; | 1764 | struct gfs2_rgrpd *rgd; |
2351 | struct gfs2_rgrpd **tmp; | 1765 | struct gfs2_rgrpd **tmp; |
2352 | unsigned int new_space; | 1766 | unsigned int new_space; |
@@ -2355,15 +1769,12 @@ void gfs2_rlist_add(struct gfs2_inode *ip, struct gfs2_rgrp_list *rlist, | |||
2355 | if (gfs2_assert_warn(sdp, !rlist->rl_ghs)) | 1769 | if (gfs2_assert_warn(sdp, !rlist->rl_ghs)) |
2356 | return; | 1770 | return; |
2357 | 1771 | ||
2358 | if (ip->i_rgd && rgrp_contains_block(ip->i_rgd, block)) | 1772 | rgd = gfs2_blk2rgrpd(sdp, block); |
2359 | rgd = ip->i_rgd; | ||
2360 | else | ||
2361 | rgd = gfs2_blk2rgrpd(sdp, block, 1); | ||
2362 | if (!rgd) { | 1773 | if (!rgd) { |
2363 | fs_err(sdp, "rlist_add: no rgrp for block %llu\n", (unsigned long long)block); | 1774 | if (gfs2_consist(sdp)) |
1775 | fs_err(sdp, "block = %llu\n", (unsigned long long)block); | ||
2364 | return; | 1776 | return; |
2365 | } | 1777 | } |
2366 | ip->i_rgd = rgd; | ||
2367 | 1778 | ||
2368 | for (x = 0; x < rlist->rl_rgrps; x++) | 1779 | for (x = 0; x < rlist->rl_rgrps; x++) |
2369 | if (rlist->rl_rgd[x] == rgd) | 1780 | if (rlist->rl_rgd[x] == rgd) |
@@ -2393,6 +1804,7 @@ void gfs2_rlist_add(struct gfs2_inode *ip, struct gfs2_rgrp_list *rlist, | |||
2393 | * and initialize an array of glock holders for them | 1804 | * and initialize an array of glock holders for them |
2394 | * @rlist: the list of resource groups | 1805 | * @rlist: the list of resource groups |
2395 | * @state: the lock state to acquire the RG lock in | 1806 | * @state: the lock state to acquire the RG lock in |
1807 | * @flags: the modifier flags for the holder structures | ||
2396 | * | 1808 | * |
2397 | * FIXME: Don't use NOFAIL | 1809 | * FIXME: Don't use NOFAIL |
2398 | * | 1810 | * |
@@ -2426,7 +1838,6 @@ void gfs2_rlist_free(struct gfs2_rgrp_list *rlist) | |||
2426 | for (x = 0; x < rlist->rl_rgrps; x++) | 1838 | for (x = 0; x < rlist->rl_rgrps; x++) |
2427 | gfs2_holder_uninit(&rlist->rl_ghs[x]); | 1839 | gfs2_holder_uninit(&rlist->rl_ghs[x]); |
2428 | kfree(rlist->rl_ghs); | 1840 | kfree(rlist->rl_ghs); |
2429 | rlist->rl_ghs = NULL; | ||
2430 | } | 1841 | } |
2431 | } | 1842 | } |
2432 | 1843 | ||