Mention branches and keyring.
[releases.git] / libxfs / xfs_rmap.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2014 Red Hat, 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_sb.h"
15 #include "xfs_defer.h"
16 #include "xfs_btree.h"
17 #include "xfs_trans.h"
18 #include "xfs_alloc.h"
19 #include "xfs_rmap.h"
20 #include "xfs_rmap_btree.h"
21 #include "xfs_trace.h"
22 #include "xfs_errortag.h"
23 #include "xfs_error.h"
24 #include "xfs_inode.h"
25 #include "xfs_ag.h"
26
27 struct kmem_cache       *xfs_rmap_intent_cache;
28
29 /*
30  * Lookup the first record less than or equal to [bno, len, owner, offset]
31  * in the btree given by cur.
32  */
33 int
34 xfs_rmap_lookup_le(
35         struct xfs_btree_cur    *cur,
36         xfs_agblock_t           bno,
37         uint64_t                owner,
38         uint64_t                offset,
39         unsigned int            flags,
40         struct xfs_rmap_irec    *irec,
41         int                     *stat)
42 {
43         int                     get_stat = 0;
44         int                     error;
45
46         cur->bc_rec.r.rm_startblock = bno;
47         cur->bc_rec.r.rm_blockcount = 0;
48         cur->bc_rec.r.rm_owner = owner;
49         cur->bc_rec.r.rm_offset = offset;
50         cur->bc_rec.r.rm_flags = flags;
51
52         error = xfs_btree_lookup(cur, XFS_LOOKUP_LE, stat);
53         if (error || !(*stat) || !irec)
54                 return error;
55
56         error = xfs_rmap_get_rec(cur, irec, &get_stat);
57         if (error)
58                 return error;
59         if (!get_stat)
60                 return -EFSCORRUPTED;
61
62         return 0;
63 }
64
65 /*
66  * Lookup the record exactly matching [bno, len, owner, offset]
67  * in the btree given by cur.
68  */
69 int
70 xfs_rmap_lookup_eq(
71         struct xfs_btree_cur    *cur,
72         xfs_agblock_t           bno,
73         xfs_extlen_t            len,
74         uint64_t                owner,
75         uint64_t                offset,
76         unsigned int            flags,
77         int                     *stat)
78 {
79         cur->bc_rec.r.rm_startblock = bno;
80         cur->bc_rec.r.rm_blockcount = len;
81         cur->bc_rec.r.rm_owner = owner;
82         cur->bc_rec.r.rm_offset = offset;
83         cur->bc_rec.r.rm_flags = flags;
84         return xfs_btree_lookup(cur, XFS_LOOKUP_EQ, stat);
85 }
86
87 /*
88  * Update the record referred to by cur to the value given
89  * by [bno, len, owner, offset].
90  * This either works (return 0) or gets an EFSCORRUPTED error.
91  */
92 STATIC int
93 xfs_rmap_update(
94         struct xfs_btree_cur    *cur,
95         struct xfs_rmap_irec    *irec)
96 {
97         union xfs_btree_rec     rec;
98         int                     error;
99
100         trace_xfs_rmap_update(cur->bc_mp, cur->bc_ag.pag->pag_agno,
101                         irec->rm_startblock, irec->rm_blockcount,
102                         irec->rm_owner, irec->rm_offset, irec->rm_flags);
103
104         rec.rmap.rm_startblock = cpu_to_be32(irec->rm_startblock);
105         rec.rmap.rm_blockcount = cpu_to_be32(irec->rm_blockcount);
106         rec.rmap.rm_owner = cpu_to_be64(irec->rm_owner);
107         rec.rmap.rm_offset = cpu_to_be64(
108                         xfs_rmap_irec_offset_pack(irec));
109         error = xfs_btree_update(cur, &rec);
110         if (error)
111                 trace_xfs_rmap_update_error(cur->bc_mp,
112                                 cur->bc_ag.pag->pag_agno, error, _RET_IP_);
113         return error;
114 }
115
116 int
117 xfs_rmap_insert(
118         struct xfs_btree_cur    *rcur,
119         xfs_agblock_t           agbno,
120         xfs_extlen_t            len,
121         uint64_t                owner,
122         uint64_t                offset,
123         unsigned int            flags)
124 {
125         int                     i;
126         int                     error;
127
128         trace_xfs_rmap_insert(rcur->bc_mp, rcur->bc_ag.pag->pag_agno, agbno,
129                         len, owner, offset, flags);
130
131         error = xfs_rmap_lookup_eq(rcur, agbno, len, owner, offset, flags, &i);
132         if (error)
133                 goto done;
134         if (XFS_IS_CORRUPT(rcur->bc_mp, i != 0)) {
135                 error = -EFSCORRUPTED;
136                 goto done;
137         }
138
139         rcur->bc_rec.r.rm_startblock = agbno;
140         rcur->bc_rec.r.rm_blockcount = len;
141         rcur->bc_rec.r.rm_owner = owner;
142         rcur->bc_rec.r.rm_offset = offset;
143         rcur->bc_rec.r.rm_flags = flags;
144         error = xfs_btree_insert(rcur, &i);
145         if (error)
146                 goto done;
147         if (XFS_IS_CORRUPT(rcur->bc_mp, i != 1)) {
148                 error = -EFSCORRUPTED;
149                 goto done;
150         }
151 done:
152         if (error)
153                 trace_xfs_rmap_insert_error(rcur->bc_mp,
154                                 rcur->bc_ag.pag->pag_agno, error, _RET_IP_);
155         return error;
156 }
157
158 STATIC int
159 xfs_rmap_delete(
160         struct xfs_btree_cur    *rcur,
161         xfs_agblock_t           agbno,
162         xfs_extlen_t            len,
163         uint64_t                owner,
164         uint64_t                offset,
165         unsigned int            flags)
166 {
167         int                     i;
168         int                     error;
169
170         trace_xfs_rmap_delete(rcur->bc_mp, rcur->bc_ag.pag->pag_agno, agbno,
171                         len, owner, offset, flags);
172
173         error = xfs_rmap_lookup_eq(rcur, agbno, len, owner, offset, flags, &i);
174         if (error)
175                 goto done;
176         if (XFS_IS_CORRUPT(rcur->bc_mp, i != 1)) {
177                 error = -EFSCORRUPTED;
178                 goto done;
179         }
180
181         error = xfs_btree_delete(rcur, &i);
182         if (error)
183                 goto done;
184         if (XFS_IS_CORRUPT(rcur->bc_mp, i != 1)) {
185                 error = -EFSCORRUPTED;
186                 goto done;
187         }
188 done:
189         if (error)
190                 trace_xfs_rmap_delete_error(rcur->bc_mp,
191                                 rcur->bc_ag.pag->pag_agno, error, _RET_IP_);
192         return error;
193 }
194
195 /* Convert an internal btree record to an rmap record. */
196 xfs_failaddr_t
197 xfs_rmap_btrec_to_irec(
198         const union xfs_btree_rec       *rec,
199         struct xfs_rmap_irec            *irec)
200 {
201         irec->rm_startblock = be32_to_cpu(rec->rmap.rm_startblock);
202         irec->rm_blockcount = be32_to_cpu(rec->rmap.rm_blockcount);
203         irec->rm_owner = be64_to_cpu(rec->rmap.rm_owner);
204         return xfs_rmap_irec_offset_unpack(be64_to_cpu(rec->rmap.rm_offset),
205                         irec);
206 }
207
208 /* Simple checks for rmap records. */
209 xfs_failaddr_t
210 xfs_rmap_check_irec(
211         struct xfs_btree_cur            *cur,
212         const struct xfs_rmap_irec      *irec)
213 {
214         struct xfs_mount                *mp = cur->bc_mp;
215         bool                            is_inode;
216         bool                            is_unwritten;
217         bool                            is_bmbt;
218         bool                            is_attr;
219
220         if (irec->rm_blockcount == 0)
221                 return __this_address;
222         if (irec->rm_startblock <= XFS_AGFL_BLOCK(mp)) {
223                 if (irec->rm_owner != XFS_RMAP_OWN_FS)
224                         return __this_address;
225                 if (irec->rm_blockcount != XFS_AGFL_BLOCK(mp) + 1)
226                         return __this_address;
227         } else {
228                 /* check for valid extent range, including overflow */
229                 if (!xfs_verify_agbext(cur->bc_ag.pag, irec->rm_startblock,
230                                                        irec->rm_blockcount))
231                         return __this_address;
232         }
233
234         if (!(xfs_verify_ino(mp, irec->rm_owner) ||
235               (irec->rm_owner <= XFS_RMAP_OWN_FS &&
236                irec->rm_owner >= XFS_RMAP_OWN_MIN)))
237                 return __this_address;
238
239         /* Check flags. */
240         is_inode = !XFS_RMAP_NON_INODE_OWNER(irec->rm_owner);
241         is_bmbt = irec->rm_flags & XFS_RMAP_BMBT_BLOCK;
242         is_attr = irec->rm_flags & XFS_RMAP_ATTR_FORK;
243         is_unwritten = irec->rm_flags & XFS_RMAP_UNWRITTEN;
244
245         if (is_bmbt && irec->rm_offset != 0)
246                 return __this_address;
247
248         if (!is_inode && irec->rm_offset != 0)
249                 return __this_address;
250
251         if (is_unwritten && (is_bmbt || !is_inode || is_attr))
252                 return __this_address;
253
254         if (!is_inode && (is_bmbt || is_unwritten || is_attr))
255                 return __this_address;
256
257         /* Check for a valid fork offset, if applicable. */
258         if (is_inode && !is_bmbt &&
259             !xfs_verify_fileext(mp, irec->rm_offset, irec->rm_blockcount))
260                 return __this_address;
261
262         return NULL;
263 }
264
265 static inline int
266 xfs_rmap_complain_bad_rec(
267         struct xfs_btree_cur            *cur,
268         xfs_failaddr_t                  fa,
269         const struct xfs_rmap_irec      *irec)
270 {
271         struct xfs_mount                *mp = cur->bc_mp;
272
273         xfs_warn(mp,
274                 "Reverse Mapping BTree record corruption in AG %d detected at %pS!",
275                 cur->bc_ag.pag->pag_agno, fa);
276         xfs_warn(mp,
277                 "Owner 0x%llx, flags 0x%x, start block 0x%x block count 0x%x",
278                 irec->rm_owner, irec->rm_flags, irec->rm_startblock,
279                 irec->rm_blockcount);
280         return -EFSCORRUPTED;
281 }
282
283 /*
284  * Get the data from the pointed-to record.
285  */
286 int
287 xfs_rmap_get_rec(
288         struct xfs_btree_cur    *cur,
289         struct xfs_rmap_irec    *irec,
290         int                     *stat)
291 {
292         union xfs_btree_rec     *rec;
293         xfs_failaddr_t          fa;
294         int                     error;
295
296         error = xfs_btree_get_rec(cur, &rec, stat);
297         if (error || !*stat)
298                 return error;
299
300         fa = xfs_rmap_btrec_to_irec(rec, irec);
301         if (!fa)
302                 fa = xfs_rmap_check_irec(cur, irec);
303         if (fa)
304                 return xfs_rmap_complain_bad_rec(cur, fa, irec);
305
306         return 0;
307 }
308
309 struct xfs_find_left_neighbor_info {
310         struct xfs_rmap_irec    high;
311         struct xfs_rmap_irec    *irec;
312 };
313
314 /* For each rmap given, figure out if it matches the key we want. */
315 STATIC int
316 xfs_rmap_find_left_neighbor_helper(
317         struct xfs_btree_cur            *cur,
318         const struct xfs_rmap_irec      *rec,
319         void                            *priv)
320 {
321         struct xfs_find_left_neighbor_info      *info = priv;
322
323         trace_xfs_rmap_find_left_neighbor_candidate(cur->bc_mp,
324                         cur->bc_ag.pag->pag_agno, rec->rm_startblock,
325                         rec->rm_blockcount, rec->rm_owner, rec->rm_offset,
326                         rec->rm_flags);
327
328         if (rec->rm_owner != info->high.rm_owner)
329                 return 0;
330         if (!XFS_RMAP_NON_INODE_OWNER(rec->rm_owner) &&
331             !(rec->rm_flags & XFS_RMAP_BMBT_BLOCK) &&
332             rec->rm_offset + rec->rm_blockcount - 1 != info->high.rm_offset)
333                 return 0;
334
335         *info->irec = *rec;
336         return -ECANCELED;
337 }
338
339 /*
340  * Find the record to the left of the given extent, being careful only to
341  * return a match with the same owner and adjacent physical and logical
342  * block ranges.
343  */
344 STATIC int
345 xfs_rmap_find_left_neighbor(
346         struct xfs_btree_cur    *cur,
347         xfs_agblock_t           bno,
348         uint64_t                owner,
349         uint64_t                offset,
350         unsigned int            flags,
351         struct xfs_rmap_irec    *irec,
352         int                     *stat)
353 {
354         struct xfs_find_left_neighbor_info      info;
355         int                     found = 0;
356         int                     error;
357
358         *stat = 0;
359         if (bno == 0)
360                 return 0;
361         info.high.rm_startblock = bno - 1;
362         info.high.rm_owner = owner;
363         if (!XFS_RMAP_NON_INODE_OWNER(owner) &&
364             !(flags & XFS_RMAP_BMBT_BLOCK)) {
365                 if (offset == 0)
366                         return 0;
367                 info.high.rm_offset = offset - 1;
368         } else
369                 info.high.rm_offset = 0;
370         info.high.rm_flags = flags;
371         info.high.rm_blockcount = 0;
372         info.irec = irec;
373
374         trace_xfs_rmap_find_left_neighbor_query(cur->bc_mp,
375                         cur->bc_ag.pag->pag_agno, bno, 0, owner, offset, flags);
376
377         /*
378          * Historically, we always used the range query to walk every reverse
379          * mapping that could possibly overlap the key that the caller asked
380          * for, and filter out the ones that don't.  That is very slow when
381          * there are a lot of records.
382          *
383          * However, there are two scenarios where the classic btree search can
384          * produce correct results -- if the index contains a record that is an
385          * exact match for the lookup key; and if there are no other records
386          * between the record we want and the key we supplied.
387          *
388          * As an optimization, try a non-overlapped lookup first.  This makes
389          * extent conversion and remap operations run a bit faster if the
390          * physical extents aren't being shared.  If we don't find what we
391          * want, we fall back to the overlapped query.
392          */
393         error = xfs_rmap_lookup_le(cur, bno, owner, offset, flags, irec,
394                         &found);
395         if (error)
396                 return error;
397         if (found)
398                 error = xfs_rmap_find_left_neighbor_helper(cur, irec, &info);
399         if (!error)
400                 error = xfs_rmap_query_range(cur, &info.high, &info.high,
401                                 xfs_rmap_find_left_neighbor_helper, &info);
402         if (error != -ECANCELED)
403                 return error;
404
405         *stat = 1;
406         trace_xfs_rmap_find_left_neighbor_result(cur->bc_mp,
407                         cur->bc_ag.pag->pag_agno, irec->rm_startblock,
408                         irec->rm_blockcount, irec->rm_owner, irec->rm_offset,
409                         irec->rm_flags);
410         return 0;
411 }
412
413 /* For each rmap given, figure out if it matches the key we want. */
414 STATIC int
415 xfs_rmap_lookup_le_range_helper(
416         struct xfs_btree_cur            *cur,
417         const struct xfs_rmap_irec      *rec,
418         void                            *priv)
419 {
420         struct xfs_find_left_neighbor_info      *info = priv;
421
422         trace_xfs_rmap_lookup_le_range_candidate(cur->bc_mp,
423                         cur->bc_ag.pag->pag_agno, rec->rm_startblock,
424                         rec->rm_blockcount, rec->rm_owner, rec->rm_offset,
425                         rec->rm_flags);
426
427         if (rec->rm_owner != info->high.rm_owner)
428                 return 0;
429         if (!XFS_RMAP_NON_INODE_OWNER(rec->rm_owner) &&
430             !(rec->rm_flags & XFS_RMAP_BMBT_BLOCK) &&
431             (rec->rm_offset > info->high.rm_offset ||
432              rec->rm_offset + rec->rm_blockcount <= info->high.rm_offset))
433                 return 0;
434
435         *info->irec = *rec;
436         return -ECANCELED;
437 }
438
439 /*
440  * Find the record to the left of the given extent, being careful only to
441  * return a match with the same owner and overlapping physical and logical
442  * block ranges.  This is the overlapping-interval version of
443  * xfs_rmap_lookup_le.
444  */
445 int
446 xfs_rmap_lookup_le_range(
447         struct xfs_btree_cur    *cur,
448         xfs_agblock_t           bno,
449         uint64_t                owner,
450         uint64_t                offset,
451         unsigned int            flags,
452         struct xfs_rmap_irec    *irec,
453         int                     *stat)
454 {
455         struct xfs_find_left_neighbor_info      info;
456         int                     found = 0;
457         int                     error;
458
459         info.high.rm_startblock = bno;
460         info.high.rm_owner = owner;
461         if (!XFS_RMAP_NON_INODE_OWNER(owner) && !(flags & XFS_RMAP_BMBT_BLOCK))
462                 info.high.rm_offset = offset;
463         else
464                 info.high.rm_offset = 0;
465         info.high.rm_flags = flags;
466         info.high.rm_blockcount = 0;
467         *stat = 0;
468         info.irec = irec;
469
470         trace_xfs_rmap_lookup_le_range(cur->bc_mp, cur->bc_ag.pag->pag_agno,
471                         bno, 0, owner, offset, flags);
472
473         /*
474          * Historically, we always used the range query to walk every reverse
475          * mapping that could possibly overlap the key that the caller asked
476          * for, and filter out the ones that don't.  That is very slow when
477          * there are a lot of records.
478          *
479          * However, there are two scenarios where the classic btree search can
480          * produce correct results -- if the index contains a record that is an
481          * exact match for the lookup key; and if there are no other records
482          * between the record we want and the key we supplied.
483          *
484          * As an optimization, try a non-overlapped lookup first.  This makes
485          * scrub run much faster on most filesystems because bmbt records are
486          * usually an exact match for rmap records.  If we don't find what we
487          * want, we fall back to the overlapped query.
488          */
489         error = xfs_rmap_lookup_le(cur, bno, owner, offset, flags, irec,
490                         &found);
491         if (error)
492                 return error;
493         if (found)
494                 error = xfs_rmap_lookup_le_range_helper(cur, irec, &info);
495         if (!error)
496                 error = xfs_rmap_query_range(cur, &info.high, &info.high,
497                                 xfs_rmap_lookup_le_range_helper, &info);
498         if (error != -ECANCELED)
499                 return error;
500
501         *stat = 1;
502         trace_xfs_rmap_lookup_le_range_result(cur->bc_mp,
503                         cur->bc_ag.pag->pag_agno, irec->rm_startblock,
504                         irec->rm_blockcount, irec->rm_owner, irec->rm_offset,
505                         irec->rm_flags);
506         return 0;
507 }
508
509 /*
510  * Perform all the relevant owner checks for a removal op.  If we're doing an
511  * unknown-owner removal then we have no owner information to check.
512  */
513 static int
514 xfs_rmap_free_check_owner(
515         struct xfs_mount        *mp,
516         uint64_t                ltoff,
517         struct xfs_rmap_irec    *rec,
518         xfs_filblks_t           len,
519         uint64_t                owner,
520         uint64_t                offset,
521         unsigned int            flags)
522 {
523         int                     error = 0;
524
525         if (owner == XFS_RMAP_OWN_UNKNOWN)
526                 return 0;
527
528         /* Make sure the unwritten flag matches. */
529         if (XFS_IS_CORRUPT(mp,
530                            (flags & XFS_RMAP_UNWRITTEN) !=
531                            (rec->rm_flags & XFS_RMAP_UNWRITTEN))) {
532                 error = -EFSCORRUPTED;
533                 goto out;
534         }
535
536         /* Make sure the owner matches what we expect to find in the tree. */
537         if (XFS_IS_CORRUPT(mp, owner != rec->rm_owner)) {
538                 error = -EFSCORRUPTED;
539                 goto out;
540         }
541
542         /* Check the offset, if necessary. */
543         if (XFS_RMAP_NON_INODE_OWNER(owner))
544                 goto out;
545
546         if (flags & XFS_RMAP_BMBT_BLOCK) {
547                 if (XFS_IS_CORRUPT(mp,
548                                    !(rec->rm_flags & XFS_RMAP_BMBT_BLOCK))) {
549                         error = -EFSCORRUPTED;
550                         goto out;
551                 }
552         } else {
553                 if (XFS_IS_CORRUPT(mp, rec->rm_offset > offset)) {
554                         error = -EFSCORRUPTED;
555                         goto out;
556                 }
557                 if (XFS_IS_CORRUPT(mp,
558                                    offset + len > ltoff + rec->rm_blockcount)) {
559                         error = -EFSCORRUPTED;
560                         goto out;
561                 }
562         }
563
564 out:
565         return error;
566 }
567
568 /*
569  * Find the extent in the rmap btree and remove it.
570  *
571  * The record we find should always be an exact match for the extent that we're
572  * looking for, since we insert them into the btree without modification.
573  *
574  * Special Case #1: when growing the filesystem, we "free" an extent when
575  * growing the last AG. This extent is new space and so it is not tracked as
576  * used space in the btree. The growfs code will pass in an owner of
577  * XFS_RMAP_OWN_NULL to indicate that it expected that there is no owner of this
578  * extent. We verify that - the extent lookup result in a record that does not
579  * overlap.
580  *
581  * Special Case #2: EFIs do not record the owner of the extent, so when
582  * recovering EFIs from the log we pass in XFS_RMAP_OWN_UNKNOWN to tell the rmap
583  * btree to ignore the owner (i.e. wildcard match) so we don't trigger
584  * corruption checks during log recovery.
585  */
586 STATIC int
587 xfs_rmap_unmap(
588         struct xfs_btree_cur            *cur,
589         xfs_agblock_t                   bno,
590         xfs_extlen_t                    len,
591         bool                            unwritten,
592         const struct xfs_owner_info     *oinfo)
593 {
594         struct xfs_mount                *mp = cur->bc_mp;
595         struct xfs_rmap_irec            ltrec;
596         uint64_t                        ltoff;
597         int                             error = 0;
598         int                             i;
599         uint64_t                        owner;
600         uint64_t                        offset;
601         unsigned int                    flags;
602         bool                            ignore_off;
603
604         xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
605         ignore_off = XFS_RMAP_NON_INODE_OWNER(owner) ||
606                         (flags & XFS_RMAP_BMBT_BLOCK);
607         if (unwritten)
608                 flags |= XFS_RMAP_UNWRITTEN;
609         trace_xfs_rmap_unmap(mp, cur->bc_ag.pag->pag_agno, bno, len,
610                         unwritten, oinfo);
611
612         /*
613          * We should always have a left record because there's a static record
614          * for the AG headers at rm_startblock == 0 created by mkfs/growfs that
615          * will not ever be removed from the tree.
616          */
617         error = xfs_rmap_lookup_le(cur, bno, owner, offset, flags, &ltrec, &i);
618         if (error)
619                 goto out_error;
620         if (XFS_IS_CORRUPT(mp, i != 1)) {
621                 error = -EFSCORRUPTED;
622                 goto out_error;
623         }
624
625         trace_xfs_rmap_lookup_le_range_result(cur->bc_mp,
626                         cur->bc_ag.pag->pag_agno, ltrec.rm_startblock,
627                         ltrec.rm_blockcount, ltrec.rm_owner,
628                         ltrec.rm_offset, ltrec.rm_flags);
629         ltoff = ltrec.rm_offset;
630
631         /*
632          * For growfs, the incoming extent must be beyond the left record we
633          * just found as it is new space and won't be used by anyone. This is
634          * just a corruption check as we don't actually do anything with this
635          * extent.  Note that we need to use >= instead of > because it might
636          * be the case that the "left" extent goes all the way to EOFS.
637          */
638         if (owner == XFS_RMAP_OWN_NULL) {
639                 if (XFS_IS_CORRUPT(mp,
640                                    bno <
641                                    ltrec.rm_startblock + ltrec.rm_blockcount)) {
642                         error = -EFSCORRUPTED;
643                         goto out_error;
644                 }
645                 goto out_done;
646         }
647
648         /*
649          * If we're doing an unknown-owner removal for EFI recovery, we expect
650          * to find the full range in the rmapbt or nothing at all.  If we
651          * don't find any rmaps overlapping either end of the range, we're
652          * done.  Hopefully this means that the EFI creator already queued
653          * (and finished) a RUI to remove the rmap.
654          */
655         if (owner == XFS_RMAP_OWN_UNKNOWN &&
656             ltrec.rm_startblock + ltrec.rm_blockcount <= bno) {
657                 struct xfs_rmap_irec    rtrec;
658
659                 error = xfs_btree_increment(cur, 0, &i);
660                 if (error)
661                         goto out_error;
662                 if (i == 0)
663                         goto out_done;
664                 error = xfs_rmap_get_rec(cur, &rtrec, &i);
665                 if (error)
666                         goto out_error;
667                 if (XFS_IS_CORRUPT(mp, i != 1)) {
668                         error = -EFSCORRUPTED;
669                         goto out_error;
670                 }
671                 if (rtrec.rm_startblock >= bno + len)
672                         goto out_done;
673         }
674
675         /* Make sure the extent we found covers the entire freeing range. */
676         if (XFS_IS_CORRUPT(mp,
677                            ltrec.rm_startblock > bno ||
678                            ltrec.rm_startblock + ltrec.rm_blockcount <
679                            bno + len)) {
680                 error = -EFSCORRUPTED;
681                 goto out_error;
682         }
683
684         /* Check owner information. */
685         error = xfs_rmap_free_check_owner(mp, ltoff, &ltrec, len, owner,
686                         offset, flags);
687         if (error)
688                 goto out_error;
689
690         if (ltrec.rm_startblock == bno && ltrec.rm_blockcount == len) {
691                 /* exact match, simply remove the record from rmap tree */
692                 trace_xfs_rmap_delete(mp, cur->bc_ag.pag->pag_agno,
693                                 ltrec.rm_startblock, ltrec.rm_blockcount,
694                                 ltrec.rm_owner, ltrec.rm_offset,
695                                 ltrec.rm_flags);
696                 error = xfs_btree_delete(cur, &i);
697                 if (error)
698                         goto out_error;
699                 if (XFS_IS_CORRUPT(mp, i != 1)) {
700                         error = -EFSCORRUPTED;
701                         goto out_error;
702                 }
703         } else if (ltrec.rm_startblock == bno) {
704                 /*
705                  * overlap left hand side of extent: move the start, trim the
706                  * length and update the current record.
707                  *
708                  *       ltbno                ltlen
709                  * Orig:    |oooooooooooooooooooo|
710                  * Freeing: |fffffffff|
711                  * Result:            |rrrrrrrrrr|
712                  *         bno       len
713                  */
714                 ltrec.rm_startblock += len;
715                 ltrec.rm_blockcount -= len;
716                 if (!ignore_off)
717                         ltrec.rm_offset += len;
718                 error = xfs_rmap_update(cur, &ltrec);
719                 if (error)
720                         goto out_error;
721         } else if (ltrec.rm_startblock + ltrec.rm_blockcount == bno + len) {
722                 /*
723                  * overlap right hand side of extent: trim the length and update
724                  * the current record.
725                  *
726                  *       ltbno                ltlen
727                  * Orig:    |oooooooooooooooooooo|
728                  * Freeing:            |fffffffff|
729                  * Result:  |rrrrrrrrrr|
730                  *                    bno       len
731                  */
732                 ltrec.rm_blockcount -= len;
733                 error = xfs_rmap_update(cur, &ltrec);
734                 if (error)
735                         goto out_error;
736         } else {
737
738                 /*
739                  * overlap middle of extent: trim the length of the existing
740                  * record to the length of the new left-extent size, increment
741                  * the insertion position so we can insert a new record
742                  * containing the remaining right-extent space.
743                  *
744                  *       ltbno                ltlen
745                  * Orig:    |oooooooooooooooooooo|
746                  * Freeing:       |fffffffff|
747                  * Result:  |rrrrr|         |rrrr|
748                  *               bno       len
749                  */
750                 xfs_extlen_t    orig_len = ltrec.rm_blockcount;
751
752                 ltrec.rm_blockcount = bno - ltrec.rm_startblock;
753                 error = xfs_rmap_update(cur, &ltrec);
754                 if (error)
755                         goto out_error;
756
757                 error = xfs_btree_increment(cur, 0, &i);
758                 if (error)
759                         goto out_error;
760
761                 cur->bc_rec.r.rm_startblock = bno + len;
762                 cur->bc_rec.r.rm_blockcount = orig_len - len -
763                                                      ltrec.rm_blockcount;
764                 cur->bc_rec.r.rm_owner = ltrec.rm_owner;
765                 if (ignore_off)
766                         cur->bc_rec.r.rm_offset = 0;
767                 else
768                         cur->bc_rec.r.rm_offset = offset + len;
769                 cur->bc_rec.r.rm_flags = flags;
770                 trace_xfs_rmap_insert(mp, cur->bc_ag.pag->pag_agno,
771                                 cur->bc_rec.r.rm_startblock,
772                                 cur->bc_rec.r.rm_blockcount,
773                                 cur->bc_rec.r.rm_owner,
774                                 cur->bc_rec.r.rm_offset,
775                                 cur->bc_rec.r.rm_flags);
776                 error = xfs_btree_insert(cur, &i);
777                 if (error)
778                         goto out_error;
779         }
780
781 out_done:
782         trace_xfs_rmap_unmap_done(mp, cur->bc_ag.pag->pag_agno, bno, len,
783                         unwritten, oinfo);
784 out_error:
785         if (error)
786                 trace_xfs_rmap_unmap_error(mp, cur->bc_ag.pag->pag_agno,
787                                 error, _RET_IP_);
788         return error;
789 }
790
791 /*
792  * Remove a reference to an extent in the rmap btree.
793  */
794 int
795 xfs_rmap_free(
796         struct xfs_trans                *tp,
797         struct xfs_buf                  *agbp,
798         struct xfs_perag                *pag,
799         xfs_agblock_t                   bno,
800         xfs_extlen_t                    len,
801         const struct xfs_owner_info     *oinfo)
802 {
803         struct xfs_mount                *mp = tp->t_mountp;
804         struct xfs_btree_cur            *cur;
805         int                             error;
806
807         if (!xfs_has_rmapbt(mp))
808                 return 0;
809
810         cur = xfs_rmapbt_init_cursor(mp, tp, agbp, pag);
811
812         error = xfs_rmap_unmap(cur, bno, len, false, oinfo);
813
814         xfs_btree_del_cursor(cur, error);
815         return error;
816 }
817
818 /*
819  * A mergeable rmap must have the same owner and the same values for
820  * the unwritten, attr_fork, and bmbt flags.  The startblock and
821  * offset are checked separately.
822  */
823 static bool
824 xfs_rmap_is_mergeable(
825         struct xfs_rmap_irec    *irec,
826         uint64_t                owner,
827         unsigned int            flags)
828 {
829         if (irec->rm_owner == XFS_RMAP_OWN_NULL)
830                 return false;
831         if (irec->rm_owner != owner)
832                 return false;
833         if ((flags & XFS_RMAP_UNWRITTEN) ^
834             (irec->rm_flags & XFS_RMAP_UNWRITTEN))
835                 return false;
836         if ((flags & XFS_RMAP_ATTR_FORK) ^
837             (irec->rm_flags & XFS_RMAP_ATTR_FORK))
838                 return false;
839         if ((flags & XFS_RMAP_BMBT_BLOCK) ^
840             (irec->rm_flags & XFS_RMAP_BMBT_BLOCK))
841                 return false;
842         return true;
843 }
844
845 /*
846  * When we allocate a new block, the first thing we do is add a reference to
847  * the extent in the rmap btree. This takes the form of a [agbno, length,
848  * owner, offset] record.  Flags are encoded in the high bits of the offset
849  * field.
850  */
851 STATIC int
852 xfs_rmap_map(
853         struct xfs_btree_cur            *cur,
854         xfs_agblock_t                   bno,
855         xfs_extlen_t                    len,
856         bool                            unwritten,
857         const struct xfs_owner_info     *oinfo)
858 {
859         struct xfs_mount                *mp = cur->bc_mp;
860         struct xfs_rmap_irec            ltrec;
861         struct xfs_rmap_irec            gtrec;
862         int                             have_gt;
863         int                             have_lt;
864         int                             error = 0;
865         int                             i;
866         uint64_t                        owner;
867         uint64_t                        offset;
868         unsigned int                    flags = 0;
869         bool                            ignore_off;
870
871         xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
872         ASSERT(owner != 0);
873         ignore_off = XFS_RMAP_NON_INODE_OWNER(owner) ||
874                         (flags & XFS_RMAP_BMBT_BLOCK);
875         if (unwritten)
876                 flags |= XFS_RMAP_UNWRITTEN;
877         trace_xfs_rmap_map(mp, cur->bc_ag.pag->pag_agno, bno, len,
878                         unwritten, oinfo);
879         ASSERT(!xfs_rmap_should_skip_owner_update(oinfo));
880
881         /*
882          * For the initial lookup, look for an exact match or the left-adjacent
883          * record for our insertion point. This will also give us the record for
884          * start block contiguity tests.
885          */
886         error = xfs_rmap_lookup_le(cur, bno, owner, offset, flags, &ltrec,
887                         &have_lt);
888         if (error)
889                 goto out_error;
890         if (have_lt) {
891                 trace_xfs_rmap_lookup_le_range_result(cur->bc_mp,
892                                 cur->bc_ag.pag->pag_agno, ltrec.rm_startblock,
893                                 ltrec.rm_blockcount, ltrec.rm_owner,
894                                 ltrec.rm_offset, ltrec.rm_flags);
895
896                 if (!xfs_rmap_is_mergeable(&ltrec, owner, flags))
897                         have_lt = 0;
898         }
899
900         if (XFS_IS_CORRUPT(mp,
901                            have_lt != 0 &&
902                            ltrec.rm_startblock + ltrec.rm_blockcount > bno)) {
903                 error = -EFSCORRUPTED;
904                 goto out_error;
905         }
906
907         /*
908          * Increment the cursor to see if we have a right-adjacent record to our
909          * insertion point. This will give us the record for end block
910          * contiguity tests.
911          */
912         error = xfs_btree_increment(cur, 0, &have_gt);
913         if (error)
914                 goto out_error;
915         if (have_gt) {
916                 error = xfs_rmap_get_rec(cur, &gtrec, &have_gt);
917                 if (error)
918                         goto out_error;
919                 if (XFS_IS_CORRUPT(mp, have_gt != 1)) {
920                         error = -EFSCORRUPTED;
921                         goto out_error;
922                 }
923                 if (XFS_IS_CORRUPT(mp, bno + len > gtrec.rm_startblock)) {
924                         error = -EFSCORRUPTED;
925                         goto out_error;
926                 }
927                 trace_xfs_rmap_find_right_neighbor_result(cur->bc_mp,
928                         cur->bc_ag.pag->pag_agno, gtrec.rm_startblock,
929                         gtrec.rm_blockcount, gtrec.rm_owner,
930                         gtrec.rm_offset, gtrec.rm_flags);
931                 if (!xfs_rmap_is_mergeable(&gtrec, owner, flags))
932                         have_gt = 0;
933         }
934
935         /*
936          * Note: cursor currently points one record to the right of ltrec, even
937          * if there is no record in the tree to the right.
938          */
939         if (have_lt &&
940             ltrec.rm_startblock + ltrec.rm_blockcount == bno &&
941             (ignore_off || ltrec.rm_offset + ltrec.rm_blockcount == offset)) {
942                 /*
943                  * left edge contiguous, merge into left record.
944                  *
945                  *       ltbno     ltlen
946                  * orig:   |ooooooooo|
947                  * adding:           |aaaaaaaaa|
948                  * result: |rrrrrrrrrrrrrrrrrrr|
949                  *                  bno       len
950                  */
951                 ltrec.rm_blockcount += len;
952                 if (have_gt &&
953                     bno + len == gtrec.rm_startblock &&
954                     (ignore_off || offset + len == gtrec.rm_offset) &&
955                     (unsigned long)ltrec.rm_blockcount + len +
956                                 gtrec.rm_blockcount <= XFS_RMAP_LEN_MAX) {
957                         /*
958                          * right edge also contiguous, delete right record
959                          * and merge into left record.
960                          *
961                          *       ltbno     ltlen    gtbno     gtlen
962                          * orig:   |ooooooooo|         |ooooooooo|
963                          * adding:           |aaaaaaaaa|
964                          * result: |rrrrrrrrrrrrrrrrrrrrrrrrrrrrr|
965                          */
966                         ltrec.rm_blockcount += gtrec.rm_blockcount;
967                         trace_xfs_rmap_delete(mp, cur->bc_ag.pag->pag_agno,
968                                         gtrec.rm_startblock,
969                                         gtrec.rm_blockcount,
970                                         gtrec.rm_owner,
971                                         gtrec.rm_offset,
972                                         gtrec.rm_flags);
973                         error = xfs_btree_delete(cur, &i);
974                         if (error)
975                                 goto out_error;
976                         if (XFS_IS_CORRUPT(mp, i != 1)) {
977                                 error = -EFSCORRUPTED;
978                                 goto out_error;
979                         }
980                 }
981
982                 /* point the cursor back to the left record and update */
983                 error = xfs_btree_decrement(cur, 0, &have_gt);
984                 if (error)
985                         goto out_error;
986                 error = xfs_rmap_update(cur, &ltrec);
987                 if (error)
988                         goto out_error;
989         } else if (have_gt &&
990                    bno + len == gtrec.rm_startblock &&
991                    (ignore_off || offset + len == gtrec.rm_offset)) {
992                 /*
993                  * right edge contiguous, merge into right record.
994                  *
995                  *                 gtbno     gtlen
996                  * Orig:             |ooooooooo|
997                  * adding: |aaaaaaaaa|
998                  * Result: |rrrrrrrrrrrrrrrrrrr|
999                  *        bno       len
1000                  */
1001                 gtrec.rm_startblock = bno;
1002                 gtrec.rm_blockcount += len;
1003                 if (!ignore_off)
1004                         gtrec.rm_offset = offset;
1005                 error = xfs_rmap_update(cur, &gtrec);
1006                 if (error)
1007                         goto out_error;
1008         } else {
1009                 /*
1010                  * no contiguous edge with identical owner, insert
1011                  * new record at current cursor position.
1012                  */
1013                 cur->bc_rec.r.rm_startblock = bno;
1014                 cur->bc_rec.r.rm_blockcount = len;
1015                 cur->bc_rec.r.rm_owner = owner;
1016                 cur->bc_rec.r.rm_offset = offset;
1017                 cur->bc_rec.r.rm_flags = flags;
1018                 trace_xfs_rmap_insert(mp, cur->bc_ag.pag->pag_agno, bno, len,
1019                         owner, offset, flags);
1020                 error = xfs_btree_insert(cur, &i);
1021                 if (error)
1022                         goto out_error;
1023                 if (XFS_IS_CORRUPT(mp, i != 1)) {
1024                         error = -EFSCORRUPTED;
1025                         goto out_error;
1026                 }
1027         }
1028
1029         trace_xfs_rmap_map_done(mp, cur->bc_ag.pag->pag_agno, bno, len,
1030                         unwritten, oinfo);
1031 out_error:
1032         if (error)
1033                 trace_xfs_rmap_map_error(mp, cur->bc_ag.pag->pag_agno,
1034                                 error, _RET_IP_);
1035         return error;
1036 }
1037
1038 /*
1039  * Add a reference to an extent in the rmap btree.
1040  */
1041 int
1042 xfs_rmap_alloc(
1043         struct xfs_trans                *tp,
1044         struct xfs_buf                  *agbp,
1045         struct xfs_perag                *pag,
1046         xfs_agblock_t                   bno,
1047         xfs_extlen_t                    len,
1048         const struct xfs_owner_info     *oinfo)
1049 {
1050         struct xfs_mount                *mp = tp->t_mountp;
1051         struct xfs_btree_cur            *cur;
1052         int                             error;
1053
1054         if (!xfs_has_rmapbt(mp))
1055                 return 0;
1056
1057         cur = xfs_rmapbt_init_cursor(mp, tp, agbp, pag);
1058         error = xfs_rmap_map(cur, bno, len, false, oinfo);
1059
1060         xfs_btree_del_cursor(cur, error);
1061         return error;
1062 }
1063
1064 #define RMAP_LEFT_CONTIG        (1 << 0)
1065 #define RMAP_RIGHT_CONTIG       (1 << 1)
1066 #define RMAP_LEFT_FILLING       (1 << 2)
1067 #define RMAP_RIGHT_FILLING      (1 << 3)
1068 #define RMAP_LEFT_VALID         (1 << 6)
1069 #define RMAP_RIGHT_VALID        (1 << 7)
1070
1071 #define LEFT            r[0]
1072 #define RIGHT           r[1]
1073 #define PREV            r[2]
1074 #define NEW             r[3]
1075
1076 /*
1077  * Convert an unwritten extent to a real extent or vice versa.
1078  * Does not handle overlapping extents.
1079  */
1080 STATIC int
1081 xfs_rmap_convert(
1082         struct xfs_btree_cur            *cur,
1083         xfs_agblock_t                   bno,
1084         xfs_extlen_t                    len,
1085         bool                            unwritten,
1086         const struct xfs_owner_info     *oinfo)
1087 {
1088         struct xfs_mount                *mp = cur->bc_mp;
1089         struct xfs_rmap_irec            r[4];   /* neighbor extent entries */
1090                                                 /* left is 0, right is 1, */
1091                                                 /* prev is 2, new is 3 */
1092         uint64_t                owner;
1093         uint64_t                offset;
1094         uint64_t                new_endoff;
1095         unsigned int            oldext;
1096         unsigned int            newext;
1097         unsigned int            flags = 0;
1098         int                     i;
1099         int                     state = 0;
1100         int                     error;
1101
1102         xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
1103         ASSERT(!(XFS_RMAP_NON_INODE_OWNER(owner) ||
1104                         (flags & (XFS_RMAP_ATTR_FORK | XFS_RMAP_BMBT_BLOCK))));
1105         oldext = unwritten ? XFS_RMAP_UNWRITTEN : 0;
1106         new_endoff = offset + len;
1107         trace_xfs_rmap_convert(mp, cur->bc_ag.pag->pag_agno, bno, len,
1108                         unwritten, oinfo);
1109
1110         /*
1111          * For the initial lookup, look for an exact match or the left-adjacent
1112          * record for our insertion point. This will also give us the record for
1113          * start block contiguity tests.
1114          */
1115         error = xfs_rmap_lookup_le(cur, bno, owner, offset, oldext, &PREV, &i);
1116         if (error)
1117                 goto done;
1118         if (XFS_IS_CORRUPT(mp, i != 1)) {
1119                 error = -EFSCORRUPTED;
1120                 goto done;
1121         }
1122
1123         trace_xfs_rmap_lookup_le_range_result(cur->bc_mp,
1124                         cur->bc_ag.pag->pag_agno, PREV.rm_startblock,
1125                         PREV.rm_blockcount, PREV.rm_owner,
1126                         PREV.rm_offset, PREV.rm_flags);
1127
1128         ASSERT(PREV.rm_offset <= offset);
1129         ASSERT(PREV.rm_offset + PREV.rm_blockcount >= new_endoff);
1130         ASSERT((PREV.rm_flags & XFS_RMAP_UNWRITTEN) == oldext);
1131         newext = ~oldext & XFS_RMAP_UNWRITTEN;
1132
1133         /*
1134          * Set flags determining what part of the previous oldext allocation
1135          * extent is being replaced by a newext allocation.
1136          */
1137         if (PREV.rm_offset == offset)
1138                 state |= RMAP_LEFT_FILLING;
1139         if (PREV.rm_offset + PREV.rm_blockcount == new_endoff)
1140                 state |= RMAP_RIGHT_FILLING;
1141
1142         /*
1143          * Decrement the cursor to see if we have a left-adjacent record to our
1144          * insertion point. This will give us the record for end block
1145          * contiguity tests.
1146          */
1147         error = xfs_btree_decrement(cur, 0, &i);
1148         if (error)
1149                 goto done;
1150         if (i) {
1151                 state |= RMAP_LEFT_VALID;
1152                 error = xfs_rmap_get_rec(cur, &LEFT, &i);
1153                 if (error)
1154                         goto done;
1155                 if (XFS_IS_CORRUPT(mp, i != 1)) {
1156                         error = -EFSCORRUPTED;
1157                         goto done;
1158                 }
1159                 if (XFS_IS_CORRUPT(mp,
1160                                    LEFT.rm_startblock + LEFT.rm_blockcount >
1161                                    bno)) {
1162                         error = -EFSCORRUPTED;
1163                         goto done;
1164                 }
1165                 trace_xfs_rmap_find_left_neighbor_result(cur->bc_mp,
1166                                 cur->bc_ag.pag->pag_agno, LEFT.rm_startblock,
1167                                 LEFT.rm_blockcount, LEFT.rm_owner,
1168                                 LEFT.rm_offset, LEFT.rm_flags);
1169                 if (LEFT.rm_startblock + LEFT.rm_blockcount == bno &&
1170                     LEFT.rm_offset + LEFT.rm_blockcount == offset &&
1171                     xfs_rmap_is_mergeable(&LEFT, owner, newext))
1172                         state |= RMAP_LEFT_CONTIG;
1173         }
1174
1175         /*
1176          * Increment the cursor to see if we have a right-adjacent record to our
1177          * insertion point. This will give us the record for end block
1178          * contiguity tests.
1179          */
1180         error = xfs_btree_increment(cur, 0, &i);
1181         if (error)
1182                 goto done;
1183         if (XFS_IS_CORRUPT(mp, i != 1)) {
1184                 error = -EFSCORRUPTED;
1185                 goto done;
1186         }
1187         error = xfs_btree_increment(cur, 0, &i);
1188         if (error)
1189                 goto done;
1190         if (i) {
1191                 state |= RMAP_RIGHT_VALID;
1192                 error = xfs_rmap_get_rec(cur, &RIGHT, &i);
1193                 if (error)
1194                         goto done;
1195                 if (XFS_IS_CORRUPT(mp, i != 1)) {
1196                         error = -EFSCORRUPTED;
1197                         goto done;
1198                 }
1199                 if (XFS_IS_CORRUPT(mp, bno + len > RIGHT.rm_startblock)) {
1200                         error = -EFSCORRUPTED;
1201                         goto done;
1202                 }
1203                 trace_xfs_rmap_find_right_neighbor_result(cur->bc_mp,
1204                                 cur->bc_ag.pag->pag_agno, RIGHT.rm_startblock,
1205                                 RIGHT.rm_blockcount, RIGHT.rm_owner,
1206                                 RIGHT.rm_offset, RIGHT.rm_flags);
1207                 if (bno + len == RIGHT.rm_startblock &&
1208                     offset + len == RIGHT.rm_offset &&
1209                     xfs_rmap_is_mergeable(&RIGHT, owner, newext))
1210                         state |= RMAP_RIGHT_CONTIG;
1211         }
1212
1213         /* check that left + prev + right is not too long */
1214         if ((state & (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
1215                          RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG)) ==
1216             (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
1217              RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG) &&
1218             (unsigned long)LEFT.rm_blockcount + len +
1219              RIGHT.rm_blockcount > XFS_RMAP_LEN_MAX)
1220                 state &= ~RMAP_RIGHT_CONTIG;
1221
1222         trace_xfs_rmap_convert_state(mp, cur->bc_ag.pag->pag_agno, state,
1223                         _RET_IP_);
1224
1225         /* reset the cursor back to PREV */
1226         error = xfs_rmap_lookup_le(cur, bno, owner, offset, oldext, NULL, &i);
1227         if (error)
1228                 goto done;
1229         if (XFS_IS_CORRUPT(mp, i != 1)) {
1230                 error = -EFSCORRUPTED;
1231                 goto done;
1232         }
1233
1234         /*
1235          * Switch out based on the FILLING and CONTIG state bits.
1236          */
1237         switch (state & (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
1238                          RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG)) {
1239         case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
1240              RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG:
1241                 /*
1242                  * Setting all of a previous oldext extent to newext.
1243                  * The left and right neighbors are both contiguous with new.
1244                  */
1245                 error = xfs_btree_increment(cur, 0, &i);
1246                 if (error)
1247                         goto done;
1248                 if (XFS_IS_CORRUPT(mp, i != 1)) {
1249                         error = -EFSCORRUPTED;
1250                         goto done;
1251                 }
1252                 trace_xfs_rmap_delete(mp, cur->bc_ag.pag->pag_agno,
1253                                 RIGHT.rm_startblock, RIGHT.rm_blockcount,
1254                                 RIGHT.rm_owner, RIGHT.rm_offset,
1255                                 RIGHT.rm_flags);
1256                 error = xfs_btree_delete(cur, &i);
1257                 if (error)
1258                         goto done;
1259                 if (XFS_IS_CORRUPT(mp, i != 1)) {
1260                         error = -EFSCORRUPTED;
1261                         goto done;
1262                 }
1263                 error = xfs_btree_decrement(cur, 0, &i);
1264                 if (error)
1265                         goto done;
1266                 if (XFS_IS_CORRUPT(mp, i != 1)) {
1267                         error = -EFSCORRUPTED;
1268                         goto done;
1269                 }
1270                 trace_xfs_rmap_delete(mp, cur->bc_ag.pag->pag_agno,
1271                                 PREV.rm_startblock, PREV.rm_blockcount,
1272                                 PREV.rm_owner, PREV.rm_offset,
1273                                 PREV.rm_flags);
1274                 error = xfs_btree_delete(cur, &i);
1275                 if (error)
1276                         goto done;
1277                 if (XFS_IS_CORRUPT(mp, i != 1)) {
1278                         error = -EFSCORRUPTED;
1279                         goto done;
1280                 }
1281                 error = xfs_btree_decrement(cur, 0, &i);
1282                 if (error)
1283                         goto done;
1284                 if (XFS_IS_CORRUPT(mp, i != 1)) {
1285                         error = -EFSCORRUPTED;
1286                         goto done;
1287                 }
1288                 NEW = LEFT;
1289                 NEW.rm_blockcount += PREV.rm_blockcount + RIGHT.rm_blockcount;
1290                 error = xfs_rmap_update(cur, &NEW);
1291                 if (error)
1292                         goto done;
1293                 break;
1294
1295         case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG:
1296                 /*
1297                  * Setting all of a previous oldext extent to newext.
1298                  * The left neighbor is contiguous, the right is not.
1299                  */
1300                 trace_xfs_rmap_delete(mp, cur->bc_ag.pag->pag_agno,
1301                                 PREV.rm_startblock, PREV.rm_blockcount,
1302                                 PREV.rm_owner, PREV.rm_offset,
1303                                 PREV.rm_flags);
1304                 error = xfs_btree_delete(cur, &i);
1305                 if (error)
1306                         goto done;
1307                 if (XFS_IS_CORRUPT(mp, i != 1)) {
1308                         error = -EFSCORRUPTED;
1309                         goto done;
1310                 }
1311                 error = xfs_btree_decrement(cur, 0, &i);
1312                 if (error)
1313                         goto done;
1314                 if (XFS_IS_CORRUPT(mp, i != 1)) {
1315                         error = -EFSCORRUPTED;
1316                         goto done;
1317                 }
1318                 NEW = LEFT;
1319                 NEW.rm_blockcount += PREV.rm_blockcount;
1320                 error = xfs_rmap_update(cur, &NEW);
1321                 if (error)
1322                         goto done;
1323                 break;
1324
1325         case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG:
1326                 /*
1327                  * Setting all of a previous oldext extent to newext.
1328                  * The right neighbor is contiguous, the left is not.
1329                  */
1330                 error = xfs_btree_increment(cur, 0, &i);
1331                 if (error)
1332                         goto done;
1333                 if (XFS_IS_CORRUPT(mp, i != 1)) {
1334                         error = -EFSCORRUPTED;
1335                         goto done;
1336                 }
1337                 trace_xfs_rmap_delete(mp, cur->bc_ag.pag->pag_agno,
1338                                 RIGHT.rm_startblock, RIGHT.rm_blockcount,
1339                                 RIGHT.rm_owner, RIGHT.rm_offset,
1340                                 RIGHT.rm_flags);
1341                 error = xfs_btree_delete(cur, &i);
1342                 if (error)
1343                         goto done;
1344                 if (XFS_IS_CORRUPT(mp, i != 1)) {
1345                         error = -EFSCORRUPTED;
1346                         goto done;
1347                 }
1348                 error = xfs_btree_decrement(cur, 0, &i);
1349                 if (error)
1350                         goto done;
1351                 if (XFS_IS_CORRUPT(mp, i != 1)) {
1352                         error = -EFSCORRUPTED;
1353                         goto done;
1354                 }
1355                 NEW = PREV;
1356                 NEW.rm_blockcount = len + RIGHT.rm_blockcount;
1357                 NEW.rm_flags = newext;
1358                 error = xfs_rmap_update(cur, &NEW);
1359                 if (error)
1360                         goto done;
1361                 break;
1362
1363         case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING:
1364                 /*
1365                  * Setting all of a previous oldext extent to newext.
1366                  * Neither the left nor right neighbors are contiguous with
1367                  * the new one.
1368                  */
1369                 NEW = PREV;
1370                 NEW.rm_flags = newext;
1371                 error = xfs_rmap_update(cur, &NEW);
1372                 if (error)
1373                         goto done;
1374                 break;
1375
1376         case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG:
1377                 /*
1378                  * Setting the first part of a previous oldext extent to newext.
1379                  * The left neighbor is contiguous.
1380                  */
1381                 NEW = PREV;
1382                 NEW.rm_offset += len;
1383                 NEW.rm_startblock += len;
1384                 NEW.rm_blockcount -= len;
1385                 error = xfs_rmap_update(cur, &NEW);
1386                 if (error)
1387                         goto done;
1388                 error = xfs_btree_decrement(cur, 0, &i);
1389                 if (error)
1390                         goto done;
1391                 NEW = LEFT;
1392                 NEW.rm_blockcount += len;
1393                 error = xfs_rmap_update(cur, &NEW);
1394                 if (error)
1395                         goto done;
1396                 break;
1397
1398         case RMAP_LEFT_FILLING:
1399                 /*
1400                  * Setting the first part of a previous oldext extent to newext.
1401                  * The left neighbor is not contiguous.
1402                  */
1403                 NEW = PREV;
1404                 NEW.rm_startblock += len;
1405                 NEW.rm_offset += len;
1406                 NEW.rm_blockcount -= len;
1407                 error = xfs_rmap_update(cur, &NEW);
1408                 if (error)
1409                         goto done;
1410                 NEW.rm_startblock = bno;
1411                 NEW.rm_owner = owner;
1412                 NEW.rm_offset = offset;
1413                 NEW.rm_blockcount = len;
1414                 NEW.rm_flags = newext;
1415                 cur->bc_rec.r = NEW;
1416                 trace_xfs_rmap_insert(mp, cur->bc_ag.pag->pag_agno, bno,
1417                                 len, owner, offset, newext);
1418                 error = xfs_btree_insert(cur, &i);
1419                 if (error)
1420                         goto done;
1421                 if (XFS_IS_CORRUPT(mp, i != 1)) {
1422                         error = -EFSCORRUPTED;
1423                         goto done;
1424                 }
1425                 break;
1426
1427         case RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG:
1428                 /*
1429                  * Setting the last part of a previous oldext extent to newext.
1430                  * The right neighbor is contiguous with the new allocation.
1431                  */
1432                 NEW = PREV;
1433                 NEW.rm_blockcount -= len;
1434                 error = xfs_rmap_update(cur, &NEW);
1435                 if (error)
1436                         goto done;
1437                 error = xfs_btree_increment(cur, 0, &i);
1438                 if (error)
1439                         goto done;
1440                 NEW = RIGHT;
1441                 NEW.rm_offset = offset;
1442                 NEW.rm_startblock = bno;
1443                 NEW.rm_blockcount += len;
1444                 error = xfs_rmap_update(cur, &NEW);
1445                 if (error)
1446                         goto done;
1447                 break;
1448
1449         case RMAP_RIGHT_FILLING:
1450                 /*
1451                  * Setting the last part of a previous oldext extent to newext.
1452                  * The right neighbor is not contiguous.
1453                  */
1454                 NEW = PREV;
1455                 NEW.rm_blockcount -= len;
1456                 error = xfs_rmap_update(cur, &NEW);
1457                 if (error)
1458                         goto done;
1459                 error = xfs_rmap_lookup_eq(cur, bno, len, owner, offset,
1460                                 oldext, &i);
1461                 if (error)
1462                         goto done;
1463                 if (XFS_IS_CORRUPT(mp, i != 0)) {
1464                         error = -EFSCORRUPTED;
1465                         goto done;
1466                 }
1467                 NEW.rm_startblock = bno;
1468                 NEW.rm_owner = owner;
1469                 NEW.rm_offset = offset;
1470                 NEW.rm_blockcount = len;
1471                 NEW.rm_flags = newext;
1472                 cur->bc_rec.r = NEW;
1473                 trace_xfs_rmap_insert(mp, cur->bc_ag.pag->pag_agno, bno,
1474                                 len, owner, offset, newext);
1475                 error = xfs_btree_insert(cur, &i);
1476                 if (error)
1477                         goto done;
1478                 if (XFS_IS_CORRUPT(mp, i != 1)) {
1479                         error = -EFSCORRUPTED;
1480                         goto done;
1481                 }
1482                 break;
1483
1484         case 0:
1485                 /*
1486                  * Setting the middle part of a previous oldext extent to
1487                  * newext.  Contiguity is impossible here.
1488                  * One extent becomes three extents.
1489                  */
1490                 /* new right extent - oldext */
1491                 NEW.rm_startblock = bno + len;
1492                 NEW.rm_owner = owner;
1493                 NEW.rm_offset = new_endoff;
1494                 NEW.rm_blockcount = PREV.rm_offset + PREV.rm_blockcount -
1495                                 new_endoff;
1496                 NEW.rm_flags = PREV.rm_flags;
1497                 error = xfs_rmap_update(cur, &NEW);
1498                 if (error)
1499                         goto done;
1500                 /* new left extent - oldext */
1501                 NEW = PREV;
1502                 NEW.rm_blockcount = offset - PREV.rm_offset;
1503                 cur->bc_rec.r = NEW;
1504                 trace_xfs_rmap_insert(mp, cur->bc_ag.pag->pag_agno,
1505                                 NEW.rm_startblock, NEW.rm_blockcount,
1506                                 NEW.rm_owner, NEW.rm_offset,
1507                                 NEW.rm_flags);
1508                 error = xfs_btree_insert(cur, &i);
1509                 if (error)
1510                         goto done;
1511                 if (XFS_IS_CORRUPT(mp, i != 1)) {
1512                         error = -EFSCORRUPTED;
1513                         goto done;
1514                 }
1515                 /*
1516                  * Reset the cursor to the position of the new extent
1517                  * we are about to insert as we can't trust it after
1518                  * the previous insert.
1519                  */
1520                 error = xfs_rmap_lookup_eq(cur, bno, len, owner, offset,
1521                                 oldext, &i);
1522                 if (error)
1523                         goto done;
1524                 if (XFS_IS_CORRUPT(mp, i != 0)) {
1525                         error = -EFSCORRUPTED;
1526                         goto done;
1527                 }
1528                 /* new middle extent - newext */
1529                 cur->bc_rec.r.rm_flags &= ~XFS_RMAP_UNWRITTEN;
1530                 cur->bc_rec.r.rm_flags |= newext;
1531                 trace_xfs_rmap_insert(mp, cur->bc_ag.pag->pag_agno, bno, len,
1532                                 owner, offset, newext);
1533                 error = xfs_btree_insert(cur, &i);
1534                 if (error)
1535                         goto done;
1536                 if (XFS_IS_CORRUPT(mp, i != 1)) {
1537                         error = -EFSCORRUPTED;
1538                         goto done;
1539                 }
1540                 break;
1541
1542         case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG:
1543         case RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG:
1544         case RMAP_LEFT_FILLING | RMAP_RIGHT_CONTIG:
1545         case RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG:
1546         case RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG:
1547         case RMAP_LEFT_CONTIG:
1548         case RMAP_RIGHT_CONTIG:
1549                 /*
1550                  * These cases are all impossible.
1551                  */
1552                 ASSERT(0);
1553         }
1554
1555         trace_xfs_rmap_convert_done(mp, cur->bc_ag.pag->pag_agno, bno, len,
1556                         unwritten, oinfo);
1557 done:
1558         if (error)
1559                 trace_xfs_rmap_convert_error(cur->bc_mp,
1560                                 cur->bc_ag.pag->pag_agno, error, _RET_IP_);
1561         return error;
1562 }
1563
1564 /*
1565  * Convert an unwritten extent to a real extent or vice versa.  If there is no
1566  * possibility of overlapping extents, delegate to the simpler convert
1567  * function.
1568  */
1569 STATIC int
1570 xfs_rmap_convert_shared(
1571         struct xfs_btree_cur            *cur,
1572         xfs_agblock_t                   bno,
1573         xfs_extlen_t                    len,
1574         bool                            unwritten,
1575         const struct xfs_owner_info     *oinfo)
1576 {
1577         struct xfs_mount                *mp = cur->bc_mp;
1578         struct xfs_rmap_irec            r[4];   /* neighbor extent entries */
1579                                                 /* left is 0, right is 1, */
1580                                                 /* prev is 2, new is 3 */
1581         uint64_t                owner;
1582         uint64_t                offset;
1583         uint64_t                new_endoff;
1584         unsigned int            oldext;
1585         unsigned int            newext;
1586         unsigned int            flags = 0;
1587         int                     i;
1588         int                     state = 0;
1589         int                     error;
1590
1591         xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
1592         ASSERT(!(XFS_RMAP_NON_INODE_OWNER(owner) ||
1593                         (flags & (XFS_RMAP_ATTR_FORK | XFS_RMAP_BMBT_BLOCK))));
1594         oldext = unwritten ? XFS_RMAP_UNWRITTEN : 0;
1595         new_endoff = offset + len;
1596         trace_xfs_rmap_convert(mp, cur->bc_ag.pag->pag_agno, bno, len,
1597                         unwritten, oinfo);
1598
1599         /*
1600          * For the initial lookup, look for and exact match or the left-adjacent
1601          * record for our insertion point. This will also give us the record for
1602          * start block contiguity tests.
1603          */
1604         error = xfs_rmap_lookup_le_range(cur, bno, owner, offset, oldext,
1605                         &PREV, &i);
1606         if (error)
1607                 goto done;
1608         if (XFS_IS_CORRUPT(mp, i != 1)) {
1609                 error = -EFSCORRUPTED;
1610                 goto done;
1611         }
1612
1613         ASSERT(PREV.rm_offset <= offset);
1614         ASSERT(PREV.rm_offset + PREV.rm_blockcount >= new_endoff);
1615         ASSERT((PREV.rm_flags & XFS_RMAP_UNWRITTEN) == oldext);
1616         newext = ~oldext & XFS_RMAP_UNWRITTEN;
1617
1618         /*
1619          * Set flags determining what part of the previous oldext allocation
1620          * extent is being replaced by a newext allocation.
1621          */
1622         if (PREV.rm_offset == offset)
1623                 state |= RMAP_LEFT_FILLING;
1624         if (PREV.rm_offset + PREV.rm_blockcount == new_endoff)
1625                 state |= RMAP_RIGHT_FILLING;
1626
1627         /* Is there a left record that abuts our range? */
1628         error = xfs_rmap_find_left_neighbor(cur, bno, owner, offset, newext,
1629                         &LEFT, &i);
1630         if (error)
1631                 goto done;
1632         if (i) {
1633                 state |= RMAP_LEFT_VALID;
1634                 if (XFS_IS_CORRUPT(mp,
1635                                    LEFT.rm_startblock + LEFT.rm_blockcount >
1636                                    bno)) {
1637                         error = -EFSCORRUPTED;
1638                         goto done;
1639                 }
1640                 if (xfs_rmap_is_mergeable(&LEFT, owner, newext))
1641                         state |= RMAP_LEFT_CONTIG;
1642         }
1643
1644         /* Is there a right record that abuts our range? */
1645         error = xfs_rmap_lookup_eq(cur, bno + len, len, owner, offset + len,
1646                         newext, &i);
1647         if (error)
1648                 goto done;
1649         if (i) {
1650                 state |= RMAP_RIGHT_VALID;
1651                 error = xfs_rmap_get_rec(cur, &RIGHT, &i);
1652                 if (error)
1653                         goto done;
1654                 if (XFS_IS_CORRUPT(mp, i != 1)) {
1655                         error = -EFSCORRUPTED;
1656                         goto done;
1657                 }
1658                 if (XFS_IS_CORRUPT(mp, bno + len > RIGHT.rm_startblock)) {
1659                         error = -EFSCORRUPTED;
1660                         goto done;
1661                 }
1662                 trace_xfs_rmap_find_right_neighbor_result(cur->bc_mp,
1663                                 cur->bc_ag.pag->pag_agno, RIGHT.rm_startblock,
1664                                 RIGHT.rm_blockcount, RIGHT.rm_owner,
1665                                 RIGHT.rm_offset, RIGHT.rm_flags);
1666                 if (xfs_rmap_is_mergeable(&RIGHT, owner, newext))
1667                         state |= RMAP_RIGHT_CONTIG;
1668         }
1669
1670         /* check that left + prev + right is not too long */
1671         if ((state & (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
1672                          RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG)) ==
1673             (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
1674              RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG) &&
1675             (unsigned long)LEFT.rm_blockcount + len +
1676              RIGHT.rm_blockcount > XFS_RMAP_LEN_MAX)
1677                 state &= ~RMAP_RIGHT_CONTIG;
1678
1679         trace_xfs_rmap_convert_state(mp, cur->bc_ag.pag->pag_agno, state,
1680                         _RET_IP_);
1681         /*
1682          * Switch out based on the FILLING and CONTIG state bits.
1683          */
1684         switch (state & (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
1685                          RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG)) {
1686         case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
1687              RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG:
1688                 /*
1689                  * Setting all of a previous oldext extent to newext.
1690                  * The left and right neighbors are both contiguous with new.
1691                  */
1692                 error = xfs_rmap_delete(cur, RIGHT.rm_startblock,
1693                                 RIGHT.rm_blockcount, RIGHT.rm_owner,
1694                                 RIGHT.rm_offset, RIGHT.rm_flags);
1695                 if (error)
1696                         goto done;
1697                 error = xfs_rmap_delete(cur, PREV.rm_startblock,
1698                                 PREV.rm_blockcount, PREV.rm_owner,
1699                                 PREV.rm_offset, PREV.rm_flags);
1700                 if (error)
1701                         goto done;
1702                 NEW = LEFT;
1703                 error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
1704                                 NEW.rm_blockcount, NEW.rm_owner,
1705                                 NEW.rm_offset, NEW.rm_flags, &i);
1706                 if (error)
1707                         goto done;
1708                 if (XFS_IS_CORRUPT(mp, i != 1)) {
1709                         error = -EFSCORRUPTED;
1710                         goto done;
1711                 }
1712                 NEW.rm_blockcount += PREV.rm_blockcount + RIGHT.rm_blockcount;
1713                 error = xfs_rmap_update(cur, &NEW);
1714                 if (error)
1715                         goto done;
1716                 break;
1717
1718         case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG:
1719                 /*
1720                  * Setting all of a previous oldext extent to newext.
1721                  * The left neighbor is contiguous, the right is not.
1722                  */
1723                 error = xfs_rmap_delete(cur, PREV.rm_startblock,
1724                                 PREV.rm_blockcount, PREV.rm_owner,
1725                                 PREV.rm_offset, PREV.rm_flags);
1726                 if (error)
1727                         goto done;
1728                 NEW = LEFT;
1729                 error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
1730                                 NEW.rm_blockcount, NEW.rm_owner,
1731                                 NEW.rm_offset, NEW.rm_flags, &i);
1732                 if (error)
1733                         goto done;
1734                 if (XFS_IS_CORRUPT(mp, i != 1)) {
1735                         error = -EFSCORRUPTED;
1736                         goto done;
1737                 }
1738                 NEW.rm_blockcount += PREV.rm_blockcount;
1739                 error = xfs_rmap_update(cur, &NEW);
1740                 if (error)
1741                         goto done;
1742                 break;
1743
1744         case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG:
1745                 /*
1746                  * Setting all of a previous oldext extent to newext.
1747                  * The right neighbor is contiguous, the left is not.
1748                  */
1749                 error = xfs_rmap_delete(cur, RIGHT.rm_startblock,
1750                                 RIGHT.rm_blockcount, RIGHT.rm_owner,
1751                                 RIGHT.rm_offset, RIGHT.rm_flags);
1752                 if (error)
1753                         goto done;
1754                 NEW = PREV;
1755                 error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
1756                                 NEW.rm_blockcount, NEW.rm_owner,
1757                                 NEW.rm_offset, NEW.rm_flags, &i);
1758                 if (error)
1759                         goto done;
1760                 if (XFS_IS_CORRUPT(mp, i != 1)) {
1761                         error = -EFSCORRUPTED;
1762                         goto done;
1763                 }
1764                 NEW.rm_blockcount += RIGHT.rm_blockcount;
1765                 NEW.rm_flags = RIGHT.rm_flags;
1766                 error = xfs_rmap_update(cur, &NEW);
1767                 if (error)
1768                         goto done;
1769                 break;
1770
1771         case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING:
1772                 /*
1773                  * Setting all of a previous oldext extent to newext.
1774                  * Neither the left nor right neighbors are contiguous with
1775                  * the new one.
1776                  */
1777                 NEW = PREV;
1778                 error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
1779                                 NEW.rm_blockcount, NEW.rm_owner,
1780                                 NEW.rm_offset, NEW.rm_flags, &i);
1781                 if (error)
1782                         goto done;
1783                 if (XFS_IS_CORRUPT(mp, i != 1)) {
1784                         error = -EFSCORRUPTED;
1785                         goto done;
1786                 }
1787                 NEW.rm_flags = newext;
1788                 error = xfs_rmap_update(cur, &NEW);
1789                 if (error)
1790                         goto done;
1791                 break;
1792
1793         case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG:
1794                 /*
1795                  * Setting the first part of a previous oldext extent to newext.
1796                  * The left neighbor is contiguous.
1797                  */
1798                 NEW = PREV;
1799                 error = xfs_rmap_delete(cur, NEW.rm_startblock,
1800                                 NEW.rm_blockcount, NEW.rm_owner,
1801                                 NEW.rm_offset, NEW.rm_flags);
1802                 if (error)
1803                         goto done;
1804                 NEW.rm_offset += len;
1805                 NEW.rm_startblock += len;
1806                 NEW.rm_blockcount -= len;
1807                 error = xfs_rmap_insert(cur, NEW.rm_startblock,
1808                                 NEW.rm_blockcount, NEW.rm_owner,
1809                                 NEW.rm_offset, NEW.rm_flags);
1810                 if (error)
1811                         goto done;
1812                 NEW = LEFT;
1813                 error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
1814                                 NEW.rm_blockcount, NEW.rm_owner,
1815                                 NEW.rm_offset, NEW.rm_flags, &i);
1816                 if (error)
1817                         goto done;
1818                 if (XFS_IS_CORRUPT(mp, i != 1)) {
1819                         error = -EFSCORRUPTED;
1820                         goto done;
1821                 }
1822                 NEW.rm_blockcount += len;
1823                 error = xfs_rmap_update(cur, &NEW);
1824                 if (error)
1825                         goto done;
1826                 break;
1827
1828         case RMAP_LEFT_FILLING:
1829                 /*
1830                  * Setting the first part of a previous oldext extent to newext.
1831                  * The left neighbor is not contiguous.
1832                  */
1833                 NEW = PREV;
1834                 error = xfs_rmap_delete(cur, NEW.rm_startblock,
1835                                 NEW.rm_blockcount, NEW.rm_owner,
1836                                 NEW.rm_offset, NEW.rm_flags);
1837                 if (error)
1838                         goto done;
1839                 NEW.rm_offset += len;
1840                 NEW.rm_startblock += len;
1841                 NEW.rm_blockcount -= len;
1842                 error = xfs_rmap_insert(cur, NEW.rm_startblock,
1843                                 NEW.rm_blockcount, NEW.rm_owner,
1844                                 NEW.rm_offset, NEW.rm_flags);
1845                 if (error)
1846                         goto done;
1847                 error = xfs_rmap_insert(cur, bno, len, owner, offset, newext);
1848                 if (error)
1849                         goto done;
1850                 break;
1851
1852         case RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG:
1853                 /*
1854                  * Setting the last part of a previous oldext extent to newext.
1855                  * The right neighbor is contiguous with the new allocation.
1856                  */
1857                 NEW = PREV;
1858                 error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
1859                                 NEW.rm_blockcount, NEW.rm_owner,
1860                                 NEW.rm_offset, NEW.rm_flags, &i);
1861                 if (error)
1862                         goto done;
1863                 if (XFS_IS_CORRUPT(mp, i != 1)) {
1864                         error = -EFSCORRUPTED;
1865                         goto done;
1866                 }
1867                 NEW.rm_blockcount = offset - NEW.rm_offset;
1868                 error = xfs_rmap_update(cur, &NEW);
1869                 if (error)
1870                         goto done;
1871                 NEW = RIGHT;
1872                 error = xfs_rmap_delete(cur, NEW.rm_startblock,
1873                                 NEW.rm_blockcount, NEW.rm_owner,
1874                                 NEW.rm_offset, NEW.rm_flags);
1875                 if (error)
1876                         goto done;
1877                 NEW.rm_offset = offset;
1878                 NEW.rm_startblock = bno;
1879                 NEW.rm_blockcount += len;
1880                 error = xfs_rmap_insert(cur, NEW.rm_startblock,
1881                                 NEW.rm_blockcount, NEW.rm_owner,
1882                                 NEW.rm_offset, NEW.rm_flags);
1883                 if (error)
1884                         goto done;
1885                 break;
1886
1887         case RMAP_RIGHT_FILLING:
1888                 /*
1889                  * Setting the last part of a previous oldext extent to newext.
1890                  * The right neighbor is not contiguous.
1891                  */
1892                 NEW = PREV;
1893                 error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
1894                                 NEW.rm_blockcount, NEW.rm_owner,
1895                                 NEW.rm_offset, NEW.rm_flags, &i);
1896                 if (error)
1897                         goto done;
1898                 if (XFS_IS_CORRUPT(mp, i != 1)) {
1899                         error = -EFSCORRUPTED;
1900                         goto done;
1901                 }
1902                 NEW.rm_blockcount -= len;
1903                 error = xfs_rmap_update(cur, &NEW);
1904                 if (error)
1905                         goto done;
1906                 error = xfs_rmap_insert(cur, bno, len, owner, offset, newext);
1907                 if (error)
1908                         goto done;
1909                 break;
1910
1911         case 0:
1912                 /*
1913                  * Setting the middle part of a previous oldext extent to
1914                  * newext.  Contiguity is impossible here.
1915                  * One extent becomes three extents.
1916                  */
1917                 /* new right extent - oldext */
1918                 NEW.rm_startblock = bno + len;
1919                 NEW.rm_owner = owner;
1920                 NEW.rm_offset = new_endoff;
1921                 NEW.rm_blockcount = PREV.rm_offset + PREV.rm_blockcount -
1922                                 new_endoff;
1923                 NEW.rm_flags = PREV.rm_flags;
1924                 error = xfs_rmap_insert(cur, NEW.rm_startblock,
1925                                 NEW.rm_blockcount, NEW.rm_owner, NEW.rm_offset,
1926                                 NEW.rm_flags);
1927                 if (error)
1928                         goto done;
1929                 /* new left extent - oldext */
1930                 NEW = PREV;
1931                 error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
1932                                 NEW.rm_blockcount, NEW.rm_owner,
1933                                 NEW.rm_offset, NEW.rm_flags, &i);
1934                 if (error)
1935                         goto done;
1936                 if (XFS_IS_CORRUPT(mp, i != 1)) {
1937                         error = -EFSCORRUPTED;
1938                         goto done;
1939                 }
1940                 NEW.rm_blockcount = offset - NEW.rm_offset;
1941                 error = xfs_rmap_update(cur, &NEW);
1942                 if (error)
1943                         goto done;
1944                 /* new middle extent - newext */
1945                 NEW.rm_startblock = bno;
1946                 NEW.rm_blockcount = len;
1947                 NEW.rm_owner = owner;
1948                 NEW.rm_offset = offset;
1949                 NEW.rm_flags = newext;
1950                 error = xfs_rmap_insert(cur, NEW.rm_startblock,
1951                                 NEW.rm_blockcount, NEW.rm_owner, NEW.rm_offset,
1952                                 NEW.rm_flags);
1953                 if (error)
1954                         goto done;
1955                 break;
1956
1957         case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG:
1958         case RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG:
1959         case RMAP_LEFT_FILLING | RMAP_RIGHT_CONTIG:
1960         case RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG:
1961         case RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG:
1962         case RMAP_LEFT_CONTIG:
1963         case RMAP_RIGHT_CONTIG:
1964                 /*
1965                  * These cases are all impossible.
1966                  */
1967                 ASSERT(0);
1968         }
1969
1970         trace_xfs_rmap_convert_done(mp, cur->bc_ag.pag->pag_agno, bno, len,
1971                         unwritten, oinfo);
1972 done:
1973         if (error)
1974                 trace_xfs_rmap_convert_error(cur->bc_mp,
1975                                 cur->bc_ag.pag->pag_agno, error, _RET_IP_);
1976         return error;
1977 }
1978
1979 #undef  NEW
1980 #undef  LEFT
1981 #undef  RIGHT
1982 #undef  PREV
1983
1984 /*
1985  * Find an extent in the rmap btree and unmap it.  For rmap extent types that
1986  * can overlap (data fork rmaps on reflink filesystems) we must be careful
1987  * that the prev/next records in the btree might belong to another owner.
1988  * Therefore we must use delete+insert to alter any of the key fields.
1989  *
1990  * For every other situation there can only be one owner for a given extent,
1991  * so we can call the regular _free function.
1992  */
1993 STATIC int
1994 xfs_rmap_unmap_shared(
1995         struct xfs_btree_cur            *cur,
1996         xfs_agblock_t                   bno,
1997         xfs_extlen_t                    len,
1998         bool                            unwritten,
1999         const struct xfs_owner_info     *oinfo)
2000 {
2001         struct xfs_mount                *mp = cur->bc_mp;
2002         struct xfs_rmap_irec            ltrec;
2003         uint64_t                        ltoff;
2004         int                             error = 0;
2005         int                             i;
2006         uint64_t                        owner;
2007         uint64_t                        offset;
2008         unsigned int                    flags;
2009
2010         xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
2011         if (unwritten)
2012                 flags |= XFS_RMAP_UNWRITTEN;
2013         trace_xfs_rmap_unmap(mp, cur->bc_ag.pag->pag_agno, bno, len,
2014                         unwritten, oinfo);
2015
2016         /*
2017          * We should always have a left record because there's a static record
2018          * for the AG headers at rm_startblock == 0 created by mkfs/growfs that
2019          * will not ever be removed from the tree.
2020          */
2021         error = xfs_rmap_lookup_le_range(cur, bno, owner, offset, flags,
2022                         &ltrec, &i);
2023         if (error)
2024                 goto out_error;
2025         if (XFS_IS_CORRUPT(mp, i != 1)) {
2026                 error = -EFSCORRUPTED;
2027                 goto out_error;
2028         }
2029         ltoff = ltrec.rm_offset;
2030
2031         /* Make sure the extent we found covers the entire freeing range. */
2032         if (XFS_IS_CORRUPT(mp,
2033                            ltrec.rm_startblock > bno ||
2034                            ltrec.rm_startblock + ltrec.rm_blockcount <
2035                            bno + len)) {
2036                 error = -EFSCORRUPTED;
2037                 goto out_error;
2038         }
2039
2040         /* Make sure the owner matches what we expect to find in the tree. */
2041         if (XFS_IS_CORRUPT(mp, owner != ltrec.rm_owner)) {
2042                 error = -EFSCORRUPTED;
2043                 goto out_error;
2044         }
2045
2046         /* Make sure the unwritten flag matches. */
2047         if (XFS_IS_CORRUPT(mp,
2048                            (flags & XFS_RMAP_UNWRITTEN) !=
2049                            (ltrec.rm_flags & XFS_RMAP_UNWRITTEN))) {
2050                 error = -EFSCORRUPTED;
2051                 goto out_error;
2052         }
2053
2054         /* Check the offset. */
2055         if (XFS_IS_CORRUPT(mp, ltrec.rm_offset > offset)) {
2056                 error = -EFSCORRUPTED;
2057                 goto out_error;
2058         }
2059         if (XFS_IS_CORRUPT(mp, offset > ltoff + ltrec.rm_blockcount)) {
2060                 error = -EFSCORRUPTED;
2061                 goto out_error;
2062         }
2063
2064         if (ltrec.rm_startblock == bno && ltrec.rm_blockcount == len) {
2065                 /* Exact match, simply remove the record from rmap tree. */
2066                 error = xfs_rmap_delete(cur, ltrec.rm_startblock,
2067                                 ltrec.rm_blockcount, ltrec.rm_owner,
2068                                 ltrec.rm_offset, ltrec.rm_flags);
2069                 if (error)
2070                         goto out_error;
2071         } else if (ltrec.rm_startblock == bno) {
2072                 /*
2073                  * Overlap left hand side of extent: move the start, trim the
2074                  * length and update the current record.
2075                  *
2076                  *       ltbno                ltlen
2077                  * Orig:    |oooooooooooooooooooo|
2078                  * Freeing: |fffffffff|
2079                  * Result:            |rrrrrrrrrr|
2080                  *         bno       len
2081                  */
2082
2083                 /* Delete prev rmap. */
2084                 error = xfs_rmap_delete(cur, ltrec.rm_startblock,
2085                                 ltrec.rm_blockcount, ltrec.rm_owner,
2086                                 ltrec.rm_offset, ltrec.rm_flags);
2087                 if (error)
2088                         goto out_error;
2089
2090                 /* Add an rmap at the new offset. */
2091                 ltrec.rm_startblock += len;
2092                 ltrec.rm_blockcount -= len;
2093                 ltrec.rm_offset += len;
2094                 error = xfs_rmap_insert(cur, ltrec.rm_startblock,
2095                                 ltrec.rm_blockcount, ltrec.rm_owner,
2096                                 ltrec.rm_offset, ltrec.rm_flags);
2097                 if (error)
2098                         goto out_error;
2099         } else if (ltrec.rm_startblock + ltrec.rm_blockcount == bno + len) {
2100                 /*
2101                  * Overlap right hand side of extent: trim the length and
2102                  * update the current record.
2103                  *
2104                  *       ltbno                ltlen
2105                  * Orig:    |oooooooooooooooooooo|
2106                  * Freeing:            |fffffffff|
2107                  * Result:  |rrrrrrrrrr|
2108                  *                    bno       len
2109                  */
2110                 error = xfs_rmap_lookup_eq(cur, ltrec.rm_startblock,
2111                                 ltrec.rm_blockcount, ltrec.rm_owner,
2112                                 ltrec.rm_offset, ltrec.rm_flags, &i);
2113                 if (error)
2114                         goto out_error;
2115                 if (XFS_IS_CORRUPT(mp, i != 1)) {
2116                         error = -EFSCORRUPTED;
2117                         goto out_error;
2118                 }
2119                 ltrec.rm_blockcount -= len;
2120                 error = xfs_rmap_update(cur, &ltrec);
2121                 if (error)
2122                         goto out_error;
2123         } else {
2124                 /*
2125                  * Overlap middle of extent: trim the length of the existing
2126                  * record to the length of the new left-extent size, increment
2127                  * the insertion position so we can insert a new record
2128                  * containing the remaining right-extent space.
2129                  *
2130                  *       ltbno                ltlen
2131                  * Orig:    |oooooooooooooooooooo|
2132                  * Freeing:       |fffffffff|
2133                  * Result:  |rrrrr|         |rrrr|
2134                  *               bno       len
2135                  */
2136                 xfs_extlen_t    orig_len = ltrec.rm_blockcount;
2137
2138                 /* Shrink the left side of the rmap */
2139                 error = xfs_rmap_lookup_eq(cur, ltrec.rm_startblock,
2140                                 ltrec.rm_blockcount, ltrec.rm_owner,
2141                                 ltrec.rm_offset, ltrec.rm_flags, &i);
2142                 if (error)
2143                         goto out_error;
2144                 if (XFS_IS_CORRUPT(mp, i != 1)) {
2145                         error = -EFSCORRUPTED;
2146                         goto out_error;
2147                 }
2148                 ltrec.rm_blockcount = bno - ltrec.rm_startblock;
2149                 error = xfs_rmap_update(cur, &ltrec);
2150                 if (error)
2151                         goto out_error;
2152
2153                 /* Add an rmap at the new offset */
2154                 error = xfs_rmap_insert(cur, bno + len,
2155                                 orig_len - len - ltrec.rm_blockcount,
2156                                 ltrec.rm_owner, offset + len,
2157                                 ltrec.rm_flags);
2158                 if (error)
2159                         goto out_error;
2160         }
2161
2162         trace_xfs_rmap_unmap_done(mp, cur->bc_ag.pag->pag_agno, bno, len,
2163                         unwritten, oinfo);
2164 out_error:
2165         if (error)
2166                 trace_xfs_rmap_unmap_error(cur->bc_mp,
2167                                 cur->bc_ag.pag->pag_agno, error, _RET_IP_);
2168         return error;
2169 }
2170
2171 /*
2172  * Find an extent in the rmap btree and map it.  For rmap extent types that
2173  * can overlap (data fork rmaps on reflink filesystems) we must be careful
2174  * that the prev/next records in the btree might belong to another owner.
2175  * Therefore we must use delete+insert to alter any of the key fields.
2176  *
2177  * For every other situation there can only be one owner for a given extent,
2178  * so we can call the regular _alloc function.
2179  */
2180 STATIC int
2181 xfs_rmap_map_shared(
2182         struct xfs_btree_cur            *cur,
2183         xfs_agblock_t                   bno,
2184         xfs_extlen_t                    len,
2185         bool                            unwritten,
2186         const struct xfs_owner_info     *oinfo)
2187 {
2188         struct xfs_mount                *mp = cur->bc_mp;
2189         struct xfs_rmap_irec            ltrec;
2190         struct xfs_rmap_irec            gtrec;
2191         int                             have_gt;
2192         int                             have_lt;
2193         int                             error = 0;
2194         int                             i;
2195         uint64_t                        owner;
2196         uint64_t                        offset;
2197         unsigned int                    flags = 0;
2198
2199         xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
2200         if (unwritten)
2201                 flags |= XFS_RMAP_UNWRITTEN;
2202         trace_xfs_rmap_map(mp, cur->bc_ag.pag->pag_agno, bno, len,
2203                         unwritten, oinfo);
2204
2205         /* Is there a left record that abuts our range? */
2206         error = xfs_rmap_find_left_neighbor(cur, bno, owner, offset, flags,
2207                         &ltrec, &have_lt);
2208         if (error)
2209                 goto out_error;
2210         if (have_lt &&
2211             !xfs_rmap_is_mergeable(&ltrec, owner, flags))
2212                 have_lt = 0;
2213
2214         /* Is there a right record that abuts our range? */
2215         error = xfs_rmap_lookup_eq(cur, bno + len, len, owner, offset + len,
2216                         flags, &have_gt);
2217         if (error)
2218                 goto out_error;
2219         if (have_gt) {
2220                 error = xfs_rmap_get_rec(cur, &gtrec, &have_gt);
2221                 if (error)
2222                         goto out_error;
2223                 if (XFS_IS_CORRUPT(mp, have_gt != 1)) {
2224                         error = -EFSCORRUPTED;
2225                         goto out_error;
2226                 }
2227                 trace_xfs_rmap_find_right_neighbor_result(cur->bc_mp,
2228                         cur->bc_ag.pag->pag_agno, gtrec.rm_startblock,
2229                         gtrec.rm_blockcount, gtrec.rm_owner,
2230                         gtrec.rm_offset, gtrec.rm_flags);
2231
2232                 if (!xfs_rmap_is_mergeable(&gtrec, owner, flags))
2233                         have_gt = 0;
2234         }
2235
2236         if (have_lt &&
2237             ltrec.rm_startblock + ltrec.rm_blockcount == bno &&
2238             ltrec.rm_offset + ltrec.rm_blockcount == offset) {
2239                 /*
2240                  * Left edge contiguous, merge into left record.
2241                  *
2242                  *       ltbno     ltlen
2243                  * orig:   |ooooooooo|
2244                  * adding:           |aaaaaaaaa|
2245                  * result: |rrrrrrrrrrrrrrrrrrr|
2246                  *                  bno       len
2247                  */
2248                 ltrec.rm_blockcount += len;
2249                 if (have_gt &&
2250                     bno + len == gtrec.rm_startblock &&
2251                     offset + len == gtrec.rm_offset) {
2252                         /*
2253                          * Right edge also contiguous, delete right record
2254                          * and merge into left record.
2255                          *
2256                          *       ltbno     ltlen    gtbno     gtlen
2257                          * orig:   |ooooooooo|         |ooooooooo|
2258                          * adding:           |aaaaaaaaa|
2259                          * result: |rrrrrrrrrrrrrrrrrrrrrrrrrrrrr|
2260                          */
2261                         ltrec.rm_blockcount += gtrec.rm_blockcount;
2262                         error = xfs_rmap_delete(cur, gtrec.rm_startblock,
2263                                         gtrec.rm_blockcount, gtrec.rm_owner,
2264                                         gtrec.rm_offset, gtrec.rm_flags);
2265                         if (error)
2266                                 goto out_error;
2267                 }
2268
2269                 /* Point the cursor back to the left record and update. */
2270                 error = xfs_rmap_lookup_eq(cur, ltrec.rm_startblock,
2271                                 ltrec.rm_blockcount, ltrec.rm_owner,
2272                                 ltrec.rm_offset, ltrec.rm_flags, &i);
2273                 if (error)
2274                         goto out_error;
2275                 if (XFS_IS_CORRUPT(mp, i != 1)) {
2276                         error = -EFSCORRUPTED;
2277                         goto out_error;
2278                 }
2279
2280                 error = xfs_rmap_update(cur, &ltrec);
2281                 if (error)
2282                         goto out_error;
2283         } else if (have_gt &&
2284                    bno + len == gtrec.rm_startblock &&
2285                    offset + len == gtrec.rm_offset) {
2286                 /*
2287                  * Right edge contiguous, merge into right record.
2288                  *
2289                  *                 gtbno     gtlen
2290                  * Orig:             |ooooooooo|
2291                  * adding: |aaaaaaaaa|
2292                  * Result: |rrrrrrrrrrrrrrrrrrr|
2293                  *        bno       len
2294                  */
2295                 /* Delete the old record. */
2296                 error = xfs_rmap_delete(cur, gtrec.rm_startblock,
2297                                 gtrec.rm_blockcount, gtrec.rm_owner,
2298                                 gtrec.rm_offset, gtrec.rm_flags);
2299                 if (error)
2300                         goto out_error;
2301
2302                 /* Move the start and re-add it. */
2303                 gtrec.rm_startblock = bno;
2304                 gtrec.rm_blockcount += len;
2305                 gtrec.rm_offset = offset;
2306                 error = xfs_rmap_insert(cur, gtrec.rm_startblock,
2307                                 gtrec.rm_blockcount, gtrec.rm_owner,
2308                                 gtrec.rm_offset, gtrec.rm_flags);
2309                 if (error)
2310                         goto out_error;
2311         } else {
2312                 /*
2313                  * No contiguous edge with identical owner, insert
2314                  * new record at current cursor position.
2315                  */
2316                 error = xfs_rmap_insert(cur, bno, len, owner, offset, flags);
2317                 if (error)
2318                         goto out_error;
2319         }
2320
2321         trace_xfs_rmap_map_done(mp, cur->bc_ag.pag->pag_agno, bno, len,
2322                         unwritten, oinfo);
2323 out_error:
2324         if (error)
2325                 trace_xfs_rmap_map_error(cur->bc_mp,
2326                                 cur->bc_ag.pag->pag_agno, error, _RET_IP_);
2327         return error;
2328 }
2329
2330 /* Insert a raw rmap into the rmapbt. */
2331 int
2332 xfs_rmap_map_raw(
2333         struct xfs_btree_cur    *cur,
2334         struct xfs_rmap_irec    *rmap)
2335 {
2336         struct xfs_owner_info   oinfo;
2337
2338         oinfo.oi_owner = rmap->rm_owner;
2339         oinfo.oi_offset = rmap->rm_offset;
2340         oinfo.oi_flags = 0;
2341         if (rmap->rm_flags & XFS_RMAP_ATTR_FORK)
2342                 oinfo.oi_flags |= XFS_OWNER_INFO_ATTR_FORK;
2343         if (rmap->rm_flags & XFS_RMAP_BMBT_BLOCK)
2344                 oinfo.oi_flags |= XFS_OWNER_INFO_BMBT_BLOCK;
2345
2346         if (rmap->rm_flags || XFS_RMAP_NON_INODE_OWNER(rmap->rm_owner))
2347                 return xfs_rmap_map(cur, rmap->rm_startblock,
2348                                 rmap->rm_blockcount,
2349                                 rmap->rm_flags & XFS_RMAP_UNWRITTEN,
2350                                 &oinfo);
2351
2352         return xfs_rmap_map_shared(cur, rmap->rm_startblock,
2353                         rmap->rm_blockcount,
2354                         rmap->rm_flags & XFS_RMAP_UNWRITTEN,
2355                         &oinfo);
2356 }
2357
2358 struct xfs_rmap_query_range_info {
2359         xfs_rmap_query_range_fn fn;
2360         void                            *priv;
2361 };
2362
2363 /* Format btree record and pass to our callback. */
2364 STATIC int
2365 xfs_rmap_query_range_helper(
2366         struct xfs_btree_cur            *cur,
2367         const union xfs_btree_rec       *rec,
2368         void                            *priv)
2369 {
2370         struct xfs_rmap_query_range_info        *query = priv;
2371         struct xfs_rmap_irec                    irec;
2372         xfs_failaddr_t                          fa;
2373
2374         fa = xfs_rmap_btrec_to_irec(rec, &irec);
2375         if (!fa)
2376                 fa = xfs_rmap_check_irec(cur, &irec);
2377         if (fa)
2378                 return xfs_rmap_complain_bad_rec(cur, fa, &irec);
2379
2380         return query->fn(cur, &irec, query->priv);
2381 }
2382
2383 /* Find all rmaps between two keys. */
2384 int
2385 xfs_rmap_query_range(
2386         struct xfs_btree_cur                    *cur,
2387         const struct xfs_rmap_irec              *low_rec,
2388         const struct xfs_rmap_irec              *high_rec,
2389         xfs_rmap_query_range_fn                 fn,
2390         void                                    *priv)
2391 {
2392         union xfs_btree_irec                    low_brec = { .r = *low_rec };
2393         union xfs_btree_irec                    high_brec = { .r = *high_rec };
2394         struct xfs_rmap_query_range_info        query = { .priv = priv, .fn = fn };
2395
2396         return xfs_btree_query_range(cur, &low_brec, &high_brec,
2397                         xfs_rmap_query_range_helper, &query);
2398 }
2399
2400 /* Find all rmaps. */
2401 int
2402 xfs_rmap_query_all(
2403         struct xfs_btree_cur                    *cur,
2404         xfs_rmap_query_range_fn                 fn,
2405         void                                    *priv)
2406 {
2407         struct xfs_rmap_query_range_info        query;
2408
2409         query.priv = priv;
2410         query.fn = fn;
2411         return xfs_btree_query_all(cur, xfs_rmap_query_range_helper, &query);
2412 }
2413
2414 /* Clean up after calling xfs_rmap_finish_one. */
2415 void
2416 xfs_rmap_finish_one_cleanup(
2417         struct xfs_trans        *tp,
2418         struct xfs_btree_cur    *rcur,
2419         int                     error)
2420 {
2421         struct xfs_buf          *agbp;
2422
2423         if (rcur == NULL)
2424                 return;
2425         agbp = rcur->bc_ag.agbp;
2426         xfs_btree_del_cursor(rcur, error);
2427         if (error)
2428                 xfs_trans_brelse(tp, agbp);
2429 }
2430
2431 /*
2432  * Process one of the deferred rmap operations.  We pass back the
2433  * btree cursor to maintain our lock on the rmapbt between calls.
2434  * This saves time and eliminates a buffer deadlock between the
2435  * superblock and the AGF because we'll always grab them in the same
2436  * order.
2437  */
2438 int
2439 xfs_rmap_finish_one(
2440         struct xfs_trans                *tp,
2441         struct xfs_rmap_intent          *ri,
2442         struct xfs_btree_cur            **pcur)
2443 {
2444         struct xfs_mount                *mp = tp->t_mountp;
2445         struct xfs_btree_cur            *rcur;
2446         struct xfs_buf                  *agbp = NULL;
2447         int                             error = 0;
2448         struct xfs_owner_info           oinfo;
2449         xfs_agblock_t                   bno;
2450         bool                            unwritten;
2451
2452         bno = XFS_FSB_TO_AGBNO(mp, ri->ri_bmap.br_startblock);
2453
2454         trace_xfs_rmap_deferred(mp, ri->ri_pag->pag_agno, ri->ri_type, bno,
2455                         ri->ri_owner, ri->ri_whichfork,
2456                         ri->ri_bmap.br_startoff, ri->ri_bmap.br_blockcount,
2457                         ri->ri_bmap.br_state);
2458
2459         if (XFS_TEST_ERROR(false, mp, XFS_ERRTAG_RMAP_FINISH_ONE))
2460                 return -EIO;
2461
2462         /*
2463          * If we haven't gotten a cursor or the cursor AG doesn't match
2464          * the startblock, get one now.
2465          */
2466         rcur = *pcur;
2467         if (rcur != NULL && rcur->bc_ag.pag != ri->ri_pag) {
2468                 xfs_rmap_finish_one_cleanup(tp, rcur, 0);
2469                 rcur = NULL;
2470                 *pcur = NULL;
2471         }
2472         if (rcur == NULL) {
2473                 /*
2474                  * Refresh the freelist before we start changing the
2475                  * rmapbt, because a shape change could cause us to
2476                  * allocate blocks.
2477                  */
2478                 error = xfs_free_extent_fix_freelist(tp, ri->ri_pag, &agbp);
2479                 if (error)
2480                         return error;
2481                 if (XFS_IS_CORRUPT(tp->t_mountp, !agbp))
2482                         return -EFSCORRUPTED;
2483
2484                 rcur = xfs_rmapbt_init_cursor(mp, tp, agbp, ri->ri_pag);
2485         }
2486         *pcur = rcur;
2487
2488         xfs_rmap_ino_owner(&oinfo, ri->ri_owner, ri->ri_whichfork,
2489                         ri->ri_bmap.br_startoff);
2490         unwritten = ri->ri_bmap.br_state == XFS_EXT_UNWRITTEN;
2491         bno = XFS_FSB_TO_AGBNO(rcur->bc_mp, ri->ri_bmap.br_startblock);
2492
2493         switch (ri->ri_type) {
2494         case XFS_RMAP_ALLOC:
2495         case XFS_RMAP_MAP:
2496                 error = xfs_rmap_map(rcur, bno, ri->ri_bmap.br_blockcount,
2497                                 unwritten, &oinfo);
2498                 break;
2499         case XFS_RMAP_MAP_SHARED:
2500                 error = xfs_rmap_map_shared(rcur, bno,
2501                                 ri->ri_bmap.br_blockcount, unwritten, &oinfo);
2502                 break;
2503         case XFS_RMAP_FREE:
2504         case XFS_RMAP_UNMAP:
2505                 error = xfs_rmap_unmap(rcur, bno, ri->ri_bmap.br_blockcount,
2506                                 unwritten, &oinfo);
2507                 break;
2508         case XFS_RMAP_UNMAP_SHARED:
2509                 error = xfs_rmap_unmap_shared(rcur, bno,
2510                                 ri->ri_bmap.br_blockcount, unwritten, &oinfo);
2511                 break;
2512         case XFS_RMAP_CONVERT:
2513                 error = xfs_rmap_convert(rcur, bno, ri->ri_bmap.br_blockcount,
2514                                 !unwritten, &oinfo);
2515                 break;
2516         case XFS_RMAP_CONVERT_SHARED:
2517                 error = xfs_rmap_convert_shared(rcur, bno,
2518                                 ri->ri_bmap.br_blockcount, !unwritten, &oinfo);
2519                 break;
2520         default:
2521                 ASSERT(0);
2522                 error = -EFSCORRUPTED;
2523         }
2524
2525         return error;
2526 }
2527
2528 /*
2529  * Don't defer an rmap if we aren't an rmap filesystem.
2530  */
2531 static bool
2532 xfs_rmap_update_is_needed(
2533         struct xfs_mount        *mp,
2534         int                     whichfork)
2535 {
2536         return xfs_has_rmapbt(mp) && whichfork != XFS_COW_FORK;
2537 }
2538
2539 /*
2540  * Record a rmap intent; the list is kept sorted first by AG and then by
2541  * increasing age.
2542  */
2543 static void
2544 __xfs_rmap_add(
2545         struct xfs_trans                *tp,
2546         enum xfs_rmap_intent_type       type,
2547         uint64_t                        owner,
2548         int                             whichfork,
2549         struct xfs_bmbt_irec            *bmap)
2550 {
2551         struct xfs_rmap_intent          *ri;
2552
2553         trace_xfs_rmap_defer(tp->t_mountp,
2554                         XFS_FSB_TO_AGNO(tp->t_mountp, bmap->br_startblock),
2555                         type,
2556                         XFS_FSB_TO_AGBNO(tp->t_mountp, bmap->br_startblock),
2557                         owner, whichfork,
2558                         bmap->br_startoff,
2559                         bmap->br_blockcount,
2560                         bmap->br_state);
2561
2562         ri = kmem_cache_alloc(xfs_rmap_intent_cache, GFP_NOFS | __GFP_NOFAIL);
2563         INIT_LIST_HEAD(&ri->ri_list);
2564         ri->ri_type = type;
2565         ri->ri_owner = owner;
2566         ri->ri_whichfork = whichfork;
2567         ri->ri_bmap = *bmap;
2568
2569         xfs_rmap_update_get_group(tp->t_mountp, ri);
2570         xfs_defer_add(tp, &ri->ri_list, &xfs_rmap_update_defer_type);
2571 }
2572
2573 /* Map an extent into a file. */
2574 void
2575 xfs_rmap_map_extent(
2576         struct xfs_trans        *tp,
2577         struct xfs_inode        *ip,
2578         int                     whichfork,
2579         struct xfs_bmbt_irec    *PREV)
2580 {
2581         enum xfs_rmap_intent_type type = XFS_RMAP_MAP;
2582
2583         if (!xfs_rmap_update_is_needed(tp->t_mountp, whichfork))
2584                 return;
2585
2586         if (whichfork != XFS_ATTR_FORK && xfs_is_reflink_inode(ip))
2587                 type = XFS_RMAP_MAP_SHARED;
2588
2589         __xfs_rmap_add(tp, type, ip->i_ino, whichfork, PREV);
2590 }
2591
2592 /* Unmap an extent out of a file. */
2593 void
2594 xfs_rmap_unmap_extent(
2595         struct xfs_trans        *tp,
2596         struct xfs_inode        *ip,
2597         int                     whichfork,
2598         struct xfs_bmbt_irec    *PREV)
2599 {
2600         enum xfs_rmap_intent_type type = XFS_RMAP_UNMAP;
2601
2602         if (!xfs_rmap_update_is_needed(tp->t_mountp, whichfork))
2603                 return;
2604
2605         if (whichfork != XFS_ATTR_FORK && xfs_is_reflink_inode(ip))
2606                 type = XFS_RMAP_UNMAP_SHARED;
2607
2608         __xfs_rmap_add(tp, type, ip->i_ino, whichfork, PREV);
2609 }
2610
2611 /*
2612  * Convert a data fork extent from unwritten to real or vice versa.
2613  *
2614  * Note that tp can be NULL here as no transaction is used for COW fork
2615  * unwritten conversion.
2616  */
2617 void
2618 xfs_rmap_convert_extent(
2619         struct xfs_mount        *mp,
2620         struct xfs_trans        *tp,
2621         struct xfs_inode        *ip,
2622         int                     whichfork,
2623         struct xfs_bmbt_irec    *PREV)
2624 {
2625         enum xfs_rmap_intent_type type = XFS_RMAP_CONVERT;
2626
2627         if (!xfs_rmap_update_is_needed(mp, whichfork))
2628                 return;
2629
2630         if (whichfork != XFS_ATTR_FORK && xfs_is_reflink_inode(ip))
2631                 type = XFS_RMAP_CONVERT_SHARED;
2632
2633         __xfs_rmap_add(tp, type, ip->i_ino, whichfork, PREV);
2634 }
2635
2636 /* Schedule the creation of an rmap for non-file data. */
2637 void
2638 xfs_rmap_alloc_extent(
2639         struct xfs_trans        *tp,
2640         xfs_agnumber_t          agno,
2641         xfs_agblock_t           bno,
2642         xfs_extlen_t            len,
2643         uint64_t                owner)
2644 {
2645         struct xfs_bmbt_irec    bmap;
2646
2647         if (!xfs_rmap_update_is_needed(tp->t_mountp, XFS_DATA_FORK))
2648                 return;
2649
2650         bmap.br_startblock = XFS_AGB_TO_FSB(tp->t_mountp, agno, bno);
2651         bmap.br_blockcount = len;
2652         bmap.br_startoff = 0;
2653         bmap.br_state = XFS_EXT_NORM;
2654
2655         __xfs_rmap_add(tp, XFS_RMAP_ALLOC, owner, XFS_DATA_FORK, &bmap);
2656 }
2657
2658 /* Schedule the deletion of an rmap for non-file data. */
2659 void
2660 xfs_rmap_free_extent(
2661         struct xfs_trans        *tp,
2662         xfs_agnumber_t          agno,
2663         xfs_agblock_t           bno,
2664         xfs_extlen_t            len,
2665         uint64_t                owner)
2666 {
2667         struct xfs_bmbt_irec    bmap;
2668
2669         if (!xfs_rmap_update_is_needed(tp->t_mountp, XFS_DATA_FORK))
2670                 return;
2671
2672         bmap.br_startblock = XFS_AGB_TO_FSB(tp->t_mountp, agno, bno);
2673         bmap.br_blockcount = len;
2674         bmap.br_startoff = 0;
2675         bmap.br_state = XFS_EXT_NORM;
2676
2677         __xfs_rmap_add(tp, XFS_RMAP_FREE, owner, XFS_DATA_FORK, &bmap);
2678 }
2679
2680 /* Compare rmap records.  Returns -1 if a < b, 1 if a > b, and 0 if equal. */
2681 int
2682 xfs_rmap_compare(
2683         const struct xfs_rmap_irec      *a,
2684         const struct xfs_rmap_irec      *b)
2685 {
2686         __u64                           oa;
2687         __u64                           ob;
2688
2689         oa = xfs_rmap_irec_offset_pack(a);
2690         ob = xfs_rmap_irec_offset_pack(b);
2691
2692         if (a->rm_startblock < b->rm_startblock)
2693                 return -1;
2694         else if (a->rm_startblock > b->rm_startblock)
2695                 return 1;
2696         else if (a->rm_owner < b->rm_owner)
2697                 return -1;
2698         else if (a->rm_owner > b->rm_owner)
2699                 return 1;
2700         else if (oa < ob)
2701                 return -1;
2702         else if (oa > ob)
2703                 return 1;
2704         else
2705                 return 0;
2706 }
2707
2708 /*
2709  * Scan the physical storage part of the keyspace of the reverse mapping index
2710  * and tell us if the area has no records, is fully mapped by records, or is
2711  * partially filled.
2712  */
2713 int
2714 xfs_rmap_has_records(
2715         struct xfs_btree_cur    *cur,
2716         xfs_agblock_t           bno,
2717         xfs_extlen_t            len,
2718         enum xbtree_recpacking  *outcome)
2719 {
2720         union xfs_btree_key     mask = {
2721                 .rmap.rm_startblock = cpu_to_be32(-1U),
2722         };
2723         union xfs_btree_irec    low;
2724         union xfs_btree_irec    high;
2725
2726         memset(&low, 0, sizeof(low));
2727         low.r.rm_startblock = bno;
2728         memset(&high, 0xFF, sizeof(high));
2729         high.r.rm_startblock = bno + len - 1;
2730
2731         return xfs_btree_has_records(cur, &low, &high, &mask, outcome);
2732 }
2733
2734 struct xfs_rmap_ownercount {
2735         /* Owner that we're looking for. */
2736         struct xfs_rmap_irec    good;
2737
2738         /* rmap search keys */
2739         struct xfs_rmap_irec    low;
2740         struct xfs_rmap_irec    high;
2741
2742         struct xfs_rmap_matches *results;
2743
2744         /* Stop early if we find a nonmatch? */
2745         bool                    stop_on_nonmatch;
2746 };
2747
2748 /* Does this rmap represent space that can have multiple owners? */
2749 static inline bool
2750 xfs_rmap_shareable(
2751         struct xfs_mount                *mp,
2752         const struct xfs_rmap_irec      *rmap)
2753 {
2754         if (!xfs_has_reflink(mp))
2755                 return false;
2756         if (XFS_RMAP_NON_INODE_OWNER(rmap->rm_owner))
2757                 return false;
2758         if (rmap->rm_flags & (XFS_RMAP_ATTR_FORK |
2759                               XFS_RMAP_BMBT_BLOCK))
2760                 return false;
2761         return true;
2762 }
2763
2764 static inline void
2765 xfs_rmap_ownercount_init(
2766         struct xfs_rmap_ownercount      *roc,
2767         xfs_agblock_t                   bno,
2768         xfs_extlen_t                    len,
2769         const struct xfs_owner_info     *oinfo,
2770         struct xfs_rmap_matches         *results)
2771 {
2772         memset(roc, 0, sizeof(*roc));
2773         roc->results = results;
2774
2775         roc->low.rm_startblock = bno;
2776         memset(&roc->high, 0xFF, sizeof(roc->high));
2777         roc->high.rm_startblock = bno + len - 1;
2778
2779         memset(results, 0, sizeof(*results));
2780         roc->good.rm_startblock = bno;
2781         roc->good.rm_blockcount = len;
2782         roc->good.rm_owner = oinfo->oi_owner;
2783         roc->good.rm_offset = oinfo->oi_offset;
2784         if (oinfo->oi_flags & XFS_OWNER_INFO_ATTR_FORK)
2785                 roc->good.rm_flags |= XFS_RMAP_ATTR_FORK;
2786         if (oinfo->oi_flags & XFS_OWNER_INFO_BMBT_BLOCK)
2787                 roc->good.rm_flags |= XFS_RMAP_BMBT_BLOCK;
2788 }
2789
2790 /* Figure out if this is a match for the owner. */
2791 STATIC int
2792 xfs_rmap_count_owners_helper(
2793         struct xfs_btree_cur            *cur,
2794         const struct xfs_rmap_irec      *rec,
2795         void                            *priv)
2796 {
2797         struct xfs_rmap_ownercount      *roc = priv;
2798         struct xfs_rmap_irec            check = *rec;
2799         unsigned int                    keyflags;
2800         bool                            filedata;
2801         int64_t                         delta;
2802
2803         filedata = !XFS_RMAP_NON_INODE_OWNER(check.rm_owner) &&
2804                    !(check.rm_flags & XFS_RMAP_BMBT_BLOCK);
2805
2806         /* Trim the part of check that comes before the comparison range. */
2807         delta = (int64_t)roc->good.rm_startblock - check.rm_startblock;
2808         if (delta > 0) {
2809                 check.rm_startblock += delta;
2810                 check.rm_blockcount -= delta;
2811                 if (filedata)
2812                         check.rm_offset += delta;
2813         }
2814
2815         /* Trim the part of check that comes after the comparison range. */
2816         delta = (check.rm_startblock + check.rm_blockcount) -
2817                 (roc->good.rm_startblock + roc->good.rm_blockcount);
2818         if (delta > 0)
2819                 check.rm_blockcount -= delta;
2820
2821         /* Don't care about unwritten status for establishing ownership. */
2822         keyflags = check.rm_flags & (XFS_RMAP_ATTR_FORK | XFS_RMAP_BMBT_BLOCK);
2823
2824         if (check.rm_startblock == roc->good.rm_startblock &&
2825             check.rm_blockcount == roc->good.rm_blockcount &&
2826             check.rm_owner      == roc->good.rm_owner &&
2827             check.rm_offset     == roc->good.rm_offset &&
2828             keyflags            == roc->good.rm_flags) {
2829                 roc->results->matches++;
2830         } else {
2831                 roc->results->non_owner_matches++;
2832                 if (xfs_rmap_shareable(cur->bc_mp, &roc->good) ^
2833                     xfs_rmap_shareable(cur->bc_mp, &check))
2834                         roc->results->bad_non_owner_matches++;
2835         }
2836
2837         if (roc->results->non_owner_matches && roc->stop_on_nonmatch)
2838                 return -ECANCELED;
2839
2840         return 0;
2841 }
2842
2843 /* Count the number of owners and non-owners of this range of blocks. */
2844 int
2845 xfs_rmap_count_owners(
2846         struct xfs_btree_cur            *cur,
2847         xfs_agblock_t                   bno,
2848         xfs_extlen_t                    len,
2849         const struct xfs_owner_info     *oinfo,
2850         struct xfs_rmap_matches         *results)
2851 {
2852         struct xfs_rmap_ownercount      roc;
2853         int                             error;
2854
2855         xfs_rmap_ownercount_init(&roc, bno, len, oinfo, results);
2856         error = xfs_rmap_query_range(cur, &roc.low, &roc.high,
2857                         xfs_rmap_count_owners_helper, &roc);
2858         if (error)
2859                 return error;
2860
2861         /*
2862          * There can't be any non-owner rmaps that conflict with the given
2863          * owner if we didn't find any rmaps matching the owner.
2864          */
2865         if (!results->matches)
2866                 results->bad_non_owner_matches = 0;
2867
2868         return 0;
2869 }
2870
2871 /*
2872  * Given an extent and some owner info, can we find records overlapping
2873  * the extent whose owner info does not match the given owner?
2874  */
2875 int
2876 xfs_rmap_has_other_keys(
2877         struct xfs_btree_cur            *cur,
2878         xfs_agblock_t                   bno,
2879         xfs_extlen_t                    len,
2880         const struct xfs_owner_info     *oinfo,
2881         bool                            *has_other)
2882 {
2883         struct xfs_rmap_matches         res;
2884         struct xfs_rmap_ownercount      roc;
2885         int                             error;
2886
2887         xfs_rmap_ownercount_init(&roc, bno, len, oinfo, &res);
2888         roc.stop_on_nonmatch = true;
2889
2890         error = xfs_rmap_query_range(cur, &roc.low, &roc.high,
2891                         xfs_rmap_count_owners_helper, &roc);
2892         if (error == -ECANCELED) {
2893                 *has_other = true;
2894                 return 0;
2895         }
2896         if (error)
2897                 return error;
2898
2899         *has_other = false;
2900         return 0;
2901 }
2902
2903 const struct xfs_owner_info XFS_RMAP_OINFO_SKIP_UPDATE = {
2904         .oi_owner = XFS_RMAP_OWN_NULL,
2905 };
2906 const struct xfs_owner_info XFS_RMAP_OINFO_ANY_OWNER = {
2907         .oi_owner = XFS_RMAP_OWN_UNKNOWN,
2908 };
2909 const struct xfs_owner_info XFS_RMAP_OINFO_FS = {
2910         .oi_owner = XFS_RMAP_OWN_FS,
2911 };
2912 const struct xfs_owner_info XFS_RMAP_OINFO_LOG = {
2913         .oi_owner = XFS_RMAP_OWN_LOG,
2914 };
2915 const struct xfs_owner_info XFS_RMAP_OINFO_AG = {
2916         .oi_owner = XFS_RMAP_OWN_AG,
2917 };
2918 const struct xfs_owner_info XFS_RMAP_OINFO_INOBT = {
2919         .oi_owner = XFS_RMAP_OWN_INOBT,
2920 };
2921 const struct xfs_owner_info XFS_RMAP_OINFO_INODES = {
2922         .oi_owner = XFS_RMAP_OWN_INODES,
2923 };
2924 const struct xfs_owner_info XFS_RMAP_OINFO_REFC = {
2925         .oi_owner = XFS_RMAP_OWN_REFC,
2926 };
2927 const struct xfs_owner_info XFS_RMAP_OINFO_COW = {
2928         .oi_owner = XFS_RMAP_OWN_COW,
2929 };
2930
2931 int __init
2932 xfs_rmap_intent_init_cache(void)
2933 {
2934         xfs_rmap_intent_cache = kmem_cache_create("xfs_rmap_intent",
2935                         sizeof(struct xfs_rmap_intent),
2936                         0, 0, NULL);
2937
2938         return xfs_rmap_intent_cache != NULL ? 0 : -ENOMEM;
2939 }
2940
2941 void
2942 xfs_rmap_intent_destroy_cache(void)
2943 {
2944         kmem_cache_destroy(xfs_rmap_intent_cache);
2945         xfs_rmap_intent_cache = NULL;
2946 }