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