1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Copyright (c) 2000-2005 Silicon Graphics, Inc. |
4 | * All Rights Reserved. |
5 | */ |
6 | #include "xfs.h" |
7 | #include "xfs_fs.h" |
8 | #include "xfs_shared.h" |
9 | #include "xfs_format.h" |
10 | #include "xfs_log_format.h" |
11 | #include "xfs_trans_resv.h" |
12 | #include "xfs_bit.h" |
13 | #include "xfs_mount.h" |
14 | #include "xfs_inode.h" |
15 | #include "xfs_bmap.h" |
16 | #include "xfs_bmap_btree.h" |
17 | #include "xfs_bmap_util.h" |
18 | #include "xfs_trans.h" |
19 | #include "xfs_trans_space.h" |
20 | #include "xfs_icache.h" |
21 | #include "xfs_rtalloc.h" |
22 | #include "xfs_sb.h" |
23 | #include "xfs_rtbitmap.h" |
24 | #include "xfs_quota.h" |
25 | #include "xfs_log_priv.h" |
26 | #include "xfs_health.h" |
27 | |
28 | /* |
29 | * Return whether there are any free extents in the size range given |
30 | * by low and high, for the bitmap block bbno. |
31 | */ |
32 | STATIC int |
33 | xfs_rtany_summary( |
34 | struct xfs_rtalloc_args *args, |
35 | int low, /* low log2 extent size */ |
36 | int high, /* high log2 extent size */ |
37 | xfs_fileoff_t bbno, /* bitmap block number */ |
38 | int *maxlog) /* out: max log2 extent size free */ |
39 | { |
40 | struct xfs_mount *mp = args->mp; |
41 | int error; |
42 | int log; /* loop counter, log2 of ext. size */ |
43 | xfs_suminfo_t sum; /* summary data */ |
44 | |
45 | /* There are no extents at levels >= m_rsum_cache[bbno]. */ |
46 | if (mp->m_rsum_cache) { |
47 | high = min(high, mp->m_rsum_cache[bbno] - 1); |
48 | if (low > high) { |
49 | *maxlog = -1; |
50 | return 0; |
51 | } |
52 | } |
53 | |
54 | /* |
55 | * Loop over logs of extent sizes. |
56 | */ |
57 | for (log = high; log >= low; log--) { |
58 | /* |
59 | * Get one summary datum. |
60 | */ |
61 | error = xfs_rtget_summary(args, log, bbno, &sum); |
62 | if (error) { |
63 | return error; |
64 | } |
65 | /* |
66 | * If there are any, return success. |
67 | */ |
68 | if (sum) { |
69 | *maxlog = log; |
70 | goto out; |
71 | } |
72 | } |
73 | /* |
74 | * Found nothing, return failure. |
75 | */ |
76 | *maxlog = -1; |
77 | out: |
78 | /* There were no extents at levels > log. */ |
79 | if (mp->m_rsum_cache && log + 1 < mp->m_rsum_cache[bbno]) |
80 | mp->m_rsum_cache[bbno] = log + 1; |
81 | return 0; |
82 | } |
83 | |
84 | |
85 | /* |
86 | * Copy and transform the summary file, given the old and new |
87 | * parameters in the mount structures. |
88 | */ |
89 | STATIC int |
90 | xfs_rtcopy_summary( |
91 | struct xfs_rtalloc_args *oargs, |
92 | struct xfs_rtalloc_args *nargs) |
93 | { |
94 | xfs_fileoff_t bbno; /* bitmap block number */ |
95 | int error; |
96 | int log; /* summary level number (log length) */ |
97 | xfs_suminfo_t sum; /* summary data */ |
98 | |
99 | for (log = oargs->mp->m_rsumlevels - 1; log >= 0; log--) { |
100 | for (bbno = oargs->mp->m_sb.sb_rbmblocks - 1; |
101 | (xfs_srtblock_t)bbno >= 0; |
102 | bbno--) { |
103 | error = xfs_rtget_summary(oargs, log, bbno, &sum); |
104 | if (error) |
105 | goto out; |
106 | if (sum == 0) |
107 | continue; |
108 | error = xfs_rtmodify_summary(oargs, log, bbno, -sum); |
109 | if (error) |
110 | goto out; |
111 | error = xfs_rtmodify_summary(nargs, log, bbno, sum); |
112 | if (error) |
113 | goto out; |
114 | ASSERT(sum > 0); |
115 | } |
116 | } |
117 | error = 0; |
118 | out: |
119 | xfs_rtbuf_cache_relse(oargs); |
120 | return 0; |
121 | } |
122 | /* |
123 | * Mark an extent specified by start and len allocated. |
124 | * Updates all the summary information as well as the bitmap. |
125 | */ |
126 | STATIC int |
127 | xfs_rtallocate_range( |
128 | struct xfs_rtalloc_args *args, |
129 | xfs_rtxnum_t start, /* start rtext to allocate */ |
130 | xfs_rtxlen_t len) /* in/out: summary block number */ |
131 | { |
132 | struct xfs_mount *mp = args->mp; |
133 | xfs_rtxnum_t end; /* end of the allocated rtext */ |
134 | int error; |
135 | xfs_rtxnum_t postblock = 0; /* first rtext allocated > end */ |
136 | xfs_rtxnum_t preblock = 0; /* first rtext allocated < start */ |
137 | |
138 | end = start + len - 1; |
139 | /* |
140 | * Assume we're allocating out of the middle of a free extent. |
141 | * We need to find the beginning and end of the extent so we can |
142 | * properly update the summary. |
143 | */ |
144 | error = xfs_rtfind_back(args, start, 0, &preblock); |
145 | if (error) |
146 | return error; |
147 | |
148 | /* |
149 | * Find the next allocated block (end of free extent). |
150 | */ |
151 | error = xfs_rtfind_forw(args, end, mp->m_sb.sb_rextents - 1, |
152 | &postblock); |
153 | if (error) |
154 | return error; |
155 | |
156 | /* |
157 | * Decrement the summary information corresponding to the entire |
158 | * (old) free extent. |
159 | */ |
160 | error = xfs_rtmodify_summary(args, |
161 | xfs_highbit64(postblock + 1 - preblock), |
162 | xfs_rtx_to_rbmblock(mp, preblock), -1); |
163 | if (error) |
164 | return error; |
165 | |
166 | /* |
167 | * If there are blocks not being allocated at the front of the |
168 | * old extent, add summary data for them to be free. |
169 | */ |
170 | if (preblock < start) { |
171 | error = xfs_rtmodify_summary(args, |
172 | xfs_highbit64(start - preblock), |
173 | xfs_rtx_to_rbmblock(mp, preblock), 1); |
174 | if (error) |
175 | return error; |
176 | } |
177 | |
178 | /* |
179 | * If there are blocks not being allocated at the end of the |
180 | * old extent, add summary data for them to be free. |
181 | */ |
182 | if (postblock > end) { |
183 | error = xfs_rtmodify_summary(args, |
184 | xfs_highbit64(postblock - end), |
185 | xfs_rtx_to_rbmblock(mp, end + 1), 1); |
186 | if (error) |
187 | return error; |
188 | } |
189 | |
190 | /* |
191 | * Modify the bitmap to mark this extent allocated. |
192 | */ |
193 | return xfs_rtmodify_range(args, start, len, 0); |
194 | } |
195 | |
196 | /* |
197 | * Make sure we don't run off the end of the rt volume. Be careful that |
198 | * adjusting maxlen downwards doesn't cause us to fail the alignment checks. |
199 | */ |
200 | static inline xfs_rtxlen_t |
201 | xfs_rtallocate_clamp_len( |
202 | struct xfs_mount *mp, |
203 | xfs_rtxnum_t startrtx, |
204 | xfs_rtxlen_t rtxlen, |
205 | xfs_rtxlen_t prod) |
206 | { |
207 | xfs_rtxlen_t ret; |
208 | |
209 | ret = min(mp->m_sb.sb_rextents, startrtx + rtxlen) - startrtx; |
210 | return rounddown(ret, prod); |
211 | } |
212 | |
213 | /* |
214 | * Attempt to allocate an extent minlen<=len<=maxlen starting from |
215 | * bitmap block bbno. If we don't get maxlen then use prod to trim |
216 | * the length, if given. Returns error; returns starting block in *rtx. |
217 | * The lengths are all in rtextents. |
218 | */ |
219 | STATIC int |
220 | xfs_rtallocate_extent_block( |
221 | struct xfs_rtalloc_args *args, |
222 | xfs_fileoff_t bbno, /* bitmap block number */ |
223 | xfs_rtxlen_t minlen, /* minimum length to allocate */ |
224 | xfs_rtxlen_t maxlen, /* maximum length to allocate */ |
225 | xfs_rtxlen_t *len, /* out: actual length allocated */ |
226 | xfs_rtxnum_t *nextp, /* out: next rtext to try */ |
227 | xfs_rtxlen_t prod, /* extent product factor */ |
228 | xfs_rtxnum_t *rtx) /* out: start rtext allocated */ |
229 | { |
230 | struct xfs_mount *mp = args->mp; |
231 | xfs_rtxnum_t besti; /* best rtext found so far */ |
232 | xfs_rtxnum_t bestlen;/* best length found so far */ |
233 | xfs_rtxnum_t end; /* last rtext in chunk */ |
234 | int error; |
235 | xfs_rtxnum_t i; /* current rtext trying */ |
236 | xfs_rtxnum_t next; /* next rtext to try */ |
237 | int stat; /* status from internal calls */ |
238 | |
239 | /* |
240 | * Loop over all the extents starting in this bitmap block, |
241 | * looking for one that's long enough. |
242 | */ |
243 | for (i = xfs_rbmblock_to_rtx(mp, bbno), besti = -1, bestlen = 0, |
244 | end = xfs_rbmblock_to_rtx(mp, bbno + 1) - 1; |
245 | i <= end; |
246 | i++) { |
247 | /* Make sure we don't scan off the end of the rt volume. */ |
248 | maxlen = xfs_rtallocate_clamp_len(mp, i, maxlen, prod); |
249 | |
250 | /* |
251 | * See if there's a free extent of maxlen starting at i. |
252 | * If it's not so then next will contain the first non-free. |
253 | */ |
254 | error = xfs_rtcheck_range(args, i, maxlen, 1, &next, &stat); |
255 | if (error) |
256 | return error; |
257 | if (stat) { |
258 | /* |
259 | * i for maxlen is all free, allocate and return that. |
260 | */ |
261 | bestlen = maxlen; |
262 | besti = i; |
263 | goto allocate; |
264 | } |
265 | |
266 | /* |
267 | * In the case where we have a variable-sized allocation |
268 | * request, figure out how big this free piece is, |
269 | * and if it's big enough for the minimum, and the best |
270 | * so far, remember it. |
271 | */ |
272 | if (minlen < maxlen) { |
273 | xfs_rtxnum_t thislen; /* this extent size */ |
274 | |
275 | thislen = next - i; |
276 | if (thislen >= minlen && thislen > bestlen) { |
277 | besti = i; |
278 | bestlen = thislen; |
279 | } |
280 | } |
281 | /* |
282 | * If not done yet, find the start of the next free space. |
283 | */ |
284 | if (next >= end) |
285 | break; |
286 | error = xfs_rtfind_forw(args, next, end, &i); |
287 | if (error) |
288 | return error; |
289 | } |
290 | |
291 | /* |
292 | * Searched the whole thing & didn't find a maxlen free extent. |
293 | */ |
294 | if (minlen > maxlen || besti == -1) { |
295 | /* |
296 | * Allocation failed. Set *nextp to the next block to try. |
297 | */ |
298 | *nextp = next; |
299 | return -ENOSPC; |
300 | } |
301 | |
302 | /* |
303 | * If size should be a multiple of prod, make that so. |
304 | */ |
305 | if (prod > 1) { |
306 | xfs_rtxlen_t p; /* amount to trim length by */ |
307 | |
308 | div_u64_rem(bestlen, prod, &p); |
309 | if (p) |
310 | bestlen -= p; |
311 | } |
312 | |
313 | /* |
314 | * Allocate besti for bestlen & return that. |
315 | */ |
316 | allocate: |
317 | error = xfs_rtallocate_range(args, besti, bestlen); |
318 | if (error) |
319 | return error; |
320 | *len = bestlen; |
321 | *rtx = besti; |
322 | return 0; |
323 | } |
324 | |
325 | /* |
326 | * Allocate an extent of length minlen<=len<=maxlen, starting at block |
327 | * bno. If we don't get maxlen then use prod to trim the length, if given. |
328 | * Returns error; returns starting block in *rtx. |
329 | * The lengths are all in rtextents. |
330 | */ |
331 | STATIC int |
332 | xfs_rtallocate_extent_exact( |
333 | struct xfs_rtalloc_args *args, |
334 | xfs_rtxnum_t start, /* starting rtext number to allocate */ |
335 | xfs_rtxlen_t minlen, /* minimum length to allocate */ |
336 | xfs_rtxlen_t maxlen, /* maximum length to allocate */ |
337 | xfs_rtxlen_t *len, /* out: actual length allocated */ |
338 | xfs_rtxlen_t prod, /* extent product factor */ |
339 | xfs_rtxnum_t *rtx) /* out: start rtext allocated */ |
340 | { |
341 | int error; |
342 | xfs_rtxlen_t i; /* extent length trimmed due to prod */ |
343 | int isfree; /* extent is free */ |
344 | xfs_rtxnum_t next; /* next rtext to try (dummy) */ |
345 | |
346 | ASSERT(minlen % prod == 0); |
347 | ASSERT(maxlen % prod == 0); |
348 | /* |
349 | * Check if the range in question (for maxlen) is free. |
350 | */ |
351 | error = xfs_rtcheck_range(args, start, maxlen, 1, &next, &isfree); |
352 | if (error) |
353 | return error; |
354 | |
355 | if (!isfree) { |
356 | /* |
357 | * If not, allocate what there is, if it's at least minlen. |
358 | */ |
359 | maxlen = next - start; |
360 | if (maxlen < minlen) |
361 | return -ENOSPC; |
362 | |
363 | /* |
364 | * Trim off tail of extent, if prod is specified. |
365 | */ |
366 | if (prod > 1 && (i = maxlen % prod)) { |
367 | maxlen -= i; |
368 | if (maxlen < minlen) |
369 | return -ENOSPC; |
370 | } |
371 | } |
372 | |
373 | /* |
374 | * Allocate what we can and return it. |
375 | */ |
376 | error = xfs_rtallocate_range(args, start, maxlen); |
377 | if (error) |
378 | return error; |
379 | *len = maxlen; |
380 | *rtx = start; |
381 | return 0; |
382 | } |
383 | |
384 | /* |
385 | * Allocate an extent of length minlen<=len<=maxlen, starting as near |
386 | * to start as possible. If we don't get maxlen then use prod to trim |
387 | * the length, if given. The lengths are all in rtextents. |
388 | */ |
389 | STATIC int |
390 | xfs_rtallocate_extent_near( |
391 | struct xfs_rtalloc_args *args, |
392 | xfs_rtxnum_t start, /* starting rtext number to allocate */ |
393 | xfs_rtxlen_t minlen, /* minimum length to allocate */ |
394 | xfs_rtxlen_t maxlen, /* maximum length to allocate */ |
395 | xfs_rtxlen_t *len, /* out: actual length allocated */ |
396 | xfs_rtxlen_t prod, /* extent product factor */ |
397 | xfs_rtxnum_t *rtx) /* out: start rtext allocated */ |
398 | { |
399 | struct xfs_mount *mp = args->mp; |
400 | int maxlog; /* max useful extent from summary */ |
401 | xfs_fileoff_t bbno; /* bitmap block number */ |
402 | int error; |
403 | int i; /* bitmap block offset (loop control) */ |
404 | int j; /* secondary loop control */ |
405 | int log2len; /* log2 of minlen */ |
406 | xfs_rtxnum_t n; /* next rtext to try */ |
407 | |
408 | ASSERT(minlen % prod == 0); |
409 | ASSERT(maxlen % prod == 0); |
410 | |
411 | /* |
412 | * If the block number given is off the end, silently set it to |
413 | * the last block. |
414 | */ |
415 | if (start >= mp->m_sb.sb_rextents) |
416 | start = mp->m_sb.sb_rextents - 1; |
417 | |
418 | /* Make sure we don't run off the end of the rt volume. */ |
419 | maxlen = xfs_rtallocate_clamp_len(mp, start, maxlen, prod); |
420 | if (maxlen < minlen) |
421 | return -ENOSPC; |
422 | |
423 | /* |
424 | * Try the exact allocation first. |
425 | */ |
426 | error = xfs_rtallocate_extent_exact(args, start, minlen, maxlen, len, |
427 | prod, rtx); |
428 | if (error != -ENOSPC) |
429 | return error; |
430 | |
431 | |
432 | bbno = xfs_rtx_to_rbmblock(mp, start); |
433 | i = 0; |
434 | j = -1; |
435 | ASSERT(minlen != 0); |
436 | log2len = xfs_highbit32(minlen); |
437 | /* |
438 | * Loop over all bitmap blocks (bbno + i is current block). |
439 | */ |
440 | for (;;) { |
441 | /* |
442 | * Get summary information of extents of all useful levels |
443 | * starting in this bitmap block. |
444 | */ |
445 | error = xfs_rtany_summary(args, log2len, mp->m_rsumlevels - 1, |
446 | bbno + i, &maxlog); |
447 | if (error) |
448 | return error; |
449 | |
450 | /* |
451 | * If there are any useful extents starting here, try |
452 | * allocating one. |
453 | */ |
454 | if (maxlog >= 0) { |
455 | xfs_extlen_t maxavail = |
456 | min_t(xfs_rtblock_t, maxlen, |
457 | (1ULL << (maxlog + 1)) - 1); |
458 | /* |
459 | * On the positive side of the starting location. |
460 | */ |
461 | if (i >= 0) { |
462 | /* |
463 | * Try to allocate an extent starting in |
464 | * this block. |
465 | */ |
466 | error = xfs_rtallocate_extent_block(args, |
467 | bbno + i, minlen, maxavail, len, |
468 | &n, prod, rtx); |
469 | if (error != -ENOSPC) |
470 | return error; |
471 | } |
472 | /* |
473 | * On the negative side of the starting location. |
474 | */ |
475 | else { /* i < 0 */ |
476 | int maxblocks; |
477 | |
478 | /* |
479 | * Loop backwards to find the end of the extent |
480 | * we found in the realtime summary. |
481 | * |
482 | * maxblocks is the maximum possible number of |
483 | * bitmap blocks from the start of the extent |
484 | * to the end of the extent. |
485 | */ |
486 | if (maxlog == 0) |
487 | maxblocks = 0; |
488 | else if (maxlog < mp->m_blkbit_log) |
489 | maxblocks = 1; |
490 | else |
491 | maxblocks = 2 << (maxlog - mp->m_blkbit_log); |
492 | |
493 | /* |
494 | * We need to check bbno + i + maxblocks down to |
495 | * bbno + i. We already checked bbno down to |
496 | * bbno + j + 1, so we don't need to check those |
497 | * again. |
498 | */ |
499 | j = min(i + maxblocks, j); |
500 | for (; j >= i; j--) { |
501 | error = xfs_rtallocate_extent_block(args, |
502 | bbno + j, minlen, |
503 | maxavail, len, &n, prod, |
504 | rtx); |
505 | if (error != -ENOSPC) |
506 | return error; |
507 | } |
508 | } |
509 | } |
510 | /* |
511 | * Loop control. If we were on the positive side, and there's |
512 | * still more blocks on the negative side, go there. |
513 | */ |
514 | if (i > 0 && (int)bbno - i >= 0) |
515 | i = -i; |
516 | /* |
517 | * If positive, and no more negative, but there are more |
518 | * positive, go there. |
519 | */ |
520 | else if (i > 0 && (int)bbno + i < mp->m_sb.sb_rbmblocks - 1) |
521 | i++; |
522 | /* |
523 | * If negative or 0 (just started), and there are positive |
524 | * blocks to go, go there. The 0 case moves to block 1. |
525 | */ |
526 | else if (i <= 0 && (int)bbno - i < mp->m_sb.sb_rbmblocks - 1) |
527 | i = 1 - i; |
528 | /* |
529 | * If negative or 0 and there are more negative blocks, |
530 | * go there. |
531 | */ |
532 | else if (i <= 0 && (int)bbno + i > 0) |
533 | i--; |
534 | /* |
535 | * Must be done. Return failure. |
536 | */ |
537 | else |
538 | break; |
539 | } |
540 | return -ENOSPC; |
541 | } |
542 | |
543 | static int |
544 | xfs_rtalloc_sumlevel( |
545 | struct xfs_rtalloc_args *args, |
546 | int l, /* level number */ |
547 | xfs_rtxlen_t minlen, /* minimum length to allocate */ |
548 | xfs_rtxlen_t maxlen, /* maximum length to allocate */ |
549 | xfs_rtxlen_t prod, /* extent product factor */ |
550 | xfs_rtxlen_t *len, /* out: actual length allocated */ |
551 | xfs_rtxnum_t *rtx) /* out: start rtext allocated */ |
552 | { |
553 | xfs_fileoff_t i; /* bitmap block number */ |
554 | |
555 | for (i = 0; i < args->mp->m_sb.sb_rbmblocks; i++) { |
556 | xfs_suminfo_t sum; /* summary information for extents */ |
557 | xfs_rtxnum_t n; /* next rtext to be tried */ |
558 | int error; |
559 | |
560 | error = xfs_rtget_summary(args, l, i, &sum); |
561 | if (error) |
562 | return error; |
563 | |
564 | /* |
565 | * Nothing there, on to the next block. |
566 | */ |
567 | if (!sum) |
568 | continue; |
569 | |
570 | /* |
571 | * Try allocating the extent. |
572 | */ |
573 | error = xfs_rtallocate_extent_block(args, i, minlen, maxlen, |
574 | len, &n, prod, rtx); |
575 | if (error != -ENOSPC) |
576 | return error; |
577 | |
578 | /* |
579 | * If the "next block to try" returned from the allocator is |
580 | * beyond the next bitmap block, skip to that bitmap block. |
581 | */ |
582 | if (xfs_rtx_to_rbmblock(args->mp, n) > i + 1) |
583 | i = xfs_rtx_to_rbmblock(args->mp, n) - 1; |
584 | } |
585 | |
586 | return -ENOSPC; |
587 | } |
588 | |
589 | /* |
590 | * Allocate an extent of length minlen<=len<=maxlen, with no position |
591 | * specified. If we don't get maxlen then use prod to trim |
592 | * the length, if given. The lengths are all in rtextents. |
593 | */ |
594 | STATIC int |
595 | xfs_rtallocate_extent_size( |
596 | struct xfs_rtalloc_args *args, |
597 | xfs_rtxlen_t minlen, /* minimum length to allocate */ |
598 | xfs_rtxlen_t maxlen, /* maximum length to allocate */ |
599 | xfs_rtxlen_t *len, /* out: actual length allocated */ |
600 | xfs_rtxlen_t prod, /* extent product factor */ |
601 | xfs_rtxnum_t *rtx) /* out: start rtext allocated */ |
602 | { |
603 | int error; |
604 | int l; /* level number (loop control) */ |
605 | |
606 | ASSERT(minlen % prod == 0); |
607 | ASSERT(maxlen % prod == 0); |
608 | ASSERT(maxlen != 0); |
609 | |
610 | /* |
611 | * Loop over all the levels starting with maxlen. |
612 | * |
613 | * At each level, look at all the bitmap blocks, to see if there are |
614 | * extents starting there that are long enough (>= maxlen). |
615 | * |
616 | * Note, only on the initial level can the allocation fail if the |
617 | * summary says there's an extent. |
618 | */ |
619 | for (l = xfs_highbit32(maxlen); l < args->mp->m_rsumlevels; l++) { |
620 | error = xfs_rtalloc_sumlevel(args, l, minlen, maxlen, prod, len, |
621 | rtx); |
622 | if (error != -ENOSPC) |
623 | return error; |
624 | } |
625 | |
626 | /* |
627 | * Didn't find any maxlen blocks. Try smaller ones, unless we are |
628 | * looking for a fixed size extent. |
629 | */ |
630 | if (minlen > --maxlen) |
631 | return -ENOSPC; |
632 | ASSERT(minlen != 0); |
633 | ASSERT(maxlen != 0); |
634 | |
635 | /* |
636 | * Loop over sizes, from maxlen down to minlen. |
637 | * |
638 | * This time, when we do the allocations, allow smaller ones to succeed, |
639 | * but make sure the specified minlen/maxlen are in the possible range |
640 | * for this summary level. |
641 | */ |
642 | for (l = xfs_highbit32(maxlen); l >= xfs_highbit32(minlen); l--) { |
643 | error = xfs_rtalloc_sumlevel(args, l, |
644 | max_t(xfs_rtxlen_t, minlen, 1 << l), |
645 | min_t(xfs_rtxlen_t, maxlen, (1 << (l + 1)) - 1), |
646 | prod, len, rtx); |
647 | if (error != -ENOSPC) |
648 | return error; |
649 | } |
650 | |
651 | return -ENOSPC; |
652 | } |
653 | |
654 | /* |
655 | * Allocate space to the bitmap or summary file, and zero it, for growfs. |
656 | */ |
657 | STATIC int |
658 | xfs_growfs_rt_alloc( |
659 | struct xfs_mount *mp, /* file system mount point */ |
660 | xfs_extlen_t oblocks, /* old count of blocks */ |
661 | xfs_extlen_t nblocks, /* new count of blocks */ |
662 | struct xfs_inode *ip) /* inode (bitmap/summary) */ |
663 | { |
664 | xfs_fileoff_t bno; /* block number in file */ |
665 | struct xfs_buf *bp; /* temporary buffer for zeroing */ |
666 | xfs_daddr_t d; /* disk block address */ |
667 | int error; /* error return value */ |
668 | xfs_fsblock_t fsbno; /* filesystem block for bno */ |
669 | struct xfs_bmbt_irec map; /* block map output */ |
670 | int nmap; /* number of block maps */ |
671 | int resblks; /* space reservation */ |
672 | enum xfs_blft buf_type; |
673 | struct xfs_trans *tp; |
674 | |
675 | if (ip == mp->m_rsumip) |
676 | buf_type = XFS_BLFT_RTSUMMARY_BUF; |
677 | else |
678 | buf_type = XFS_BLFT_RTBITMAP_BUF; |
679 | |
680 | /* |
681 | * Allocate space to the file, as necessary. |
682 | */ |
683 | while (oblocks < nblocks) { |
684 | resblks = XFS_GROWFSRT_SPACE_RES(mp, nblocks - oblocks); |
685 | /* |
686 | * Reserve space & log for one extent added to the file. |
687 | */ |
688 | error = xfs_trans_alloc(mp, resp: &M_RES(mp)->tr_growrtalloc, blocks: resblks, |
689 | rtextents: 0, flags: 0, tpp: &tp); |
690 | if (error) |
691 | return error; |
692 | /* |
693 | * Lock the inode. |
694 | */ |
695 | xfs_ilock(ip, XFS_ILOCK_EXCL); |
696 | xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); |
697 | |
698 | error = xfs_iext_count_may_overflow(ip, XFS_DATA_FORK, |
699 | XFS_IEXT_ADD_NOSPLIT_CNT); |
700 | if (error == -EFBIG) |
701 | error = xfs_iext_count_upgrade(tp, ip, |
702 | XFS_IEXT_ADD_NOSPLIT_CNT); |
703 | if (error) |
704 | goto out_trans_cancel; |
705 | |
706 | /* |
707 | * Allocate blocks to the bitmap file. |
708 | */ |
709 | nmap = 1; |
710 | error = xfs_bmapi_write(tp, ip, oblocks, nblocks - oblocks, |
711 | XFS_BMAPI_METADATA, 0, &map, &nmap); |
712 | if (!error && nmap < 1) |
713 | error = -ENOSPC; |
714 | if (error) |
715 | goto out_trans_cancel; |
716 | /* |
717 | * Free any blocks freed up in the transaction, then commit. |
718 | */ |
719 | error = xfs_trans_commit(tp); |
720 | if (error) |
721 | return error; |
722 | /* |
723 | * Now we need to clear the allocated blocks. |
724 | * Do this one block per transaction, to keep it simple. |
725 | */ |
726 | for (bno = map.br_startoff, fsbno = map.br_startblock; |
727 | bno < map.br_startoff + map.br_blockcount; |
728 | bno++, fsbno++) { |
729 | /* |
730 | * Reserve log for one block zeroing. |
731 | */ |
732 | error = xfs_trans_alloc(mp, &M_RES(mp)->tr_growrtzero, |
733 | 0, 0, 0, &tp); |
734 | if (error) |
735 | return error; |
736 | /* |
737 | * Lock the bitmap inode. |
738 | */ |
739 | xfs_ilock(ip, XFS_ILOCK_EXCL); |
740 | xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); |
741 | /* |
742 | * Get a buffer for the block. |
743 | */ |
744 | d = XFS_FSB_TO_DADDR(mp, fsbno); |
745 | error = xfs_trans_get_buf(tp, mp->m_ddev_targp, d, |
746 | mp->m_bsize, 0, &bp); |
747 | if (error) |
748 | goto out_trans_cancel; |
749 | |
750 | xfs_trans_buf_set_type(tp, bp, buf_type); |
751 | bp->b_ops = &xfs_rtbuf_ops; |
752 | memset(bp->b_addr, 0, mp->m_sb.sb_blocksize); |
753 | xfs_trans_log_buf(tp, bp, 0, mp->m_sb.sb_blocksize - 1); |
754 | /* |
755 | * Commit the transaction. |
756 | */ |
757 | error = xfs_trans_commit(tp); |
758 | if (error) |
759 | return error; |
760 | } |
761 | /* |
762 | * Go on to the next extent, if any. |
763 | */ |
764 | oblocks = map.br_startoff + map.br_blockcount; |
765 | } |
766 | |
767 | return 0; |
768 | |
769 | out_trans_cancel: |
770 | xfs_trans_cancel(tp); |
771 | return error; |
772 | } |
773 | |
774 | static void |
775 | xfs_alloc_rsum_cache( |
776 | xfs_mount_t *mp, /* file system mount structure */ |
777 | xfs_extlen_t rbmblocks) /* number of rt bitmap blocks */ |
778 | { |
779 | /* |
780 | * The rsum cache is initialized to the maximum value, which is |
781 | * trivially an upper bound on the maximum level with any free extents. |
782 | * We can continue without the cache if it couldn't be allocated. |
783 | */ |
784 | mp->m_rsum_cache = kvmalloc(size: rbmblocks, GFP_KERNEL); |
785 | if (mp->m_rsum_cache) |
786 | memset(mp->m_rsum_cache, -1, rbmblocks); |
787 | else |
788 | xfs_warn(mp, "could not allocate realtime summary cache" ); |
789 | } |
790 | |
791 | /* |
792 | * Visible (exported) functions. |
793 | */ |
794 | |
795 | /* |
796 | * Grow the realtime area of the filesystem. |
797 | */ |
798 | int |
799 | xfs_growfs_rt( |
800 | xfs_mount_t *mp, /* mount point for filesystem */ |
801 | xfs_growfs_rt_t *in) /* growfs rt input struct */ |
802 | { |
803 | xfs_fileoff_t bmbno; /* bitmap block number */ |
804 | struct xfs_buf *bp; /* temporary buffer */ |
805 | int error; /* error return value */ |
806 | xfs_mount_t *nmp; /* new (fake) mount structure */ |
807 | xfs_rfsblock_t nrblocks; /* new number of realtime blocks */ |
808 | xfs_extlen_t nrbmblocks; /* new number of rt bitmap blocks */ |
809 | xfs_rtxnum_t nrextents; /* new number of realtime extents */ |
810 | uint8_t nrextslog; /* new log2 of sb_rextents */ |
811 | xfs_extlen_t nrsumblocks; /* new number of summary blocks */ |
812 | uint nrsumlevels; /* new rt summary levels */ |
813 | uint nrsumsize; /* new size of rt summary, bytes */ |
814 | xfs_sb_t *nsbp; /* new superblock */ |
815 | xfs_extlen_t rbmblocks; /* current number of rt bitmap blocks */ |
816 | xfs_extlen_t rsumblocks; /* current number of rt summary blks */ |
817 | xfs_sb_t *sbp; /* old superblock */ |
818 | uint8_t *rsum_cache; /* old summary cache */ |
819 | |
820 | sbp = &mp->m_sb; |
821 | |
822 | if (!capable(CAP_SYS_ADMIN)) |
823 | return -EPERM; |
824 | |
825 | /* Needs to have been mounted with an rt device. */ |
826 | if (!XFS_IS_REALTIME_MOUNT(mp)) |
827 | return -EINVAL; |
828 | /* |
829 | * Mount should fail if the rt bitmap/summary files don't load, but |
830 | * we'll check anyway. |
831 | */ |
832 | if (!mp->m_rbmip || !mp->m_rsumip) |
833 | return -EINVAL; |
834 | |
835 | /* Shrink not supported. */ |
836 | if (in->newblocks <= sbp->sb_rblocks) |
837 | return -EINVAL; |
838 | |
839 | /* Can only change rt extent size when adding rt volume. */ |
840 | if (sbp->sb_rblocks > 0 && in->extsize != sbp->sb_rextsize) |
841 | return -EINVAL; |
842 | |
843 | /* Range check the extent size. */ |
844 | if (XFS_FSB_TO_B(mp, in->extsize) > XFS_MAX_RTEXTSIZE || |
845 | XFS_FSB_TO_B(mp, in->extsize) < XFS_MIN_RTEXTSIZE) |
846 | return -EINVAL; |
847 | |
848 | /* Unsupported realtime features. */ |
849 | if (xfs_has_rmapbt(mp) || xfs_has_reflink(mp) || xfs_has_quota(mp)) |
850 | return -EOPNOTSUPP; |
851 | |
852 | nrblocks = in->newblocks; |
853 | error = xfs_sb_validate_fsb_count(sbp, nrblocks); |
854 | if (error) |
855 | return error; |
856 | /* |
857 | * Read in the last block of the device, make sure it exists. |
858 | */ |
859 | error = xfs_buf_read_uncached(mp->m_rtdev_targp, |
860 | XFS_FSB_TO_BB(mp, nrblocks - 1), |
861 | XFS_FSB_TO_BB(mp, 1), 0, &bp, NULL); |
862 | if (error) |
863 | return error; |
864 | xfs_buf_relse(bp); |
865 | |
866 | /* |
867 | * Calculate new parameters. These are the final values to be reached. |
868 | */ |
869 | nrextents = nrblocks; |
870 | do_div(nrextents, in->extsize); |
871 | if (!xfs_validate_rtextents(nrextents)) |
872 | return -EINVAL; |
873 | nrbmblocks = xfs_rtbitmap_blockcount(mp, nrextents); |
874 | nrextslog = xfs_compute_rextslog(nrextents); |
875 | nrsumlevels = nrextslog + 1; |
876 | nrsumblocks = xfs_rtsummary_blockcount(mp, nrsumlevels, nrbmblocks); |
877 | nrsumsize = XFS_FSB_TO_B(mp, nrsumblocks); |
878 | /* |
879 | * New summary size can't be more than half the size of |
880 | * the log. This prevents us from getting a log overflow, |
881 | * since we'll log basically the whole summary file at once. |
882 | */ |
883 | if (nrsumblocks > (mp->m_sb.sb_logblocks >> 1)) |
884 | return -EINVAL; |
885 | /* |
886 | * Get the old block counts for bitmap and summary inodes. |
887 | * These can't change since other growfs callers are locked out. |
888 | */ |
889 | rbmblocks = XFS_B_TO_FSB(mp, mp->m_rbmip->i_disk_size); |
890 | rsumblocks = XFS_B_TO_FSB(mp, mp->m_rsumip->i_disk_size); |
891 | /* |
892 | * Allocate space to the bitmap and summary files, as necessary. |
893 | */ |
894 | error = xfs_growfs_rt_alloc(mp, rbmblocks, nrbmblocks, mp->m_rbmip); |
895 | if (error) |
896 | return error; |
897 | error = xfs_growfs_rt_alloc(mp, rsumblocks, nrsumblocks, mp->m_rsumip); |
898 | if (error) |
899 | return error; |
900 | |
901 | rsum_cache = mp->m_rsum_cache; |
902 | if (nrbmblocks != sbp->sb_rbmblocks) |
903 | xfs_alloc_rsum_cache(mp, nrbmblocks); |
904 | |
905 | /* |
906 | * Allocate a new (fake) mount/sb. |
907 | */ |
908 | nmp = kmalloc(size: sizeof(*nmp), GFP_KERNEL | __GFP_NOFAIL); |
909 | /* |
910 | * Loop over the bitmap blocks. |
911 | * We will do everything one bitmap block at a time. |
912 | * Skip the current block if it is exactly full. |
913 | * This also deals with the case where there were no rtextents before. |
914 | */ |
915 | for (bmbno = sbp->sb_rbmblocks - |
916 | ((sbp->sb_rextents & ((1 << mp->m_blkbit_log) - 1)) != 0); |
917 | bmbno < nrbmblocks; |
918 | bmbno++) { |
919 | struct xfs_rtalloc_args args = { |
920 | .mp = mp, |
921 | }; |
922 | struct xfs_rtalloc_args nargs = { |
923 | .mp = nmp, |
924 | }; |
925 | struct xfs_trans *tp; |
926 | xfs_rfsblock_t nrblocks_step; |
927 | |
928 | *nmp = *mp; |
929 | nsbp = &nmp->m_sb; |
930 | /* |
931 | * Calculate new sb and mount fields for this round. |
932 | */ |
933 | nsbp->sb_rextsize = in->extsize; |
934 | nmp->m_rtxblklog = -1; /* don't use shift or masking */ |
935 | nsbp->sb_rbmblocks = bmbno + 1; |
936 | nrblocks_step = (bmbno + 1) * NBBY * nsbp->sb_blocksize * |
937 | nsbp->sb_rextsize; |
938 | nsbp->sb_rblocks = min(nrblocks, nrblocks_step); |
939 | nsbp->sb_rextents = xfs_rtb_to_rtx(nmp, nsbp->sb_rblocks); |
940 | ASSERT(nsbp->sb_rextents != 0); |
941 | nsbp->sb_rextslog = xfs_compute_rextslog(nsbp->sb_rextents); |
942 | nrsumlevels = nmp->m_rsumlevels = nsbp->sb_rextslog + 1; |
943 | nrsumblocks = xfs_rtsummary_blockcount(mp, nrsumlevels, |
944 | nsbp->sb_rbmblocks); |
945 | nmp->m_rsumsize = nrsumsize = XFS_FSB_TO_B(mp, nrsumblocks); |
946 | /* recompute growfsrt reservation from new rsumsize */ |
947 | xfs_trans_resv_calc(nmp, &nmp->m_resv); |
948 | |
949 | /* |
950 | * Start a transaction, get the log reservation. |
951 | */ |
952 | error = xfs_trans_alloc(mp, &M_RES(mp)->tr_growrtfree, 0, 0, 0, |
953 | &tp); |
954 | if (error) |
955 | break; |
956 | args.tp = tp; |
957 | nargs.tp = tp; |
958 | |
959 | /* |
960 | * Lock out other callers by grabbing the bitmap inode lock. |
961 | */ |
962 | xfs_ilock(mp->m_rbmip, XFS_ILOCK_EXCL | XFS_ILOCK_RTBITMAP); |
963 | xfs_trans_ijoin(tp, mp->m_rbmip, XFS_ILOCK_EXCL); |
964 | /* |
965 | * Update the bitmap inode's size ondisk and incore. We need |
966 | * to update the incore size so that inode inactivation won't |
967 | * punch what it thinks are "posteof" blocks. |
968 | */ |
969 | mp->m_rbmip->i_disk_size = |
970 | nsbp->sb_rbmblocks * nsbp->sb_blocksize; |
971 | i_size_write(VFS_I(mp->m_rbmip), mp->m_rbmip->i_disk_size); |
972 | xfs_trans_log_inode(tp, mp->m_rbmip, XFS_ILOG_CORE); |
973 | /* |
974 | * Get the summary inode into the transaction. |
975 | */ |
976 | xfs_ilock(mp->m_rsumip, XFS_ILOCK_EXCL | XFS_ILOCK_RTSUM); |
977 | xfs_trans_ijoin(tp, mp->m_rsumip, XFS_ILOCK_EXCL); |
978 | /* |
979 | * Update the summary inode's size. We need to update the |
980 | * incore size so that inode inactivation won't punch what it |
981 | * thinks are "posteof" blocks. |
982 | */ |
983 | mp->m_rsumip->i_disk_size = nmp->m_rsumsize; |
984 | i_size_write(VFS_I(mp->m_rsumip), mp->m_rsumip->i_disk_size); |
985 | xfs_trans_log_inode(tp, mp->m_rsumip, XFS_ILOG_CORE); |
986 | /* |
987 | * Copy summary data from old to new sizes. |
988 | * Do this when the real size (not block-aligned) changes. |
989 | */ |
990 | if (sbp->sb_rbmblocks != nsbp->sb_rbmblocks || |
991 | mp->m_rsumlevels != nmp->m_rsumlevels) { |
992 | error = xfs_rtcopy_summary(&args, &nargs); |
993 | if (error) |
994 | goto error_cancel; |
995 | } |
996 | /* |
997 | * Update superblock fields. |
998 | */ |
999 | if (nsbp->sb_rextsize != sbp->sb_rextsize) |
1000 | xfs_trans_mod_sb(tp, XFS_TRANS_SB_REXTSIZE, |
1001 | nsbp->sb_rextsize - sbp->sb_rextsize); |
1002 | if (nsbp->sb_rbmblocks != sbp->sb_rbmblocks) |
1003 | xfs_trans_mod_sb(tp, XFS_TRANS_SB_RBMBLOCKS, |
1004 | nsbp->sb_rbmblocks - sbp->sb_rbmblocks); |
1005 | if (nsbp->sb_rblocks != sbp->sb_rblocks) |
1006 | xfs_trans_mod_sb(tp, XFS_TRANS_SB_RBLOCKS, |
1007 | nsbp->sb_rblocks - sbp->sb_rblocks); |
1008 | if (nsbp->sb_rextents != sbp->sb_rextents) |
1009 | xfs_trans_mod_sb(tp, XFS_TRANS_SB_REXTENTS, |
1010 | nsbp->sb_rextents - sbp->sb_rextents); |
1011 | if (nsbp->sb_rextslog != sbp->sb_rextslog) |
1012 | xfs_trans_mod_sb(tp, XFS_TRANS_SB_REXTSLOG, |
1013 | nsbp->sb_rextslog - sbp->sb_rextslog); |
1014 | /* |
1015 | * Free new extent. |
1016 | */ |
1017 | error = xfs_rtfree_range(&nargs, sbp->sb_rextents, |
1018 | nsbp->sb_rextents - sbp->sb_rextents); |
1019 | xfs_rtbuf_cache_relse(&nargs); |
1020 | if (error) { |
1021 | error_cancel: |
1022 | xfs_trans_cancel(tp); |
1023 | break; |
1024 | } |
1025 | /* |
1026 | * Mark more blocks free in the superblock. |
1027 | */ |
1028 | xfs_trans_mod_sb(tp, XFS_TRANS_SB_FREXTENTS, |
1029 | nsbp->sb_rextents - sbp->sb_rextents); |
1030 | /* |
1031 | * Update mp values into the real mp structure. |
1032 | */ |
1033 | mp->m_rsumlevels = nrsumlevels; |
1034 | mp->m_rsumsize = nrsumsize; |
1035 | /* recompute growfsrt reservation from new rsumsize */ |
1036 | xfs_trans_resv_calc(mp, &mp->m_resv); |
1037 | |
1038 | error = xfs_trans_commit(tp); |
1039 | if (error) |
1040 | break; |
1041 | |
1042 | /* Ensure the mount RT feature flag is now set. */ |
1043 | mp->m_features |= XFS_FEAT_REALTIME; |
1044 | } |
1045 | if (error) |
1046 | goto out_free; |
1047 | |
1048 | /* Update secondary superblocks now the physical grow has completed */ |
1049 | error = xfs_update_secondary_sbs(mp); |
1050 | |
1051 | out_free: |
1052 | /* |
1053 | * Free the fake mp structure. |
1054 | */ |
1055 | kfree(objp: nmp); |
1056 | |
1057 | /* |
1058 | * If we had to allocate a new rsum_cache, we either need to free the |
1059 | * old one (if we succeeded) or free the new one and restore the old one |
1060 | * (if there was an error). |
1061 | */ |
1062 | if (rsum_cache != mp->m_rsum_cache) { |
1063 | if (error) { |
1064 | kvfree(addr: mp->m_rsum_cache); |
1065 | mp->m_rsum_cache = rsum_cache; |
1066 | } else { |
1067 | kvfree(addr: rsum_cache); |
1068 | } |
1069 | } |
1070 | |
1071 | return error; |
1072 | } |
1073 | |
1074 | /* |
1075 | * Initialize realtime fields in the mount structure. |
1076 | */ |
1077 | int /* error */ |
1078 | xfs_rtmount_init( |
1079 | struct xfs_mount *mp) /* file system mount structure */ |
1080 | { |
1081 | struct xfs_buf *bp; /* buffer for last block of subvolume */ |
1082 | struct xfs_sb *sbp; /* filesystem superblock copy in mount */ |
1083 | xfs_daddr_t d; /* address of last block of subvolume */ |
1084 | unsigned int rsumblocks; |
1085 | int error; |
1086 | |
1087 | sbp = &mp->m_sb; |
1088 | if (sbp->sb_rblocks == 0) |
1089 | return 0; |
1090 | if (mp->m_rtdev_targp == NULL) { |
1091 | xfs_warn(mp, |
1092 | "Filesystem has a realtime volume, use rtdev=device option" ); |
1093 | return -ENODEV; |
1094 | } |
1095 | mp->m_rsumlevels = sbp->sb_rextslog + 1; |
1096 | rsumblocks = xfs_rtsummary_blockcount(mp, mp->m_rsumlevels, |
1097 | mp->m_sb.sb_rbmblocks); |
1098 | mp->m_rsumsize = XFS_FSB_TO_B(mp, rsumblocks); |
1099 | mp->m_rbmip = mp->m_rsumip = NULL; |
1100 | /* |
1101 | * Check that the realtime section is an ok size. |
1102 | */ |
1103 | d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_rblocks); |
1104 | if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_rblocks) { |
1105 | xfs_warn(mp, "realtime mount -- %llu != %llu" , |
1106 | (unsigned long long) XFS_BB_TO_FSB(mp, d), |
1107 | (unsigned long long) mp->m_sb.sb_rblocks); |
1108 | return -EFBIG; |
1109 | } |
1110 | error = xfs_buf_read_uncached(target: mp->m_rtdev_targp, |
1111 | daddr: d - XFS_FSB_TO_BB(mp, 1), |
1112 | numblks: XFS_FSB_TO_BB(mp, 1), flags: 0, bpp: &bp, NULL); |
1113 | if (error) { |
1114 | xfs_warn(mp, "realtime device size check failed" ); |
1115 | return error; |
1116 | } |
1117 | xfs_buf_relse(bp); |
1118 | return 0; |
1119 | } |
1120 | |
1121 | static int |
1122 | xfs_rtalloc_count_frextent( |
1123 | struct xfs_mount *mp, |
1124 | struct xfs_trans *tp, |
1125 | const struct xfs_rtalloc_rec *rec, |
1126 | void *priv) |
1127 | { |
1128 | uint64_t *valp = priv; |
1129 | |
1130 | *valp += rec->ar_extcount; |
1131 | return 0; |
1132 | } |
1133 | |
1134 | /* |
1135 | * Reinitialize the number of free realtime extents from the realtime bitmap. |
1136 | * Callers must ensure that there is no other activity in the filesystem. |
1137 | */ |
1138 | int |
1139 | xfs_rtalloc_reinit_frextents( |
1140 | struct xfs_mount *mp) |
1141 | { |
1142 | uint64_t val = 0; |
1143 | int error; |
1144 | |
1145 | xfs_ilock(mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP); |
1146 | error = xfs_rtalloc_query_all(mp, NULL, xfs_rtalloc_count_frextent, |
1147 | &val); |
1148 | xfs_iunlock(mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP); |
1149 | if (error) |
1150 | return error; |
1151 | |
1152 | spin_lock(lock: &mp->m_sb_lock); |
1153 | mp->m_sb.sb_frextents = val; |
1154 | spin_unlock(lock: &mp->m_sb_lock); |
1155 | percpu_counter_set(fbc: &mp->m_frextents, amount: mp->m_sb.sb_frextents); |
1156 | return 0; |
1157 | } |
1158 | |
1159 | /* |
1160 | * Read in the bmbt of an rt metadata inode so that we never have to load them |
1161 | * at runtime. This enables the use of shared ILOCKs for rtbitmap scans. Use |
1162 | * an empty transaction to avoid deadlocking on loops in the bmbt. |
1163 | */ |
1164 | static inline int |
1165 | xfs_rtmount_iread_extents( |
1166 | struct xfs_inode *ip, |
1167 | unsigned int lock_class) |
1168 | { |
1169 | struct xfs_trans *tp; |
1170 | int error; |
1171 | |
1172 | error = xfs_trans_alloc_empty(mp: ip->i_mount, tpp: &tp); |
1173 | if (error) |
1174 | return error; |
1175 | |
1176 | xfs_ilock(ip, XFS_ILOCK_EXCL | lock_class); |
1177 | |
1178 | error = xfs_iread_extents(tp, ip, XFS_DATA_FORK); |
1179 | if (error) |
1180 | goto out_unlock; |
1181 | |
1182 | if (xfs_inode_has_attr_fork(ip)) { |
1183 | error = xfs_iread_extents(tp, ip, XFS_ATTR_FORK); |
1184 | if (error) |
1185 | goto out_unlock; |
1186 | } |
1187 | |
1188 | out_unlock: |
1189 | xfs_iunlock(ip, XFS_ILOCK_EXCL | lock_class); |
1190 | xfs_trans_cancel(tp); |
1191 | return error; |
1192 | } |
1193 | |
1194 | /* |
1195 | * Get the bitmap and summary inodes and the summary cache into the mount |
1196 | * structure at mount time. |
1197 | */ |
1198 | int /* error */ |
1199 | xfs_rtmount_inodes( |
1200 | xfs_mount_t *mp) /* file system mount structure */ |
1201 | { |
1202 | int error; /* error return value */ |
1203 | xfs_sb_t *sbp; |
1204 | |
1205 | sbp = &mp->m_sb; |
1206 | error = xfs_iget(mp, NULL, sbp->sb_rbmino, 0, 0, &mp->m_rbmip); |
1207 | if (xfs_metadata_is_sick(error)) |
1208 | xfs_rt_mark_sick(mp, XFS_SICK_RT_BITMAP); |
1209 | if (error) |
1210 | return error; |
1211 | ASSERT(mp->m_rbmip != NULL); |
1212 | |
1213 | error = xfs_rtmount_iread_extents(ip: mp->m_rbmip, XFS_ILOCK_RTBITMAP); |
1214 | if (error) |
1215 | goto out_rele_bitmap; |
1216 | |
1217 | error = xfs_iget(mp, NULL, sbp->sb_rsumino, 0, 0, &mp->m_rsumip); |
1218 | if (xfs_metadata_is_sick(error)) |
1219 | xfs_rt_mark_sick(mp, XFS_SICK_RT_SUMMARY); |
1220 | if (error) |
1221 | goto out_rele_bitmap; |
1222 | ASSERT(mp->m_rsumip != NULL); |
1223 | |
1224 | error = xfs_rtmount_iread_extents(ip: mp->m_rsumip, XFS_ILOCK_RTSUM); |
1225 | if (error) |
1226 | goto out_rele_summary; |
1227 | |
1228 | xfs_alloc_rsum_cache(mp, sbp->sb_rbmblocks); |
1229 | return 0; |
1230 | |
1231 | out_rele_summary: |
1232 | xfs_irele(ip: mp->m_rsumip); |
1233 | out_rele_bitmap: |
1234 | xfs_irele(ip: mp->m_rbmip); |
1235 | return error; |
1236 | } |
1237 | |
1238 | void |
1239 | xfs_rtunmount_inodes( |
1240 | struct xfs_mount *mp) |
1241 | { |
1242 | kvfree(addr: mp->m_rsum_cache); |
1243 | if (mp->m_rbmip) |
1244 | xfs_irele(ip: mp->m_rbmip); |
1245 | if (mp->m_rsumip) |
1246 | xfs_irele(ip: mp->m_rsumip); |
1247 | } |
1248 | |
1249 | /* |
1250 | * Pick an extent for allocation at the start of a new realtime file. |
1251 | * Use the sequence number stored in the atime field of the bitmap inode. |
1252 | * Translate this to a fraction of the rtextents, and return the product |
1253 | * of rtextents and the fraction. |
1254 | * The fraction sequence is 0, 1/2, 1/4, 3/4, 1/8, ..., 7/8, 1/16, ... |
1255 | */ |
1256 | static int |
1257 | xfs_rtpick_extent( |
1258 | xfs_mount_t *mp, /* file system mount point */ |
1259 | xfs_trans_t *tp, /* transaction pointer */ |
1260 | xfs_rtxlen_t len, /* allocation length (rtextents) */ |
1261 | xfs_rtxnum_t *pick) /* result rt extent */ |
1262 | { |
1263 | xfs_rtxnum_t b; /* result rtext */ |
1264 | int log2; /* log of sequence number */ |
1265 | uint64_t resid; /* residual after log removed */ |
1266 | uint64_t seq; /* sequence number of file creation */ |
1267 | struct timespec64 ts; /* timespec in inode */ |
1268 | |
1269 | xfs_assert_ilocked(mp->m_rbmip, XFS_ILOCK_EXCL); |
1270 | |
1271 | ts = inode_get_atime(inode: VFS_I(ip: mp->m_rbmip)); |
1272 | if (!(mp->m_rbmip->i_diflags & XFS_DIFLAG_NEWRTBM)) { |
1273 | mp->m_rbmip->i_diflags |= XFS_DIFLAG_NEWRTBM; |
1274 | seq = 0; |
1275 | } else { |
1276 | seq = ts.tv_sec; |
1277 | } |
1278 | if ((log2 = xfs_highbit64(seq)) == -1) |
1279 | b = 0; |
1280 | else { |
1281 | resid = seq - (1ULL << log2); |
1282 | b = (mp->m_sb.sb_rextents * ((resid << 1) + 1ULL)) >> |
1283 | (log2 + 1); |
1284 | if (b >= mp->m_sb.sb_rextents) |
1285 | div64_u64_rem(b, mp->m_sb.sb_rextents, &b); |
1286 | if (b + len > mp->m_sb.sb_rextents) |
1287 | b = mp->m_sb.sb_rextents - len; |
1288 | } |
1289 | ts.tv_sec = seq + 1; |
1290 | inode_set_atime_to_ts(inode: VFS_I(ip: mp->m_rbmip), ts); |
1291 | xfs_trans_log_inode(tp, mp->m_rbmip, XFS_ILOG_CORE); |
1292 | *pick = b; |
1293 | return 0; |
1294 | } |
1295 | |
1296 | static void |
1297 | xfs_rtalloc_align_minmax( |
1298 | xfs_rtxlen_t *raminlen, |
1299 | xfs_rtxlen_t *ramaxlen, |
1300 | xfs_rtxlen_t *prod) |
1301 | { |
1302 | xfs_rtxlen_t newmaxlen = *ramaxlen; |
1303 | xfs_rtxlen_t newminlen = *raminlen; |
1304 | xfs_rtxlen_t slack; |
1305 | |
1306 | slack = newmaxlen % *prod; |
1307 | if (slack) |
1308 | newmaxlen -= slack; |
1309 | slack = newminlen % *prod; |
1310 | if (slack) |
1311 | newminlen += *prod - slack; |
1312 | |
1313 | /* |
1314 | * If adjusting for extent size hint alignment produces an invalid |
1315 | * min/max len combination, go ahead without it. |
1316 | */ |
1317 | if (newmaxlen < newminlen) { |
1318 | *prod = 1; |
1319 | return; |
1320 | } |
1321 | *ramaxlen = newmaxlen; |
1322 | *raminlen = newminlen; |
1323 | } |
1324 | |
1325 | int |
1326 | xfs_bmap_rtalloc( |
1327 | struct xfs_bmalloca *ap) |
1328 | { |
1329 | struct xfs_mount *mp = ap->ip->i_mount; |
1330 | xfs_fileoff_t orig_offset = ap->offset; |
1331 | xfs_rtxnum_t start; /* allocation hint rtextent no */ |
1332 | xfs_rtxnum_t rtx; /* actually allocated rtextent no */ |
1333 | xfs_rtxlen_t prod = 0; /* product factor for allocators */ |
1334 | xfs_extlen_t mod = 0; /* product factor for allocators */ |
1335 | xfs_rtxlen_t ralen = 0; /* realtime allocation length */ |
1336 | xfs_extlen_t align; /* minimum allocation alignment */ |
1337 | xfs_extlen_t orig_length = ap->length; |
1338 | xfs_extlen_t minlen = mp->m_sb.sb_rextsize; |
1339 | xfs_rtxlen_t raminlen; |
1340 | bool rtlocked = false; |
1341 | bool ignore_locality = false; |
1342 | struct xfs_rtalloc_args args = { |
1343 | .mp = mp, |
1344 | .tp = ap->tp, |
1345 | }; |
1346 | int error; |
1347 | |
1348 | align = xfs_get_extsz_hint(ap->ip); |
1349 | retry: |
1350 | error = xfs_bmap_extsize_align(mp, &ap->got, &ap->prev, |
1351 | align, 1, ap->eof, 0, |
1352 | ap->conv, &ap->offset, &ap->length); |
1353 | if (error) |
1354 | return error; |
1355 | ASSERT(ap->length); |
1356 | ASSERT(xfs_extlen_to_rtxmod(mp, ap->length) == 0); |
1357 | |
1358 | /* |
1359 | * If we shifted the file offset downward to satisfy an extent size |
1360 | * hint, increase minlen by that amount so that the allocator won't |
1361 | * give us an allocation that's too short to cover at least one of the |
1362 | * blocks that the caller asked for. |
1363 | */ |
1364 | if (ap->offset != orig_offset) |
1365 | minlen += orig_offset - ap->offset; |
1366 | |
1367 | /* |
1368 | * Set ralen to be the actual requested length in rtextents. |
1369 | * |
1370 | * If the old value was close enough to XFS_BMBT_MAX_EXTLEN that |
1371 | * we rounded up to it, cut it back so it's valid again. |
1372 | * Note that if it's a really large request (bigger than |
1373 | * XFS_BMBT_MAX_EXTLEN), we don't hear about that number, and can't |
1374 | * adjust the starting point to match it. |
1375 | */ |
1376 | ralen = xfs_extlen_to_rtxlen(mp, min(ap->length, XFS_MAX_BMBT_EXTLEN)); |
1377 | raminlen = max_t(xfs_rtxlen_t, 1, xfs_extlen_to_rtxlen(mp, minlen)); |
1378 | ASSERT(raminlen > 0); |
1379 | ASSERT(raminlen <= ralen); |
1380 | |
1381 | /* |
1382 | * Lock out modifications to both the RT bitmap and summary inodes |
1383 | */ |
1384 | if (!rtlocked) { |
1385 | xfs_ilock(mp->m_rbmip, XFS_ILOCK_EXCL|XFS_ILOCK_RTBITMAP); |
1386 | xfs_trans_ijoin(ap->tp, mp->m_rbmip, XFS_ILOCK_EXCL); |
1387 | xfs_ilock(mp->m_rsumip, XFS_ILOCK_EXCL|XFS_ILOCK_RTSUM); |
1388 | xfs_trans_ijoin(ap->tp, mp->m_rsumip, XFS_ILOCK_EXCL); |
1389 | rtlocked = true; |
1390 | } |
1391 | |
1392 | if (ignore_locality) { |
1393 | start = 0; |
1394 | } else if (xfs_bmap_adjacent(ap)) { |
1395 | start = xfs_rtb_to_rtx(mp, ap->blkno); |
1396 | } else if (ap->eof && ap->offset == 0) { |
1397 | /* |
1398 | * If it's an allocation to an empty file at offset 0, pick an |
1399 | * extent that will space things out in the rt area. |
1400 | */ |
1401 | error = xfs_rtpick_extent(mp, ap->tp, ralen, &start); |
1402 | if (error) |
1403 | return error; |
1404 | } else { |
1405 | start = 0; |
1406 | } |
1407 | |
1408 | /* |
1409 | * Only bother calculating a real prod factor if offset & length are |
1410 | * perfectly aligned, otherwise it will just get us in trouble. |
1411 | */ |
1412 | div_u64_rem(ap->offset, align, &mod); |
1413 | if (mod || ap->length % align) { |
1414 | prod = 1; |
1415 | } else { |
1416 | prod = xfs_extlen_to_rtxlen(mp, align); |
1417 | if (prod > 1) |
1418 | xfs_rtalloc_align_minmax(&raminlen, &ralen, &prod); |
1419 | } |
1420 | |
1421 | if (start) { |
1422 | error = xfs_rtallocate_extent_near(&args, start, raminlen, |
1423 | ralen, &ralen, prod, &rtx); |
1424 | } else { |
1425 | error = xfs_rtallocate_extent_size(&args, raminlen, |
1426 | ralen, &ralen, prod, &rtx); |
1427 | } |
1428 | xfs_rtbuf_cache_relse(&args); |
1429 | |
1430 | if (error == -ENOSPC) { |
1431 | if (align > mp->m_sb.sb_rextsize) { |
1432 | /* |
1433 | * We previously enlarged the request length to try to |
1434 | * satisfy an extent size hint. The allocator didn't |
1435 | * return anything, so reset the parameters to the |
1436 | * original values and try again without alignment |
1437 | * criteria. |
1438 | */ |
1439 | ap->offset = orig_offset; |
1440 | ap->length = orig_length; |
1441 | minlen = align = mp->m_sb.sb_rextsize; |
1442 | goto retry; |
1443 | } |
1444 | |
1445 | if (!ignore_locality && start != 0) { |
1446 | /* |
1447 | * If we can't allocate near a specific rt extent, try |
1448 | * again without locality criteria. |
1449 | */ |
1450 | ignore_locality = true; |
1451 | goto retry; |
1452 | } |
1453 | |
1454 | ap->blkno = NULLFSBLOCK; |
1455 | ap->length = 0; |
1456 | return 0; |
1457 | } |
1458 | if (error) |
1459 | return error; |
1460 | |
1461 | xfs_trans_mod_sb(ap->tp, ap->wasdel ? |
1462 | XFS_TRANS_SB_RES_FREXTENTS : XFS_TRANS_SB_FREXTENTS, |
1463 | -(long)ralen); |
1464 | ap->blkno = xfs_rtx_to_rtb(mp, rtx); |
1465 | ap->length = xfs_rtxlen_to_extlen(mp, ralen); |
1466 | xfs_bmap_alloc_account(ap); |
1467 | return 0; |
1468 | } |
1469 | |