]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - libxfs/xfs_refcount.c
xfs: fix warnings about unused stack variables
[thirdparty/xfsprogs-dev.git] / libxfs / xfs_refcount.c
CommitLineData
bc859611
DW
1/*
2 * Copyright (C) 2016 Oracle. All Rights Reserved.
3 *
4 * Author: Darrick J. Wong <darrick.wong@oracle.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it would be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20#include "libxfs_priv.h"
21#include "xfs_fs.h"
22#include "xfs_shared.h"
23#include "xfs_format.h"
24#include "xfs_log_format.h"
25#include "xfs_trans_resv.h"
26#include "xfs_sb.h"
27#include "xfs_mount.h"
28#include "xfs_defer.h"
29#include "xfs_btree.h"
30#include "xfs_bmap.h"
31#include "xfs_refcount_btree.h"
32#include "xfs_alloc.h"
33#include "xfs_trace.h"
34#include "xfs_cksum.h"
35#include "xfs_trans.h"
36#include "xfs_bit.h"
37#include "xfs_refcount.h"
10e65503 38#include "xfs_rmap.h"
bc859611 39
56ef8c33
DW
40/* Allowable refcount adjustment amounts. */
41enum xfs_refc_adjust_op {
42 XFS_REFCOUNT_ADJUST_INCREASE = 1,
43 XFS_REFCOUNT_ADJUST_DECREASE = -1,
10e65503
DW
44 XFS_REFCOUNT_ADJUST_COW_ALLOC = 0,
45 XFS_REFCOUNT_ADJUST_COW_FREE = -1,
56ef8c33
DW
46};
47
10e65503
DW
48STATIC int __xfs_refcount_cow_alloc(struct xfs_btree_cur *rcur,
49 xfs_agblock_t agbno, xfs_extlen_t aglen,
50 struct xfs_defer_ops *dfops);
51STATIC int __xfs_refcount_cow_free(struct xfs_btree_cur *rcur,
52 xfs_agblock_t agbno, xfs_extlen_t aglen,
53 struct xfs_defer_ops *dfops);
54
bc859611
DW
55/*
56 * Look up the first record less than or equal to [bno, len] in the btree
57 * given by cur.
58 */
59int
60xfs_refcount_lookup_le(
61 struct xfs_btree_cur *cur,
62 xfs_agblock_t bno,
63 int *stat)
64{
65 trace_xfs_refcount_lookup(cur->bc_mp, cur->bc_private.a.agno, bno,
66 XFS_LOOKUP_LE);
67 cur->bc_rec.rc.rc_startblock = bno;
68 cur->bc_rec.rc.rc_blockcount = 0;
69 return xfs_btree_lookup(cur, XFS_LOOKUP_LE, stat);
70}
71
72/*
73 * Look up the first record greater than or equal to [bno, len] in the btree
74 * given by cur.
75 */
76int
77xfs_refcount_lookup_ge(
78 struct xfs_btree_cur *cur,
79 xfs_agblock_t bno,
80 int *stat)
81{
82 trace_xfs_refcount_lookup(cur->bc_mp, cur->bc_private.a.agno, bno,
83 XFS_LOOKUP_GE);
84 cur->bc_rec.rc.rc_startblock = bno;
85 cur->bc_rec.rc.rc_blockcount = 0;
86 return xfs_btree_lookup(cur, XFS_LOOKUP_GE, stat);
87}
88
10e65503
DW
89/* Convert on-disk record to in-core format. */
90static inline void
91xfs_refcount_btrec_to_irec(
92 union xfs_btree_rec *rec,
93 struct xfs_refcount_irec *irec)
94{
95 irec->rc_startblock = be32_to_cpu(rec->refc.rc_startblock);
96 irec->rc_blockcount = be32_to_cpu(rec->refc.rc_blockcount);
97 irec->rc_refcount = be32_to_cpu(rec->refc.rc_refcount);
98}
99
bc859611
DW
100/*
101 * Get the data from the pointed-to record.
102 */
103int
104xfs_refcount_get_rec(
105 struct xfs_btree_cur *cur,
106 struct xfs_refcount_irec *irec,
107 int *stat)
108{
10e65503
DW
109 union xfs_btree_rec *rec;
110 int error;
bc859611
DW
111
112 error = xfs_btree_get_rec(cur, &rec, stat);
113 if (!error && *stat == 1) {
10e65503 114 xfs_refcount_btrec_to_irec(rec, irec);
bc859611
DW
115 trace_xfs_refcount_get(cur->bc_mp, cur->bc_private.a.agno,
116 irec);
117 }
118 return error;
119}
120
121/*
122 * Update the record referred to by cur to the value given
123 * by [bno, len, refcount].
124 * This either works (return 0) or gets an EFSCORRUPTED error.
125 */
126STATIC int
127xfs_refcount_update(
128 struct xfs_btree_cur *cur,
129 struct xfs_refcount_irec *irec)
130{
131 union xfs_btree_rec rec;
132 int error;
133
134 trace_xfs_refcount_update(cur->bc_mp, cur->bc_private.a.agno, irec);
135 rec.refc.rc_startblock = cpu_to_be32(irec->rc_startblock);
136 rec.refc.rc_blockcount = cpu_to_be32(irec->rc_blockcount);
137 rec.refc.rc_refcount = cpu_to_be32(irec->rc_refcount);
138 error = xfs_btree_update(cur, &rec);
139 if (error)
140 trace_xfs_refcount_update_error(cur->bc_mp,
141 cur->bc_private.a.agno, error, _RET_IP_);
142 return error;
143}
144
145/*
146 * Insert the record referred to by cur to the value given
147 * by [bno, len, refcount].
148 * This either works (return 0) or gets an EFSCORRUPTED error.
149 */
150STATIC int
151xfs_refcount_insert(
152 struct xfs_btree_cur *cur,
153 struct xfs_refcount_irec *irec,
154 int *i)
155{
156 int error;
157
158 trace_xfs_refcount_insert(cur->bc_mp, cur->bc_private.a.agno, irec);
159 cur->bc_rec.rc.rc_startblock = irec->rc_startblock;
160 cur->bc_rec.rc.rc_blockcount = irec->rc_blockcount;
161 cur->bc_rec.rc.rc_refcount = irec->rc_refcount;
162 error = xfs_btree_insert(cur, i);
163 XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, *i == 1, out_error);
164out_error:
165 if (error)
166 trace_xfs_refcount_insert_error(cur->bc_mp,
167 cur->bc_private.a.agno, error, _RET_IP_);
168 return error;
169}
170
171/*
172 * Remove the record referred to by cur, then set the pointer to the spot
173 * where the record could be re-inserted, in case we want to increment or
174 * decrement the cursor.
175 * This either works (return 0) or gets an EFSCORRUPTED error.
176 */
177STATIC int
178xfs_refcount_delete(
179 struct xfs_btree_cur *cur,
180 int *i)
181{
182 struct xfs_refcount_irec irec;
183 int found_rec;
184 int error;
185
186 error = xfs_refcount_get_rec(cur, &irec, &found_rec);
187 if (error)
188 goto out_error;
189 XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error);
190 trace_xfs_refcount_delete(cur->bc_mp, cur->bc_private.a.agno, &irec);
191 error = xfs_btree_delete(cur, i);
192 XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, *i == 1, out_error);
193 if (error)
194 goto out_error;
195 error = xfs_refcount_lookup_ge(cur, irec.rc_startblock, &found_rec);
196out_error:
197 if (error)
198 trace_xfs_refcount_delete_error(cur->bc_mp,
199 cur->bc_private.a.agno, error, _RET_IP_);
200 return error;
201}
56ef8c33
DW
202
203/*
204 * Adjusting the Reference Count
205 *
206 * As stated elsewhere, the reference count btree (refcbt) stores
207 * >1 reference counts for extents of physical blocks. In this
208 * operation, we're either raising or lowering the reference count of
209 * some subrange stored in the tree:
210 *
211 * <------ adjustment range ------>
212 * ----+ +---+-----+ +--+--------+---------
213 * 2 | | 3 | 4 | |17| 55 | 10
214 * ----+ +---+-----+ +--+--------+---------
215 * X axis is physical blocks number;
216 * reference counts are the numbers inside the rectangles
217 *
218 * The first thing we need to do is to ensure that there are no
219 * refcount extents crossing either boundary of the range to be
220 * adjusted. For any extent that does cross a boundary, split it into
221 * two extents so that we can increment the refcount of one of the
222 * pieces later:
223 *
224 * <------ adjustment range ------>
225 * ----+ +---+-----+ +--+--------+----+----
226 * 2 | | 3 | 2 | |17| 55 | 10 | 10
227 * ----+ +---+-----+ +--+--------+----+----
228 *
229 * For this next step, let's assume that all the physical blocks in
230 * the adjustment range are mapped to a file and are therefore in use
231 * at least once. Therefore, we can infer that any gap in the
232 * refcount tree within the adjustment range represents a physical
233 * extent with refcount == 1:
234 *
235 * <------ adjustment range ------>
236 * ----+---+---+-----+-+--+--------+----+----
237 * 2 |"1"| 3 | 2 |1|17| 55 | 10 | 10
238 * ----+---+---+-----+-+--+--------+----+----
239 * ^
240 *
241 * For each extent that falls within the interval range, figure out
242 * which extent is to the left or the right of that extent. Now we
243 * have a left, current, and right extent. If the new reference count
244 * of the center extent enables us to merge left, center, and right
245 * into one record covering all three, do so. If the center extent is
246 * at the left end of the range, abuts the left extent, and its new
247 * reference count matches the left extent's record, then merge them.
248 * If the center extent is at the right end of the range, abuts the
249 * right extent, and the reference counts match, merge those. In the
250 * example, we can left merge (assuming an increment operation):
251 *
252 * <------ adjustment range ------>
253 * --------+---+-----+-+--+--------+----+----
254 * 2 | 3 | 2 |1|17| 55 | 10 | 10
255 * --------+---+-----+-+--+--------+----+----
256 * ^
257 *
258 * For all other extents within the range, adjust the reference count
259 * or delete it if the refcount falls below 2. If we were
260 * incrementing, the end result looks like this:
261 *
262 * <------ adjustment range ------>
263 * --------+---+-----+-+--+--------+----+----
264 * 2 | 4 | 3 |2|18| 56 | 11 | 10
265 * --------+---+-----+-+--+--------+----+----
266 *
267 * The result of a decrement operation looks as such:
268 *
269 * <------ adjustment range ------>
270 * ----+ +---+ +--+--------+----+----
271 * 2 | | 2 | |16| 54 | 9 | 10
272 * ----+ +---+ +--+--------+----+----
273 * DDDD 111111DD
274 *
275 * The blocks marked "D" are freed; the blocks marked "1" are only
276 * referenced once and therefore the record is removed from the
277 * refcount btree.
278 */
279
280/* Next block after this extent. */
281static inline xfs_agblock_t
282xfs_refc_next(
283 struct xfs_refcount_irec *rc)
284{
285 return rc->rc_startblock + rc->rc_blockcount;
286}
287
288/*
289 * Split a refcount extent that crosses agbno.
290 */
291STATIC int
292xfs_refcount_split_extent(
293 struct xfs_btree_cur *cur,
294 xfs_agblock_t agbno,
295 bool *shape_changed)
296{
297 struct xfs_refcount_irec rcext, tmp;
298 int found_rec;
299 int error;
300
301 *shape_changed = false;
302 error = xfs_refcount_lookup_le(cur, agbno, &found_rec);
303 if (error)
304 goto out_error;
305 if (!found_rec)
306 return 0;
307
308 error = xfs_refcount_get_rec(cur, &rcext, &found_rec);
309 if (error)
310 goto out_error;
311 XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error);
312 if (rcext.rc_startblock == agbno || xfs_refc_next(&rcext) <= agbno)
313 return 0;
314
315 *shape_changed = true;
316 trace_xfs_refcount_split_extent(cur->bc_mp, cur->bc_private.a.agno,
317 &rcext, agbno);
318
319 /* Establish the right extent. */
320 tmp = rcext;
321 tmp.rc_startblock = agbno;
322 tmp.rc_blockcount -= (agbno - rcext.rc_startblock);
323 error = xfs_refcount_update(cur, &tmp);
324 if (error)
325 goto out_error;
326
327 /* Insert the left extent. */
328 tmp = rcext;
329 tmp.rc_blockcount = agbno - rcext.rc_startblock;
330 error = xfs_refcount_insert(cur, &tmp, &found_rec);
331 if (error)
332 goto out_error;
333 XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error);
334 return error;
335
336out_error:
337 trace_xfs_refcount_split_extent_error(cur->bc_mp,
338 cur->bc_private.a.agno, error, _RET_IP_);
339 return error;
340}
341
342/*
343 * Merge the left, center, and right extents.
344 */
345STATIC int
346xfs_refcount_merge_center_extents(
347 struct xfs_btree_cur *cur,
348 struct xfs_refcount_irec *left,
349 struct xfs_refcount_irec *center,
350 struct xfs_refcount_irec *right,
351 unsigned long long extlen,
352 xfs_agblock_t *agbno,
353 xfs_extlen_t *aglen)
354{
355 int error;
356 int found_rec;
357
358 trace_xfs_refcount_merge_center_extents(cur->bc_mp,
359 cur->bc_private.a.agno, left, center, right);
360
361 /*
362 * Make sure the center and right extents are not in the btree.
363 * If the center extent was synthesized, the first delete call
364 * removes the right extent and we skip the second deletion.
365 * If center and right were in the btree, then the first delete
366 * call removes the center and the second one removes the right
367 * extent.
368 */
369 error = xfs_refcount_lookup_ge(cur, center->rc_startblock,
370 &found_rec);
371 if (error)
372 goto out_error;
373 XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error);
374
375 error = xfs_refcount_delete(cur, &found_rec);
376 if (error)
377 goto out_error;
378 XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error);
379
380 if (center->rc_refcount > 1) {
381 error = xfs_refcount_delete(cur, &found_rec);
382 if (error)
383 goto out_error;
384 XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1,
385 out_error);
386 }
387
388 /* Enlarge the left extent. */
389 error = xfs_refcount_lookup_le(cur, left->rc_startblock,
390 &found_rec);
391 if (error)
392 goto out_error;
393 XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error);
394
395 left->rc_blockcount = extlen;
396 error = xfs_refcount_update(cur, left);
397 if (error)
398 goto out_error;
399
400 *aglen = 0;
401 return error;
402
403out_error:
404 trace_xfs_refcount_merge_center_extents_error(cur->bc_mp,
405 cur->bc_private.a.agno, error, _RET_IP_);
406 return error;
407}
408
409/*
410 * Merge with the left extent.
411 */
412STATIC int
413xfs_refcount_merge_left_extent(
414 struct xfs_btree_cur *cur,
415 struct xfs_refcount_irec *left,
416 struct xfs_refcount_irec *cleft,
417 xfs_agblock_t *agbno,
418 xfs_extlen_t *aglen)
419{
420 int error;
421 int found_rec;
422
423 trace_xfs_refcount_merge_left_extent(cur->bc_mp,
424 cur->bc_private.a.agno, left, cleft);
425
426 /* If the extent at agbno (cleft) wasn't synthesized, remove it. */
427 if (cleft->rc_refcount > 1) {
428 error = xfs_refcount_lookup_le(cur, cleft->rc_startblock,
429 &found_rec);
430 if (error)
431 goto out_error;
432 XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1,
433 out_error);
434
435 error = xfs_refcount_delete(cur, &found_rec);
436 if (error)
437 goto out_error;
438 XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1,
439 out_error);
440 }
441
442 /* Enlarge the left extent. */
443 error = xfs_refcount_lookup_le(cur, left->rc_startblock,
444 &found_rec);
445 if (error)
446 goto out_error;
447 XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error);
448
449 left->rc_blockcount += cleft->rc_blockcount;
450 error = xfs_refcount_update(cur, left);
451 if (error)
452 goto out_error;
453
454 *agbno += cleft->rc_blockcount;
455 *aglen -= cleft->rc_blockcount;
456 return error;
457
458out_error:
459 trace_xfs_refcount_merge_left_extent_error(cur->bc_mp,
460 cur->bc_private.a.agno, error, _RET_IP_);
461 return error;
462}
463
464/*
465 * Merge with the right extent.
466 */
467STATIC int
468xfs_refcount_merge_right_extent(
469 struct xfs_btree_cur *cur,
470 struct xfs_refcount_irec *right,
471 struct xfs_refcount_irec *cright,
472 xfs_agblock_t *agbno,
473 xfs_extlen_t *aglen)
474{
475 int error;
476 int found_rec;
477
478 trace_xfs_refcount_merge_right_extent(cur->bc_mp,
479 cur->bc_private.a.agno, cright, right);
480
481 /*
482 * If the extent ending at agbno+aglen (cright) wasn't synthesized,
483 * remove it.
484 */
485 if (cright->rc_refcount > 1) {
486 error = xfs_refcount_lookup_le(cur, cright->rc_startblock,
487 &found_rec);
488 if (error)
489 goto out_error;
490 XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1,
491 out_error);
492
493 error = xfs_refcount_delete(cur, &found_rec);
494 if (error)
495 goto out_error;
496 XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1,
497 out_error);
498 }
499
500 /* Enlarge the right extent. */
501 error = xfs_refcount_lookup_le(cur, right->rc_startblock,
502 &found_rec);
503 if (error)
504 goto out_error;
505 XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error);
506
507 right->rc_startblock -= cright->rc_blockcount;
508 right->rc_blockcount += cright->rc_blockcount;
509 error = xfs_refcount_update(cur, right);
510 if (error)
511 goto out_error;
512
513 *aglen -= cright->rc_blockcount;
514 return error;
515
516out_error:
517 trace_xfs_refcount_merge_right_extent_error(cur->bc_mp,
518 cur->bc_private.a.agno, error, _RET_IP_);
519 return error;
520}
521
10e65503
DW
522#define XFS_FIND_RCEXT_SHARED 1
523#define XFS_FIND_RCEXT_COW 2
56ef8c33
DW
524/*
525 * Find the left extent and the one after it (cleft). This function assumes
526 * that we've already split any extent crossing agbno.
527 */
528STATIC int
529xfs_refcount_find_left_extents(
530 struct xfs_btree_cur *cur,
531 struct xfs_refcount_irec *left,
532 struct xfs_refcount_irec *cleft,
533 xfs_agblock_t agbno,
10e65503
DW
534 xfs_extlen_t aglen,
535 int flags)
56ef8c33
DW
536{
537 struct xfs_refcount_irec tmp;
538 int error;
539 int found_rec;
540
541 left->rc_startblock = cleft->rc_startblock = NULLAGBLOCK;
542 error = xfs_refcount_lookup_le(cur, agbno - 1, &found_rec);
543 if (error)
544 goto out_error;
545 if (!found_rec)
546 return 0;
547
548 error = xfs_refcount_get_rec(cur, &tmp, &found_rec);
549 if (error)
550 goto out_error;
551 XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error);
552
553 if (xfs_refc_next(&tmp) != agbno)
554 return 0;
10e65503
DW
555 if ((flags & XFS_FIND_RCEXT_SHARED) && tmp.rc_refcount < 2)
556 return 0;
557 if ((flags & XFS_FIND_RCEXT_COW) && tmp.rc_refcount > 1)
558 return 0;
56ef8c33
DW
559 /* We have a left extent; retrieve (or invent) the next right one */
560 *left = tmp;
561
562 error = xfs_btree_increment(cur, 0, &found_rec);
563 if (error)
564 goto out_error;
565 if (found_rec) {
566 error = xfs_refcount_get_rec(cur, &tmp, &found_rec);
567 if (error)
568 goto out_error;
569 XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1,
570 out_error);
571
572 /* if tmp starts at the end of our range, just use that */
573 if (tmp.rc_startblock == agbno)
574 *cleft = tmp;
575 else {
576 /*
577 * There's a gap in the refcntbt at the start of the
578 * range we're interested in (refcount == 1) so
579 * synthesize the implied extent and pass it back.
580 * We assume here that the agbno/aglen range was
581 * passed in from a data fork extent mapping and
582 * therefore is allocated to exactly one owner.
583 */
584 cleft->rc_startblock = agbno;
585 cleft->rc_blockcount = min(aglen,
586 tmp.rc_startblock - agbno);
587 cleft->rc_refcount = 1;
588 }
589 } else {
590 /*
591 * No extents, so pretend that there's one covering the whole
592 * range.
593 */
594 cleft->rc_startblock = agbno;
595 cleft->rc_blockcount = aglen;
596 cleft->rc_refcount = 1;
597 }
598 trace_xfs_refcount_find_left_extent(cur->bc_mp, cur->bc_private.a.agno,
599 left, cleft, agbno);
600 return error;
601
602out_error:
603 trace_xfs_refcount_find_left_extent_error(cur->bc_mp,
604 cur->bc_private.a.agno, error, _RET_IP_);
605 return error;
606}
607
608/*
609 * Find the right extent and the one before it (cright). This function
610 * assumes that we've already split any extents crossing agbno + aglen.
611 */
612STATIC int
613xfs_refcount_find_right_extents(
614 struct xfs_btree_cur *cur,
615 struct xfs_refcount_irec *right,
616 struct xfs_refcount_irec *cright,
617 xfs_agblock_t agbno,
10e65503
DW
618 xfs_extlen_t aglen,
619 int flags)
56ef8c33
DW
620{
621 struct xfs_refcount_irec tmp;
622 int error;
623 int found_rec;
624
625 right->rc_startblock = cright->rc_startblock = NULLAGBLOCK;
626 error = xfs_refcount_lookup_ge(cur, agbno + aglen, &found_rec);
627 if (error)
628 goto out_error;
629 if (!found_rec)
630 return 0;
631
632 error = xfs_refcount_get_rec(cur, &tmp, &found_rec);
633 if (error)
634 goto out_error;
635 XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error);
636
637 if (tmp.rc_startblock != agbno + aglen)
638 return 0;
10e65503
DW
639 if ((flags & XFS_FIND_RCEXT_SHARED) && tmp.rc_refcount < 2)
640 return 0;
641 if ((flags & XFS_FIND_RCEXT_COW) && tmp.rc_refcount > 1)
642 return 0;
56ef8c33
DW
643 /* We have a right extent; retrieve (or invent) the next left one */
644 *right = tmp;
645
646 error = xfs_btree_decrement(cur, 0, &found_rec);
647 if (error)
648 goto out_error;
649 if (found_rec) {
650 error = xfs_refcount_get_rec(cur, &tmp, &found_rec);
651 if (error)
652 goto out_error;
653 XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1,
654 out_error);
655
656 /* if tmp ends at the end of our range, just use that */
657 if (xfs_refc_next(&tmp) == agbno + aglen)
658 *cright = tmp;
659 else {
660 /*
661 * There's a gap in the refcntbt at the end of the
662 * range we're interested in (refcount == 1) so
663 * create the implied extent and pass it back.
664 * We assume here that the agbno/aglen range was
665 * passed in from a data fork extent mapping and
666 * therefore is allocated to exactly one owner.
667 */
668 cright->rc_startblock = max(agbno, xfs_refc_next(&tmp));
669 cright->rc_blockcount = right->rc_startblock -
670 cright->rc_startblock;
671 cright->rc_refcount = 1;
672 }
673 } else {
674 /*
675 * No extents, so pretend that there's one covering the whole
676 * range.
677 */
678 cright->rc_startblock = agbno;
679 cright->rc_blockcount = aglen;
680 cright->rc_refcount = 1;
681 }
682 trace_xfs_refcount_find_right_extent(cur->bc_mp, cur->bc_private.a.agno,
683 cright, right, agbno + aglen);
684 return error;
685
686out_error:
687 trace_xfs_refcount_find_right_extent_error(cur->bc_mp,
688 cur->bc_private.a.agno, error, _RET_IP_);
689 return error;
690}
691
692/* Is this extent valid? */
693static inline bool
694xfs_refc_valid(
695 struct xfs_refcount_irec *rc)
696{
697 return rc->rc_startblock != NULLAGBLOCK;
698}
699
700/*
701 * Try to merge with any extents on the boundaries of the adjustment range.
702 */
703STATIC int
704xfs_refcount_merge_extents(
705 struct xfs_btree_cur *cur,
706 xfs_agblock_t *agbno,
707 xfs_extlen_t *aglen,
708 enum xfs_refc_adjust_op adjust,
10e65503 709 int flags,
56ef8c33
DW
710 bool *shape_changed)
711{
712 struct xfs_refcount_irec left = {0}, cleft = {0};
713 struct xfs_refcount_irec cright = {0}, right = {0};
714 int error;
715 unsigned long long ulen;
716 bool cequal;
717
718 *shape_changed = false;
719 /*
720 * Find the extent just below agbno [left], just above agbno [cleft],
721 * just below (agbno + aglen) [cright], and just above (agbno + aglen)
722 * [right].
723 */
724 error = xfs_refcount_find_left_extents(cur, &left, &cleft, *agbno,
10e65503 725 *aglen, flags);
56ef8c33
DW
726 if (error)
727 return error;
728 error = xfs_refcount_find_right_extents(cur, &right, &cright, *agbno,
10e65503 729 *aglen, flags);
56ef8c33
DW
730 if (error)
731 return error;
732
733 /* No left or right extent to merge; exit. */
734 if (!xfs_refc_valid(&left) && !xfs_refc_valid(&right))
735 return 0;
736
737 cequal = (cleft.rc_startblock == cright.rc_startblock) &&
738 (cleft.rc_blockcount == cright.rc_blockcount);
739
740 /* Try to merge left, cleft, and right. cleft must == cright. */
741 ulen = (unsigned long long)left.rc_blockcount + cleft.rc_blockcount +
742 right.rc_blockcount;
743 if (xfs_refc_valid(&left) && xfs_refc_valid(&right) &&
744 xfs_refc_valid(&cleft) && xfs_refc_valid(&cright) && cequal &&
745 left.rc_refcount == cleft.rc_refcount + adjust &&
746 right.rc_refcount == cleft.rc_refcount + adjust &&
747 ulen < MAXREFCEXTLEN) {
748 *shape_changed = true;
749 return xfs_refcount_merge_center_extents(cur, &left, &cleft,
750 &right, ulen, agbno, aglen);
751 }
752
753 /* Try to merge left and cleft. */
754 ulen = (unsigned long long)left.rc_blockcount + cleft.rc_blockcount;
755 if (xfs_refc_valid(&left) && xfs_refc_valid(&cleft) &&
756 left.rc_refcount == cleft.rc_refcount + adjust &&
757 ulen < MAXREFCEXTLEN) {
758 *shape_changed = true;
759 error = xfs_refcount_merge_left_extent(cur, &left, &cleft,
760 agbno, aglen);
761 if (error)
762 return error;
763
764 /*
765 * If we just merged left + cleft and cleft == cright,
766 * we no longer have a cright to merge with right. We're done.
767 */
768 if (cequal)
769 return 0;
770 }
771
772 /* Try to merge cright and right. */
773 ulen = (unsigned long long)right.rc_blockcount + cright.rc_blockcount;
774 if (xfs_refc_valid(&right) && xfs_refc_valid(&cright) &&
775 right.rc_refcount == cright.rc_refcount + adjust &&
776 ulen < MAXREFCEXTLEN) {
777 *shape_changed = true;
778 return xfs_refcount_merge_right_extent(cur, &right, &cright,
779 agbno, aglen);
780 }
781
782 return error;
783}
784
785/*
786 * While we're adjusting the refcounts records of an extent, we have
787 * to keep an eye on the number of extents we're dirtying -- run too
788 * many in a single transaction and we'll exceed the transaction's
789 * reservation and crash the fs. Each record adds 12 bytes to the
790 * log (plus any key updates) so we'll conservatively assume 24 bytes
791 * per record. We must also leave space for btree splits on both ends
792 * of the range and space for the CUD and a new CUI.
793 *
794 * XXX: This is a pretty hand-wavy estimate. The penalty for guessing
795 * true incorrectly is a shutdown FS; the penalty for guessing false
796 * incorrectly is more transaction rolls than might be necessary.
797 * Be conservative here.
798 */
799static bool
800xfs_refcount_still_have_space(
801 struct xfs_btree_cur *cur)
802{
803 unsigned long overhead;
804
805 overhead = cur->bc_private.a.priv.refc.shape_changes *
806 xfs_allocfree_log_count(cur->bc_mp, 1);
807 overhead *= cur->bc_mp->m_sb.sb_blocksize;
808
809 /*
810 * Only allow 2 refcount extent updates per transaction if the
811 * refcount continue update "error" has been injected.
812 */
813 if (cur->bc_private.a.priv.refc.nr_ops > 2 &&
814 XFS_TEST_ERROR(false, cur->bc_mp,
815 XFS_ERRTAG_REFCOUNT_CONTINUE_UPDATE,
816 XFS_RANDOM_REFCOUNT_CONTINUE_UPDATE))
817 return false;
818
819 if (cur->bc_private.a.priv.refc.nr_ops == 0)
820 return true;
821 else if (overhead > cur->bc_tp->t_log_res)
822 return false;
823 return cur->bc_tp->t_log_res - overhead >
824 cur->bc_private.a.priv.refc.nr_ops * 32;
825}
826
827/*
828 * Adjust the refcounts of middle extents. At this point we should have
829 * split extents that crossed the adjustment range; merged with adjacent
830 * extents; and updated agbno/aglen to reflect the merges. Therefore,
831 * all we have to do is update the extents inside [agbno, agbno + aglen].
832 */
833STATIC int
834xfs_refcount_adjust_extents(
835 struct xfs_btree_cur *cur,
836 xfs_agblock_t *agbno,
837 xfs_extlen_t *aglen,
838 enum xfs_refc_adjust_op adj,
839 struct xfs_defer_ops *dfops,
840 struct xfs_owner_info *oinfo)
841{
842 struct xfs_refcount_irec ext, tmp;
843 int error;
844 int found_rec, found_tmp;
845 xfs_fsblock_t fsbno;
846
847 /* Merging did all the work already. */
848 if (*aglen == 0)
849 return 0;
850
851 error = xfs_refcount_lookup_ge(cur, *agbno, &found_rec);
852 if (error)
853 goto out_error;
854
855 while (*aglen > 0 && xfs_refcount_still_have_space(cur)) {
856 error = xfs_refcount_get_rec(cur, &ext, &found_rec);
857 if (error)
858 goto out_error;
859 if (!found_rec) {
860 ext.rc_startblock = cur->bc_mp->m_sb.sb_agblocks;
861 ext.rc_blockcount = 0;
862 ext.rc_refcount = 0;
863 }
864
865 /*
866 * Deal with a hole in the refcount tree; if a file maps to
867 * these blocks and there's no refcountbt record, pretend that
868 * there is one with refcount == 1.
869 */
870 if (ext.rc_startblock != *agbno) {
871 tmp.rc_startblock = *agbno;
872 tmp.rc_blockcount = min(*aglen,
873 ext.rc_startblock - *agbno);
874 tmp.rc_refcount = 1 + adj;
875 trace_xfs_refcount_modify_extent(cur->bc_mp,
876 cur->bc_private.a.agno, &tmp);
877
878 /*
879 * Either cover the hole (increment) or
880 * delete the range (decrement).
881 */
882 if (tmp.rc_refcount) {
883 error = xfs_refcount_insert(cur, &tmp,
884 &found_tmp);
885 if (error)
886 goto out_error;
887 XFS_WANT_CORRUPTED_GOTO(cur->bc_mp,
888 found_tmp == 1, out_error);
889 cur->bc_private.a.priv.refc.nr_ops++;
890 } else {
891 fsbno = XFS_AGB_TO_FSB(cur->bc_mp,
892 cur->bc_private.a.agno,
893 tmp.rc_startblock);
894 xfs_bmap_add_free(cur->bc_mp, dfops, fsbno,
895 tmp.rc_blockcount, oinfo);
896 }
897
898 (*agbno) += tmp.rc_blockcount;
899 (*aglen) -= tmp.rc_blockcount;
900
901 error = xfs_refcount_lookup_ge(cur, *agbno,
902 &found_rec);
903 if (error)
904 goto out_error;
905 }
906
907 /* Stop if there's nothing left to modify */
908 if (*aglen == 0 || !xfs_refcount_still_have_space(cur))
909 break;
910
911 /*
912 * Adjust the reference count and either update the tree
913 * (incr) or free the blocks (decr).
914 */
915 if (ext.rc_refcount == MAXREFCOUNT)
916 goto skip;
917 ext.rc_refcount += adj;
918 trace_xfs_refcount_modify_extent(cur->bc_mp,
919 cur->bc_private.a.agno, &ext);
920 if (ext.rc_refcount > 1) {
921 error = xfs_refcount_update(cur, &ext);
922 if (error)
923 goto out_error;
924 cur->bc_private.a.priv.refc.nr_ops++;
925 } else if (ext.rc_refcount == 1) {
926 error = xfs_refcount_delete(cur, &found_rec);
927 if (error)
928 goto out_error;
929 XFS_WANT_CORRUPTED_GOTO(cur->bc_mp,
930 found_rec == 1, out_error);
931 cur->bc_private.a.priv.refc.nr_ops++;
932 goto advloop;
933 } else {
934 fsbno = XFS_AGB_TO_FSB(cur->bc_mp,
935 cur->bc_private.a.agno,
936 ext.rc_startblock);
937 xfs_bmap_add_free(cur->bc_mp, dfops, fsbno,
938 ext.rc_blockcount, oinfo);
939 }
940
941skip:
942 error = xfs_btree_increment(cur, 0, &found_rec);
943 if (error)
944 goto out_error;
945
946advloop:
947 (*agbno) += ext.rc_blockcount;
948 (*aglen) -= ext.rc_blockcount;
949 }
950
951 return error;
952out_error:
953 trace_xfs_refcount_modify_extent_error(cur->bc_mp,
954 cur->bc_private.a.agno, error, _RET_IP_);
955 return error;
956}
957
958/* Adjust the reference count of a range of AG blocks. */
959STATIC int
960xfs_refcount_adjust(
961 struct xfs_btree_cur *cur,
962 xfs_agblock_t agbno,
963 xfs_extlen_t aglen,
964 xfs_agblock_t *new_agbno,
965 xfs_extlen_t *new_aglen,
966 enum xfs_refc_adjust_op adj,
967 struct xfs_defer_ops *dfops,
968 struct xfs_owner_info *oinfo)
969{
970 bool shape_changed;
971 int shape_changes = 0;
972 int error;
973
974 *new_agbno = agbno;
975 *new_aglen = aglen;
976 if (adj == XFS_REFCOUNT_ADJUST_INCREASE)
977 trace_xfs_refcount_increase(cur->bc_mp, cur->bc_private.a.agno,
978 agbno, aglen);
979 else
980 trace_xfs_refcount_decrease(cur->bc_mp, cur->bc_private.a.agno,
981 agbno, aglen);
982
983 /*
984 * Ensure that no rcextents cross the boundary of the adjustment range.
985 */
986 error = xfs_refcount_split_extent(cur, agbno, &shape_changed);
987 if (error)
988 goto out_error;
989 if (shape_changed)
990 shape_changes++;
991
992 error = xfs_refcount_split_extent(cur, agbno + aglen, &shape_changed);
993 if (error)
994 goto out_error;
995 if (shape_changed)
996 shape_changes++;
997
998 /*
999 * Try to merge with the left or right extents of the range.
1000 */
1001 error = xfs_refcount_merge_extents(cur, new_agbno, new_aglen, adj,
10e65503 1002 XFS_FIND_RCEXT_SHARED, &shape_changed);
56ef8c33
DW
1003 if (error)
1004 goto out_error;
1005 if (shape_changed)
1006 shape_changes++;
1007 if (shape_changes)
1008 cur->bc_private.a.priv.refc.shape_changes++;
1009
1010 /* Now that we've taken care of the ends, adjust the middle extents */
1011 error = xfs_refcount_adjust_extents(cur, new_agbno, new_aglen,
1012 adj, dfops, oinfo);
1013 if (error)
1014 goto out_error;
1015
1016 return 0;
1017
1018out_error:
1019 trace_xfs_refcount_adjust_error(cur->bc_mp, cur->bc_private.a.agno,
1020 error, _RET_IP_);
1021 return error;
1022}
23a15a6c
DW
1023
1024/* Clean up after calling xfs_refcount_finish_one. */
1025void
1026xfs_refcount_finish_one_cleanup(
1027 struct xfs_trans *tp,
1028 struct xfs_btree_cur *rcur,
1029 int error)
1030{
1031 struct xfs_buf *agbp;
1032
1033 if (rcur == NULL)
1034 return;
1035 agbp = rcur->bc_private.a.agbp;
1036 xfs_btree_del_cursor(rcur, error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR);
1037 if (error)
1038 xfs_trans_brelse(tp, agbp);
1039}
1040
1041/*
1042 * Process one of the deferred refcount operations. We pass back the
1043 * btree cursor to maintain our lock on the btree between calls.
1044 * This saves time and eliminates a buffer deadlock between the
1045 * superblock and the AGF because we'll always grab them in the same
1046 * order.
1047 */
1048int
1049xfs_refcount_finish_one(
1050 struct xfs_trans *tp,
1051 struct xfs_defer_ops *dfops,
1052 enum xfs_refcount_intent_type type,
1053 xfs_fsblock_t startblock,
1054 xfs_extlen_t blockcount,
1055 xfs_fsblock_t *new_fsb,
1056 xfs_extlen_t *new_len,
1057 struct xfs_btree_cur **pcur)
1058{
1059 struct xfs_mount *mp = tp->t_mountp;
1060 struct xfs_btree_cur *rcur;
1061 struct xfs_buf *agbp = NULL;
1062 int error = 0;
1063 xfs_agnumber_t agno;
1064 xfs_agblock_t bno;
1065 xfs_agblock_t new_agbno;
1066 unsigned long nr_ops = 0;
1067 int shape_changes = 0;
1068
1069 agno = XFS_FSB_TO_AGNO(mp, startblock);
1070 ASSERT(agno != NULLAGNUMBER);
1071 bno = XFS_FSB_TO_AGBNO(mp, startblock);
1072
1073 trace_xfs_refcount_deferred(mp, XFS_FSB_TO_AGNO(mp, startblock),
1074 type, XFS_FSB_TO_AGBNO(mp, startblock),
1075 blockcount);
1076
1077 if (XFS_TEST_ERROR(false, mp,
1078 XFS_ERRTAG_REFCOUNT_FINISH_ONE,
1079 XFS_RANDOM_REFCOUNT_FINISH_ONE))
1080 return -EIO;
1081
1082 /*
1083 * If we haven't gotten a cursor or the cursor AG doesn't match
1084 * the startblock, get one now.
1085 */
1086 rcur = *pcur;
1087 if (rcur != NULL && rcur->bc_private.a.agno != agno) {
1088 nr_ops = rcur->bc_private.a.priv.refc.nr_ops;
1089 shape_changes = rcur->bc_private.a.priv.refc.shape_changes;
1090 xfs_refcount_finish_one_cleanup(tp, rcur, 0);
1091 rcur = NULL;
1092 *pcur = NULL;
1093 }
1094 if (rcur == NULL) {
1095 error = xfs_alloc_read_agf(tp->t_mountp, tp, agno,
1096 XFS_ALLOC_FLAG_FREEING, &agbp);
1097 if (error)
1098 return error;
1099 if (!agbp)
1100 return -EFSCORRUPTED;
1101
1102 rcur = xfs_refcountbt_init_cursor(mp, tp, agbp, agno, dfops);
1103 if (!rcur) {
1104 error = -ENOMEM;
1105 goto out_cur;
1106 }
1107 rcur->bc_private.a.priv.refc.nr_ops = nr_ops;
1108 rcur->bc_private.a.priv.refc.shape_changes = shape_changes;
1109 }
1110 *pcur = rcur;
1111
1112 switch (type) {
1113 case XFS_REFCOUNT_INCREASE:
1114 error = xfs_refcount_adjust(rcur, bno, blockcount, &new_agbno,
1115 new_len, XFS_REFCOUNT_ADJUST_INCREASE, dfops, NULL);
1116 *new_fsb = XFS_AGB_TO_FSB(mp, agno, new_agbno);
1117 break;
1118 case XFS_REFCOUNT_DECREASE:
1119 error = xfs_refcount_adjust(rcur, bno, blockcount, &new_agbno,
1120 new_len, XFS_REFCOUNT_ADJUST_DECREASE, dfops, NULL);
1121 *new_fsb = XFS_AGB_TO_FSB(mp, agno, new_agbno);
1122 break;
10e65503
DW
1123 case XFS_REFCOUNT_ALLOC_COW:
1124 *new_fsb = startblock + blockcount;
1125 *new_len = 0;
1126 error = __xfs_refcount_cow_alloc(rcur, bno, blockcount, dfops);
1127 break;
1128 case XFS_REFCOUNT_FREE_COW:
1129 *new_fsb = startblock + blockcount;
1130 *new_len = 0;
1131 error = __xfs_refcount_cow_free(rcur, bno, blockcount, dfops);
1132 break;
23a15a6c
DW
1133 default:
1134 ASSERT(0);
1135 error = -EFSCORRUPTED;
1136 }
1137 if (!error && *new_len > 0)
1138 trace_xfs_refcount_finish_one_leftover(mp, agno, type,
1139 bno, blockcount, new_agbno, *new_len);
1140 return error;
1141
1142out_cur:
1143 xfs_trans_brelse(tp, agbp);
1144
1145 return error;
1146}
1147
1148/*
1149 * Record a refcount intent for later processing.
1150 */
1151static int
1152__xfs_refcount_add(
1153 struct xfs_mount *mp,
1154 struct xfs_defer_ops *dfops,
1155 enum xfs_refcount_intent_type type,
1156 xfs_fsblock_t startblock,
1157 xfs_extlen_t blockcount)
1158{
1159 struct xfs_refcount_intent *ri;
1160
1161 trace_xfs_refcount_defer(mp, XFS_FSB_TO_AGNO(mp, startblock),
1162 type, XFS_FSB_TO_AGBNO(mp, startblock),
1163 blockcount);
1164
1165 ri = kmem_alloc(sizeof(struct xfs_refcount_intent),
1166 KM_SLEEP | KM_NOFS);
1167 INIT_LIST_HEAD(&ri->ri_list);
1168 ri->ri_type = type;
1169 ri->ri_startblock = startblock;
1170 ri->ri_blockcount = blockcount;
1171
1172 xfs_defer_add(dfops, XFS_DEFER_OPS_TYPE_REFCOUNT, &ri->ri_list);
1173 return 0;
1174}
1175
1176/*
1177 * Increase the reference count of the blocks backing a file's extent.
1178 */
1179int
1180xfs_refcount_increase_extent(
1181 struct xfs_mount *mp,
1182 struct xfs_defer_ops *dfops,
1183 struct xfs_bmbt_irec *PREV)
1184{
1185 if (!xfs_sb_version_hasreflink(&mp->m_sb))
1186 return 0;
1187
1188 return __xfs_refcount_add(mp, dfops, XFS_REFCOUNT_INCREASE,
1189 PREV->br_startblock, PREV->br_blockcount);
1190}
1191
1192/*
1193 * Decrease the reference count of the blocks backing a file's extent.
1194 */
1195int
1196xfs_refcount_decrease_extent(
1197 struct xfs_mount *mp,
1198 struct xfs_defer_ops *dfops,
1199 struct xfs_bmbt_irec *PREV)
1200{
1201 if (!xfs_sb_version_hasreflink(&mp->m_sb))
1202 return 0;
1203
1204 return __xfs_refcount_add(mp, dfops, XFS_REFCOUNT_DECREASE,
1205 PREV->br_startblock, PREV->br_blockcount);
1206}
94097330
DW
1207
1208/*
1209 * Given an AG extent, find the lowest-numbered run of shared blocks
1210 * within that range and return the range in fbno/flen. If
1211 * find_end_of_shared is set, return the longest contiguous extent of
1212 * shared blocks; if not, just return the first extent we find. If no
1213 * shared blocks are found, fbno and flen will be set to NULLAGBLOCK
1214 * and 0, respectively.
1215 */
1216int
1217xfs_refcount_find_shared(
1218 struct xfs_btree_cur *cur,
1219 xfs_agblock_t agbno,
1220 xfs_extlen_t aglen,
1221 xfs_agblock_t *fbno,
1222 xfs_extlen_t *flen,
1223 bool find_end_of_shared)
1224{
1225 struct xfs_refcount_irec tmp;
1226 int i;
1227 int have;
1228 int error;
1229
1230 trace_xfs_refcount_find_shared(cur->bc_mp, cur->bc_private.a.agno,
1231 agbno, aglen);
1232
1233 /* By default, skip the whole range */
1234 *fbno = NULLAGBLOCK;
1235 *flen = 0;
1236
1237 /* Try to find a refcount extent that crosses the start */
1238 error = xfs_refcount_lookup_le(cur, agbno, &have);
1239 if (error)
1240 goto out_error;
1241 if (!have) {
1242 /* No left extent, look at the next one */
1243 error = xfs_btree_increment(cur, 0, &have);
1244 if (error)
1245 goto out_error;
1246 if (!have)
1247 goto done;
1248 }
1249 error = xfs_refcount_get_rec(cur, &tmp, &i);
1250 if (error)
1251 goto out_error;
1252 XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, i == 1, out_error);
1253
1254 /* If the extent ends before the start, look at the next one */
1255 if (tmp.rc_startblock + tmp.rc_blockcount <= agbno) {
1256 error = xfs_btree_increment(cur, 0, &have);
1257 if (error)
1258 goto out_error;
1259 if (!have)
1260 goto done;
1261 error = xfs_refcount_get_rec(cur, &tmp, &i);
1262 if (error)
1263 goto out_error;
1264 XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, i == 1, out_error);
1265 }
1266
1267 /* If the extent starts after the range we want, bail out */
1268 if (tmp.rc_startblock >= agbno + aglen)
1269 goto done;
1270
1271 /* We found the start of a shared extent! */
1272 if (tmp.rc_startblock < agbno) {
1273 tmp.rc_blockcount -= (agbno - tmp.rc_startblock);
1274 tmp.rc_startblock = agbno;
1275 }
1276
1277 *fbno = tmp.rc_startblock;
1278 *flen = min(tmp.rc_blockcount, agbno + aglen - *fbno);
1279 if (!find_end_of_shared)
1280 goto done;
1281
1282 /* Otherwise, find the end of this shared extent */
1283 while (*fbno + *flen < agbno + aglen) {
1284 error = xfs_btree_increment(cur, 0, &have);
1285 if (error)
1286 goto out_error;
1287 if (!have)
1288 break;
1289 error = xfs_refcount_get_rec(cur, &tmp, &i);
1290 if (error)
1291 goto out_error;
1292 XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, i == 1, out_error);
1293 if (tmp.rc_startblock >= agbno + aglen ||
1294 tmp.rc_startblock != *fbno + *flen)
1295 break;
1296 *flen = min(*flen + tmp.rc_blockcount, agbno + aglen - *fbno);
1297 }
1298
1299done:
1300 trace_xfs_refcount_find_shared_result(cur->bc_mp,
1301 cur->bc_private.a.agno, *fbno, *flen);
1302
1303out_error:
1304 if (error)
1305 trace_xfs_refcount_find_shared_error(cur->bc_mp,
1306 cur->bc_private.a.agno, error, _RET_IP_);
1307 return error;
1308}
10e65503
DW
1309
1310/*
1311 * Recovering CoW Blocks After a Crash
1312 *
1313 * Due to the way that the copy on write mechanism works, there's a window of
1314 * opportunity in which we can lose track of allocated blocks during a crash.
1315 * Because CoW uses delayed allocation in the in-core CoW fork, writeback
1316 * causes blocks to be allocated and stored in the CoW fork. The blocks are
1317 * no longer in the free space btree but are not otherwise recorded anywhere
1318 * until the write completes and the blocks are mapped into the file. A crash
1319 * in between allocation and remapping results in the replacement blocks being
1320 * lost. This situation is exacerbated by the CoW extent size hint because
1321 * allocations can hang around for long time.
1322 *
1323 * However, there is a place where we can record these allocations before they
1324 * become mappings -- the reference count btree. The btree does not record
1325 * extents with refcount == 1, so we can record allocations with a refcount of
1326 * 1. Blocks being used for CoW writeout cannot be shared, so there should be
1327 * no conflict with shared block records. These mappings should be created
1328 * when we allocate blocks to the CoW fork and deleted when they're removed
1329 * from the CoW fork.
1330 *
1331 * Minor nit: records for in-progress CoW allocations and records for shared
1332 * extents must never be merged, to preserve the property that (except for CoW
1333 * allocations) there are no refcount btree entries with refcount == 1. The
1334 * only time this could potentially happen is when unsharing a block that's
1335 * adjacent to CoW allocations, so we must be careful to avoid this.
1336 *
1337 * At mount time we recover lost CoW allocations by searching the refcount
1338 * btree for these refcount == 1 mappings. These represent CoW allocations
1339 * that were in progress at the time the filesystem went down, so we can free
1340 * them to get the space back.
1341 *
1342 * This mechanism is superior to creating EFIs for unmapped CoW extents for
1343 * several reasons -- first, EFIs pin the tail of the log and would have to be
1344 * periodically relogged to avoid filling up the log. Second, CoW completions
1345 * will have to file an EFD and create new EFIs for whatever remains in the
1346 * CoW fork; this partially takes care of (1) but extent-size reservations
1347 * will have to periodically relog even if there's no writeout in progress.
1348 * This can happen if the CoW extent size hint is set, which you really want.
1349 * Third, EFIs cannot currently be automatically relogged into newer
1350 * transactions to advance the log tail. Fourth, stuffing the log full of
1351 * EFIs places an upper bound on the number of CoW allocations that can be
1352 * held filesystem-wide at any given time. Recording them in the refcount
1353 * btree doesn't require us to maintain any state in memory and doesn't pin
1354 * the log.
1355 */
1356/*
1357 * Adjust the refcounts of CoW allocations. These allocations are "magic"
1358 * in that they're not referenced anywhere else in the filesystem, so we
1359 * stash them in the refcount btree with a refcount of 1 until either file
1360 * remapping (or CoW cancellation) happens.
1361 */
1362STATIC int
1363xfs_refcount_adjust_cow_extents(
1364 struct xfs_btree_cur *cur,
1365 xfs_agblock_t agbno,
1366 xfs_extlen_t aglen,
1367 enum xfs_refc_adjust_op adj,
1368 struct xfs_defer_ops *dfops,
1369 struct xfs_owner_info *oinfo)
1370{
1371 struct xfs_refcount_irec ext, tmp;
1372 int error;
1373 int found_rec, found_tmp;
1374
1375 if (aglen == 0)
1376 return 0;
1377
1378 /* Find any overlapping refcount records */
1379 error = xfs_refcount_lookup_ge(cur, agbno, &found_rec);
1380 if (error)
1381 goto out_error;
1382 error = xfs_refcount_get_rec(cur, &ext, &found_rec);
1383 if (error)
1384 goto out_error;
1385 if (!found_rec) {
1386 ext.rc_startblock = cur->bc_mp->m_sb.sb_agblocks +
1387 XFS_REFC_COW_START;
1388 ext.rc_blockcount = 0;
1389 ext.rc_refcount = 0;
1390 }
1391
1392 switch (adj) {
1393 case XFS_REFCOUNT_ADJUST_COW_ALLOC:
1394 /* Adding a CoW reservation, there should be nothing here. */
1395 XFS_WANT_CORRUPTED_GOTO(cur->bc_mp,
1396 ext.rc_startblock >= agbno + aglen, out_error);
1397
1398 tmp.rc_startblock = agbno;
1399 tmp.rc_blockcount = aglen;
1400 tmp.rc_refcount = 1;
1401 trace_xfs_refcount_modify_extent(cur->bc_mp,
1402 cur->bc_private.a.agno, &tmp);
1403
1404 error = xfs_refcount_insert(cur, &tmp,
1405 &found_tmp);
1406 if (error)
1407 goto out_error;
1408 XFS_WANT_CORRUPTED_GOTO(cur->bc_mp,
1409 found_tmp == 1, out_error);
1410 break;
1411 case XFS_REFCOUNT_ADJUST_COW_FREE:
1412 /* Removing a CoW reservation, there should be one extent. */
1413 XFS_WANT_CORRUPTED_GOTO(cur->bc_mp,
1414 ext.rc_startblock == agbno, out_error);
1415 XFS_WANT_CORRUPTED_GOTO(cur->bc_mp,
1416 ext.rc_blockcount == aglen, out_error);
1417 XFS_WANT_CORRUPTED_GOTO(cur->bc_mp,
1418 ext.rc_refcount == 1, out_error);
1419
1420 ext.rc_refcount = 0;
1421 trace_xfs_refcount_modify_extent(cur->bc_mp,
1422 cur->bc_private.a.agno, &ext);
1423 error = xfs_refcount_delete(cur, &found_rec);
1424 if (error)
1425 goto out_error;
1426 XFS_WANT_CORRUPTED_GOTO(cur->bc_mp,
1427 found_rec == 1, out_error);
1428 break;
1429 default:
1430 ASSERT(0);
1431 }
1432
1433 return error;
1434out_error:
1435 trace_xfs_refcount_modify_extent_error(cur->bc_mp,
1436 cur->bc_private.a.agno, error, _RET_IP_);
1437 return error;
1438}
1439
1440/*
1441 * Add or remove refcount btree entries for CoW reservations.
1442 */
1443STATIC int
1444xfs_refcount_adjust_cow(
1445 struct xfs_btree_cur *cur,
1446 xfs_agblock_t agbno,
1447 xfs_extlen_t aglen,
1448 enum xfs_refc_adjust_op adj,
1449 struct xfs_defer_ops *dfops)
1450{
1451 bool shape_changed;
1452 int error;
1453
1454 agbno += XFS_REFC_COW_START;
1455
1456 /*
1457 * Ensure that no rcextents cross the boundary of the adjustment range.
1458 */
1459 error = xfs_refcount_split_extent(cur, agbno, &shape_changed);
1460 if (error)
1461 goto out_error;
1462
1463 error = xfs_refcount_split_extent(cur, agbno + aglen, &shape_changed);
1464 if (error)
1465 goto out_error;
1466
1467 /*
1468 * Try to merge with the left or right extents of the range.
1469 */
1470 error = xfs_refcount_merge_extents(cur, &agbno, &aglen, adj,
1471 XFS_FIND_RCEXT_COW, &shape_changed);
1472 if (error)
1473 goto out_error;
1474
1475 /* Now that we've taken care of the ends, adjust the middle extents */
1476 error = xfs_refcount_adjust_cow_extents(cur, agbno, aglen, adj,
1477 dfops, NULL);
1478 if (error)
1479 goto out_error;
1480
1481 return 0;
1482
1483out_error:
1484 trace_xfs_refcount_adjust_cow_error(cur->bc_mp, cur->bc_private.a.agno,
1485 error, _RET_IP_);
1486 return error;
1487}
1488
1489/*
1490 * Record a CoW allocation in the refcount btree.
1491 */
1492STATIC int
1493__xfs_refcount_cow_alloc(
1494 struct xfs_btree_cur *rcur,
1495 xfs_agblock_t agbno,
1496 xfs_extlen_t aglen,
1497 struct xfs_defer_ops *dfops)
1498{
1499 int error;
1500
1501 trace_xfs_refcount_cow_increase(rcur->bc_mp, rcur->bc_private.a.agno,
1502 agbno, aglen);
1503
1504 /* Add refcount btree reservation */
1505 error = xfs_refcount_adjust_cow(rcur, agbno, aglen,
1506 XFS_REFCOUNT_ADJUST_COW_ALLOC, dfops);
1507 if (error)
1508 return error;
1509
1510 /* Add rmap entry */
1511 if (xfs_sb_version_hasrmapbt(&rcur->bc_mp->m_sb)) {
1512 error = xfs_rmap_alloc_extent(rcur->bc_mp, dfops,
1513 rcur->bc_private.a.agno,
1514 agbno, aglen, XFS_RMAP_OWN_COW);
1515 if (error)
1516 return error;
1517 }
1518
1519 return error;
1520}
1521
1522/*
1523 * Remove a CoW allocation from the refcount btree.
1524 */
1525STATIC int
1526__xfs_refcount_cow_free(
1527 struct xfs_btree_cur *rcur,
1528 xfs_agblock_t agbno,
1529 xfs_extlen_t aglen,
1530 struct xfs_defer_ops *dfops)
1531{
1532 int error;
1533
1534 trace_xfs_refcount_cow_decrease(rcur->bc_mp, rcur->bc_private.a.agno,
1535 agbno, aglen);
1536
1537 /* Remove refcount btree reservation */
1538 error = xfs_refcount_adjust_cow(rcur, agbno, aglen,
1539 XFS_REFCOUNT_ADJUST_COW_FREE, dfops);
1540 if (error)
1541 return error;
1542
1543 /* Remove rmap entry */
1544 if (xfs_sb_version_hasrmapbt(&rcur->bc_mp->m_sb)) {
1545 error = xfs_rmap_free_extent(rcur->bc_mp, dfops,
1546 rcur->bc_private.a.agno,
1547 agbno, aglen, XFS_RMAP_OWN_COW);
1548 if (error)
1549 return error;
1550 }
1551
1552 return error;
1553}
1554
1555/* Record a CoW staging extent in the refcount btree. */
1556int
1557xfs_refcount_alloc_cow_extent(
1558 struct xfs_mount *mp,
1559 struct xfs_defer_ops *dfops,
1560 xfs_fsblock_t fsb,
1561 xfs_extlen_t len)
1562{
1563 if (!xfs_sb_version_hasreflink(&mp->m_sb))
1564 return 0;
1565
1566 return __xfs_refcount_add(mp, dfops, XFS_REFCOUNT_ALLOC_COW,
1567 fsb, len);
1568}
1569
1570/* Forget a CoW staging event in the refcount btree. */
1571int
1572xfs_refcount_free_cow_extent(
1573 struct xfs_mount *mp,
1574 struct xfs_defer_ops *dfops,
1575 xfs_fsblock_t fsb,
1576 xfs_extlen_t len)
1577{
1578 if (!xfs_sb_version_hasreflink(&mp->m_sb))
1579 return 0;
1580
1581 return __xfs_refcount_add(mp, dfops, XFS_REFCOUNT_FREE_COW,
1582 fsb, len);
1583}
1584
1585struct xfs_refcount_recovery {
1586 struct list_head rr_list;
1587 struct xfs_refcount_irec rr_rrec;
1588};
1589
1590/* Stuff an extent on the recovery list. */
1591STATIC int
1592xfs_refcount_recover_extent(
1593 struct xfs_btree_cur *cur,
1594 union xfs_btree_rec *rec,
1595 void *priv)
1596{
1597 struct list_head *debris = priv;
1598 struct xfs_refcount_recovery *rr;
1599
1600 if (be32_to_cpu(rec->refc.rc_refcount) != 1)
1601 return -EFSCORRUPTED;
1602
1603 rr = kmem_alloc(sizeof(struct xfs_refcount_recovery), KM_SLEEP);
1604 xfs_refcount_btrec_to_irec(rec, &rr->rr_rrec);
1605 list_add_tail(&rr->rr_list, debris);
1606
1607 return 0;
1608}
1609
1610/* Find and remove leftover CoW reservations. */
1611int
1612xfs_refcount_recover_cow_leftovers(
1613 struct xfs_mount *mp,
1614 xfs_agnumber_t agno)
1615{
1616 struct xfs_trans *tp;
1617 struct xfs_btree_cur *cur;
1618 struct xfs_buf *agbp;
1619 struct xfs_refcount_recovery *rr, *n;
1620 struct list_head debris;
1621 union xfs_btree_irec low;
1622 union xfs_btree_irec high;
1623 struct xfs_defer_ops dfops;
1624 xfs_fsblock_t fsb;
1625 xfs_agblock_t agbno;
1626 int error;
1627
1628 if (mp->m_sb.sb_agblocks >= XFS_REFC_COW_START)
1629 return -EOPNOTSUPP;
1630
1631 error = xfs_alloc_read_agf(mp, NULL, agno, 0, &agbp);
1632 if (error)
1633 return error;
1634 cur = xfs_refcountbt_init_cursor(mp, NULL, agbp, agno, NULL);
1635
1636 /* Find all the leftover CoW staging extents. */
1637 INIT_LIST_HEAD(&debris);
1638 memset(&low, 0, sizeof(low));
1639 memset(&high, 0, sizeof(high));
1640 low.rc.rc_startblock = XFS_REFC_COW_START;
1641 high.rc.rc_startblock = -1U;
1642 error = xfs_btree_query_range(cur, &low, &high,
1643 xfs_refcount_recover_extent, &debris);
1644 if (error)
22a69322 1645 goto out_cursor;
10e65503
DW
1646 xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
1647 xfs_buf_relse(agbp);
1648
1649 /* Now iterate the list to free the leftovers */
1650 list_for_each_entry(rr, &debris, rr_list) {
1651 /* Set up transaction. */
1652 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, 0, 0, 0, &tp);
1653 if (error)
1654 goto out_free;
1655
1656 trace_xfs_refcount_recover_extent(mp, agno, &rr->rr_rrec);
1657
1658 /* Free the orphan record */
1659 xfs_defer_init(&dfops, &fsb);
1660 agbno = rr->rr_rrec.rc_startblock - XFS_REFC_COW_START;
1661 fsb = XFS_AGB_TO_FSB(mp, agno, agbno);
1662 error = xfs_refcount_free_cow_extent(mp, &dfops, fsb,
1663 rr->rr_rrec.rc_blockcount);
1664 if (error)
1665 goto out_defer;
1666
1667 /* Free the block. */
1668 xfs_bmap_add_free(mp, &dfops, fsb,
1669 rr->rr_rrec.rc_blockcount, NULL);
1670
1671 error = xfs_defer_finish(&tp, &dfops, NULL);
1672 if (error)
1673 goto out_defer;
1674
1675 error = xfs_trans_commit(tp);
1676 if (error)
22a69322 1677 goto out_free;
10e65503 1678 }
10e65503
DW
1679
1680out_free:
1681 /* Free the leftover list */
1682 list_for_each_entry_safe(rr, n, &debris, rr_list) {
1683 list_del(&rr->rr_list);
1684 kmem_free(rr);
1685 }
10e65503
DW
1686 return error;
1687
22a69322 1688out_cursor:
10e65503
DW
1689 xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
1690 xfs_buf_relse(agbp);
22a69322
DW
1691 goto out_free;
1692
1693out_defer:
1694 xfs_defer_cancel(&dfops);
1695 xfs_trans_cancel(tp);
1696 goto out_free;
10e65503 1697}