GNU Linux-libre 4.14.266-gnu1
[releases.git] / fs / xfs / libxfs / xfs_rmap.c
1 /*
2  * Copyright (c) 2014 Red Hat, Inc.
3  * All Rights Reserved.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it would be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write the Free Software Foundation,
16  * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17  */
18 #include "xfs.h"
19 #include "xfs_fs.h"
20 #include "xfs_shared.h"
21 #include "xfs_format.h"
22 #include "xfs_log_format.h"
23 #include "xfs_trans_resv.h"
24 #include "xfs_bit.h"
25 #include "xfs_sb.h"
26 #include "xfs_mount.h"
27 #include "xfs_defer.h"
28 #include "xfs_da_format.h"
29 #include "xfs_da_btree.h"
30 #include "xfs_btree.h"
31 #include "xfs_trans.h"
32 #include "xfs_alloc.h"
33 #include "xfs_rmap.h"
34 #include "xfs_rmap_btree.h"
35 #include "xfs_trans_space.h"
36 #include "xfs_trace.h"
37 #include "xfs_error.h"
38 #include "xfs_extent_busy.h"
39 #include "xfs_bmap.h"
40 #include "xfs_inode.h"
41
42 /*
43  * Lookup the first record less than or equal to [bno, len, owner, offset]
44  * in the btree given by cur.
45  */
46 int
47 xfs_rmap_lookup_le(
48         struct xfs_btree_cur    *cur,
49         xfs_agblock_t           bno,
50         xfs_extlen_t            len,
51         uint64_t                owner,
52         uint64_t                offset,
53         unsigned int            flags,
54         int                     *stat)
55 {
56         cur->bc_rec.r.rm_startblock = bno;
57         cur->bc_rec.r.rm_blockcount = len;
58         cur->bc_rec.r.rm_owner = owner;
59         cur->bc_rec.r.rm_offset = offset;
60         cur->bc_rec.r.rm_flags = flags;
61         return xfs_btree_lookup(cur, XFS_LOOKUP_LE, stat);
62 }
63
64 /*
65  * Lookup the record exactly matching [bno, len, owner, offset]
66  * in the btree given by cur.
67  */
68 int
69 xfs_rmap_lookup_eq(
70         struct xfs_btree_cur    *cur,
71         xfs_agblock_t           bno,
72         xfs_extlen_t            len,
73         uint64_t                owner,
74         uint64_t                offset,
75         unsigned int            flags,
76         int                     *stat)
77 {
78         cur->bc_rec.r.rm_startblock = bno;
79         cur->bc_rec.r.rm_blockcount = len;
80         cur->bc_rec.r.rm_owner = owner;
81         cur->bc_rec.r.rm_offset = offset;
82         cur->bc_rec.r.rm_flags = flags;
83         return xfs_btree_lookup(cur, XFS_LOOKUP_EQ, stat);
84 }
85
86 /*
87  * Update the record referred to by cur to the value given
88  * by [bno, len, owner, offset].
89  * This either works (return 0) or gets an EFSCORRUPTED error.
90  */
91 STATIC int
92 xfs_rmap_update(
93         struct xfs_btree_cur    *cur,
94         struct xfs_rmap_irec    *irec)
95 {
96         union xfs_btree_rec     rec;
97         int                     error;
98
99         trace_xfs_rmap_update(cur->bc_mp, cur->bc_private.a.agno,
100                         irec->rm_startblock, irec->rm_blockcount,
101                         irec->rm_owner, irec->rm_offset, irec->rm_flags);
102
103         rec.rmap.rm_startblock = cpu_to_be32(irec->rm_startblock);
104         rec.rmap.rm_blockcount = cpu_to_be32(irec->rm_blockcount);
105         rec.rmap.rm_owner = cpu_to_be64(irec->rm_owner);
106         rec.rmap.rm_offset = cpu_to_be64(
107                         xfs_rmap_irec_offset_pack(irec));
108         error = xfs_btree_update(cur, &rec);
109         if (error)
110                 trace_xfs_rmap_update_error(cur->bc_mp,
111                                 cur->bc_private.a.agno, error, _RET_IP_);
112         return error;
113 }
114
115 int
116 xfs_rmap_insert(
117         struct xfs_btree_cur    *rcur,
118         xfs_agblock_t           agbno,
119         xfs_extlen_t            len,
120         uint64_t                owner,
121         uint64_t                offset,
122         unsigned int            flags)
123 {
124         int                     i;
125         int                     error;
126
127         trace_xfs_rmap_insert(rcur->bc_mp, rcur->bc_private.a.agno, agbno,
128                         len, owner, offset, flags);
129
130         error = xfs_rmap_lookup_eq(rcur, agbno, len, owner, offset, flags, &i);
131         if (error)
132                 goto done;
133         XFS_WANT_CORRUPTED_GOTO(rcur->bc_mp, i == 0, done);
134
135         rcur->bc_rec.r.rm_startblock = agbno;
136         rcur->bc_rec.r.rm_blockcount = len;
137         rcur->bc_rec.r.rm_owner = owner;
138         rcur->bc_rec.r.rm_offset = offset;
139         rcur->bc_rec.r.rm_flags = flags;
140         error = xfs_btree_insert(rcur, &i);
141         if (error)
142                 goto done;
143         XFS_WANT_CORRUPTED_GOTO(rcur->bc_mp, i == 1, done);
144 done:
145         if (error)
146                 trace_xfs_rmap_insert_error(rcur->bc_mp,
147                                 rcur->bc_private.a.agno, error, _RET_IP_);
148         return error;
149 }
150
151 STATIC int
152 xfs_rmap_delete(
153         struct xfs_btree_cur    *rcur,
154         xfs_agblock_t           agbno,
155         xfs_extlen_t            len,
156         uint64_t                owner,
157         uint64_t                offset,
158         unsigned int            flags)
159 {
160         int                     i;
161         int                     error;
162
163         trace_xfs_rmap_delete(rcur->bc_mp, rcur->bc_private.a.agno, agbno,
164                         len, owner, offset, flags);
165
166         error = xfs_rmap_lookup_eq(rcur, agbno, len, owner, offset, flags, &i);
167         if (error)
168                 goto done;
169         XFS_WANT_CORRUPTED_GOTO(rcur->bc_mp, i == 1, done);
170
171         error = xfs_btree_delete(rcur, &i);
172         if (error)
173                 goto done;
174         XFS_WANT_CORRUPTED_GOTO(rcur->bc_mp, i == 1, done);
175 done:
176         if (error)
177                 trace_xfs_rmap_delete_error(rcur->bc_mp,
178                                 rcur->bc_private.a.agno, error, _RET_IP_);
179         return error;
180 }
181
182 /* Convert an internal btree record to an rmap record. */
183 int
184 xfs_rmap_btrec_to_irec(
185         union xfs_btree_rec     *rec,
186         struct xfs_rmap_irec    *irec)
187 {
188         irec->rm_flags = 0;
189         irec->rm_startblock = be32_to_cpu(rec->rmap.rm_startblock);
190         irec->rm_blockcount = be32_to_cpu(rec->rmap.rm_blockcount);
191         irec->rm_owner = be64_to_cpu(rec->rmap.rm_owner);
192         return xfs_rmap_irec_offset_unpack(be64_to_cpu(rec->rmap.rm_offset),
193                         irec);
194 }
195
196 /*
197  * Get the data from the pointed-to record.
198  */
199 int
200 xfs_rmap_get_rec(
201         struct xfs_btree_cur    *cur,
202         struct xfs_rmap_irec    *irec,
203         int                     *stat)
204 {
205         union xfs_btree_rec     *rec;
206         int                     error;
207
208         error = xfs_btree_get_rec(cur, &rec, stat);
209         if (error || !*stat)
210                 return error;
211
212         return xfs_rmap_btrec_to_irec(rec, irec);
213 }
214
215 struct xfs_find_left_neighbor_info {
216         struct xfs_rmap_irec    high;
217         struct xfs_rmap_irec    *irec;
218         int                     *stat;
219 };
220
221 /* For each rmap given, figure out if it matches the key we want. */
222 STATIC int
223 xfs_rmap_find_left_neighbor_helper(
224         struct xfs_btree_cur    *cur,
225         struct xfs_rmap_irec    *rec,
226         void                    *priv)
227 {
228         struct xfs_find_left_neighbor_info      *info = priv;
229
230         trace_xfs_rmap_find_left_neighbor_candidate(cur->bc_mp,
231                         cur->bc_private.a.agno, rec->rm_startblock,
232                         rec->rm_blockcount, rec->rm_owner, rec->rm_offset,
233                         rec->rm_flags);
234
235         if (rec->rm_owner != info->high.rm_owner)
236                 return XFS_BTREE_QUERY_RANGE_CONTINUE;
237         if (!XFS_RMAP_NON_INODE_OWNER(rec->rm_owner) &&
238             !(rec->rm_flags & XFS_RMAP_BMBT_BLOCK) &&
239             rec->rm_offset + rec->rm_blockcount - 1 != info->high.rm_offset)
240                 return XFS_BTREE_QUERY_RANGE_CONTINUE;
241
242         *info->irec = *rec;
243         *info->stat = 1;
244         return XFS_BTREE_QUERY_RANGE_ABORT;
245 }
246
247 /*
248  * Find the record to the left of the given extent, being careful only to
249  * return a match with the same owner and adjacent physical and logical
250  * block ranges.
251  */
252 int
253 xfs_rmap_find_left_neighbor(
254         struct xfs_btree_cur    *cur,
255         xfs_agblock_t           bno,
256         uint64_t                owner,
257         uint64_t                offset,
258         unsigned int            flags,
259         struct xfs_rmap_irec    *irec,
260         int                     *stat)
261 {
262         struct xfs_find_left_neighbor_info      info;
263         int                     error;
264
265         *stat = 0;
266         if (bno == 0)
267                 return 0;
268         info.high.rm_startblock = bno - 1;
269         info.high.rm_owner = owner;
270         if (!XFS_RMAP_NON_INODE_OWNER(owner) &&
271             !(flags & XFS_RMAP_BMBT_BLOCK)) {
272                 if (offset == 0)
273                         return 0;
274                 info.high.rm_offset = offset - 1;
275         } else
276                 info.high.rm_offset = 0;
277         info.high.rm_flags = flags;
278         info.high.rm_blockcount = 0;
279         info.irec = irec;
280         info.stat = stat;
281
282         trace_xfs_rmap_find_left_neighbor_query(cur->bc_mp,
283                         cur->bc_private.a.agno, bno, 0, owner, offset, flags);
284
285         error = xfs_rmap_query_range(cur, &info.high, &info.high,
286                         xfs_rmap_find_left_neighbor_helper, &info);
287         if (error == XFS_BTREE_QUERY_RANGE_ABORT)
288                 error = 0;
289         if (*stat)
290                 trace_xfs_rmap_find_left_neighbor_result(cur->bc_mp,
291                                 cur->bc_private.a.agno, irec->rm_startblock,
292                                 irec->rm_blockcount, irec->rm_owner,
293                                 irec->rm_offset, irec->rm_flags);
294         return error;
295 }
296
297 /* For each rmap given, figure out if it matches the key we want. */
298 STATIC int
299 xfs_rmap_lookup_le_range_helper(
300         struct xfs_btree_cur    *cur,
301         struct xfs_rmap_irec    *rec,
302         void                    *priv)
303 {
304         struct xfs_find_left_neighbor_info      *info = priv;
305
306         trace_xfs_rmap_lookup_le_range_candidate(cur->bc_mp,
307                         cur->bc_private.a.agno, rec->rm_startblock,
308                         rec->rm_blockcount, rec->rm_owner, rec->rm_offset,
309                         rec->rm_flags);
310
311         if (rec->rm_owner != info->high.rm_owner)
312                 return XFS_BTREE_QUERY_RANGE_CONTINUE;
313         if (!XFS_RMAP_NON_INODE_OWNER(rec->rm_owner) &&
314             !(rec->rm_flags & XFS_RMAP_BMBT_BLOCK) &&
315             (rec->rm_offset > info->high.rm_offset ||
316              rec->rm_offset + rec->rm_blockcount <= info->high.rm_offset))
317                 return XFS_BTREE_QUERY_RANGE_CONTINUE;
318
319         *info->irec = *rec;
320         *info->stat = 1;
321         return XFS_BTREE_QUERY_RANGE_ABORT;
322 }
323
324 /*
325  * Find the record to the left of the given extent, being careful only to
326  * return a match with the same owner and overlapping physical and logical
327  * block ranges.  This is the overlapping-interval version of
328  * xfs_rmap_lookup_le.
329  */
330 int
331 xfs_rmap_lookup_le_range(
332         struct xfs_btree_cur    *cur,
333         xfs_agblock_t           bno,
334         uint64_t                owner,
335         uint64_t                offset,
336         unsigned int            flags,
337         struct xfs_rmap_irec    *irec,
338         int                     *stat)
339 {
340         struct xfs_find_left_neighbor_info      info;
341         int                     error;
342
343         info.high.rm_startblock = bno;
344         info.high.rm_owner = owner;
345         if (!XFS_RMAP_NON_INODE_OWNER(owner) && !(flags & XFS_RMAP_BMBT_BLOCK))
346                 info.high.rm_offset = offset;
347         else
348                 info.high.rm_offset = 0;
349         info.high.rm_flags = flags;
350         info.high.rm_blockcount = 0;
351         *stat = 0;
352         info.irec = irec;
353         info.stat = stat;
354
355         trace_xfs_rmap_lookup_le_range(cur->bc_mp,
356                         cur->bc_private.a.agno, bno, 0, owner, offset, flags);
357         error = xfs_rmap_query_range(cur, &info.high, &info.high,
358                         xfs_rmap_lookup_le_range_helper, &info);
359         if (error == XFS_BTREE_QUERY_RANGE_ABORT)
360                 error = 0;
361         if (*stat)
362                 trace_xfs_rmap_lookup_le_range_result(cur->bc_mp,
363                                 cur->bc_private.a.agno, irec->rm_startblock,
364                                 irec->rm_blockcount, irec->rm_owner,
365                                 irec->rm_offset, irec->rm_flags);
366         return error;
367 }
368
369 /*
370  * Find the extent in the rmap btree and remove it.
371  *
372  * The record we find should always be an exact match for the extent that we're
373  * looking for, since we insert them into the btree without modification.
374  *
375  * Special Case #1: when growing the filesystem, we "free" an extent when
376  * growing the last AG. This extent is new space and so it is not tracked as
377  * used space in the btree. The growfs code will pass in an owner of
378  * XFS_RMAP_OWN_NULL to indicate that it expected that there is no owner of this
379  * extent. We verify that - the extent lookup result in a record that does not
380  * overlap.
381  *
382  * Special Case #2: EFIs do not record the owner of the extent, so when
383  * recovering EFIs from the log we pass in XFS_RMAP_OWN_UNKNOWN to tell the rmap
384  * btree to ignore the owner (i.e. wildcard match) so we don't trigger
385  * corruption checks during log recovery.
386  */
387 STATIC int
388 xfs_rmap_unmap(
389         struct xfs_btree_cur    *cur,
390         xfs_agblock_t           bno,
391         xfs_extlen_t            len,
392         bool                    unwritten,
393         struct xfs_owner_info   *oinfo)
394 {
395         struct xfs_mount        *mp = cur->bc_mp;
396         struct xfs_rmap_irec    ltrec;
397         uint64_t                ltoff;
398         int                     error = 0;
399         int                     i;
400         uint64_t                owner;
401         uint64_t                offset;
402         unsigned int            flags;
403         bool                    ignore_off;
404
405         xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
406         ignore_off = XFS_RMAP_NON_INODE_OWNER(owner) ||
407                         (flags & XFS_RMAP_BMBT_BLOCK);
408         if (unwritten)
409                 flags |= XFS_RMAP_UNWRITTEN;
410         trace_xfs_rmap_unmap(mp, cur->bc_private.a.agno, bno, len,
411                         unwritten, oinfo);
412
413         /*
414          * We should always have a left record because there's a static record
415          * for the AG headers at rm_startblock == 0 created by mkfs/growfs that
416          * will not ever be removed from the tree.
417          */
418         error = xfs_rmap_lookup_le(cur, bno, len, owner, offset, flags, &i);
419         if (error)
420                 goto out_error;
421         XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error);
422
423         error = xfs_rmap_get_rec(cur, &ltrec, &i);
424         if (error)
425                 goto out_error;
426         XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error);
427         trace_xfs_rmap_lookup_le_range_result(cur->bc_mp,
428                         cur->bc_private.a.agno, ltrec.rm_startblock,
429                         ltrec.rm_blockcount, ltrec.rm_owner,
430                         ltrec.rm_offset, ltrec.rm_flags);
431         ltoff = ltrec.rm_offset;
432
433         /*
434          * For growfs, the incoming extent must be beyond the left record we
435          * just found as it is new space and won't be used by anyone. This is
436          * just a corruption check as we don't actually do anything with this
437          * extent.  Note that we need to use >= instead of > because it might
438          * be the case that the "left" extent goes all the way to EOFS.
439          */
440         if (owner == XFS_RMAP_OWN_NULL) {
441                 XFS_WANT_CORRUPTED_GOTO(mp, bno >= ltrec.rm_startblock +
442                                                 ltrec.rm_blockcount, out_error);
443                 goto out_done;
444         }
445
446         /* Make sure the unwritten flag matches. */
447         XFS_WANT_CORRUPTED_GOTO(mp, (flags & XFS_RMAP_UNWRITTEN) ==
448                         (ltrec.rm_flags & XFS_RMAP_UNWRITTEN), out_error);
449
450         /* Make sure the extent we found covers the entire freeing range. */
451         XFS_WANT_CORRUPTED_GOTO(mp, ltrec.rm_startblock <= bno &&
452                 ltrec.rm_startblock + ltrec.rm_blockcount >=
453                 bno + len, out_error);
454
455         /* Make sure the owner matches what we expect to find in the tree. */
456         XFS_WANT_CORRUPTED_GOTO(mp, owner == ltrec.rm_owner ||
457                                     XFS_RMAP_NON_INODE_OWNER(owner), out_error);
458
459         /* Check the offset, if necessary. */
460         if (!XFS_RMAP_NON_INODE_OWNER(owner)) {
461                 if (flags & XFS_RMAP_BMBT_BLOCK) {
462                         XFS_WANT_CORRUPTED_GOTO(mp,
463                                         ltrec.rm_flags & XFS_RMAP_BMBT_BLOCK,
464                                         out_error);
465                 } else {
466                         XFS_WANT_CORRUPTED_GOTO(mp,
467                                         ltrec.rm_offset <= offset, out_error);
468                         XFS_WANT_CORRUPTED_GOTO(mp,
469                                         ltoff + ltrec.rm_blockcount >= offset + len,
470                                         out_error);
471                 }
472         }
473
474         if (ltrec.rm_startblock == bno && ltrec.rm_blockcount == len) {
475                 /* exact match, simply remove the record from rmap tree */
476                 trace_xfs_rmap_delete(mp, cur->bc_private.a.agno,
477                                 ltrec.rm_startblock, ltrec.rm_blockcount,
478                                 ltrec.rm_owner, ltrec.rm_offset,
479                                 ltrec.rm_flags);
480                 error = xfs_btree_delete(cur, &i);
481                 if (error)
482                         goto out_error;
483                 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error);
484         } else if (ltrec.rm_startblock == bno) {
485                 /*
486                  * overlap left hand side of extent: move the start, trim the
487                  * length and update the current record.
488                  *
489                  *       ltbno                ltlen
490                  * Orig:    |oooooooooooooooooooo|
491                  * Freeing: |fffffffff|
492                  * Result:            |rrrrrrrrrr|
493                  *         bno       len
494                  */
495                 ltrec.rm_startblock += len;
496                 ltrec.rm_blockcount -= len;
497                 if (!ignore_off)
498                         ltrec.rm_offset += len;
499                 error = xfs_rmap_update(cur, &ltrec);
500                 if (error)
501                         goto out_error;
502         } else if (ltrec.rm_startblock + ltrec.rm_blockcount == bno + len) {
503                 /*
504                  * overlap right hand side of extent: trim the length and update
505                  * the current record.
506                  *
507                  *       ltbno                ltlen
508                  * Orig:    |oooooooooooooooooooo|
509                  * Freeing:            |fffffffff|
510                  * Result:  |rrrrrrrrrr|
511                  *                    bno       len
512                  */
513                 ltrec.rm_blockcount -= len;
514                 error = xfs_rmap_update(cur, &ltrec);
515                 if (error)
516                         goto out_error;
517         } else {
518
519                 /*
520                  * overlap middle of extent: trim the length of the existing
521                  * record to the length of the new left-extent size, increment
522                  * the insertion position so we can insert a new record
523                  * containing the remaining right-extent space.
524                  *
525                  *       ltbno                ltlen
526                  * Orig:    |oooooooooooooooooooo|
527                  * Freeing:       |fffffffff|
528                  * Result:  |rrrrr|         |rrrr|
529                  *               bno       len
530                  */
531                 xfs_extlen_t    orig_len = ltrec.rm_blockcount;
532
533                 ltrec.rm_blockcount = bno - ltrec.rm_startblock;
534                 error = xfs_rmap_update(cur, &ltrec);
535                 if (error)
536                         goto out_error;
537
538                 error = xfs_btree_increment(cur, 0, &i);
539                 if (error)
540                         goto out_error;
541
542                 cur->bc_rec.r.rm_startblock = bno + len;
543                 cur->bc_rec.r.rm_blockcount = orig_len - len -
544                                                      ltrec.rm_blockcount;
545                 cur->bc_rec.r.rm_owner = ltrec.rm_owner;
546                 if (ignore_off)
547                         cur->bc_rec.r.rm_offset = 0;
548                 else
549                         cur->bc_rec.r.rm_offset = offset + len;
550                 cur->bc_rec.r.rm_flags = flags;
551                 trace_xfs_rmap_insert(mp, cur->bc_private.a.agno,
552                                 cur->bc_rec.r.rm_startblock,
553                                 cur->bc_rec.r.rm_blockcount,
554                                 cur->bc_rec.r.rm_owner,
555                                 cur->bc_rec.r.rm_offset,
556                                 cur->bc_rec.r.rm_flags);
557                 error = xfs_btree_insert(cur, &i);
558                 if (error)
559                         goto out_error;
560         }
561
562 out_done:
563         trace_xfs_rmap_unmap_done(mp, cur->bc_private.a.agno, bno, len,
564                         unwritten, oinfo);
565 out_error:
566         if (error)
567                 trace_xfs_rmap_unmap_error(mp, cur->bc_private.a.agno,
568                                 error, _RET_IP_);
569         return error;
570 }
571
572 /*
573  * Remove a reference to an extent in the rmap btree.
574  */
575 int
576 xfs_rmap_free(
577         struct xfs_trans        *tp,
578         struct xfs_buf          *agbp,
579         xfs_agnumber_t          agno,
580         xfs_agblock_t           bno,
581         xfs_extlen_t            len,
582         struct xfs_owner_info   *oinfo)
583 {
584         struct xfs_mount        *mp = tp->t_mountp;
585         struct xfs_btree_cur    *cur;
586         int                     error;
587
588         if (!xfs_sb_version_hasrmapbt(&mp->m_sb))
589                 return 0;
590
591         cur = xfs_rmapbt_init_cursor(mp, tp, agbp, agno);
592
593         error = xfs_rmap_unmap(cur, bno, len, false, oinfo);
594         if (error)
595                 goto out_error;
596
597         xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
598         return 0;
599
600 out_error:
601         xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
602         return error;
603 }
604
605 /*
606  * A mergeable rmap must have the same owner and the same values for
607  * the unwritten, attr_fork, and bmbt flags.  The startblock and
608  * offset are checked separately.
609  */
610 static bool
611 xfs_rmap_is_mergeable(
612         struct xfs_rmap_irec    *irec,
613         uint64_t                owner,
614         unsigned int            flags)
615 {
616         if (irec->rm_owner == XFS_RMAP_OWN_NULL)
617                 return false;
618         if (irec->rm_owner != owner)
619                 return false;
620         if ((flags & XFS_RMAP_UNWRITTEN) ^
621             (irec->rm_flags & XFS_RMAP_UNWRITTEN))
622                 return false;
623         if ((flags & XFS_RMAP_ATTR_FORK) ^
624             (irec->rm_flags & XFS_RMAP_ATTR_FORK))
625                 return false;
626         if ((flags & XFS_RMAP_BMBT_BLOCK) ^
627             (irec->rm_flags & XFS_RMAP_BMBT_BLOCK))
628                 return false;
629         return true;
630 }
631
632 /*
633  * When we allocate a new block, the first thing we do is add a reference to
634  * the extent in the rmap btree. This takes the form of a [agbno, length,
635  * owner, offset] record.  Flags are encoded in the high bits of the offset
636  * field.
637  */
638 STATIC int
639 xfs_rmap_map(
640         struct xfs_btree_cur    *cur,
641         xfs_agblock_t           bno,
642         xfs_extlen_t            len,
643         bool                    unwritten,
644         struct xfs_owner_info   *oinfo)
645 {
646         struct xfs_mount        *mp = cur->bc_mp;
647         struct xfs_rmap_irec    ltrec;
648         struct xfs_rmap_irec    gtrec;
649         int                     have_gt;
650         int                     have_lt;
651         int                     error = 0;
652         int                     i;
653         uint64_t                owner;
654         uint64_t                offset;
655         unsigned int            flags = 0;
656         bool                    ignore_off;
657
658         xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
659         ASSERT(owner != 0);
660         ignore_off = XFS_RMAP_NON_INODE_OWNER(owner) ||
661                         (flags & XFS_RMAP_BMBT_BLOCK);
662         if (unwritten)
663                 flags |= XFS_RMAP_UNWRITTEN;
664         trace_xfs_rmap_map(mp, cur->bc_private.a.agno, bno, len,
665                         unwritten, oinfo);
666
667         /*
668          * For the initial lookup, look for an exact match or the left-adjacent
669          * record for our insertion point. This will also give us the record for
670          * start block contiguity tests.
671          */
672         error = xfs_rmap_lookup_le(cur, bno, len, owner, offset, flags,
673                         &have_lt);
674         if (error)
675                 goto out_error;
676         XFS_WANT_CORRUPTED_GOTO(mp, have_lt == 1, out_error);
677
678         error = xfs_rmap_get_rec(cur, &ltrec, &have_lt);
679         if (error)
680                 goto out_error;
681         XFS_WANT_CORRUPTED_GOTO(mp, have_lt == 1, out_error);
682         trace_xfs_rmap_lookup_le_range_result(cur->bc_mp,
683                         cur->bc_private.a.agno, ltrec.rm_startblock,
684                         ltrec.rm_blockcount, ltrec.rm_owner,
685                         ltrec.rm_offset, ltrec.rm_flags);
686
687         if (!xfs_rmap_is_mergeable(&ltrec, owner, flags))
688                 have_lt = 0;
689
690         XFS_WANT_CORRUPTED_GOTO(mp,
691                 have_lt == 0 ||
692                 ltrec.rm_startblock + ltrec.rm_blockcount <= bno, out_error);
693
694         /*
695          * Increment the cursor to see if we have a right-adjacent record to our
696          * insertion point. This will give us the record for end block
697          * contiguity tests.
698          */
699         error = xfs_btree_increment(cur, 0, &have_gt);
700         if (error)
701                 goto out_error;
702         if (have_gt) {
703                 error = xfs_rmap_get_rec(cur, &gtrec, &have_gt);
704                 if (error)
705                         goto out_error;
706                 XFS_WANT_CORRUPTED_GOTO(mp, have_gt == 1, out_error);
707                 XFS_WANT_CORRUPTED_GOTO(mp, bno + len <= gtrec.rm_startblock,
708                                         out_error);
709                 trace_xfs_rmap_find_right_neighbor_result(cur->bc_mp,
710                         cur->bc_private.a.agno, gtrec.rm_startblock,
711                         gtrec.rm_blockcount, gtrec.rm_owner,
712                         gtrec.rm_offset, gtrec.rm_flags);
713                 if (!xfs_rmap_is_mergeable(&gtrec, owner, flags))
714                         have_gt = 0;
715         }
716
717         /*
718          * Note: cursor currently points one record to the right of ltrec, even
719          * if there is no record in the tree to the right.
720          */
721         if (have_lt &&
722             ltrec.rm_startblock + ltrec.rm_blockcount == bno &&
723             (ignore_off || ltrec.rm_offset + ltrec.rm_blockcount == offset)) {
724                 /*
725                  * left edge contiguous, merge into left record.
726                  *
727                  *       ltbno     ltlen
728                  * orig:   |ooooooooo|
729                  * adding:           |aaaaaaaaa|
730                  * result: |rrrrrrrrrrrrrrrrrrr|
731                  *                  bno       len
732                  */
733                 ltrec.rm_blockcount += len;
734                 if (have_gt &&
735                     bno + len == gtrec.rm_startblock &&
736                     (ignore_off || offset + len == gtrec.rm_offset) &&
737                     (unsigned long)ltrec.rm_blockcount + len +
738                                 gtrec.rm_blockcount <= XFS_RMAP_LEN_MAX) {
739                         /*
740                          * right edge also contiguous, delete right record
741                          * and merge into left record.
742                          *
743                          *       ltbno     ltlen    gtbno     gtlen
744                          * orig:   |ooooooooo|         |ooooooooo|
745                          * adding:           |aaaaaaaaa|
746                          * result: |rrrrrrrrrrrrrrrrrrrrrrrrrrrrr|
747                          */
748                         ltrec.rm_blockcount += gtrec.rm_blockcount;
749                         trace_xfs_rmap_delete(mp, cur->bc_private.a.agno,
750                                         gtrec.rm_startblock,
751                                         gtrec.rm_blockcount,
752                                         gtrec.rm_owner,
753                                         gtrec.rm_offset,
754                                         gtrec.rm_flags);
755                         error = xfs_btree_delete(cur, &i);
756                         if (error)
757                                 goto out_error;
758                         XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error);
759                 }
760
761                 /* point the cursor back to the left record and update */
762                 error = xfs_btree_decrement(cur, 0, &have_gt);
763                 if (error)
764                         goto out_error;
765                 error = xfs_rmap_update(cur, &ltrec);
766                 if (error)
767                         goto out_error;
768         } else if (have_gt &&
769                    bno + len == gtrec.rm_startblock &&
770                    (ignore_off || offset + len == gtrec.rm_offset)) {
771                 /*
772                  * right edge contiguous, merge into right record.
773                  *
774                  *                 gtbno     gtlen
775                  * Orig:             |ooooooooo|
776                  * adding: |aaaaaaaaa|
777                  * Result: |rrrrrrrrrrrrrrrrrrr|
778                  *        bno       len
779                  */
780                 gtrec.rm_startblock = bno;
781                 gtrec.rm_blockcount += len;
782                 if (!ignore_off)
783                         gtrec.rm_offset = offset;
784                 error = xfs_rmap_update(cur, &gtrec);
785                 if (error)
786                         goto out_error;
787         } else {
788                 /*
789                  * no contiguous edge with identical owner, insert
790                  * new record at current cursor position.
791                  */
792                 cur->bc_rec.r.rm_startblock = bno;
793                 cur->bc_rec.r.rm_blockcount = len;
794                 cur->bc_rec.r.rm_owner = owner;
795                 cur->bc_rec.r.rm_offset = offset;
796                 cur->bc_rec.r.rm_flags = flags;
797                 trace_xfs_rmap_insert(mp, cur->bc_private.a.agno, bno, len,
798                         owner, offset, flags);
799                 error = xfs_btree_insert(cur, &i);
800                 if (error)
801                         goto out_error;
802                 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error);
803         }
804
805         trace_xfs_rmap_map_done(mp, cur->bc_private.a.agno, bno, len,
806                         unwritten, oinfo);
807 out_error:
808         if (error)
809                 trace_xfs_rmap_map_error(mp, cur->bc_private.a.agno,
810                                 error, _RET_IP_);
811         return error;
812 }
813
814 /*
815  * Add a reference to an extent in the rmap btree.
816  */
817 int
818 xfs_rmap_alloc(
819         struct xfs_trans        *tp,
820         struct xfs_buf          *agbp,
821         xfs_agnumber_t          agno,
822         xfs_agblock_t           bno,
823         xfs_extlen_t            len,
824         struct xfs_owner_info   *oinfo)
825 {
826         struct xfs_mount        *mp = tp->t_mountp;
827         struct xfs_btree_cur    *cur;
828         int                     error;
829
830         if (!xfs_sb_version_hasrmapbt(&mp->m_sb))
831                 return 0;
832
833         cur = xfs_rmapbt_init_cursor(mp, tp, agbp, agno);
834         error = xfs_rmap_map(cur, bno, len, false, oinfo);
835         if (error)
836                 goto out_error;
837
838         xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
839         return 0;
840
841 out_error:
842         xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
843         return error;
844 }
845
846 #define RMAP_LEFT_CONTIG        (1 << 0)
847 #define RMAP_RIGHT_CONTIG       (1 << 1)
848 #define RMAP_LEFT_FILLING       (1 << 2)
849 #define RMAP_RIGHT_FILLING      (1 << 3)
850 #define RMAP_LEFT_VALID         (1 << 6)
851 #define RMAP_RIGHT_VALID        (1 << 7)
852
853 #define LEFT            r[0]
854 #define RIGHT           r[1]
855 #define PREV            r[2]
856 #define NEW             r[3]
857
858 /*
859  * Convert an unwritten extent to a real extent or vice versa.
860  * Does not handle overlapping extents.
861  */
862 STATIC int
863 xfs_rmap_convert(
864         struct xfs_btree_cur    *cur,
865         xfs_agblock_t           bno,
866         xfs_extlen_t            len,
867         bool                    unwritten,
868         struct xfs_owner_info   *oinfo)
869 {
870         struct xfs_mount        *mp = cur->bc_mp;
871         struct xfs_rmap_irec    r[4];   /* neighbor extent entries */
872                                         /* left is 0, right is 1, prev is 2 */
873                                         /* new is 3 */
874         uint64_t                owner;
875         uint64_t                offset;
876         uint64_t                new_endoff;
877         unsigned int            oldext;
878         unsigned int            newext;
879         unsigned int            flags = 0;
880         int                     i;
881         int                     state = 0;
882         int                     error;
883
884         xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
885         ASSERT(!(XFS_RMAP_NON_INODE_OWNER(owner) ||
886                         (flags & (XFS_RMAP_ATTR_FORK | XFS_RMAP_BMBT_BLOCK))));
887         oldext = unwritten ? XFS_RMAP_UNWRITTEN : 0;
888         new_endoff = offset + len;
889         trace_xfs_rmap_convert(mp, cur->bc_private.a.agno, bno, len,
890                         unwritten, oinfo);
891
892         /*
893          * For the initial lookup, look for an exact match or the left-adjacent
894          * record for our insertion point. This will also give us the record for
895          * start block contiguity tests.
896          */
897         error = xfs_rmap_lookup_le(cur, bno, len, owner, offset, oldext, &i);
898         if (error)
899                 goto done;
900         XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
901
902         error = xfs_rmap_get_rec(cur, &PREV, &i);
903         if (error)
904                 goto done;
905         XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
906         trace_xfs_rmap_lookup_le_range_result(cur->bc_mp,
907                         cur->bc_private.a.agno, PREV.rm_startblock,
908                         PREV.rm_blockcount, PREV.rm_owner,
909                         PREV.rm_offset, PREV.rm_flags);
910
911         ASSERT(PREV.rm_offset <= offset);
912         ASSERT(PREV.rm_offset + PREV.rm_blockcount >= new_endoff);
913         ASSERT((PREV.rm_flags & XFS_RMAP_UNWRITTEN) == oldext);
914         newext = ~oldext & XFS_RMAP_UNWRITTEN;
915
916         /*
917          * Set flags determining what part of the previous oldext allocation
918          * extent is being replaced by a newext allocation.
919          */
920         if (PREV.rm_offset == offset)
921                 state |= RMAP_LEFT_FILLING;
922         if (PREV.rm_offset + PREV.rm_blockcount == new_endoff)
923                 state |= RMAP_RIGHT_FILLING;
924
925         /*
926          * Decrement the cursor to see if we have a left-adjacent record to our
927          * insertion point. This will give us the record for end block
928          * contiguity tests.
929          */
930         error = xfs_btree_decrement(cur, 0, &i);
931         if (error)
932                 goto done;
933         if (i) {
934                 state |= RMAP_LEFT_VALID;
935                 error = xfs_rmap_get_rec(cur, &LEFT, &i);
936                 if (error)
937                         goto done;
938                 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
939                 XFS_WANT_CORRUPTED_GOTO(mp,
940                                 LEFT.rm_startblock + LEFT.rm_blockcount <= bno,
941                                 done);
942                 trace_xfs_rmap_find_left_neighbor_result(cur->bc_mp,
943                                 cur->bc_private.a.agno, LEFT.rm_startblock,
944                                 LEFT.rm_blockcount, LEFT.rm_owner,
945                                 LEFT.rm_offset, LEFT.rm_flags);
946                 if (LEFT.rm_startblock + LEFT.rm_blockcount == bno &&
947                     LEFT.rm_offset + LEFT.rm_blockcount == offset &&
948                     xfs_rmap_is_mergeable(&LEFT, owner, newext))
949                         state |= RMAP_LEFT_CONTIG;
950         }
951
952         /*
953          * Increment the cursor to see if we have a right-adjacent record to our
954          * insertion point. This will give us the record for end block
955          * contiguity tests.
956          */
957         error = xfs_btree_increment(cur, 0, &i);
958         if (error)
959                 goto done;
960         XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
961         error = xfs_btree_increment(cur, 0, &i);
962         if (error)
963                 goto done;
964         if (i) {
965                 state |= RMAP_RIGHT_VALID;
966                 error = xfs_rmap_get_rec(cur, &RIGHT, &i);
967                 if (error)
968                         goto done;
969                 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
970                 XFS_WANT_CORRUPTED_GOTO(mp, bno + len <= RIGHT.rm_startblock,
971                                         done);
972                 trace_xfs_rmap_find_right_neighbor_result(cur->bc_mp,
973                                 cur->bc_private.a.agno, RIGHT.rm_startblock,
974                                 RIGHT.rm_blockcount, RIGHT.rm_owner,
975                                 RIGHT.rm_offset, RIGHT.rm_flags);
976                 if (bno + len == RIGHT.rm_startblock &&
977                     offset + len == RIGHT.rm_offset &&
978                     xfs_rmap_is_mergeable(&RIGHT, owner, newext))
979                         state |= RMAP_RIGHT_CONTIG;
980         }
981
982         /* check that left + prev + right is not too long */
983         if ((state & (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
984                          RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG)) ==
985             (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
986              RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG) &&
987             (unsigned long)LEFT.rm_blockcount + len +
988              RIGHT.rm_blockcount > XFS_RMAP_LEN_MAX)
989                 state &= ~RMAP_RIGHT_CONTIG;
990
991         trace_xfs_rmap_convert_state(mp, cur->bc_private.a.agno, state,
992                         _RET_IP_);
993
994         /* reset the cursor back to PREV */
995         error = xfs_rmap_lookup_le(cur, bno, len, owner, offset, oldext, &i);
996         if (error)
997                 goto done;
998         XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
999
1000         /*
1001          * Switch out based on the FILLING and CONTIG state bits.
1002          */
1003         switch (state & (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
1004                          RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG)) {
1005         case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
1006              RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG:
1007                 /*
1008                  * Setting all of a previous oldext extent to newext.
1009                  * The left and right neighbors are both contiguous with new.
1010                  */
1011                 error = xfs_btree_increment(cur, 0, &i);
1012                 if (error)
1013                         goto done;
1014                 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1015                 trace_xfs_rmap_delete(mp, cur->bc_private.a.agno,
1016                                 RIGHT.rm_startblock, RIGHT.rm_blockcount,
1017                                 RIGHT.rm_owner, RIGHT.rm_offset,
1018                                 RIGHT.rm_flags);
1019                 error = xfs_btree_delete(cur, &i);
1020                 if (error)
1021                         goto done;
1022                 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1023                 error = xfs_btree_decrement(cur, 0, &i);
1024                 if (error)
1025                         goto done;
1026                 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1027                 trace_xfs_rmap_delete(mp, cur->bc_private.a.agno,
1028                                 PREV.rm_startblock, PREV.rm_blockcount,
1029                                 PREV.rm_owner, PREV.rm_offset,
1030                                 PREV.rm_flags);
1031                 error = xfs_btree_delete(cur, &i);
1032                 if (error)
1033                         goto done;
1034                 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1035                 error = xfs_btree_decrement(cur, 0, &i);
1036                 if (error)
1037                         goto done;
1038                 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1039                 NEW = LEFT;
1040                 NEW.rm_blockcount += PREV.rm_blockcount + RIGHT.rm_blockcount;
1041                 error = xfs_rmap_update(cur, &NEW);
1042                 if (error)
1043                         goto done;
1044                 break;
1045
1046         case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG:
1047                 /*
1048                  * Setting all of a previous oldext extent to newext.
1049                  * The left neighbor is contiguous, the right is not.
1050                  */
1051                 trace_xfs_rmap_delete(mp, cur->bc_private.a.agno,
1052                                 PREV.rm_startblock, PREV.rm_blockcount,
1053                                 PREV.rm_owner, PREV.rm_offset,
1054                                 PREV.rm_flags);
1055                 error = xfs_btree_delete(cur, &i);
1056                 if (error)
1057                         goto done;
1058                 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1059                 error = xfs_btree_decrement(cur, 0, &i);
1060                 if (error)
1061                         goto done;
1062                 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1063                 NEW = LEFT;
1064                 NEW.rm_blockcount += PREV.rm_blockcount;
1065                 error = xfs_rmap_update(cur, &NEW);
1066                 if (error)
1067                         goto done;
1068                 break;
1069
1070         case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG:
1071                 /*
1072                  * Setting all of a previous oldext extent to newext.
1073                  * The right neighbor is contiguous, the left is not.
1074                  */
1075                 error = xfs_btree_increment(cur, 0, &i);
1076                 if (error)
1077                         goto done;
1078                 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1079                 trace_xfs_rmap_delete(mp, cur->bc_private.a.agno,
1080                                 RIGHT.rm_startblock, RIGHT.rm_blockcount,
1081                                 RIGHT.rm_owner, RIGHT.rm_offset,
1082                                 RIGHT.rm_flags);
1083                 error = xfs_btree_delete(cur, &i);
1084                 if (error)
1085                         goto done;
1086                 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1087                 error = xfs_btree_decrement(cur, 0, &i);
1088                 if (error)
1089                         goto done;
1090                 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1091                 NEW = PREV;
1092                 NEW.rm_blockcount = len + RIGHT.rm_blockcount;
1093                 NEW.rm_flags = newext;
1094                 error = xfs_rmap_update(cur, &NEW);
1095                 if (error)
1096                         goto done;
1097                 break;
1098
1099         case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING:
1100                 /*
1101                  * Setting all of a previous oldext extent to newext.
1102                  * Neither the left nor right neighbors are contiguous with
1103                  * the new one.
1104                  */
1105                 NEW = PREV;
1106                 NEW.rm_flags = newext;
1107                 error = xfs_rmap_update(cur, &NEW);
1108                 if (error)
1109                         goto done;
1110                 break;
1111
1112         case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG:
1113                 /*
1114                  * Setting the first part of a previous oldext extent to newext.
1115                  * The left neighbor is contiguous.
1116                  */
1117                 NEW = PREV;
1118                 NEW.rm_offset += len;
1119                 NEW.rm_startblock += len;
1120                 NEW.rm_blockcount -= len;
1121                 error = xfs_rmap_update(cur, &NEW);
1122                 if (error)
1123                         goto done;
1124                 error = xfs_btree_decrement(cur, 0, &i);
1125                 if (error)
1126                         goto done;
1127                 NEW = LEFT;
1128                 NEW.rm_blockcount += len;
1129                 error = xfs_rmap_update(cur, &NEW);
1130                 if (error)
1131                         goto done;
1132                 break;
1133
1134         case RMAP_LEFT_FILLING:
1135                 /*
1136                  * Setting the first part of a previous oldext extent to newext.
1137                  * The left neighbor is not contiguous.
1138                  */
1139                 NEW = PREV;
1140                 NEW.rm_startblock += len;
1141                 NEW.rm_offset += len;
1142                 NEW.rm_blockcount -= len;
1143                 error = xfs_rmap_update(cur, &NEW);
1144                 if (error)
1145                         goto done;
1146                 NEW.rm_startblock = bno;
1147                 NEW.rm_owner = owner;
1148                 NEW.rm_offset = offset;
1149                 NEW.rm_blockcount = len;
1150                 NEW.rm_flags = newext;
1151                 cur->bc_rec.r = NEW;
1152                 trace_xfs_rmap_insert(mp, cur->bc_private.a.agno, bno,
1153                                 len, owner, offset, newext);
1154                 error = xfs_btree_insert(cur, &i);
1155                 if (error)
1156                         goto done;
1157                 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1158                 break;
1159
1160         case RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG:
1161                 /*
1162                  * Setting the last part of a previous oldext extent to newext.
1163                  * The right neighbor is contiguous with the new allocation.
1164                  */
1165                 NEW = PREV;
1166                 NEW.rm_blockcount -= len;
1167                 error = xfs_rmap_update(cur, &NEW);
1168                 if (error)
1169                         goto done;
1170                 error = xfs_btree_increment(cur, 0, &i);
1171                 if (error)
1172                         goto done;
1173                 NEW = RIGHT;
1174                 NEW.rm_offset = offset;
1175                 NEW.rm_startblock = bno;
1176                 NEW.rm_blockcount += len;
1177                 error = xfs_rmap_update(cur, &NEW);
1178                 if (error)
1179                         goto done;
1180                 break;
1181
1182         case RMAP_RIGHT_FILLING:
1183                 /*
1184                  * Setting the last part of a previous oldext extent to newext.
1185                  * The right neighbor is not contiguous.
1186                  */
1187                 NEW = PREV;
1188                 NEW.rm_blockcount -= len;
1189                 error = xfs_rmap_update(cur, &NEW);
1190                 if (error)
1191                         goto done;
1192                 error = xfs_rmap_lookup_eq(cur, bno, len, owner, offset,
1193                                 oldext, &i);
1194                 if (error)
1195                         goto done;
1196                 XFS_WANT_CORRUPTED_GOTO(mp, i == 0, done);
1197                 NEW.rm_startblock = bno;
1198                 NEW.rm_owner = owner;
1199                 NEW.rm_offset = offset;
1200                 NEW.rm_blockcount = len;
1201                 NEW.rm_flags = newext;
1202                 cur->bc_rec.r = NEW;
1203                 trace_xfs_rmap_insert(mp, cur->bc_private.a.agno, bno,
1204                                 len, owner, offset, newext);
1205                 error = xfs_btree_insert(cur, &i);
1206                 if (error)
1207                         goto done;
1208                 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1209                 break;
1210
1211         case 0:
1212                 /*
1213                  * Setting the middle part of a previous oldext extent to
1214                  * newext.  Contiguity is impossible here.
1215                  * One extent becomes three extents.
1216                  */
1217                 /* new right extent - oldext */
1218                 NEW.rm_startblock = bno + len;
1219                 NEW.rm_owner = owner;
1220                 NEW.rm_offset = new_endoff;
1221                 NEW.rm_blockcount = PREV.rm_offset + PREV.rm_blockcount -
1222                                 new_endoff;
1223                 NEW.rm_flags = PREV.rm_flags;
1224                 error = xfs_rmap_update(cur, &NEW);
1225                 if (error)
1226                         goto done;
1227                 /* new left extent - oldext */
1228                 NEW = PREV;
1229                 NEW.rm_blockcount = offset - PREV.rm_offset;
1230                 cur->bc_rec.r = NEW;
1231                 trace_xfs_rmap_insert(mp, cur->bc_private.a.agno,
1232                                 NEW.rm_startblock, NEW.rm_blockcount,
1233                                 NEW.rm_owner, NEW.rm_offset,
1234                                 NEW.rm_flags);
1235                 error = xfs_btree_insert(cur, &i);
1236                 if (error)
1237                         goto done;
1238                 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1239                 /*
1240                  * Reset the cursor to the position of the new extent
1241                  * we are about to insert as we can't trust it after
1242                  * the previous insert.
1243                  */
1244                 error = xfs_rmap_lookup_eq(cur, bno, len, owner, offset,
1245                                 oldext, &i);
1246                 if (error)
1247                         goto done;
1248                 XFS_WANT_CORRUPTED_GOTO(mp, i == 0, done);
1249                 /* new middle extent - newext */
1250                 cur->bc_rec.r.rm_flags &= ~XFS_RMAP_UNWRITTEN;
1251                 cur->bc_rec.r.rm_flags |= newext;
1252                 trace_xfs_rmap_insert(mp, cur->bc_private.a.agno, bno, len,
1253                                 owner, offset, newext);
1254                 error = xfs_btree_insert(cur, &i);
1255                 if (error)
1256                         goto done;
1257                 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1258                 break;
1259
1260         case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG:
1261         case RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG:
1262         case RMAP_LEFT_FILLING | RMAP_RIGHT_CONTIG:
1263         case RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG:
1264         case RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG:
1265         case RMAP_LEFT_CONTIG:
1266         case RMAP_RIGHT_CONTIG:
1267                 /*
1268                  * These cases are all impossible.
1269                  */
1270                 ASSERT(0);
1271         }
1272
1273         trace_xfs_rmap_convert_done(mp, cur->bc_private.a.agno, bno, len,
1274                         unwritten, oinfo);
1275 done:
1276         if (error)
1277                 trace_xfs_rmap_convert_error(cur->bc_mp,
1278                                 cur->bc_private.a.agno, error, _RET_IP_);
1279         return error;
1280 }
1281
1282 /*
1283  * Convert an unwritten extent to a real extent or vice versa.  If there is no
1284  * possibility of overlapping extents, delegate to the simpler convert
1285  * function.
1286  */
1287 STATIC int
1288 xfs_rmap_convert_shared(
1289         struct xfs_btree_cur    *cur,
1290         xfs_agblock_t           bno,
1291         xfs_extlen_t            len,
1292         bool                    unwritten,
1293         struct xfs_owner_info   *oinfo)
1294 {
1295         struct xfs_mount        *mp = cur->bc_mp;
1296         struct xfs_rmap_irec    r[4];   /* neighbor extent entries */
1297                                         /* left is 0, right is 1, prev is 2 */
1298                                         /* new is 3 */
1299         uint64_t                owner;
1300         uint64_t                offset;
1301         uint64_t                new_endoff;
1302         unsigned int            oldext;
1303         unsigned int            newext;
1304         unsigned int            flags = 0;
1305         int                     i;
1306         int                     state = 0;
1307         int                     error;
1308
1309         xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
1310         ASSERT(!(XFS_RMAP_NON_INODE_OWNER(owner) ||
1311                         (flags & (XFS_RMAP_ATTR_FORK | XFS_RMAP_BMBT_BLOCK))));
1312         oldext = unwritten ? XFS_RMAP_UNWRITTEN : 0;
1313         new_endoff = offset + len;
1314         trace_xfs_rmap_convert(mp, cur->bc_private.a.agno, bno, len,
1315                         unwritten, oinfo);
1316
1317         /*
1318          * For the initial lookup, look for and exact match or the left-adjacent
1319          * record for our insertion point. This will also give us the record for
1320          * start block contiguity tests.
1321          */
1322         error = xfs_rmap_lookup_le_range(cur, bno, owner, offset, oldext,
1323                         &PREV, &i);
1324         XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1325
1326         ASSERT(PREV.rm_offset <= offset);
1327         ASSERT(PREV.rm_offset + PREV.rm_blockcount >= new_endoff);
1328         ASSERT((PREV.rm_flags & XFS_RMAP_UNWRITTEN) == oldext);
1329         newext = ~oldext & XFS_RMAP_UNWRITTEN;
1330
1331         /*
1332          * Set flags determining what part of the previous oldext allocation
1333          * extent is being replaced by a newext allocation.
1334          */
1335         if (PREV.rm_offset == offset)
1336                 state |= RMAP_LEFT_FILLING;
1337         if (PREV.rm_offset + PREV.rm_blockcount == new_endoff)
1338                 state |= RMAP_RIGHT_FILLING;
1339
1340         /* Is there a left record that abuts our range? */
1341         error = xfs_rmap_find_left_neighbor(cur, bno, owner, offset, newext,
1342                         &LEFT, &i);
1343         if (error)
1344                 goto done;
1345         if (i) {
1346                 state |= RMAP_LEFT_VALID;
1347                 XFS_WANT_CORRUPTED_GOTO(mp,
1348                                 LEFT.rm_startblock + LEFT.rm_blockcount <= bno,
1349                                 done);
1350                 if (xfs_rmap_is_mergeable(&LEFT, owner, newext))
1351                         state |= RMAP_LEFT_CONTIG;
1352         }
1353
1354         /* Is there a right record that abuts our range? */
1355         error = xfs_rmap_lookup_eq(cur, bno + len, len, owner, offset + len,
1356                         newext, &i);
1357         if (error)
1358                 goto done;
1359         if (i) {
1360                 state |= RMAP_RIGHT_VALID;
1361                 error = xfs_rmap_get_rec(cur, &RIGHT, &i);
1362                 if (error)
1363                         goto done;
1364                 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1365                 XFS_WANT_CORRUPTED_GOTO(mp, bno + len <= RIGHT.rm_startblock,
1366                                 done);
1367                 trace_xfs_rmap_find_right_neighbor_result(cur->bc_mp,
1368                                 cur->bc_private.a.agno, RIGHT.rm_startblock,
1369                                 RIGHT.rm_blockcount, RIGHT.rm_owner,
1370                                 RIGHT.rm_offset, RIGHT.rm_flags);
1371                 if (xfs_rmap_is_mergeable(&RIGHT, owner, newext))
1372                         state |= RMAP_RIGHT_CONTIG;
1373         }
1374
1375         /* check that left + prev + right is not too long */
1376         if ((state & (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
1377                          RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG)) ==
1378             (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
1379              RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG) &&
1380             (unsigned long)LEFT.rm_blockcount + len +
1381              RIGHT.rm_blockcount > XFS_RMAP_LEN_MAX)
1382                 state &= ~RMAP_RIGHT_CONTIG;
1383
1384         trace_xfs_rmap_convert_state(mp, cur->bc_private.a.agno, state,
1385                         _RET_IP_);
1386         /*
1387          * Switch out based on the FILLING and CONTIG state bits.
1388          */
1389         switch (state & (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
1390                          RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG)) {
1391         case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
1392              RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG:
1393                 /*
1394                  * Setting all of a previous oldext extent to newext.
1395                  * The left and right neighbors are both contiguous with new.
1396                  */
1397                 error = xfs_rmap_delete(cur, RIGHT.rm_startblock,
1398                                 RIGHT.rm_blockcount, RIGHT.rm_owner,
1399                                 RIGHT.rm_offset, RIGHT.rm_flags);
1400                 if (error)
1401                         goto done;
1402                 error = xfs_rmap_delete(cur, PREV.rm_startblock,
1403                                 PREV.rm_blockcount, PREV.rm_owner,
1404                                 PREV.rm_offset, PREV.rm_flags);
1405                 if (error)
1406                         goto done;
1407                 NEW = LEFT;
1408                 error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
1409                                 NEW.rm_blockcount, NEW.rm_owner,
1410                                 NEW.rm_offset, NEW.rm_flags, &i);
1411                 if (error)
1412                         goto done;
1413                 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1414                 NEW.rm_blockcount += PREV.rm_blockcount + RIGHT.rm_blockcount;
1415                 error = xfs_rmap_update(cur, &NEW);
1416                 if (error)
1417                         goto done;
1418                 break;
1419
1420         case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG:
1421                 /*
1422                  * Setting all of a previous oldext extent to newext.
1423                  * The left neighbor is contiguous, the right is not.
1424                  */
1425                 error = xfs_rmap_delete(cur, PREV.rm_startblock,
1426                                 PREV.rm_blockcount, PREV.rm_owner,
1427                                 PREV.rm_offset, PREV.rm_flags);
1428                 if (error)
1429                         goto done;
1430                 NEW = LEFT;
1431                 error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
1432                                 NEW.rm_blockcount, NEW.rm_owner,
1433                                 NEW.rm_offset, NEW.rm_flags, &i);
1434                 if (error)
1435                         goto done;
1436                 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1437                 NEW.rm_blockcount += PREV.rm_blockcount;
1438                 error = xfs_rmap_update(cur, &NEW);
1439                 if (error)
1440                         goto done;
1441                 break;
1442
1443         case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG:
1444                 /*
1445                  * Setting all of a previous oldext extent to newext.
1446                  * The right neighbor is contiguous, the left is not.
1447                  */
1448                 error = xfs_rmap_delete(cur, RIGHT.rm_startblock,
1449                                 RIGHT.rm_blockcount, RIGHT.rm_owner,
1450                                 RIGHT.rm_offset, RIGHT.rm_flags);
1451                 if (error)
1452                         goto done;
1453                 NEW = PREV;
1454                 error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
1455                                 NEW.rm_blockcount, NEW.rm_owner,
1456                                 NEW.rm_offset, NEW.rm_flags, &i);
1457                 if (error)
1458                         goto done;
1459                 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1460                 NEW.rm_blockcount += RIGHT.rm_blockcount;
1461                 NEW.rm_flags = RIGHT.rm_flags;
1462                 error = xfs_rmap_update(cur, &NEW);
1463                 if (error)
1464                         goto done;
1465                 break;
1466
1467         case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING:
1468                 /*
1469                  * Setting all of a previous oldext extent to newext.
1470                  * Neither the left nor right neighbors are contiguous with
1471                  * the new one.
1472                  */
1473                 NEW = PREV;
1474                 error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
1475                                 NEW.rm_blockcount, NEW.rm_owner,
1476                                 NEW.rm_offset, NEW.rm_flags, &i);
1477                 if (error)
1478                         goto done;
1479                 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1480                 NEW.rm_flags = newext;
1481                 error = xfs_rmap_update(cur, &NEW);
1482                 if (error)
1483                         goto done;
1484                 break;
1485
1486         case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG:
1487                 /*
1488                  * Setting the first part of a previous oldext extent to newext.
1489                  * The left neighbor is contiguous.
1490                  */
1491                 NEW = PREV;
1492                 error = xfs_rmap_delete(cur, NEW.rm_startblock,
1493                                 NEW.rm_blockcount, NEW.rm_owner,
1494                                 NEW.rm_offset, NEW.rm_flags);
1495                 if (error)
1496                         goto done;
1497                 NEW.rm_offset += len;
1498                 NEW.rm_startblock += len;
1499                 NEW.rm_blockcount -= len;
1500                 error = xfs_rmap_insert(cur, NEW.rm_startblock,
1501                                 NEW.rm_blockcount, NEW.rm_owner,
1502                                 NEW.rm_offset, NEW.rm_flags);
1503                 if (error)
1504                         goto done;
1505                 NEW = LEFT;
1506                 error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
1507                                 NEW.rm_blockcount, NEW.rm_owner,
1508                                 NEW.rm_offset, NEW.rm_flags, &i);
1509                 if (error)
1510                         goto done;
1511                 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1512                 NEW.rm_blockcount += len;
1513                 error = xfs_rmap_update(cur, &NEW);
1514                 if (error)
1515                         goto done;
1516                 break;
1517
1518         case RMAP_LEFT_FILLING:
1519                 /*
1520                  * Setting the first part of a previous oldext extent to newext.
1521                  * The left neighbor is not contiguous.
1522                  */
1523                 NEW = PREV;
1524                 error = xfs_rmap_delete(cur, NEW.rm_startblock,
1525                                 NEW.rm_blockcount, NEW.rm_owner,
1526                                 NEW.rm_offset, NEW.rm_flags);
1527                 if (error)
1528                         goto done;
1529                 NEW.rm_offset += len;
1530                 NEW.rm_startblock += len;
1531                 NEW.rm_blockcount -= len;
1532                 error = xfs_rmap_insert(cur, NEW.rm_startblock,
1533                                 NEW.rm_blockcount, NEW.rm_owner,
1534                                 NEW.rm_offset, NEW.rm_flags);
1535                 if (error)
1536                         goto done;
1537                 error = xfs_rmap_insert(cur, bno, len, owner, offset, newext);
1538                 if (error)
1539                         goto done;
1540                 break;
1541
1542         case RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG:
1543                 /*
1544                  * Setting the last part of a previous oldext extent to newext.
1545                  * The right neighbor is contiguous with the new allocation.
1546                  */
1547                 NEW = PREV;
1548                 error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
1549                                 NEW.rm_blockcount, NEW.rm_owner,
1550                                 NEW.rm_offset, NEW.rm_flags, &i);
1551                 if (error)
1552                         goto done;
1553                 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1554                 NEW.rm_blockcount = offset - NEW.rm_offset;
1555                 error = xfs_rmap_update(cur, &NEW);
1556                 if (error)
1557                         goto done;
1558                 NEW = RIGHT;
1559                 error = xfs_rmap_delete(cur, NEW.rm_startblock,
1560                                 NEW.rm_blockcount, NEW.rm_owner,
1561                                 NEW.rm_offset, NEW.rm_flags);
1562                 if (error)
1563                         goto done;
1564                 NEW.rm_offset = offset;
1565                 NEW.rm_startblock = bno;
1566                 NEW.rm_blockcount += len;
1567                 error = xfs_rmap_insert(cur, NEW.rm_startblock,
1568                                 NEW.rm_blockcount, NEW.rm_owner,
1569                                 NEW.rm_offset, NEW.rm_flags);
1570                 if (error)
1571                         goto done;
1572                 break;
1573
1574         case RMAP_RIGHT_FILLING:
1575                 /*
1576                  * Setting the last part of a previous oldext extent to newext.
1577                  * The right neighbor is not contiguous.
1578                  */
1579                 NEW = PREV;
1580                 error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
1581                                 NEW.rm_blockcount, NEW.rm_owner,
1582                                 NEW.rm_offset, NEW.rm_flags, &i);
1583                 if (error)
1584                         goto done;
1585                 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1586                 NEW.rm_blockcount -= len;
1587                 error = xfs_rmap_update(cur, &NEW);
1588                 if (error)
1589                         goto done;
1590                 error = xfs_rmap_insert(cur, bno, len, owner, offset, newext);
1591                 if (error)
1592                         goto done;
1593                 break;
1594
1595         case 0:
1596                 /*
1597                  * Setting the middle part of a previous oldext extent to
1598                  * newext.  Contiguity is impossible here.
1599                  * One extent becomes three extents.
1600                  */
1601                 /* new right extent - oldext */
1602                 NEW.rm_startblock = bno + len;
1603                 NEW.rm_owner = owner;
1604                 NEW.rm_offset = new_endoff;
1605                 NEW.rm_blockcount = PREV.rm_offset + PREV.rm_blockcount -
1606                                 new_endoff;
1607                 NEW.rm_flags = PREV.rm_flags;
1608                 error = xfs_rmap_insert(cur, NEW.rm_startblock,
1609                                 NEW.rm_blockcount, NEW.rm_owner, NEW.rm_offset,
1610                                 NEW.rm_flags);
1611                 if (error)
1612                         goto done;
1613                 /* new left extent - oldext */
1614                 NEW = PREV;
1615                 error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
1616                                 NEW.rm_blockcount, NEW.rm_owner,
1617                                 NEW.rm_offset, NEW.rm_flags, &i);
1618                 if (error)
1619                         goto done;
1620                 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1621                 NEW.rm_blockcount = offset - NEW.rm_offset;
1622                 error = xfs_rmap_update(cur, &NEW);
1623                 if (error)
1624                         goto done;
1625                 /* new middle extent - newext */
1626                 NEW.rm_startblock = bno;
1627                 NEW.rm_blockcount = len;
1628                 NEW.rm_owner = owner;
1629                 NEW.rm_offset = offset;
1630                 NEW.rm_flags = newext;
1631                 error = xfs_rmap_insert(cur, NEW.rm_startblock,
1632                                 NEW.rm_blockcount, NEW.rm_owner, NEW.rm_offset,
1633                                 NEW.rm_flags);
1634                 if (error)
1635                         goto done;
1636                 break;
1637
1638         case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG:
1639         case RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG:
1640         case RMAP_LEFT_FILLING | RMAP_RIGHT_CONTIG:
1641         case RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG:
1642         case RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG:
1643         case RMAP_LEFT_CONTIG:
1644         case RMAP_RIGHT_CONTIG:
1645                 /*
1646                  * These cases are all impossible.
1647                  */
1648                 ASSERT(0);
1649         }
1650
1651         trace_xfs_rmap_convert_done(mp, cur->bc_private.a.agno, bno, len,
1652                         unwritten, oinfo);
1653 done:
1654         if (error)
1655                 trace_xfs_rmap_convert_error(cur->bc_mp,
1656                                 cur->bc_private.a.agno, error, _RET_IP_);
1657         return error;
1658 }
1659
1660 #undef  NEW
1661 #undef  LEFT
1662 #undef  RIGHT
1663 #undef  PREV
1664
1665 /*
1666  * Find an extent in the rmap btree and unmap it.  For rmap extent types that
1667  * can overlap (data fork rmaps on reflink filesystems) we must be careful
1668  * that the prev/next records in the btree might belong to another owner.
1669  * Therefore we must use delete+insert to alter any of the key fields.
1670  *
1671  * For every other situation there can only be one owner for a given extent,
1672  * so we can call the regular _free function.
1673  */
1674 STATIC int
1675 xfs_rmap_unmap_shared(
1676         struct xfs_btree_cur    *cur,
1677         xfs_agblock_t           bno,
1678         xfs_extlen_t            len,
1679         bool                    unwritten,
1680         struct xfs_owner_info   *oinfo)
1681 {
1682         struct xfs_mount        *mp = cur->bc_mp;
1683         struct xfs_rmap_irec    ltrec;
1684         uint64_t                ltoff;
1685         int                     error = 0;
1686         int                     i;
1687         uint64_t                owner;
1688         uint64_t                offset;
1689         unsigned int            flags;
1690
1691         xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
1692         if (unwritten)
1693                 flags |= XFS_RMAP_UNWRITTEN;
1694         trace_xfs_rmap_unmap(mp, cur->bc_private.a.agno, bno, len,
1695                         unwritten, oinfo);
1696
1697         /*
1698          * We should always have a left record because there's a static record
1699          * for the AG headers at rm_startblock == 0 created by mkfs/growfs that
1700          * will not ever be removed from the tree.
1701          */
1702         error = xfs_rmap_lookup_le_range(cur, bno, owner, offset, flags,
1703                         &ltrec, &i);
1704         if (error)
1705                 goto out_error;
1706         XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error);
1707         ltoff = ltrec.rm_offset;
1708
1709         /* Make sure the extent we found covers the entire freeing range. */
1710         XFS_WANT_CORRUPTED_GOTO(mp, ltrec.rm_startblock <= bno &&
1711                 ltrec.rm_startblock + ltrec.rm_blockcount >=
1712                 bno + len, out_error);
1713
1714         /* Make sure the owner matches what we expect to find in the tree. */
1715         XFS_WANT_CORRUPTED_GOTO(mp, owner == ltrec.rm_owner, out_error);
1716
1717         /* Make sure the unwritten flag matches. */
1718         XFS_WANT_CORRUPTED_GOTO(mp, (flags & XFS_RMAP_UNWRITTEN) ==
1719                         (ltrec.rm_flags & XFS_RMAP_UNWRITTEN), out_error);
1720
1721         /* Check the offset. */
1722         XFS_WANT_CORRUPTED_GOTO(mp, ltrec.rm_offset <= offset, out_error);
1723         XFS_WANT_CORRUPTED_GOTO(mp, offset <= ltoff + ltrec.rm_blockcount,
1724                         out_error);
1725
1726         if (ltrec.rm_startblock == bno && ltrec.rm_blockcount == len) {
1727                 /* Exact match, simply remove the record from rmap tree. */
1728                 error = xfs_rmap_delete(cur, ltrec.rm_startblock,
1729                                 ltrec.rm_blockcount, ltrec.rm_owner,
1730                                 ltrec.rm_offset, ltrec.rm_flags);
1731                 if (error)
1732                         goto out_error;
1733         } else if (ltrec.rm_startblock == bno) {
1734                 /*
1735                  * Overlap left hand side of extent: move the start, trim the
1736                  * length and update the current record.
1737                  *
1738                  *       ltbno                ltlen
1739                  * Orig:    |oooooooooooooooooooo|
1740                  * Freeing: |fffffffff|
1741                  * Result:            |rrrrrrrrrr|
1742                  *         bno       len
1743                  */
1744
1745                 /* Delete prev rmap. */
1746                 error = xfs_rmap_delete(cur, ltrec.rm_startblock,
1747                                 ltrec.rm_blockcount, ltrec.rm_owner,
1748                                 ltrec.rm_offset, ltrec.rm_flags);
1749                 if (error)
1750                         goto out_error;
1751
1752                 /* Add an rmap at the new offset. */
1753                 ltrec.rm_startblock += len;
1754                 ltrec.rm_blockcount -= len;
1755                 ltrec.rm_offset += len;
1756                 error = xfs_rmap_insert(cur, ltrec.rm_startblock,
1757                                 ltrec.rm_blockcount, ltrec.rm_owner,
1758                                 ltrec.rm_offset, ltrec.rm_flags);
1759                 if (error)
1760                         goto out_error;
1761         } else if (ltrec.rm_startblock + ltrec.rm_blockcount == bno + len) {
1762                 /*
1763                  * Overlap right hand side of extent: trim the length and
1764                  * update the current record.
1765                  *
1766                  *       ltbno                ltlen
1767                  * Orig:    |oooooooooooooooooooo|
1768                  * Freeing:            |fffffffff|
1769                  * Result:  |rrrrrrrrrr|
1770                  *                    bno       len
1771                  */
1772                 error = xfs_rmap_lookup_eq(cur, ltrec.rm_startblock,
1773                                 ltrec.rm_blockcount, ltrec.rm_owner,
1774                                 ltrec.rm_offset, ltrec.rm_flags, &i);
1775                 if (error)
1776                         goto out_error;
1777                 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error);
1778                 ltrec.rm_blockcount -= len;
1779                 error = xfs_rmap_update(cur, &ltrec);
1780                 if (error)
1781                         goto out_error;
1782         } else {
1783                 /*
1784                  * Overlap middle of extent: trim the length of the existing
1785                  * record to the length of the new left-extent size, increment
1786                  * the insertion position so we can insert a new record
1787                  * containing the remaining right-extent space.
1788                  *
1789                  *       ltbno                ltlen
1790                  * Orig:    |oooooooooooooooooooo|
1791                  * Freeing:       |fffffffff|
1792                  * Result:  |rrrrr|         |rrrr|
1793                  *               bno       len
1794                  */
1795                 xfs_extlen_t    orig_len = ltrec.rm_blockcount;
1796
1797                 /* Shrink the left side of the rmap */
1798                 error = xfs_rmap_lookup_eq(cur, ltrec.rm_startblock,
1799                                 ltrec.rm_blockcount, ltrec.rm_owner,
1800                                 ltrec.rm_offset, ltrec.rm_flags, &i);
1801                 if (error)
1802                         goto out_error;
1803                 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error);
1804                 ltrec.rm_blockcount = bno - ltrec.rm_startblock;
1805                 error = xfs_rmap_update(cur, &ltrec);
1806                 if (error)
1807                         goto out_error;
1808
1809                 /* Add an rmap at the new offset */
1810                 error = xfs_rmap_insert(cur, bno + len,
1811                                 orig_len - len - ltrec.rm_blockcount,
1812                                 ltrec.rm_owner, offset + len,
1813                                 ltrec.rm_flags);
1814                 if (error)
1815                         goto out_error;
1816         }
1817
1818         trace_xfs_rmap_unmap_done(mp, cur->bc_private.a.agno, bno, len,
1819                         unwritten, oinfo);
1820 out_error:
1821         if (error)
1822                 trace_xfs_rmap_unmap_error(cur->bc_mp,
1823                                 cur->bc_private.a.agno, error, _RET_IP_);
1824         return error;
1825 }
1826
1827 /*
1828  * Find an extent in the rmap btree and map it.  For rmap extent types that
1829  * can overlap (data fork rmaps on reflink filesystems) we must be careful
1830  * that the prev/next records in the btree might belong to another owner.
1831  * Therefore we must use delete+insert to alter any of the key fields.
1832  *
1833  * For every other situation there can only be one owner for a given extent,
1834  * so we can call the regular _alloc function.
1835  */
1836 STATIC int
1837 xfs_rmap_map_shared(
1838         struct xfs_btree_cur    *cur,
1839         xfs_agblock_t           bno,
1840         xfs_extlen_t            len,
1841         bool                    unwritten,
1842         struct xfs_owner_info   *oinfo)
1843 {
1844         struct xfs_mount        *mp = cur->bc_mp;
1845         struct xfs_rmap_irec    ltrec;
1846         struct xfs_rmap_irec    gtrec;
1847         int                     have_gt;
1848         int                     have_lt;
1849         int                     error = 0;
1850         int                     i;
1851         uint64_t                owner;
1852         uint64_t                offset;
1853         unsigned int            flags = 0;
1854
1855         xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
1856         if (unwritten)
1857                 flags |= XFS_RMAP_UNWRITTEN;
1858         trace_xfs_rmap_map(mp, cur->bc_private.a.agno, bno, len,
1859                         unwritten, oinfo);
1860
1861         /* Is there a left record that abuts our range? */
1862         error = xfs_rmap_find_left_neighbor(cur, bno, owner, offset, flags,
1863                         &ltrec, &have_lt);
1864         if (error)
1865                 goto out_error;
1866         if (have_lt &&
1867             !xfs_rmap_is_mergeable(&ltrec, owner, flags))
1868                 have_lt = 0;
1869
1870         /* Is there a right record that abuts our range? */
1871         error = xfs_rmap_lookup_eq(cur, bno + len, len, owner, offset + len,
1872                         flags, &have_gt);
1873         if (error)
1874                 goto out_error;
1875         if (have_gt) {
1876                 error = xfs_rmap_get_rec(cur, &gtrec, &have_gt);
1877                 if (error)
1878                         goto out_error;
1879                 XFS_WANT_CORRUPTED_GOTO(mp, have_gt == 1, out_error);
1880                 trace_xfs_rmap_find_right_neighbor_result(cur->bc_mp,
1881                         cur->bc_private.a.agno, gtrec.rm_startblock,
1882                         gtrec.rm_blockcount, gtrec.rm_owner,
1883                         gtrec.rm_offset, gtrec.rm_flags);
1884
1885                 if (!xfs_rmap_is_mergeable(&gtrec, owner, flags))
1886                         have_gt = 0;
1887         }
1888
1889         if (have_lt &&
1890             ltrec.rm_startblock + ltrec.rm_blockcount == bno &&
1891             ltrec.rm_offset + ltrec.rm_blockcount == offset) {
1892                 /*
1893                  * Left edge contiguous, merge into left record.
1894                  *
1895                  *       ltbno     ltlen
1896                  * orig:   |ooooooooo|
1897                  * adding:           |aaaaaaaaa|
1898                  * result: |rrrrrrrrrrrrrrrrrrr|
1899                  *                  bno       len
1900                  */
1901                 ltrec.rm_blockcount += len;
1902                 if (have_gt &&
1903                     bno + len == gtrec.rm_startblock &&
1904                     offset + len == gtrec.rm_offset) {
1905                         /*
1906                          * Right edge also contiguous, delete right record
1907                          * and merge into left record.
1908                          *
1909                          *       ltbno     ltlen    gtbno     gtlen
1910                          * orig:   |ooooooooo|         |ooooooooo|
1911                          * adding:           |aaaaaaaaa|
1912                          * result: |rrrrrrrrrrrrrrrrrrrrrrrrrrrrr|
1913                          */
1914                         ltrec.rm_blockcount += gtrec.rm_blockcount;
1915                         error = xfs_rmap_delete(cur, gtrec.rm_startblock,
1916                                         gtrec.rm_blockcount, gtrec.rm_owner,
1917                                         gtrec.rm_offset, gtrec.rm_flags);
1918                         if (error)
1919                                 goto out_error;
1920                 }
1921
1922                 /* Point the cursor back to the left record and update. */
1923                 error = xfs_rmap_lookup_eq(cur, ltrec.rm_startblock,
1924                                 ltrec.rm_blockcount, ltrec.rm_owner,
1925                                 ltrec.rm_offset, ltrec.rm_flags, &i);
1926                 if (error)
1927                         goto out_error;
1928                 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error);
1929
1930                 error = xfs_rmap_update(cur, &ltrec);
1931                 if (error)
1932                         goto out_error;
1933         } else if (have_gt &&
1934                    bno + len == gtrec.rm_startblock &&
1935                    offset + len == gtrec.rm_offset) {
1936                 /*
1937                  * Right edge contiguous, merge into right record.
1938                  *
1939                  *                 gtbno     gtlen
1940                  * Orig:             |ooooooooo|
1941                  * adding: |aaaaaaaaa|
1942                  * Result: |rrrrrrrrrrrrrrrrrrr|
1943                  *        bno       len
1944                  */
1945                 /* Delete the old record. */
1946                 error = xfs_rmap_delete(cur, gtrec.rm_startblock,
1947                                 gtrec.rm_blockcount, gtrec.rm_owner,
1948                                 gtrec.rm_offset, gtrec.rm_flags);
1949                 if (error)
1950                         goto out_error;
1951
1952                 /* Move the start and re-add it. */
1953                 gtrec.rm_startblock = bno;
1954                 gtrec.rm_blockcount += len;
1955                 gtrec.rm_offset = offset;
1956                 error = xfs_rmap_insert(cur, gtrec.rm_startblock,
1957                                 gtrec.rm_blockcount, gtrec.rm_owner,
1958                                 gtrec.rm_offset, gtrec.rm_flags);
1959                 if (error)
1960                         goto out_error;
1961         } else {
1962                 /*
1963                  * No contiguous edge with identical owner, insert
1964                  * new record at current cursor position.
1965                  */
1966                 error = xfs_rmap_insert(cur, bno, len, owner, offset, flags);
1967                 if (error)
1968                         goto out_error;
1969         }
1970
1971         trace_xfs_rmap_map_done(mp, cur->bc_private.a.agno, bno, len,
1972                         unwritten, oinfo);
1973 out_error:
1974         if (error)
1975                 trace_xfs_rmap_map_error(cur->bc_mp,
1976                                 cur->bc_private.a.agno, error, _RET_IP_);
1977         return error;
1978 }
1979
1980 struct xfs_rmap_query_range_info {
1981         xfs_rmap_query_range_fn fn;
1982         void                            *priv;
1983 };
1984
1985 /* Format btree record and pass to our callback. */
1986 STATIC int
1987 xfs_rmap_query_range_helper(
1988         struct xfs_btree_cur    *cur,
1989         union xfs_btree_rec     *rec,
1990         void                    *priv)
1991 {
1992         struct xfs_rmap_query_range_info        *query = priv;
1993         struct xfs_rmap_irec                    irec;
1994         int                                     error;
1995
1996         error = xfs_rmap_btrec_to_irec(rec, &irec);
1997         if (error)
1998                 return error;
1999         return query->fn(cur, &irec, query->priv);
2000 }
2001
2002 /* Find all rmaps between two keys. */
2003 int
2004 xfs_rmap_query_range(
2005         struct xfs_btree_cur                    *cur,
2006         struct xfs_rmap_irec                    *low_rec,
2007         struct xfs_rmap_irec                    *high_rec,
2008         xfs_rmap_query_range_fn                 fn,
2009         void                                    *priv)
2010 {
2011         union xfs_btree_irec                    low_brec;
2012         union xfs_btree_irec                    high_brec;
2013         struct xfs_rmap_query_range_info        query;
2014
2015         low_brec.r = *low_rec;
2016         high_brec.r = *high_rec;
2017         query.priv = priv;
2018         query.fn = fn;
2019         return xfs_btree_query_range(cur, &low_brec, &high_brec,
2020                         xfs_rmap_query_range_helper, &query);
2021 }
2022
2023 /* Find all rmaps. */
2024 int
2025 xfs_rmap_query_all(
2026         struct xfs_btree_cur                    *cur,
2027         xfs_rmap_query_range_fn                 fn,
2028         void                                    *priv)
2029 {
2030         struct xfs_rmap_query_range_info        query;
2031
2032         query.priv = priv;
2033         query.fn = fn;
2034         return xfs_btree_query_all(cur, xfs_rmap_query_range_helper, &query);
2035 }
2036
2037 /* Clean up after calling xfs_rmap_finish_one. */
2038 void
2039 xfs_rmap_finish_one_cleanup(
2040         struct xfs_trans        *tp,
2041         struct xfs_btree_cur    *rcur,
2042         int                     error)
2043 {
2044         struct xfs_buf          *agbp;
2045
2046         if (rcur == NULL)
2047                 return;
2048         agbp = rcur->bc_private.a.agbp;
2049         xfs_btree_del_cursor(rcur, error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR);
2050         if (error)
2051                 xfs_trans_brelse(tp, agbp);
2052 }
2053
2054 /*
2055  * Process one of the deferred rmap operations.  We pass back the
2056  * btree cursor to maintain our lock on the rmapbt between calls.
2057  * This saves time and eliminates a buffer deadlock between the
2058  * superblock and the AGF because we'll always grab them in the same
2059  * order.
2060  */
2061 int
2062 xfs_rmap_finish_one(
2063         struct xfs_trans                *tp,
2064         enum xfs_rmap_intent_type       type,
2065         uint64_t                        owner,
2066         int                             whichfork,
2067         xfs_fileoff_t                   startoff,
2068         xfs_fsblock_t                   startblock,
2069         xfs_filblks_t                   blockcount,
2070         xfs_exntst_t                    state,
2071         struct xfs_btree_cur            **pcur)
2072 {
2073         struct xfs_mount                *mp = tp->t_mountp;
2074         struct xfs_btree_cur            *rcur;
2075         struct xfs_buf                  *agbp = NULL;
2076         int                             error = 0;
2077         xfs_agnumber_t                  agno;
2078         struct xfs_owner_info           oinfo;
2079         xfs_agblock_t                   bno;
2080         bool                            unwritten;
2081
2082         agno = XFS_FSB_TO_AGNO(mp, startblock);
2083         ASSERT(agno != NULLAGNUMBER);
2084         bno = XFS_FSB_TO_AGBNO(mp, startblock);
2085
2086         trace_xfs_rmap_deferred(mp, agno, type, bno, owner, whichfork,
2087                         startoff, blockcount, state);
2088
2089         if (XFS_TEST_ERROR(false, mp,
2090                         XFS_ERRTAG_RMAP_FINISH_ONE))
2091                 return -EIO;
2092
2093         /*
2094          * If we haven't gotten a cursor or the cursor AG doesn't match
2095          * the startblock, get one now.
2096          */
2097         rcur = *pcur;
2098         if (rcur != NULL && rcur->bc_private.a.agno != agno) {
2099                 xfs_rmap_finish_one_cleanup(tp, rcur, 0);
2100                 rcur = NULL;
2101                 *pcur = NULL;
2102         }
2103         if (rcur == NULL) {
2104                 /*
2105                  * Refresh the freelist before we start changing the
2106                  * rmapbt, because a shape change could cause us to
2107                  * allocate blocks.
2108                  */
2109                 error = xfs_free_extent_fix_freelist(tp, agno, &agbp);
2110                 if (error)
2111                         return error;
2112                 if (!agbp)
2113                         return -EFSCORRUPTED;
2114
2115                 rcur = xfs_rmapbt_init_cursor(mp, tp, agbp, agno);
2116                 if (!rcur) {
2117                         error = -ENOMEM;
2118                         goto out_cur;
2119                 }
2120         }
2121         *pcur = rcur;
2122
2123         xfs_rmap_ino_owner(&oinfo, owner, whichfork, startoff);
2124         unwritten = state == XFS_EXT_UNWRITTEN;
2125         bno = XFS_FSB_TO_AGBNO(rcur->bc_mp, startblock);
2126
2127         switch (type) {
2128         case XFS_RMAP_ALLOC:
2129         case XFS_RMAP_MAP:
2130                 error = xfs_rmap_map(rcur, bno, blockcount, unwritten, &oinfo);
2131                 break;
2132         case XFS_RMAP_MAP_SHARED:
2133                 error = xfs_rmap_map_shared(rcur, bno, blockcount, unwritten,
2134                                 &oinfo);
2135                 break;
2136         case XFS_RMAP_FREE:
2137         case XFS_RMAP_UNMAP:
2138                 error = xfs_rmap_unmap(rcur, bno, blockcount, unwritten,
2139                                 &oinfo);
2140                 break;
2141         case XFS_RMAP_UNMAP_SHARED:
2142                 error = xfs_rmap_unmap_shared(rcur, bno, blockcount, unwritten,
2143                                 &oinfo);
2144                 break;
2145         case XFS_RMAP_CONVERT:
2146                 error = xfs_rmap_convert(rcur, bno, blockcount, !unwritten,
2147                                 &oinfo);
2148                 break;
2149         case XFS_RMAP_CONVERT_SHARED:
2150                 error = xfs_rmap_convert_shared(rcur, bno, blockcount,
2151                                 !unwritten, &oinfo);
2152                 break;
2153         default:
2154                 ASSERT(0);
2155                 error = -EFSCORRUPTED;
2156         }
2157         return error;
2158
2159 out_cur:
2160         xfs_trans_brelse(tp, agbp);
2161
2162         return error;
2163 }
2164
2165 /*
2166  * Don't defer an rmap if we aren't an rmap filesystem.
2167  */
2168 static bool
2169 xfs_rmap_update_is_needed(
2170         struct xfs_mount        *mp,
2171         int                     whichfork)
2172 {
2173         return xfs_sb_version_hasrmapbt(&mp->m_sb) && whichfork != XFS_COW_FORK;
2174 }
2175
2176 /*
2177  * Record a rmap intent; the list is kept sorted first by AG and then by
2178  * increasing age.
2179  */
2180 static int
2181 __xfs_rmap_add(
2182         struct xfs_mount                *mp,
2183         struct xfs_defer_ops            *dfops,
2184         enum xfs_rmap_intent_type       type,
2185         uint64_t                        owner,
2186         int                             whichfork,
2187         struct xfs_bmbt_irec            *bmap)
2188 {
2189         struct xfs_rmap_intent  *ri;
2190
2191         trace_xfs_rmap_defer(mp, XFS_FSB_TO_AGNO(mp, bmap->br_startblock),
2192                         type,
2193                         XFS_FSB_TO_AGBNO(mp, bmap->br_startblock),
2194                         owner, whichfork,
2195                         bmap->br_startoff,
2196                         bmap->br_blockcount,
2197                         bmap->br_state);
2198
2199         ri = kmem_alloc(sizeof(struct xfs_rmap_intent), KM_SLEEP | KM_NOFS);
2200         INIT_LIST_HEAD(&ri->ri_list);
2201         ri->ri_type = type;
2202         ri->ri_owner = owner;
2203         ri->ri_whichfork = whichfork;
2204         ri->ri_bmap = *bmap;
2205
2206         xfs_defer_add(dfops, XFS_DEFER_OPS_TYPE_RMAP, &ri->ri_list);
2207         return 0;
2208 }
2209
2210 /* Map an extent into a file. */
2211 int
2212 xfs_rmap_map_extent(
2213         struct xfs_mount        *mp,
2214         struct xfs_defer_ops    *dfops,
2215         struct xfs_inode        *ip,
2216         int                     whichfork,
2217         struct xfs_bmbt_irec    *PREV)
2218 {
2219         if (!xfs_rmap_update_is_needed(mp, whichfork))
2220                 return 0;
2221
2222         return __xfs_rmap_add(mp, dfops, xfs_is_reflink_inode(ip) ?
2223                         XFS_RMAP_MAP_SHARED : XFS_RMAP_MAP, ip->i_ino,
2224                         whichfork, PREV);
2225 }
2226
2227 /* Unmap an extent out of a file. */
2228 int
2229 xfs_rmap_unmap_extent(
2230         struct xfs_mount        *mp,
2231         struct xfs_defer_ops    *dfops,
2232         struct xfs_inode        *ip,
2233         int                     whichfork,
2234         struct xfs_bmbt_irec    *PREV)
2235 {
2236         if (!xfs_rmap_update_is_needed(mp, whichfork))
2237                 return 0;
2238
2239         return __xfs_rmap_add(mp, dfops, xfs_is_reflink_inode(ip) ?
2240                         XFS_RMAP_UNMAP_SHARED : XFS_RMAP_UNMAP, ip->i_ino,
2241                         whichfork, PREV);
2242 }
2243
2244 /* Convert a data fork extent from unwritten to real or vice versa. */
2245 int
2246 xfs_rmap_convert_extent(
2247         struct xfs_mount        *mp,
2248         struct xfs_defer_ops    *dfops,
2249         struct xfs_inode        *ip,
2250         int                     whichfork,
2251         struct xfs_bmbt_irec    *PREV)
2252 {
2253         if (!xfs_rmap_update_is_needed(mp, whichfork))
2254                 return 0;
2255
2256         return __xfs_rmap_add(mp, dfops, xfs_is_reflink_inode(ip) ?
2257                         XFS_RMAP_CONVERT_SHARED : XFS_RMAP_CONVERT, ip->i_ino,
2258                         whichfork, PREV);
2259 }
2260
2261 /* Schedule the creation of an rmap for non-file data. */
2262 int
2263 xfs_rmap_alloc_extent(
2264         struct xfs_mount        *mp,
2265         struct xfs_defer_ops    *dfops,
2266         xfs_agnumber_t          agno,
2267         xfs_agblock_t           bno,
2268         xfs_extlen_t            len,
2269         uint64_t                owner)
2270 {
2271         struct xfs_bmbt_irec    bmap;
2272
2273         if (!xfs_rmap_update_is_needed(mp, XFS_DATA_FORK))
2274                 return 0;
2275
2276         bmap.br_startblock = XFS_AGB_TO_FSB(mp, agno, bno);
2277         bmap.br_blockcount = len;
2278         bmap.br_startoff = 0;
2279         bmap.br_state = XFS_EXT_NORM;
2280
2281         return __xfs_rmap_add(mp, dfops, XFS_RMAP_ALLOC, owner,
2282                         XFS_DATA_FORK, &bmap);
2283 }
2284
2285 /* Schedule the deletion of an rmap for non-file data. */
2286 int
2287 xfs_rmap_free_extent(
2288         struct xfs_mount        *mp,
2289         struct xfs_defer_ops    *dfops,
2290         xfs_agnumber_t          agno,
2291         xfs_agblock_t           bno,
2292         xfs_extlen_t            len,
2293         uint64_t                owner)
2294 {
2295         struct xfs_bmbt_irec    bmap;
2296
2297         if (!xfs_rmap_update_is_needed(mp, XFS_DATA_FORK))
2298                 return 0;
2299
2300         bmap.br_startblock = XFS_AGB_TO_FSB(mp, agno, bno);
2301         bmap.br_blockcount = len;
2302         bmap.br_startoff = 0;
2303         bmap.br_state = XFS_EXT_NORM;
2304
2305         return __xfs_rmap_add(mp, dfops, XFS_RMAP_FREE, owner,
2306                         XFS_DATA_FORK, &bmap);
2307 }
2308
2309 /* Compare rmap records.  Returns -1 if a < b, 1 if a > b, and 0 if equal. */
2310 int
2311 xfs_rmap_compare(
2312         const struct xfs_rmap_irec      *a,
2313         const struct xfs_rmap_irec      *b)
2314 {
2315         __u64                           oa;
2316         __u64                           ob;
2317
2318         oa = xfs_rmap_irec_offset_pack(a);
2319         ob = xfs_rmap_irec_offset_pack(b);
2320
2321         if (a->rm_startblock < b->rm_startblock)
2322                 return -1;
2323         else if (a->rm_startblock > b->rm_startblock)
2324                 return 1;
2325         else if (a->rm_owner < b->rm_owner)
2326                 return -1;
2327         else if (a->rm_owner > b->rm_owner)
2328                 return 1;
2329         else if (oa < ob)
2330                 return -1;
2331         else if (oa > ob)
2332                 return 1;
2333         else
2334                 return 0;
2335 }