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