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