Merge remote-tracking branches 'regulator/fix/email' and 'regulator/fix/qcom-smd...
[cascardo/linux.git] / fs / xfs / libxfs / xfs_rmap.c
1 /*
2  * Copyright (c) 2014 Red Hat, Inc.
3  * All Rights Reserved.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it would be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write the Free Software Foundation,
16  * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17  */
18 #include "xfs.h"
19 #include "xfs_fs.h"
20 #include "xfs_shared.h"
21 #include "xfs_format.h"
22 #include "xfs_log_format.h"
23 #include "xfs_trans_resv.h"
24 #include "xfs_bit.h"
25 #include "xfs_sb.h"
26 #include "xfs_mount.h"
27 #include "xfs_defer.h"
28 #include "xfs_da_format.h"
29 #include "xfs_da_btree.h"
30 #include "xfs_btree.h"
31 #include "xfs_trans.h"
32 #include "xfs_alloc.h"
33 #include "xfs_rmap.h"
34 #include "xfs_rmap_btree.h"
35 #include "xfs_trans_space.h"
36 #include "xfs_trace.h"
37 #include "xfs_error.h"
38 #include "xfs_extent_busy.h"
39 #include "xfs_bmap.h"
40 #include "xfs_inode.h"
41
42 /*
43  * Lookup the first record less than or equal to [bno, len, owner, offset]
44  * in the btree given by cur.
45  */
46 int
47 xfs_rmap_lookup_le(
48         struct xfs_btree_cur    *cur,
49         xfs_agblock_t           bno,
50         xfs_extlen_t            len,
51         uint64_t                owner,
52         uint64_t                offset,
53         unsigned int            flags,
54         int                     *stat)
55 {
56         cur->bc_rec.r.rm_startblock = bno;
57         cur->bc_rec.r.rm_blockcount = len;
58         cur->bc_rec.r.rm_owner = owner;
59         cur->bc_rec.r.rm_offset = offset;
60         cur->bc_rec.r.rm_flags = flags;
61         return xfs_btree_lookup(cur, XFS_LOOKUP_LE, stat);
62 }
63
64 /*
65  * Lookup the record exactly matching [bno, len, owner, offset]
66  * in the btree given by cur.
67  */
68 int
69 xfs_rmap_lookup_eq(
70         struct xfs_btree_cur    *cur,
71         xfs_agblock_t           bno,
72         xfs_extlen_t            len,
73         uint64_t                owner,
74         uint64_t                offset,
75         unsigned int            flags,
76         int                     *stat)
77 {
78         cur->bc_rec.r.rm_startblock = bno;
79         cur->bc_rec.r.rm_blockcount = len;
80         cur->bc_rec.r.rm_owner = owner;
81         cur->bc_rec.r.rm_offset = offset;
82         cur->bc_rec.r.rm_flags = flags;
83         return xfs_btree_lookup(cur, XFS_LOOKUP_EQ, stat);
84 }
85
86 /*
87  * Update the record referred to by cur to the value given
88  * by [bno, len, owner, offset].
89  * This either works (return 0) or gets an EFSCORRUPTED error.
90  */
91 STATIC int
92 xfs_rmap_update(
93         struct xfs_btree_cur    *cur,
94         struct xfs_rmap_irec    *irec)
95 {
96         union xfs_btree_rec     rec;
97         int                     error;
98
99         trace_xfs_rmap_update(cur->bc_mp, cur->bc_private.a.agno,
100                         irec->rm_startblock, irec->rm_blockcount,
101                         irec->rm_owner, irec->rm_offset, irec->rm_flags);
102
103         rec.rmap.rm_startblock = cpu_to_be32(irec->rm_startblock);
104         rec.rmap.rm_blockcount = cpu_to_be32(irec->rm_blockcount);
105         rec.rmap.rm_owner = cpu_to_be64(irec->rm_owner);
106         rec.rmap.rm_offset = cpu_to_be64(
107                         xfs_rmap_irec_offset_pack(irec));
108         error = xfs_btree_update(cur, &rec);
109         if (error)
110                 trace_xfs_rmap_update_error(cur->bc_mp,
111                                 cur->bc_private.a.agno, error, _RET_IP_);
112         return error;
113 }
114
115 int
116 xfs_rmap_insert(
117         struct xfs_btree_cur    *rcur,
118         xfs_agblock_t           agbno,
119         xfs_extlen_t            len,
120         uint64_t                owner,
121         uint64_t                offset,
122         unsigned int            flags)
123 {
124         int                     i;
125         int                     error;
126
127         trace_xfs_rmap_insert(rcur->bc_mp, rcur->bc_private.a.agno, agbno,
128                         len, owner, offset, flags);
129
130         error = xfs_rmap_lookup_eq(rcur, agbno, len, owner, offset, flags, &i);
131         if (error)
132                 goto done;
133         XFS_WANT_CORRUPTED_GOTO(rcur->bc_mp, i == 0, done);
134
135         rcur->bc_rec.r.rm_startblock = agbno;
136         rcur->bc_rec.r.rm_blockcount = len;
137         rcur->bc_rec.r.rm_owner = owner;
138         rcur->bc_rec.r.rm_offset = offset;
139         rcur->bc_rec.r.rm_flags = flags;
140         error = xfs_btree_insert(rcur, &i);
141         if (error)
142                 goto done;
143         XFS_WANT_CORRUPTED_GOTO(rcur->bc_mp, i == 1, done);
144 done:
145         if (error)
146                 trace_xfs_rmap_insert_error(rcur->bc_mp,
147                                 rcur->bc_private.a.agno, error, _RET_IP_);
148         return error;
149 }
150
151 static int
152 xfs_rmap_btrec_to_irec(
153         union xfs_btree_rec     *rec,
154         struct xfs_rmap_irec    *irec)
155 {
156         irec->rm_flags = 0;
157         irec->rm_startblock = be32_to_cpu(rec->rmap.rm_startblock);
158         irec->rm_blockcount = be32_to_cpu(rec->rmap.rm_blockcount);
159         irec->rm_owner = be64_to_cpu(rec->rmap.rm_owner);
160         return xfs_rmap_irec_offset_unpack(be64_to_cpu(rec->rmap.rm_offset),
161                         irec);
162 }
163
164 /*
165  * Get the data from the pointed-to record.
166  */
167 int
168 xfs_rmap_get_rec(
169         struct xfs_btree_cur    *cur,
170         struct xfs_rmap_irec    *irec,
171         int                     *stat)
172 {
173         union xfs_btree_rec     *rec;
174         int                     error;
175
176         error = xfs_btree_get_rec(cur, &rec, stat);
177         if (error || !*stat)
178                 return error;
179
180         return xfs_rmap_btrec_to_irec(rec, irec);
181 }
182
183 /*
184  * Find the extent in the rmap btree and remove it.
185  *
186  * The record we find should always be an exact match for the extent that we're
187  * looking for, since we insert them into the btree without modification.
188  *
189  * Special Case #1: when growing the filesystem, we "free" an extent when
190  * growing the last AG. This extent is new space and so it is not tracked as
191  * used space in the btree. The growfs code will pass in an owner of
192  * XFS_RMAP_OWN_NULL to indicate that it expected that there is no owner of this
193  * extent. We verify that - the extent lookup result in a record that does not
194  * overlap.
195  *
196  * Special Case #2: EFIs do not record the owner of the extent, so when
197  * recovering EFIs from the log we pass in XFS_RMAP_OWN_UNKNOWN to tell the rmap
198  * btree to ignore the owner (i.e. wildcard match) so we don't trigger
199  * corruption checks during log recovery.
200  */
201 STATIC int
202 xfs_rmap_unmap(
203         struct xfs_btree_cur    *cur,
204         xfs_agblock_t           bno,
205         xfs_extlen_t            len,
206         bool                    unwritten,
207         struct xfs_owner_info   *oinfo)
208 {
209         struct xfs_mount        *mp = cur->bc_mp;
210         struct xfs_rmap_irec    ltrec;
211         uint64_t                ltoff;
212         int                     error = 0;
213         int                     i;
214         uint64_t                owner;
215         uint64_t                offset;
216         unsigned int            flags;
217         bool                    ignore_off;
218
219         xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
220         ignore_off = XFS_RMAP_NON_INODE_OWNER(owner) ||
221                         (flags & XFS_RMAP_BMBT_BLOCK);
222         if (unwritten)
223                 flags |= XFS_RMAP_UNWRITTEN;
224         trace_xfs_rmap_unmap(mp, cur->bc_private.a.agno, bno, len,
225                         unwritten, oinfo);
226
227         /*
228          * We should always have a left record because there's a static record
229          * for the AG headers at rm_startblock == 0 created by mkfs/growfs that
230          * will not ever be removed from the tree.
231          */
232         error = xfs_rmap_lookup_le(cur, bno, len, owner, offset, flags, &i);
233         if (error)
234                 goto out_error;
235         XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error);
236
237         error = xfs_rmap_get_rec(cur, &ltrec, &i);
238         if (error)
239                 goto out_error;
240         XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error);
241         trace_xfs_rmap_lookup_le_range_result(cur->bc_mp,
242                         cur->bc_private.a.agno, ltrec.rm_startblock,
243                         ltrec.rm_blockcount, ltrec.rm_owner,
244                         ltrec.rm_offset, ltrec.rm_flags);
245         ltoff = ltrec.rm_offset;
246
247         /*
248          * For growfs, the incoming extent must be beyond the left record we
249          * just found as it is new space and won't be used by anyone. This is
250          * just a corruption check as we don't actually do anything with this
251          * extent.  Note that we need to use >= instead of > because it might
252          * be the case that the "left" extent goes all the way to EOFS.
253          */
254         if (owner == XFS_RMAP_OWN_NULL) {
255                 XFS_WANT_CORRUPTED_GOTO(mp, bno >= ltrec.rm_startblock +
256                                                 ltrec.rm_blockcount, out_error);
257                 goto out_done;
258         }
259
260         /* Make sure the unwritten flag matches. */
261         XFS_WANT_CORRUPTED_GOTO(mp, (flags & XFS_RMAP_UNWRITTEN) ==
262                         (ltrec.rm_flags & XFS_RMAP_UNWRITTEN), out_error);
263
264         /* Make sure the extent we found covers the entire freeing range. */
265         XFS_WANT_CORRUPTED_GOTO(mp, ltrec.rm_startblock <= bno &&
266                 ltrec.rm_startblock + ltrec.rm_blockcount >=
267                 bno + len, out_error);
268
269         /* Make sure the owner matches what we expect to find in the tree. */
270         XFS_WANT_CORRUPTED_GOTO(mp, owner == ltrec.rm_owner ||
271                                     XFS_RMAP_NON_INODE_OWNER(owner), out_error);
272
273         /* Check the offset, if necessary. */
274         if (!XFS_RMAP_NON_INODE_OWNER(owner)) {
275                 if (flags & XFS_RMAP_BMBT_BLOCK) {
276                         XFS_WANT_CORRUPTED_GOTO(mp,
277                                         ltrec.rm_flags & XFS_RMAP_BMBT_BLOCK,
278                                         out_error);
279                 } else {
280                         XFS_WANT_CORRUPTED_GOTO(mp,
281                                         ltrec.rm_offset <= offset, out_error);
282                         XFS_WANT_CORRUPTED_GOTO(mp,
283                                         ltoff + ltrec.rm_blockcount >= offset + len,
284                                         out_error);
285                 }
286         }
287
288         if (ltrec.rm_startblock == bno && ltrec.rm_blockcount == len) {
289                 /* exact match, simply remove the record from rmap tree */
290                 trace_xfs_rmap_delete(mp, cur->bc_private.a.agno,
291                                 ltrec.rm_startblock, ltrec.rm_blockcount,
292                                 ltrec.rm_owner, ltrec.rm_offset,
293                                 ltrec.rm_flags);
294                 error = xfs_btree_delete(cur, &i);
295                 if (error)
296                         goto out_error;
297                 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error);
298         } else if (ltrec.rm_startblock == bno) {
299                 /*
300                  * overlap left hand side of extent: move the start, trim the
301                  * length and update the current record.
302                  *
303                  *       ltbno                ltlen
304                  * Orig:    |oooooooooooooooooooo|
305                  * Freeing: |fffffffff|
306                  * Result:            |rrrrrrrrrr|
307                  *         bno       len
308                  */
309                 ltrec.rm_startblock += len;
310                 ltrec.rm_blockcount -= len;
311                 if (!ignore_off)
312                         ltrec.rm_offset += len;
313                 error = xfs_rmap_update(cur, &ltrec);
314                 if (error)
315                         goto out_error;
316         } else if (ltrec.rm_startblock + ltrec.rm_blockcount == bno + len) {
317                 /*
318                  * overlap right hand side of extent: trim the length and update
319                  * the current record.
320                  *
321                  *       ltbno                ltlen
322                  * Orig:    |oooooooooooooooooooo|
323                  * Freeing:            |fffffffff|
324                  * Result:  |rrrrrrrrrr|
325                  *                    bno       len
326                  */
327                 ltrec.rm_blockcount -= len;
328                 error = xfs_rmap_update(cur, &ltrec);
329                 if (error)
330                         goto out_error;
331         } else {
332
333                 /*
334                  * overlap middle of extent: trim the length of the existing
335                  * record to the length of the new left-extent size, increment
336                  * the insertion position so we can insert a new record
337                  * containing the remaining right-extent space.
338                  *
339                  *       ltbno                ltlen
340                  * Orig:    |oooooooooooooooooooo|
341                  * Freeing:       |fffffffff|
342                  * Result:  |rrrrr|         |rrrr|
343                  *               bno       len
344                  */
345                 xfs_extlen_t    orig_len = ltrec.rm_blockcount;
346
347                 ltrec.rm_blockcount = bno - ltrec.rm_startblock;
348                 error = xfs_rmap_update(cur, &ltrec);
349                 if (error)
350                         goto out_error;
351
352                 error = xfs_btree_increment(cur, 0, &i);
353                 if (error)
354                         goto out_error;
355
356                 cur->bc_rec.r.rm_startblock = bno + len;
357                 cur->bc_rec.r.rm_blockcount = orig_len - len -
358                                                      ltrec.rm_blockcount;
359                 cur->bc_rec.r.rm_owner = ltrec.rm_owner;
360                 if (ignore_off)
361                         cur->bc_rec.r.rm_offset = 0;
362                 else
363                         cur->bc_rec.r.rm_offset = offset + len;
364                 cur->bc_rec.r.rm_flags = flags;
365                 trace_xfs_rmap_insert(mp, cur->bc_private.a.agno,
366                                 cur->bc_rec.r.rm_startblock,
367                                 cur->bc_rec.r.rm_blockcount,
368                                 cur->bc_rec.r.rm_owner,
369                                 cur->bc_rec.r.rm_offset,
370                                 cur->bc_rec.r.rm_flags);
371                 error = xfs_btree_insert(cur, &i);
372                 if (error)
373                         goto out_error;
374         }
375
376 out_done:
377         trace_xfs_rmap_unmap_done(mp, cur->bc_private.a.agno, bno, len,
378                         unwritten, oinfo);
379 out_error:
380         if (error)
381                 trace_xfs_rmap_unmap_error(mp, cur->bc_private.a.agno,
382                                 error, _RET_IP_);
383         return error;
384 }
385
386 /*
387  * Remove a reference to an extent in the rmap btree.
388  */
389 int
390 xfs_rmap_free(
391         struct xfs_trans        *tp,
392         struct xfs_buf          *agbp,
393         xfs_agnumber_t          agno,
394         xfs_agblock_t           bno,
395         xfs_extlen_t            len,
396         struct xfs_owner_info   *oinfo)
397 {
398         struct xfs_mount        *mp = tp->t_mountp;
399         struct xfs_btree_cur    *cur;
400         int                     error;
401
402         if (!xfs_sb_version_hasrmapbt(&mp->m_sb))
403                 return 0;
404
405         cur = xfs_rmapbt_init_cursor(mp, tp, agbp, agno);
406
407         error = xfs_rmap_unmap(cur, bno, len, false, oinfo);
408         if (error)
409                 goto out_error;
410
411         xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
412         return 0;
413
414 out_error:
415         xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
416         return error;
417 }
418
419 /*
420  * A mergeable rmap must have the same owner and the same values for
421  * the unwritten, attr_fork, and bmbt flags.  The startblock and
422  * offset are checked separately.
423  */
424 static bool
425 xfs_rmap_is_mergeable(
426         struct xfs_rmap_irec    *irec,
427         uint64_t                owner,
428         unsigned int            flags)
429 {
430         if (irec->rm_owner == XFS_RMAP_OWN_NULL)
431                 return false;
432         if (irec->rm_owner != owner)
433                 return false;
434         if ((flags & XFS_RMAP_UNWRITTEN) ^
435             (irec->rm_flags & XFS_RMAP_UNWRITTEN))
436                 return false;
437         if ((flags & XFS_RMAP_ATTR_FORK) ^
438             (irec->rm_flags & XFS_RMAP_ATTR_FORK))
439                 return false;
440         if ((flags & XFS_RMAP_BMBT_BLOCK) ^
441             (irec->rm_flags & XFS_RMAP_BMBT_BLOCK))
442                 return false;
443         return true;
444 }
445
446 /*
447  * When we allocate a new block, the first thing we do is add a reference to
448  * the extent in the rmap btree. This takes the form of a [agbno, length,
449  * owner, offset] record.  Flags are encoded in the high bits of the offset
450  * field.
451  */
452 STATIC int
453 xfs_rmap_map(
454         struct xfs_btree_cur    *cur,
455         xfs_agblock_t           bno,
456         xfs_extlen_t            len,
457         bool                    unwritten,
458         struct xfs_owner_info   *oinfo)
459 {
460         struct xfs_mount        *mp = cur->bc_mp;
461         struct xfs_rmap_irec    ltrec;
462         struct xfs_rmap_irec    gtrec;
463         int                     have_gt;
464         int                     have_lt;
465         int                     error = 0;
466         int                     i;
467         uint64_t                owner;
468         uint64_t                offset;
469         unsigned int            flags = 0;
470         bool                    ignore_off;
471
472         xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
473         ASSERT(owner != 0);
474         ignore_off = XFS_RMAP_NON_INODE_OWNER(owner) ||
475                         (flags & XFS_RMAP_BMBT_BLOCK);
476         if (unwritten)
477                 flags |= XFS_RMAP_UNWRITTEN;
478         trace_xfs_rmap_map(mp, cur->bc_private.a.agno, bno, len,
479                         unwritten, oinfo);
480
481         /*
482          * For the initial lookup, look for an exact match or the left-adjacent
483          * record for our insertion point. This will also give us the record for
484          * start block contiguity tests.
485          */
486         error = xfs_rmap_lookup_le(cur, bno, len, owner, offset, flags,
487                         &have_lt);
488         if (error)
489                 goto out_error;
490         XFS_WANT_CORRUPTED_GOTO(mp, have_lt == 1, out_error);
491
492         error = xfs_rmap_get_rec(cur, &ltrec, &have_lt);
493         if (error)
494                 goto out_error;
495         XFS_WANT_CORRUPTED_GOTO(mp, have_lt == 1, out_error);
496         trace_xfs_rmap_lookup_le_range_result(cur->bc_mp,
497                         cur->bc_private.a.agno, ltrec.rm_startblock,
498                         ltrec.rm_blockcount, ltrec.rm_owner,
499                         ltrec.rm_offset, ltrec.rm_flags);
500
501         if (!xfs_rmap_is_mergeable(&ltrec, owner, flags))
502                 have_lt = 0;
503
504         XFS_WANT_CORRUPTED_GOTO(mp,
505                 have_lt == 0 ||
506                 ltrec.rm_startblock + ltrec.rm_blockcount <= bno, out_error);
507
508         /*
509          * Increment the cursor to see if we have a right-adjacent record to our
510          * insertion point. This will give us the record for end block
511          * contiguity tests.
512          */
513         error = xfs_btree_increment(cur, 0, &have_gt);
514         if (error)
515                 goto out_error;
516         if (have_gt) {
517                 error = xfs_rmap_get_rec(cur, &gtrec, &have_gt);
518                 if (error)
519                         goto out_error;
520                 XFS_WANT_CORRUPTED_GOTO(mp, have_gt == 1, out_error);
521                 XFS_WANT_CORRUPTED_GOTO(mp, bno + len <= gtrec.rm_startblock,
522                                         out_error);
523                 trace_xfs_rmap_find_right_neighbor_result(cur->bc_mp,
524                         cur->bc_private.a.agno, gtrec.rm_startblock,
525                         gtrec.rm_blockcount, gtrec.rm_owner,
526                         gtrec.rm_offset, gtrec.rm_flags);
527                 if (!xfs_rmap_is_mergeable(&gtrec, owner, flags))
528                         have_gt = 0;
529         }
530
531         /*
532          * Note: cursor currently points one record to the right of ltrec, even
533          * if there is no record in the tree to the right.
534          */
535         if (have_lt &&
536             ltrec.rm_startblock + ltrec.rm_blockcount == bno &&
537             (ignore_off || ltrec.rm_offset + ltrec.rm_blockcount == offset)) {
538                 /*
539                  * left edge contiguous, merge into left record.
540                  *
541                  *       ltbno     ltlen
542                  * orig:   |ooooooooo|
543                  * adding:           |aaaaaaaaa|
544                  * result: |rrrrrrrrrrrrrrrrrrr|
545                  *                  bno       len
546                  */
547                 ltrec.rm_blockcount += len;
548                 if (have_gt &&
549                     bno + len == gtrec.rm_startblock &&
550                     (ignore_off || offset + len == gtrec.rm_offset) &&
551                     (unsigned long)ltrec.rm_blockcount + len +
552                                 gtrec.rm_blockcount <= XFS_RMAP_LEN_MAX) {
553                         /*
554                          * right edge also contiguous, delete right record
555                          * and merge into left record.
556                          *
557                          *       ltbno     ltlen    gtbno     gtlen
558                          * orig:   |ooooooooo|         |ooooooooo|
559                          * adding:           |aaaaaaaaa|
560                          * result: |rrrrrrrrrrrrrrrrrrrrrrrrrrrrr|
561                          */
562                         ltrec.rm_blockcount += gtrec.rm_blockcount;
563                         trace_xfs_rmap_delete(mp, cur->bc_private.a.agno,
564                                         gtrec.rm_startblock,
565                                         gtrec.rm_blockcount,
566                                         gtrec.rm_owner,
567                                         gtrec.rm_offset,
568                                         gtrec.rm_flags);
569                         error = xfs_btree_delete(cur, &i);
570                         if (error)
571                                 goto out_error;
572                         XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error);
573                 }
574
575                 /* point the cursor back to the left record and update */
576                 error = xfs_btree_decrement(cur, 0, &have_gt);
577                 if (error)
578                         goto out_error;
579                 error = xfs_rmap_update(cur, &ltrec);
580                 if (error)
581                         goto out_error;
582         } else if (have_gt &&
583                    bno + len == gtrec.rm_startblock &&
584                    (ignore_off || offset + len == gtrec.rm_offset)) {
585                 /*
586                  * right edge contiguous, merge into right record.
587                  *
588                  *                 gtbno     gtlen
589                  * Orig:             |ooooooooo|
590                  * adding: |aaaaaaaaa|
591                  * Result: |rrrrrrrrrrrrrrrrrrr|
592                  *        bno       len
593                  */
594                 gtrec.rm_startblock = bno;
595                 gtrec.rm_blockcount += len;
596                 if (!ignore_off)
597                         gtrec.rm_offset = offset;
598                 error = xfs_rmap_update(cur, &gtrec);
599                 if (error)
600                         goto out_error;
601         } else {
602                 /*
603                  * no contiguous edge with identical owner, insert
604                  * new record at current cursor position.
605                  */
606                 cur->bc_rec.r.rm_startblock = bno;
607                 cur->bc_rec.r.rm_blockcount = len;
608                 cur->bc_rec.r.rm_owner = owner;
609                 cur->bc_rec.r.rm_offset = offset;
610                 cur->bc_rec.r.rm_flags = flags;
611                 trace_xfs_rmap_insert(mp, cur->bc_private.a.agno, bno, len,
612                         owner, offset, flags);
613                 error = xfs_btree_insert(cur, &i);
614                 if (error)
615                         goto out_error;
616                 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error);
617         }
618
619         trace_xfs_rmap_map_done(mp, cur->bc_private.a.agno, bno, len,
620                         unwritten, oinfo);
621 out_error:
622         if (error)
623                 trace_xfs_rmap_map_error(mp, cur->bc_private.a.agno,
624                                 error, _RET_IP_);
625         return error;
626 }
627
628 /*
629  * Add a reference to an extent in the rmap btree.
630  */
631 int
632 xfs_rmap_alloc(
633         struct xfs_trans        *tp,
634         struct xfs_buf          *agbp,
635         xfs_agnumber_t          agno,
636         xfs_agblock_t           bno,
637         xfs_extlen_t            len,
638         struct xfs_owner_info   *oinfo)
639 {
640         struct xfs_mount        *mp = tp->t_mountp;
641         struct xfs_btree_cur    *cur;
642         int                     error;
643
644         if (!xfs_sb_version_hasrmapbt(&mp->m_sb))
645                 return 0;
646
647         cur = xfs_rmapbt_init_cursor(mp, tp, agbp, agno);
648         error = xfs_rmap_map(cur, bno, len, false, oinfo);
649         if (error)
650                 goto out_error;
651
652         xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
653         return 0;
654
655 out_error:
656         xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
657         return error;
658 }
659
660 #define RMAP_LEFT_CONTIG        (1 << 0)
661 #define RMAP_RIGHT_CONTIG       (1 << 1)
662 #define RMAP_LEFT_FILLING       (1 << 2)
663 #define RMAP_RIGHT_FILLING      (1 << 3)
664 #define RMAP_LEFT_VALID         (1 << 6)
665 #define RMAP_RIGHT_VALID        (1 << 7)
666
667 #define LEFT            r[0]
668 #define RIGHT           r[1]
669 #define PREV            r[2]
670 #define NEW             r[3]
671
672 /*
673  * Convert an unwritten extent to a real extent or vice versa.
674  * Does not handle overlapping extents.
675  */
676 STATIC int
677 xfs_rmap_convert(
678         struct xfs_btree_cur    *cur,
679         xfs_agblock_t           bno,
680         xfs_extlen_t            len,
681         bool                    unwritten,
682         struct xfs_owner_info   *oinfo)
683 {
684         struct xfs_mount        *mp = cur->bc_mp;
685         struct xfs_rmap_irec    r[4];   /* neighbor extent entries */
686                                         /* left is 0, right is 1, prev is 2 */
687                                         /* new is 3 */
688         uint64_t                owner;
689         uint64_t                offset;
690         uint64_t                new_endoff;
691         unsigned int            oldext;
692         unsigned int            newext;
693         unsigned int            flags = 0;
694         int                     i;
695         int                     state = 0;
696         int                     error;
697
698         xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
699         ASSERT(!(XFS_RMAP_NON_INODE_OWNER(owner) ||
700                         (flags & (XFS_RMAP_ATTR_FORK | XFS_RMAP_BMBT_BLOCK))));
701         oldext = unwritten ? XFS_RMAP_UNWRITTEN : 0;
702         new_endoff = offset + len;
703         trace_xfs_rmap_convert(mp, cur->bc_private.a.agno, bno, len,
704                         unwritten, oinfo);
705
706         /*
707          * For the initial lookup, look for an exact match or the left-adjacent
708          * record for our insertion point. This will also give us the record for
709          * start block contiguity tests.
710          */
711         error = xfs_rmap_lookup_le(cur, bno, len, owner, offset, oldext, &i);
712         if (error)
713                 goto done;
714         XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
715
716         error = xfs_rmap_get_rec(cur, &PREV, &i);
717         if (error)
718                 goto done;
719         XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
720         trace_xfs_rmap_lookup_le_range_result(cur->bc_mp,
721                         cur->bc_private.a.agno, PREV.rm_startblock,
722                         PREV.rm_blockcount, PREV.rm_owner,
723                         PREV.rm_offset, PREV.rm_flags);
724
725         ASSERT(PREV.rm_offset <= offset);
726         ASSERT(PREV.rm_offset + PREV.rm_blockcount >= new_endoff);
727         ASSERT((PREV.rm_flags & XFS_RMAP_UNWRITTEN) == oldext);
728         newext = ~oldext & XFS_RMAP_UNWRITTEN;
729
730         /*
731          * Set flags determining what part of the previous oldext allocation
732          * extent is being replaced by a newext allocation.
733          */
734         if (PREV.rm_offset == offset)
735                 state |= RMAP_LEFT_FILLING;
736         if (PREV.rm_offset + PREV.rm_blockcount == new_endoff)
737                 state |= RMAP_RIGHT_FILLING;
738
739         /*
740          * Decrement the cursor to see if we have a left-adjacent record to our
741          * insertion point. This will give us the record for end block
742          * contiguity tests.
743          */
744         error = xfs_btree_decrement(cur, 0, &i);
745         if (error)
746                 goto done;
747         if (i) {
748                 state |= RMAP_LEFT_VALID;
749                 error = xfs_rmap_get_rec(cur, &LEFT, &i);
750                 if (error)
751                         goto done;
752                 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
753                 XFS_WANT_CORRUPTED_GOTO(mp,
754                                 LEFT.rm_startblock + LEFT.rm_blockcount <= bno,
755                                 done);
756                 trace_xfs_rmap_find_left_neighbor_result(cur->bc_mp,
757                                 cur->bc_private.a.agno, LEFT.rm_startblock,
758                                 LEFT.rm_blockcount, LEFT.rm_owner,
759                                 LEFT.rm_offset, LEFT.rm_flags);
760                 if (LEFT.rm_startblock + LEFT.rm_blockcount == bno &&
761                     LEFT.rm_offset + LEFT.rm_blockcount == offset &&
762                     xfs_rmap_is_mergeable(&LEFT, owner, newext))
763                         state |= RMAP_LEFT_CONTIG;
764         }
765
766         /*
767          * Increment the cursor to see if we have a right-adjacent record to our
768          * insertion point. This will give us the record for end block
769          * contiguity tests.
770          */
771         error = xfs_btree_increment(cur, 0, &i);
772         if (error)
773                 goto done;
774         XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
775         error = xfs_btree_increment(cur, 0, &i);
776         if (error)
777                 goto done;
778         if (i) {
779                 state |= RMAP_RIGHT_VALID;
780                 error = xfs_rmap_get_rec(cur, &RIGHT, &i);
781                 if (error)
782                         goto done;
783                 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
784                 XFS_WANT_CORRUPTED_GOTO(mp, bno + len <= RIGHT.rm_startblock,
785                                         done);
786                 trace_xfs_rmap_find_right_neighbor_result(cur->bc_mp,
787                                 cur->bc_private.a.agno, RIGHT.rm_startblock,
788                                 RIGHT.rm_blockcount, RIGHT.rm_owner,
789                                 RIGHT.rm_offset, RIGHT.rm_flags);
790                 if (bno + len == RIGHT.rm_startblock &&
791                     offset + len == RIGHT.rm_offset &&
792                     xfs_rmap_is_mergeable(&RIGHT, owner, newext))
793                         state |= RMAP_RIGHT_CONTIG;
794         }
795
796         /* check that left + prev + right is not too long */
797         if ((state & (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
798                          RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG)) ==
799             (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
800              RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG) &&
801             (unsigned long)LEFT.rm_blockcount + len +
802              RIGHT.rm_blockcount > XFS_RMAP_LEN_MAX)
803                 state &= ~RMAP_RIGHT_CONTIG;
804
805         trace_xfs_rmap_convert_state(mp, cur->bc_private.a.agno, state,
806                         _RET_IP_);
807
808         /* reset the cursor back to PREV */
809         error = xfs_rmap_lookup_le(cur, bno, len, owner, offset, oldext, &i);
810         if (error)
811                 goto done;
812         XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
813
814         /*
815          * Switch out based on the FILLING and CONTIG state bits.
816          */
817         switch (state & (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
818                          RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG)) {
819         case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
820              RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG:
821                 /*
822                  * Setting all of a previous oldext extent to newext.
823                  * The left and right neighbors are both contiguous with new.
824                  */
825                 error = xfs_btree_increment(cur, 0, &i);
826                 if (error)
827                         goto done;
828                 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
829                 trace_xfs_rmap_delete(mp, cur->bc_private.a.agno,
830                                 RIGHT.rm_startblock, RIGHT.rm_blockcount,
831                                 RIGHT.rm_owner, RIGHT.rm_offset,
832                                 RIGHT.rm_flags);
833                 error = xfs_btree_delete(cur, &i);
834                 if (error)
835                         goto done;
836                 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
837                 error = xfs_btree_decrement(cur, 0, &i);
838                 if (error)
839                         goto done;
840                 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
841                 trace_xfs_rmap_delete(mp, cur->bc_private.a.agno,
842                                 PREV.rm_startblock, PREV.rm_blockcount,
843                                 PREV.rm_owner, PREV.rm_offset,
844                                 PREV.rm_flags);
845                 error = xfs_btree_delete(cur, &i);
846                 if (error)
847                         goto done;
848                 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
849                 error = xfs_btree_decrement(cur, 0, &i);
850                 if (error)
851                         goto done;
852                 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
853                 NEW = LEFT;
854                 NEW.rm_blockcount += PREV.rm_blockcount + RIGHT.rm_blockcount;
855                 error = xfs_rmap_update(cur, &NEW);
856                 if (error)
857                         goto done;
858                 break;
859
860         case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG:
861                 /*
862                  * Setting all of a previous oldext extent to newext.
863                  * The left neighbor is contiguous, the right is not.
864                  */
865                 trace_xfs_rmap_delete(mp, cur->bc_private.a.agno,
866                                 PREV.rm_startblock, PREV.rm_blockcount,
867                                 PREV.rm_owner, PREV.rm_offset,
868                                 PREV.rm_flags);
869                 error = xfs_btree_delete(cur, &i);
870                 if (error)
871                         goto done;
872                 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
873                 error = xfs_btree_decrement(cur, 0, &i);
874                 if (error)
875                         goto done;
876                 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
877                 NEW = LEFT;
878                 NEW.rm_blockcount += PREV.rm_blockcount;
879                 error = xfs_rmap_update(cur, &NEW);
880                 if (error)
881                         goto done;
882                 break;
883
884         case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG:
885                 /*
886                  * Setting all of a previous oldext extent to newext.
887                  * The right neighbor is contiguous, the left is not.
888                  */
889                 error = xfs_btree_increment(cur, 0, &i);
890                 if (error)
891                         goto done;
892                 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
893                 trace_xfs_rmap_delete(mp, cur->bc_private.a.agno,
894                                 RIGHT.rm_startblock, RIGHT.rm_blockcount,
895                                 RIGHT.rm_owner, RIGHT.rm_offset,
896                                 RIGHT.rm_flags);
897                 error = xfs_btree_delete(cur, &i);
898                 if (error)
899                         goto done;
900                 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
901                 error = xfs_btree_decrement(cur, 0, &i);
902                 if (error)
903                         goto done;
904                 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
905                 NEW = PREV;
906                 NEW.rm_blockcount = len + RIGHT.rm_blockcount;
907                 NEW.rm_flags = newext;
908                 error = xfs_rmap_update(cur, &NEW);
909                 if (error)
910                         goto done;
911                 break;
912
913         case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING:
914                 /*
915                  * Setting all of a previous oldext extent to newext.
916                  * Neither the left nor right neighbors are contiguous with
917                  * the new one.
918                  */
919                 NEW = PREV;
920                 NEW.rm_flags = newext;
921                 error = xfs_rmap_update(cur, &NEW);
922                 if (error)
923                         goto done;
924                 break;
925
926         case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG:
927                 /*
928                  * Setting the first part of a previous oldext extent to newext.
929                  * The left neighbor is contiguous.
930                  */
931                 NEW = PREV;
932                 NEW.rm_offset += len;
933                 NEW.rm_startblock += len;
934                 NEW.rm_blockcount -= len;
935                 error = xfs_rmap_update(cur, &NEW);
936                 if (error)
937                         goto done;
938                 error = xfs_btree_decrement(cur, 0, &i);
939                 if (error)
940                         goto done;
941                 NEW = LEFT;
942                 NEW.rm_blockcount += len;
943                 error = xfs_rmap_update(cur, &NEW);
944                 if (error)
945                         goto done;
946                 break;
947
948         case RMAP_LEFT_FILLING:
949                 /*
950                  * Setting the first part of a previous oldext extent to newext.
951                  * The left neighbor is not contiguous.
952                  */
953                 NEW = PREV;
954                 NEW.rm_startblock += len;
955                 NEW.rm_offset += len;
956                 NEW.rm_blockcount -= len;
957                 error = xfs_rmap_update(cur, &NEW);
958                 if (error)
959                         goto done;
960                 NEW.rm_startblock = bno;
961                 NEW.rm_owner = owner;
962                 NEW.rm_offset = offset;
963                 NEW.rm_blockcount = len;
964                 NEW.rm_flags = newext;
965                 cur->bc_rec.r = NEW;
966                 trace_xfs_rmap_insert(mp, cur->bc_private.a.agno, bno,
967                                 len, owner, offset, newext);
968                 error = xfs_btree_insert(cur, &i);
969                 if (error)
970                         goto done;
971                 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
972                 break;
973
974         case RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG:
975                 /*
976                  * Setting the last part of a previous oldext extent to newext.
977                  * The right neighbor is contiguous with the new allocation.
978                  */
979                 NEW = PREV;
980                 NEW.rm_blockcount -= len;
981                 error = xfs_rmap_update(cur, &NEW);
982                 if (error)
983                         goto done;
984                 error = xfs_btree_increment(cur, 0, &i);
985                 if (error)
986                         goto done;
987                 NEW = RIGHT;
988                 NEW.rm_offset = offset;
989                 NEW.rm_startblock = bno;
990                 NEW.rm_blockcount += len;
991                 error = xfs_rmap_update(cur, &NEW);
992                 if (error)
993                         goto done;
994                 break;
995
996         case RMAP_RIGHT_FILLING:
997                 /*
998                  * Setting the last part of a previous oldext extent to newext.
999                  * The right neighbor is not contiguous.
1000                  */
1001                 NEW = PREV;
1002                 NEW.rm_blockcount -= len;
1003                 error = xfs_rmap_update(cur, &NEW);
1004                 if (error)
1005                         goto done;
1006                 error = xfs_rmap_lookup_eq(cur, bno, len, owner, offset,
1007                                 oldext, &i);
1008                 if (error)
1009                         goto done;
1010                 XFS_WANT_CORRUPTED_GOTO(mp, i == 0, done);
1011                 NEW.rm_startblock = bno;
1012                 NEW.rm_owner = owner;
1013                 NEW.rm_offset = offset;
1014                 NEW.rm_blockcount = len;
1015                 NEW.rm_flags = newext;
1016                 cur->bc_rec.r = NEW;
1017                 trace_xfs_rmap_insert(mp, cur->bc_private.a.agno, bno,
1018                                 len, owner, offset, newext);
1019                 error = xfs_btree_insert(cur, &i);
1020                 if (error)
1021                         goto done;
1022                 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1023                 break;
1024
1025         case 0:
1026                 /*
1027                  * Setting the middle part of a previous oldext extent to
1028                  * newext.  Contiguity is impossible here.
1029                  * One extent becomes three extents.
1030                  */
1031                 /* new right extent - oldext */
1032                 NEW.rm_startblock = bno + len;
1033                 NEW.rm_owner = owner;
1034                 NEW.rm_offset = new_endoff;
1035                 NEW.rm_blockcount = PREV.rm_offset + PREV.rm_blockcount -
1036                                 new_endoff;
1037                 NEW.rm_flags = PREV.rm_flags;
1038                 error = xfs_rmap_update(cur, &NEW);
1039                 if (error)
1040                         goto done;
1041                 /* new left extent - oldext */
1042                 NEW = PREV;
1043                 NEW.rm_blockcount = offset - PREV.rm_offset;
1044                 cur->bc_rec.r = NEW;
1045                 trace_xfs_rmap_insert(mp, cur->bc_private.a.agno,
1046                                 NEW.rm_startblock, NEW.rm_blockcount,
1047                                 NEW.rm_owner, NEW.rm_offset,
1048                                 NEW.rm_flags);
1049                 error = xfs_btree_insert(cur, &i);
1050                 if (error)
1051                         goto done;
1052                 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1053                 /*
1054                  * Reset the cursor to the position of the new extent
1055                  * we are about to insert as we can't trust it after
1056                  * the previous insert.
1057                  */
1058                 error = xfs_rmap_lookup_eq(cur, bno, len, owner, offset,
1059                                 oldext, &i);
1060                 if (error)
1061                         goto done;
1062                 XFS_WANT_CORRUPTED_GOTO(mp, i == 0, done);
1063                 /* new middle extent - newext */
1064                 cur->bc_rec.r.rm_flags &= ~XFS_RMAP_UNWRITTEN;
1065                 cur->bc_rec.r.rm_flags |= newext;
1066                 trace_xfs_rmap_insert(mp, cur->bc_private.a.agno, bno, len,
1067                                 owner, offset, newext);
1068                 error = xfs_btree_insert(cur, &i);
1069                 if (error)
1070                         goto done;
1071                 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1072                 break;
1073
1074         case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG:
1075         case RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG:
1076         case RMAP_LEFT_FILLING | RMAP_RIGHT_CONTIG:
1077         case RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG:
1078         case RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG:
1079         case RMAP_LEFT_CONTIG:
1080         case RMAP_RIGHT_CONTIG:
1081                 /*
1082                  * These cases are all impossible.
1083                  */
1084                 ASSERT(0);
1085         }
1086
1087         trace_xfs_rmap_convert_done(mp, cur->bc_private.a.agno, bno, len,
1088                         unwritten, oinfo);
1089 done:
1090         if (error)
1091                 trace_xfs_rmap_convert_error(cur->bc_mp,
1092                                 cur->bc_private.a.agno, error, _RET_IP_);
1093         return error;
1094 }
1095
1096 #undef  NEW
1097 #undef  LEFT
1098 #undef  RIGHT
1099 #undef  PREV
1100
1101 struct xfs_rmap_query_range_info {
1102         xfs_rmap_query_range_fn fn;
1103         void                            *priv;
1104 };
1105
1106 /* Format btree record and pass to our callback. */
1107 STATIC int
1108 xfs_rmap_query_range_helper(
1109         struct xfs_btree_cur    *cur,
1110         union xfs_btree_rec     *rec,
1111         void                    *priv)
1112 {
1113         struct xfs_rmap_query_range_info        *query = priv;
1114         struct xfs_rmap_irec                    irec;
1115         int                                     error;
1116
1117         error = xfs_rmap_btrec_to_irec(rec, &irec);
1118         if (error)
1119                 return error;
1120         return query->fn(cur, &irec, query->priv);
1121 }
1122
1123 /* Find all rmaps between two keys. */
1124 int
1125 xfs_rmap_query_range(
1126         struct xfs_btree_cur            *cur,
1127         struct xfs_rmap_irec            *low_rec,
1128         struct xfs_rmap_irec            *high_rec,
1129         xfs_rmap_query_range_fn fn,
1130         void                            *priv)
1131 {
1132         union xfs_btree_irec            low_brec;
1133         union xfs_btree_irec            high_brec;
1134         struct xfs_rmap_query_range_info        query;
1135
1136         low_brec.r = *low_rec;
1137         high_brec.r = *high_rec;
1138         query.priv = priv;
1139         query.fn = fn;
1140         return xfs_btree_query_range(cur, &low_brec, &high_brec,
1141                         xfs_rmap_query_range_helper, &query);
1142 }
1143
1144 /* Clean up after calling xfs_rmap_finish_one. */
1145 void
1146 xfs_rmap_finish_one_cleanup(
1147         struct xfs_trans        *tp,
1148         struct xfs_btree_cur    *rcur,
1149         int                     error)
1150 {
1151         struct xfs_buf          *agbp;
1152
1153         if (rcur == NULL)
1154                 return;
1155         agbp = rcur->bc_private.a.agbp;
1156         xfs_btree_del_cursor(rcur, error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR);
1157         if (error)
1158                 xfs_trans_brelse(tp, agbp);
1159 }
1160
1161 /*
1162  * Process one of the deferred rmap operations.  We pass back the
1163  * btree cursor to maintain our lock on the rmapbt between calls.
1164  * This saves time and eliminates a buffer deadlock between the
1165  * superblock and the AGF because we'll always grab them in the same
1166  * order.
1167  */
1168 int
1169 xfs_rmap_finish_one(
1170         struct xfs_trans                *tp,
1171         enum xfs_rmap_intent_type       type,
1172         __uint64_t                      owner,
1173         int                             whichfork,
1174         xfs_fileoff_t                   startoff,
1175         xfs_fsblock_t                   startblock,
1176         xfs_filblks_t                   blockcount,
1177         xfs_exntst_t                    state,
1178         struct xfs_btree_cur            **pcur)
1179 {
1180         struct xfs_mount                *mp = tp->t_mountp;
1181         struct xfs_btree_cur            *rcur;
1182         struct xfs_buf                  *agbp = NULL;
1183         int                             error = 0;
1184         xfs_agnumber_t                  agno;
1185         struct xfs_owner_info           oinfo;
1186         xfs_agblock_t                   bno;
1187         bool                            unwritten;
1188
1189         agno = XFS_FSB_TO_AGNO(mp, startblock);
1190         ASSERT(agno != NULLAGNUMBER);
1191         bno = XFS_FSB_TO_AGBNO(mp, startblock);
1192
1193         trace_xfs_rmap_deferred(mp, agno, type, bno, owner, whichfork,
1194                         startoff, blockcount, state);
1195
1196         if (XFS_TEST_ERROR(false, mp,
1197                         XFS_ERRTAG_RMAP_FINISH_ONE,
1198                         XFS_RANDOM_RMAP_FINISH_ONE))
1199                 return -EIO;
1200
1201         /*
1202          * If we haven't gotten a cursor or the cursor AG doesn't match
1203          * the startblock, get one now.
1204          */
1205         rcur = *pcur;
1206         if (rcur != NULL && rcur->bc_private.a.agno != agno) {
1207                 xfs_rmap_finish_one_cleanup(tp, rcur, 0);
1208                 rcur = NULL;
1209                 *pcur = NULL;
1210         }
1211         if (rcur == NULL) {
1212                 /*
1213                  * Refresh the freelist before we start changing the
1214                  * rmapbt, because a shape change could cause us to
1215                  * allocate blocks.
1216                  */
1217                 error = xfs_free_extent_fix_freelist(tp, agno, &agbp);
1218                 if (error)
1219                         return error;
1220                 if (!agbp)
1221                         return -EFSCORRUPTED;
1222
1223                 rcur = xfs_rmapbt_init_cursor(mp, tp, agbp, agno);
1224                 if (!rcur) {
1225                         error = -ENOMEM;
1226                         goto out_cur;
1227                 }
1228         }
1229         *pcur = rcur;
1230
1231         xfs_rmap_ino_owner(&oinfo, owner, whichfork, startoff);
1232         unwritten = state == XFS_EXT_UNWRITTEN;
1233         bno = XFS_FSB_TO_AGBNO(rcur->bc_mp, startblock);
1234
1235         switch (type) {
1236         case XFS_RMAP_ALLOC:
1237         case XFS_RMAP_MAP:
1238                 error = xfs_rmap_map(rcur, bno, blockcount, unwritten, &oinfo);
1239                 break;
1240         case XFS_RMAP_FREE:
1241         case XFS_RMAP_UNMAP:
1242                 error = xfs_rmap_unmap(rcur, bno, blockcount, unwritten,
1243                                 &oinfo);
1244                 break;
1245         case XFS_RMAP_CONVERT:
1246                 error = xfs_rmap_convert(rcur, bno, blockcount, !unwritten,
1247                                 &oinfo);
1248                 break;
1249         default:
1250                 ASSERT(0);
1251                 error = -EFSCORRUPTED;
1252         }
1253         return error;
1254
1255 out_cur:
1256         xfs_trans_brelse(tp, agbp);
1257
1258         return error;
1259 }
1260
1261 /*
1262  * Don't defer an rmap if we aren't an rmap filesystem.
1263  */
1264 static bool
1265 xfs_rmap_update_is_needed(
1266         struct xfs_mount        *mp)
1267 {
1268         return xfs_sb_version_hasrmapbt(&mp->m_sb);
1269 }
1270
1271 /*
1272  * Record a rmap intent; the list is kept sorted first by AG and then by
1273  * increasing age.
1274  */
1275 static int
1276 __xfs_rmap_add(
1277         struct xfs_mount                *mp,
1278         struct xfs_defer_ops            *dfops,
1279         enum xfs_rmap_intent_type       type,
1280         __uint64_t                      owner,
1281         int                             whichfork,
1282         struct xfs_bmbt_irec            *bmap)
1283 {
1284         struct xfs_rmap_intent  *ri;
1285
1286         trace_xfs_rmap_defer(mp, XFS_FSB_TO_AGNO(mp, bmap->br_startblock),
1287                         type,
1288                         XFS_FSB_TO_AGBNO(mp, bmap->br_startblock),
1289                         owner, whichfork,
1290                         bmap->br_startoff,
1291                         bmap->br_blockcount,
1292                         bmap->br_state);
1293
1294         ri = kmem_alloc(sizeof(struct xfs_rmap_intent), KM_SLEEP | KM_NOFS);
1295         INIT_LIST_HEAD(&ri->ri_list);
1296         ri->ri_type = type;
1297         ri->ri_owner = owner;
1298         ri->ri_whichfork = whichfork;
1299         ri->ri_bmap = *bmap;
1300
1301         xfs_defer_add(dfops, XFS_DEFER_OPS_TYPE_RMAP, &ri->ri_list);
1302         return 0;
1303 }
1304
1305 /* Map an extent into a file. */
1306 int
1307 xfs_rmap_map_extent(
1308         struct xfs_mount        *mp,
1309         struct xfs_defer_ops    *dfops,
1310         struct xfs_inode        *ip,
1311         int                     whichfork,
1312         struct xfs_bmbt_irec    *PREV)
1313 {
1314         if (!xfs_rmap_update_is_needed(mp))
1315                 return 0;
1316
1317         return __xfs_rmap_add(mp, dfops, XFS_RMAP_MAP, ip->i_ino,
1318                         whichfork, PREV);
1319 }
1320
1321 /* Unmap an extent out of a file. */
1322 int
1323 xfs_rmap_unmap_extent(
1324         struct xfs_mount        *mp,
1325         struct xfs_defer_ops    *dfops,
1326         struct xfs_inode        *ip,
1327         int                     whichfork,
1328         struct xfs_bmbt_irec    *PREV)
1329 {
1330         if (!xfs_rmap_update_is_needed(mp))
1331                 return 0;
1332
1333         return __xfs_rmap_add(mp, dfops, XFS_RMAP_UNMAP, ip->i_ino,
1334                         whichfork, PREV);
1335 }
1336
1337 /* Convert a data fork extent from unwritten to real or vice versa. */
1338 int
1339 xfs_rmap_convert_extent(
1340         struct xfs_mount        *mp,
1341         struct xfs_defer_ops    *dfops,
1342         struct xfs_inode        *ip,
1343         int                     whichfork,
1344         struct xfs_bmbt_irec    *PREV)
1345 {
1346         if (!xfs_rmap_update_is_needed(mp))
1347                 return 0;
1348
1349         return __xfs_rmap_add(mp, dfops, XFS_RMAP_CONVERT, ip->i_ino,
1350                         whichfork, PREV);
1351 }
1352
1353 /* Schedule the creation of an rmap for non-file data. */
1354 int
1355 xfs_rmap_alloc_extent(
1356         struct xfs_mount        *mp,
1357         struct xfs_defer_ops    *dfops,
1358         xfs_agnumber_t          agno,
1359         xfs_agblock_t           bno,
1360         xfs_extlen_t            len,
1361         __uint64_t              owner)
1362 {
1363         struct xfs_bmbt_irec    bmap;
1364
1365         if (!xfs_rmap_update_is_needed(mp))
1366                 return 0;
1367
1368         bmap.br_startblock = XFS_AGB_TO_FSB(mp, agno, bno);
1369         bmap.br_blockcount = len;
1370         bmap.br_startoff = 0;
1371         bmap.br_state = XFS_EXT_NORM;
1372
1373         return __xfs_rmap_add(mp, dfops, XFS_RMAP_ALLOC, owner,
1374                         XFS_DATA_FORK, &bmap);
1375 }
1376
1377 /* Schedule the deletion of an rmap for non-file data. */
1378 int
1379 xfs_rmap_free_extent(
1380         struct xfs_mount        *mp,
1381         struct xfs_defer_ops    *dfops,
1382         xfs_agnumber_t          agno,
1383         xfs_agblock_t           bno,
1384         xfs_extlen_t            len,
1385         __uint64_t              owner)
1386 {
1387         struct xfs_bmbt_irec    bmap;
1388
1389         if (!xfs_rmap_update_is_needed(mp))
1390                 return 0;
1391
1392         bmap.br_startblock = XFS_AGB_TO_FSB(mp, agno, bno);
1393         bmap.br_blockcount = len;
1394         bmap.br_startoff = 0;
1395         bmap.br_state = XFS_EXT_NORM;
1396
1397         return __xfs_rmap_add(mp, dfops, XFS_RMAP_FREE, owner,
1398                         XFS_DATA_FORK, &bmap);
1399 }