xref: /openbmc/linux/fs/xfs/libxfs/xfs_bmap_btree.c (revision 4f205687)
1 /*
2  * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
3  * All Rights Reserved.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it would be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write the Free Software Foundation,
16  * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17  */
18 #include "xfs.h"
19 #include "xfs_fs.h"
20 #include "xfs_shared.h"
21 #include "xfs_format.h"
22 #include "xfs_log_format.h"
23 #include "xfs_trans_resv.h"
24 #include "xfs_bit.h"
25 #include "xfs_mount.h"
26 #include "xfs_inode.h"
27 #include "xfs_trans.h"
28 #include "xfs_inode_item.h"
29 #include "xfs_alloc.h"
30 #include "xfs_btree.h"
31 #include "xfs_bmap_btree.h"
32 #include "xfs_bmap.h"
33 #include "xfs_error.h"
34 #include "xfs_quota.h"
35 #include "xfs_trace.h"
36 #include "xfs_cksum.h"
37 
38 /*
39  * Determine the extent state.
40  */
41 /* ARGSUSED */
42 STATIC xfs_exntst_t
43 xfs_extent_state(
44 	xfs_filblks_t		blks,
45 	int			extent_flag)
46 {
47 	if (extent_flag) {
48 		ASSERT(blks != 0);	/* saved for DMIG */
49 		return XFS_EXT_UNWRITTEN;
50 	}
51 	return XFS_EXT_NORM;
52 }
53 
54 /*
55  * Convert on-disk form of btree root to in-memory form.
56  */
57 void
58 xfs_bmdr_to_bmbt(
59 	struct xfs_inode	*ip,
60 	xfs_bmdr_block_t	*dblock,
61 	int			dblocklen,
62 	struct xfs_btree_block	*rblock,
63 	int			rblocklen)
64 {
65 	struct xfs_mount	*mp = ip->i_mount;
66 	int			dmxr;
67 	xfs_bmbt_key_t		*fkp;
68 	__be64			*fpp;
69 	xfs_bmbt_key_t		*tkp;
70 	__be64			*tpp;
71 
72 	if (xfs_sb_version_hascrc(&mp->m_sb))
73 		xfs_btree_init_block_int(mp, rblock, XFS_BUF_DADDR_NULL,
74 				 XFS_BMAP_CRC_MAGIC, 0, 0, ip->i_ino,
75 				 XFS_BTREE_LONG_PTRS | XFS_BTREE_CRC_BLOCKS);
76 	else
77 		xfs_btree_init_block_int(mp, rblock, XFS_BUF_DADDR_NULL,
78 				 XFS_BMAP_MAGIC, 0, 0, ip->i_ino,
79 				 XFS_BTREE_LONG_PTRS);
80 
81 	rblock->bb_level = dblock->bb_level;
82 	ASSERT(be16_to_cpu(rblock->bb_level) > 0);
83 	rblock->bb_numrecs = dblock->bb_numrecs;
84 	dmxr = xfs_bmdr_maxrecs(dblocklen, 0);
85 	fkp = XFS_BMDR_KEY_ADDR(dblock, 1);
86 	tkp = XFS_BMBT_KEY_ADDR(mp, rblock, 1);
87 	fpp = XFS_BMDR_PTR_ADDR(dblock, 1, dmxr);
88 	tpp = XFS_BMAP_BROOT_PTR_ADDR(mp, rblock, 1, rblocklen);
89 	dmxr = be16_to_cpu(dblock->bb_numrecs);
90 	memcpy(tkp, fkp, sizeof(*fkp) * dmxr);
91 	memcpy(tpp, fpp, sizeof(*fpp) * dmxr);
92 }
93 
94 /*
95  * Convert a compressed bmap extent record to an uncompressed form.
96  * This code must be in sync with the routines xfs_bmbt_get_startoff,
97  * xfs_bmbt_get_startblock, xfs_bmbt_get_blockcount and xfs_bmbt_get_state.
98  */
99 STATIC void
100 __xfs_bmbt_get_all(
101 		__uint64_t l0,
102 		__uint64_t l1,
103 		xfs_bmbt_irec_t *s)
104 {
105 	int	ext_flag;
106 	xfs_exntst_t st;
107 
108 	ext_flag = (int)(l0 >> (64 - BMBT_EXNTFLAG_BITLEN));
109 	s->br_startoff = ((xfs_fileoff_t)l0 &
110 			   xfs_mask64lo(64 - BMBT_EXNTFLAG_BITLEN)) >> 9;
111 	s->br_startblock = (((xfs_fsblock_t)l0 & xfs_mask64lo(9)) << 43) |
112 			   (((xfs_fsblock_t)l1) >> 21);
113 	s->br_blockcount = (xfs_filblks_t)(l1 & xfs_mask64lo(21));
114 	/* This is xfs_extent_state() in-line */
115 	if (ext_flag) {
116 		ASSERT(s->br_blockcount != 0);	/* saved for DMIG */
117 		st = XFS_EXT_UNWRITTEN;
118 	} else
119 		st = XFS_EXT_NORM;
120 	s->br_state = st;
121 }
122 
123 void
124 xfs_bmbt_get_all(
125 	xfs_bmbt_rec_host_t *r,
126 	xfs_bmbt_irec_t *s)
127 {
128 	__xfs_bmbt_get_all(r->l0, r->l1, s);
129 }
130 
131 /*
132  * Extract the blockcount field from an in memory bmap extent record.
133  */
134 xfs_filblks_t
135 xfs_bmbt_get_blockcount(
136 	xfs_bmbt_rec_host_t	*r)
137 {
138 	return (xfs_filblks_t)(r->l1 & xfs_mask64lo(21));
139 }
140 
141 /*
142  * Extract the startblock field from an in memory bmap extent record.
143  */
144 xfs_fsblock_t
145 xfs_bmbt_get_startblock(
146 	xfs_bmbt_rec_host_t	*r)
147 {
148 	return (((xfs_fsblock_t)r->l0 & xfs_mask64lo(9)) << 43) |
149 	       (((xfs_fsblock_t)r->l1) >> 21);
150 }
151 
152 /*
153  * Extract the startoff field from an in memory bmap extent record.
154  */
155 xfs_fileoff_t
156 xfs_bmbt_get_startoff(
157 	xfs_bmbt_rec_host_t	*r)
158 {
159 	return ((xfs_fileoff_t)r->l0 &
160 		 xfs_mask64lo(64 - BMBT_EXNTFLAG_BITLEN)) >> 9;
161 }
162 
163 xfs_exntst_t
164 xfs_bmbt_get_state(
165 	xfs_bmbt_rec_host_t	*r)
166 {
167 	int	ext_flag;
168 
169 	ext_flag = (int)((r->l0) >> (64 - BMBT_EXNTFLAG_BITLEN));
170 	return xfs_extent_state(xfs_bmbt_get_blockcount(r),
171 				ext_flag);
172 }
173 
174 /*
175  * Extract the blockcount field from an on disk bmap extent record.
176  */
177 xfs_filblks_t
178 xfs_bmbt_disk_get_blockcount(
179 	xfs_bmbt_rec_t	*r)
180 {
181 	return (xfs_filblks_t)(be64_to_cpu(r->l1) & xfs_mask64lo(21));
182 }
183 
184 /*
185  * Extract the startoff field from a disk format bmap extent record.
186  */
187 xfs_fileoff_t
188 xfs_bmbt_disk_get_startoff(
189 	xfs_bmbt_rec_t	*r)
190 {
191 	return ((xfs_fileoff_t)be64_to_cpu(r->l0) &
192 		 xfs_mask64lo(64 - BMBT_EXNTFLAG_BITLEN)) >> 9;
193 }
194 
195 
196 /*
197  * Set all the fields in a bmap extent record from the arguments.
198  */
199 void
200 xfs_bmbt_set_allf(
201 	xfs_bmbt_rec_host_t	*r,
202 	xfs_fileoff_t		startoff,
203 	xfs_fsblock_t		startblock,
204 	xfs_filblks_t		blockcount,
205 	xfs_exntst_t		state)
206 {
207 	int		extent_flag = (state == XFS_EXT_NORM) ? 0 : 1;
208 
209 	ASSERT(state == XFS_EXT_NORM || state == XFS_EXT_UNWRITTEN);
210 	ASSERT((startoff & xfs_mask64hi(64-BMBT_STARTOFF_BITLEN)) == 0);
211 	ASSERT((blockcount & xfs_mask64hi(64-BMBT_BLOCKCOUNT_BITLEN)) == 0);
212 
213 	ASSERT((startblock & xfs_mask64hi(64-BMBT_STARTBLOCK_BITLEN)) == 0);
214 
215 	r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) |
216 		((xfs_bmbt_rec_base_t)startoff << 9) |
217 		((xfs_bmbt_rec_base_t)startblock >> 43);
218 	r->l1 = ((xfs_bmbt_rec_base_t)startblock << 21) |
219 		((xfs_bmbt_rec_base_t)blockcount &
220 		(xfs_bmbt_rec_base_t)xfs_mask64lo(21));
221 }
222 
223 /*
224  * Set all the fields in a bmap extent record from the uncompressed form.
225  */
226 void
227 xfs_bmbt_set_all(
228 	xfs_bmbt_rec_host_t *r,
229 	xfs_bmbt_irec_t	*s)
230 {
231 	xfs_bmbt_set_allf(r, s->br_startoff, s->br_startblock,
232 			     s->br_blockcount, s->br_state);
233 }
234 
235 
236 /*
237  * Set all the fields in a disk format bmap extent record from the arguments.
238  */
239 void
240 xfs_bmbt_disk_set_allf(
241 	xfs_bmbt_rec_t		*r,
242 	xfs_fileoff_t		startoff,
243 	xfs_fsblock_t		startblock,
244 	xfs_filblks_t		blockcount,
245 	xfs_exntst_t		state)
246 {
247 	int			extent_flag = (state == XFS_EXT_NORM) ? 0 : 1;
248 
249 	ASSERT(state == XFS_EXT_NORM || state == XFS_EXT_UNWRITTEN);
250 	ASSERT((startoff & xfs_mask64hi(64-BMBT_STARTOFF_BITLEN)) == 0);
251 	ASSERT((blockcount & xfs_mask64hi(64-BMBT_BLOCKCOUNT_BITLEN)) == 0);
252 	ASSERT((startblock & xfs_mask64hi(64-BMBT_STARTBLOCK_BITLEN)) == 0);
253 
254 	r->l0 = cpu_to_be64(
255 		((xfs_bmbt_rec_base_t)extent_flag << 63) |
256 		 ((xfs_bmbt_rec_base_t)startoff << 9) |
257 		 ((xfs_bmbt_rec_base_t)startblock >> 43));
258 	r->l1 = cpu_to_be64(
259 		((xfs_bmbt_rec_base_t)startblock << 21) |
260 		 ((xfs_bmbt_rec_base_t)blockcount &
261 		  (xfs_bmbt_rec_base_t)xfs_mask64lo(21)));
262 }
263 
264 /*
265  * Set all the fields in a bmap extent record from the uncompressed form.
266  */
267 STATIC void
268 xfs_bmbt_disk_set_all(
269 	xfs_bmbt_rec_t	*r,
270 	xfs_bmbt_irec_t *s)
271 {
272 	xfs_bmbt_disk_set_allf(r, s->br_startoff, s->br_startblock,
273 				  s->br_blockcount, s->br_state);
274 }
275 
276 /*
277  * Set the blockcount field in a bmap extent record.
278  */
279 void
280 xfs_bmbt_set_blockcount(
281 	xfs_bmbt_rec_host_t *r,
282 	xfs_filblks_t	v)
283 {
284 	ASSERT((v & xfs_mask64hi(43)) == 0);
285 	r->l1 = (r->l1 & (xfs_bmbt_rec_base_t)xfs_mask64hi(43)) |
286 		  (xfs_bmbt_rec_base_t)(v & xfs_mask64lo(21));
287 }
288 
289 /*
290  * Set the startblock field in a bmap extent record.
291  */
292 void
293 xfs_bmbt_set_startblock(
294 	xfs_bmbt_rec_host_t *r,
295 	xfs_fsblock_t	v)
296 {
297 	ASSERT((v & xfs_mask64hi(12)) == 0);
298 	r->l0 = (r->l0 & (xfs_bmbt_rec_base_t)xfs_mask64hi(55)) |
299 		  (xfs_bmbt_rec_base_t)(v >> 43);
300 	r->l1 = (r->l1 & (xfs_bmbt_rec_base_t)xfs_mask64lo(21)) |
301 		  (xfs_bmbt_rec_base_t)(v << 21);
302 }
303 
304 /*
305  * Set the startoff field in a bmap extent record.
306  */
307 void
308 xfs_bmbt_set_startoff(
309 	xfs_bmbt_rec_host_t *r,
310 	xfs_fileoff_t	v)
311 {
312 	ASSERT((v & xfs_mask64hi(9)) == 0);
313 	r->l0 = (r->l0 & (xfs_bmbt_rec_base_t) xfs_mask64hi(1)) |
314 		((xfs_bmbt_rec_base_t)v << 9) |
315 		  (r->l0 & (xfs_bmbt_rec_base_t)xfs_mask64lo(9));
316 }
317 
318 /*
319  * Set the extent state field in a bmap extent record.
320  */
321 void
322 xfs_bmbt_set_state(
323 	xfs_bmbt_rec_host_t *r,
324 	xfs_exntst_t	v)
325 {
326 	ASSERT(v == XFS_EXT_NORM || v == XFS_EXT_UNWRITTEN);
327 	if (v == XFS_EXT_NORM)
328 		r->l0 &= xfs_mask64lo(64 - BMBT_EXNTFLAG_BITLEN);
329 	else
330 		r->l0 |= xfs_mask64hi(BMBT_EXNTFLAG_BITLEN);
331 }
332 
333 /*
334  * Convert in-memory form of btree root to on-disk form.
335  */
336 void
337 xfs_bmbt_to_bmdr(
338 	struct xfs_mount	*mp,
339 	struct xfs_btree_block	*rblock,
340 	int			rblocklen,
341 	xfs_bmdr_block_t	*dblock,
342 	int			dblocklen)
343 {
344 	int			dmxr;
345 	xfs_bmbt_key_t		*fkp;
346 	__be64			*fpp;
347 	xfs_bmbt_key_t		*tkp;
348 	__be64			*tpp;
349 
350 	if (xfs_sb_version_hascrc(&mp->m_sb)) {
351 		ASSERT(rblock->bb_magic == cpu_to_be32(XFS_BMAP_CRC_MAGIC));
352 		ASSERT(uuid_equal(&rblock->bb_u.l.bb_uuid,
353 		       &mp->m_sb.sb_meta_uuid));
354 		ASSERT(rblock->bb_u.l.bb_blkno ==
355 		       cpu_to_be64(XFS_BUF_DADDR_NULL));
356 	} else
357 		ASSERT(rblock->bb_magic == cpu_to_be32(XFS_BMAP_MAGIC));
358 	ASSERT(rblock->bb_u.l.bb_leftsib == cpu_to_be64(NULLFSBLOCK));
359 	ASSERT(rblock->bb_u.l.bb_rightsib == cpu_to_be64(NULLFSBLOCK));
360 	ASSERT(rblock->bb_level != 0);
361 	dblock->bb_level = rblock->bb_level;
362 	dblock->bb_numrecs = rblock->bb_numrecs;
363 	dmxr = xfs_bmdr_maxrecs(dblocklen, 0);
364 	fkp = XFS_BMBT_KEY_ADDR(mp, rblock, 1);
365 	tkp = XFS_BMDR_KEY_ADDR(dblock, 1);
366 	fpp = XFS_BMAP_BROOT_PTR_ADDR(mp, rblock, 1, rblocklen);
367 	tpp = XFS_BMDR_PTR_ADDR(dblock, 1, dmxr);
368 	dmxr = be16_to_cpu(dblock->bb_numrecs);
369 	memcpy(tkp, fkp, sizeof(*fkp) * dmxr);
370 	memcpy(tpp, fpp, sizeof(*fpp) * dmxr);
371 }
372 
373 /*
374  * Check extent records, which have just been read, for
375  * any bit in the extent flag field. ASSERT on debug
376  * kernels, as this condition should not occur.
377  * Return an error condition (1) if any flags found,
378  * otherwise return 0.
379  */
380 
381 int
382 xfs_check_nostate_extents(
383 	xfs_ifork_t		*ifp,
384 	xfs_extnum_t		idx,
385 	xfs_extnum_t		num)
386 {
387 	for (; num > 0; num--, idx++) {
388 		xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, idx);
389 		if ((ep->l0 >>
390 		     (64 - BMBT_EXNTFLAG_BITLEN)) != 0) {
391 			ASSERT(0);
392 			return 1;
393 		}
394 	}
395 	return 0;
396 }
397 
398 
399 STATIC struct xfs_btree_cur *
400 xfs_bmbt_dup_cursor(
401 	struct xfs_btree_cur	*cur)
402 {
403 	struct xfs_btree_cur	*new;
404 
405 	new = xfs_bmbt_init_cursor(cur->bc_mp, cur->bc_tp,
406 			cur->bc_private.b.ip, cur->bc_private.b.whichfork);
407 
408 	/*
409 	 * Copy the firstblock, flist, and flags values,
410 	 * since init cursor doesn't get them.
411 	 */
412 	new->bc_private.b.firstblock = cur->bc_private.b.firstblock;
413 	new->bc_private.b.flist = cur->bc_private.b.flist;
414 	new->bc_private.b.flags = cur->bc_private.b.flags;
415 
416 	return new;
417 }
418 
419 STATIC void
420 xfs_bmbt_update_cursor(
421 	struct xfs_btree_cur	*src,
422 	struct xfs_btree_cur	*dst)
423 {
424 	ASSERT((dst->bc_private.b.firstblock != NULLFSBLOCK) ||
425 	       (dst->bc_private.b.ip->i_d.di_flags & XFS_DIFLAG_REALTIME));
426 	ASSERT(dst->bc_private.b.flist == src->bc_private.b.flist);
427 
428 	dst->bc_private.b.allocated += src->bc_private.b.allocated;
429 	dst->bc_private.b.firstblock = src->bc_private.b.firstblock;
430 
431 	src->bc_private.b.allocated = 0;
432 }
433 
434 STATIC int
435 xfs_bmbt_alloc_block(
436 	struct xfs_btree_cur	*cur,
437 	union xfs_btree_ptr	*start,
438 	union xfs_btree_ptr	*new,
439 	int			*stat)
440 {
441 	xfs_alloc_arg_t		args;		/* block allocation args */
442 	int			error;		/* error return value */
443 
444 	memset(&args, 0, sizeof(args));
445 	args.tp = cur->bc_tp;
446 	args.mp = cur->bc_mp;
447 	args.fsbno = cur->bc_private.b.firstblock;
448 	args.firstblock = args.fsbno;
449 
450 	if (args.fsbno == NULLFSBLOCK) {
451 		args.fsbno = be64_to_cpu(start->l);
452 		args.type = XFS_ALLOCTYPE_START_BNO;
453 		/*
454 		 * Make sure there is sufficient room left in the AG to
455 		 * complete a full tree split for an extent insert.  If
456 		 * we are converting the middle part of an extent then
457 		 * we may need space for two tree splits.
458 		 *
459 		 * We are relying on the caller to make the correct block
460 		 * reservation for this operation to succeed.  If the
461 		 * reservation amount is insufficient then we may fail a
462 		 * block allocation here and corrupt the filesystem.
463 		 */
464 		args.minleft = args.tp->t_blk_res;
465 	} else if (cur->bc_private.b.flist->xbf_low) {
466 		args.type = XFS_ALLOCTYPE_START_BNO;
467 	} else {
468 		args.type = XFS_ALLOCTYPE_NEAR_BNO;
469 	}
470 
471 	args.minlen = args.maxlen = args.prod = 1;
472 	args.wasdel = cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL;
473 	if (!args.wasdel && args.tp->t_blk_res == 0) {
474 		error = -ENOSPC;
475 		goto error0;
476 	}
477 	error = xfs_alloc_vextent(&args);
478 	if (error)
479 		goto error0;
480 
481 	if (args.fsbno == NULLFSBLOCK && args.minleft) {
482 		/*
483 		 * Could not find an AG with enough free space to satisfy
484 		 * a full btree split.  Try again without minleft and if
485 		 * successful activate the lowspace algorithm.
486 		 */
487 		args.fsbno = 0;
488 		args.type = XFS_ALLOCTYPE_FIRST_AG;
489 		args.minleft = 0;
490 		error = xfs_alloc_vextent(&args);
491 		if (error)
492 			goto error0;
493 		cur->bc_private.b.flist->xbf_low = 1;
494 	}
495 	if (args.fsbno == NULLFSBLOCK) {
496 		XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
497 		*stat = 0;
498 		return 0;
499 	}
500 	ASSERT(args.len == 1);
501 	cur->bc_private.b.firstblock = args.fsbno;
502 	cur->bc_private.b.allocated++;
503 	cur->bc_private.b.ip->i_d.di_nblocks++;
504 	xfs_trans_log_inode(args.tp, cur->bc_private.b.ip, XFS_ILOG_CORE);
505 	xfs_trans_mod_dquot_byino(args.tp, cur->bc_private.b.ip,
506 			XFS_TRANS_DQ_BCOUNT, 1L);
507 
508 	new->l = cpu_to_be64(args.fsbno);
509 
510 	XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
511 	*stat = 1;
512 	return 0;
513 
514  error0:
515 	XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR);
516 	return error;
517 }
518 
519 STATIC int
520 xfs_bmbt_free_block(
521 	struct xfs_btree_cur	*cur,
522 	struct xfs_buf		*bp)
523 {
524 	struct xfs_mount	*mp = cur->bc_mp;
525 	struct xfs_inode	*ip = cur->bc_private.b.ip;
526 	struct xfs_trans	*tp = cur->bc_tp;
527 	xfs_fsblock_t		fsbno = XFS_DADDR_TO_FSB(mp, XFS_BUF_ADDR(bp));
528 
529 	xfs_bmap_add_free(fsbno, 1, cur->bc_private.b.flist, mp);
530 	ip->i_d.di_nblocks--;
531 
532 	xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
533 	xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, -1L);
534 	return 0;
535 }
536 
537 STATIC int
538 xfs_bmbt_get_minrecs(
539 	struct xfs_btree_cur	*cur,
540 	int			level)
541 {
542 	if (level == cur->bc_nlevels - 1) {
543 		struct xfs_ifork	*ifp;
544 
545 		ifp = XFS_IFORK_PTR(cur->bc_private.b.ip,
546 				    cur->bc_private.b.whichfork);
547 
548 		return xfs_bmbt_maxrecs(cur->bc_mp,
549 					ifp->if_broot_bytes, level == 0) / 2;
550 	}
551 
552 	return cur->bc_mp->m_bmap_dmnr[level != 0];
553 }
554 
555 int
556 xfs_bmbt_get_maxrecs(
557 	struct xfs_btree_cur	*cur,
558 	int			level)
559 {
560 	if (level == cur->bc_nlevels - 1) {
561 		struct xfs_ifork	*ifp;
562 
563 		ifp = XFS_IFORK_PTR(cur->bc_private.b.ip,
564 				    cur->bc_private.b.whichfork);
565 
566 		return xfs_bmbt_maxrecs(cur->bc_mp,
567 					ifp->if_broot_bytes, level == 0);
568 	}
569 
570 	return cur->bc_mp->m_bmap_dmxr[level != 0];
571 
572 }
573 
574 /*
575  * Get the maximum records we could store in the on-disk format.
576  *
577  * For non-root nodes this is equivalent to xfs_bmbt_get_maxrecs, but
578  * for the root node this checks the available space in the dinode fork
579  * so that we can resize the in-memory buffer to match it.  After a
580  * resize to the maximum size this function returns the same value
581  * as xfs_bmbt_get_maxrecs for the root node, too.
582  */
583 STATIC int
584 xfs_bmbt_get_dmaxrecs(
585 	struct xfs_btree_cur	*cur,
586 	int			level)
587 {
588 	if (level != cur->bc_nlevels - 1)
589 		return cur->bc_mp->m_bmap_dmxr[level != 0];
590 	return xfs_bmdr_maxrecs(cur->bc_private.b.forksize, level == 0);
591 }
592 
593 STATIC void
594 xfs_bmbt_init_key_from_rec(
595 	union xfs_btree_key	*key,
596 	union xfs_btree_rec	*rec)
597 {
598 	key->bmbt.br_startoff =
599 		cpu_to_be64(xfs_bmbt_disk_get_startoff(&rec->bmbt));
600 }
601 
602 STATIC void
603 xfs_bmbt_init_rec_from_key(
604 	union xfs_btree_key	*key,
605 	union xfs_btree_rec	*rec)
606 {
607 	ASSERT(key->bmbt.br_startoff != 0);
608 
609 	xfs_bmbt_disk_set_allf(&rec->bmbt, be64_to_cpu(key->bmbt.br_startoff),
610 			       0, 0, XFS_EXT_NORM);
611 }
612 
613 STATIC void
614 xfs_bmbt_init_rec_from_cur(
615 	struct xfs_btree_cur	*cur,
616 	union xfs_btree_rec	*rec)
617 {
618 	xfs_bmbt_disk_set_all(&rec->bmbt, &cur->bc_rec.b);
619 }
620 
621 STATIC void
622 xfs_bmbt_init_ptr_from_cur(
623 	struct xfs_btree_cur	*cur,
624 	union xfs_btree_ptr	*ptr)
625 {
626 	ptr->l = 0;
627 }
628 
629 STATIC __int64_t
630 xfs_bmbt_key_diff(
631 	struct xfs_btree_cur	*cur,
632 	union xfs_btree_key	*key)
633 {
634 	return (__int64_t)be64_to_cpu(key->bmbt.br_startoff) -
635 				      cur->bc_rec.b.br_startoff;
636 }
637 
638 static bool
639 xfs_bmbt_verify(
640 	struct xfs_buf		*bp)
641 {
642 	struct xfs_mount	*mp = bp->b_target->bt_mount;
643 	struct xfs_btree_block	*block = XFS_BUF_TO_BLOCK(bp);
644 	unsigned int		level;
645 
646 	switch (block->bb_magic) {
647 	case cpu_to_be32(XFS_BMAP_CRC_MAGIC):
648 		if (!xfs_sb_version_hascrc(&mp->m_sb))
649 			return false;
650 		if (!uuid_equal(&block->bb_u.l.bb_uuid, &mp->m_sb.sb_meta_uuid))
651 			return false;
652 		if (be64_to_cpu(block->bb_u.l.bb_blkno) != bp->b_bn)
653 			return false;
654 		/*
655 		 * XXX: need a better way of verifying the owner here. Right now
656 		 * just make sure there has been one set.
657 		 */
658 		if (be64_to_cpu(block->bb_u.l.bb_owner) == 0)
659 			return false;
660 		/* fall through */
661 	case cpu_to_be32(XFS_BMAP_MAGIC):
662 		break;
663 	default:
664 		return false;
665 	}
666 
667 	/*
668 	 * numrecs and level verification.
669 	 *
670 	 * We don't know what fork we belong to, so just verify that the level
671 	 * is less than the maximum of the two. Later checks will be more
672 	 * precise.
673 	 */
674 	level = be16_to_cpu(block->bb_level);
675 	if (level > max(mp->m_bm_maxlevels[0], mp->m_bm_maxlevels[1]))
676 		return false;
677 	if (be16_to_cpu(block->bb_numrecs) > mp->m_bmap_dmxr[level != 0])
678 		return false;
679 
680 	/* sibling pointer verification */
681 	if (!block->bb_u.l.bb_leftsib ||
682 	    (block->bb_u.l.bb_leftsib != cpu_to_be64(NULLFSBLOCK) &&
683 	     !XFS_FSB_SANITY_CHECK(mp, be64_to_cpu(block->bb_u.l.bb_leftsib))))
684 		return false;
685 	if (!block->bb_u.l.bb_rightsib ||
686 	    (block->bb_u.l.bb_rightsib != cpu_to_be64(NULLFSBLOCK) &&
687 	     !XFS_FSB_SANITY_CHECK(mp, be64_to_cpu(block->bb_u.l.bb_rightsib))))
688 		return false;
689 
690 	return true;
691 }
692 
693 static void
694 xfs_bmbt_read_verify(
695 	struct xfs_buf	*bp)
696 {
697 	if (!xfs_btree_lblock_verify_crc(bp))
698 		xfs_buf_ioerror(bp, -EFSBADCRC);
699 	else if (!xfs_bmbt_verify(bp))
700 		xfs_buf_ioerror(bp, -EFSCORRUPTED);
701 
702 	if (bp->b_error) {
703 		trace_xfs_btree_corrupt(bp, _RET_IP_);
704 		xfs_verifier_error(bp);
705 	}
706 }
707 
708 static void
709 xfs_bmbt_write_verify(
710 	struct xfs_buf	*bp)
711 {
712 	if (!xfs_bmbt_verify(bp)) {
713 		trace_xfs_btree_corrupt(bp, _RET_IP_);
714 		xfs_buf_ioerror(bp, -EFSCORRUPTED);
715 		xfs_verifier_error(bp);
716 		return;
717 	}
718 	xfs_btree_lblock_calc_crc(bp);
719 }
720 
721 const struct xfs_buf_ops xfs_bmbt_buf_ops = {
722 	.name = "xfs_bmbt",
723 	.verify_read = xfs_bmbt_read_verify,
724 	.verify_write = xfs_bmbt_write_verify,
725 };
726 
727 
728 #if defined(DEBUG) || defined(XFS_WARN)
729 STATIC int
730 xfs_bmbt_keys_inorder(
731 	struct xfs_btree_cur	*cur,
732 	union xfs_btree_key	*k1,
733 	union xfs_btree_key	*k2)
734 {
735 	return be64_to_cpu(k1->bmbt.br_startoff) <
736 		be64_to_cpu(k2->bmbt.br_startoff);
737 }
738 
739 STATIC int
740 xfs_bmbt_recs_inorder(
741 	struct xfs_btree_cur	*cur,
742 	union xfs_btree_rec	*r1,
743 	union xfs_btree_rec	*r2)
744 {
745 	return xfs_bmbt_disk_get_startoff(&r1->bmbt) +
746 		xfs_bmbt_disk_get_blockcount(&r1->bmbt) <=
747 		xfs_bmbt_disk_get_startoff(&r2->bmbt);
748 }
749 #endif	/* DEBUG */
750 
751 static const struct xfs_btree_ops xfs_bmbt_ops = {
752 	.rec_len		= sizeof(xfs_bmbt_rec_t),
753 	.key_len		= sizeof(xfs_bmbt_key_t),
754 
755 	.dup_cursor		= xfs_bmbt_dup_cursor,
756 	.update_cursor		= xfs_bmbt_update_cursor,
757 	.alloc_block		= xfs_bmbt_alloc_block,
758 	.free_block		= xfs_bmbt_free_block,
759 	.get_maxrecs		= xfs_bmbt_get_maxrecs,
760 	.get_minrecs		= xfs_bmbt_get_minrecs,
761 	.get_dmaxrecs		= xfs_bmbt_get_dmaxrecs,
762 	.init_key_from_rec	= xfs_bmbt_init_key_from_rec,
763 	.init_rec_from_key	= xfs_bmbt_init_rec_from_key,
764 	.init_rec_from_cur	= xfs_bmbt_init_rec_from_cur,
765 	.init_ptr_from_cur	= xfs_bmbt_init_ptr_from_cur,
766 	.key_diff		= xfs_bmbt_key_diff,
767 	.buf_ops		= &xfs_bmbt_buf_ops,
768 #if defined(DEBUG) || defined(XFS_WARN)
769 	.keys_inorder		= xfs_bmbt_keys_inorder,
770 	.recs_inorder		= xfs_bmbt_recs_inorder,
771 #endif
772 };
773 
774 /*
775  * Allocate a new bmap btree cursor.
776  */
777 struct xfs_btree_cur *				/* new bmap btree cursor */
778 xfs_bmbt_init_cursor(
779 	struct xfs_mount	*mp,		/* file system mount point */
780 	struct xfs_trans	*tp,		/* transaction pointer */
781 	struct xfs_inode	*ip,		/* inode owning the btree */
782 	int			whichfork)	/* data or attr fork */
783 {
784 	struct xfs_ifork	*ifp = XFS_IFORK_PTR(ip, whichfork);
785 	struct xfs_btree_cur	*cur;
786 
787 	cur = kmem_zone_zalloc(xfs_btree_cur_zone, KM_SLEEP);
788 
789 	cur->bc_tp = tp;
790 	cur->bc_mp = mp;
791 	cur->bc_nlevels = be16_to_cpu(ifp->if_broot->bb_level) + 1;
792 	cur->bc_btnum = XFS_BTNUM_BMAP;
793 	cur->bc_blocklog = mp->m_sb.sb_blocklog;
794 
795 	cur->bc_ops = &xfs_bmbt_ops;
796 	cur->bc_flags = XFS_BTREE_LONG_PTRS | XFS_BTREE_ROOT_IN_INODE;
797 	if (xfs_sb_version_hascrc(&mp->m_sb))
798 		cur->bc_flags |= XFS_BTREE_CRC_BLOCKS;
799 
800 	cur->bc_private.b.forksize = XFS_IFORK_SIZE(ip, whichfork);
801 	cur->bc_private.b.ip = ip;
802 	cur->bc_private.b.firstblock = NULLFSBLOCK;
803 	cur->bc_private.b.flist = NULL;
804 	cur->bc_private.b.allocated = 0;
805 	cur->bc_private.b.flags = 0;
806 	cur->bc_private.b.whichfork = whichfork;
807 
808 	return cur;
809 }
810 
811 /*
812  * Calculate number of records in a bmap btree block.
813  */
814 int
815 xfs_bmbt_maxrecs(
816 	struct xfs_mount	*mp,
817 	int			blocklen,
818 	int			leaf)
819 {
820 	blocklen -= XFS_BMBT_BLOCK_LEN(mp);
821 
822 	if (leaf)
823 		return blocklen / sizeof(xfs_bmbt_rec_t);
824 	return blocklen / (sizeof(xfs_bmbt_key_t) + sizeof(xfs_bmbt_ptr_t));
825 }
826 
827 /*
828  * Calculate number of records in a bmap btree inode root.
829  */
830 int
831 xfs_bmdr_maxrecs(
832 	int			blocklen,
833 	int			leaf)
834 {
835 	blocklen -= sizeof(xfs_bmdr_block_t);
836 
837 	if (leaf)
838 		return blocklen / sizeof(xfs_bmdr_rec_t);
839 	return blocklen / (sizeof(xfs_bmdr_key_t) + sizeof(xfs_bmdr_ptr_t));
840 }
841 
842 /*
843  * Change the owner of a btree format fork fo the inode passed in. Change it to
844  * the owner of that is passed in so that we can change owners before or after
845  * we switch forks between inodes. The operation that the caller is doing will
846  * determine whether is needs to change owner before or after the switch.
847  *
848  * For demand paged transactional modification, the fork switch should be done
849  * after reading in all the blocks, modifying them and pinning them in the
850  * transaction. For modification when the buffers are already pinned in memory,
851  * the fork switch can be done before changing the owner as we won't need to
852  * validate the owner until the btree buffers are unpinned and writes can occur
853  * again.
854  *
855  * For recovery based ownership change, there is no transactional context and
856  * so a buffer list must be supplied so that we can record the buffers that we
857  * modified for the caller to issue IO on.
858  */
859 int
860 xfs_bmbt_change_owner(
861 	struct xfs_trans	*tp,
862 	struct xfs_inode	*ip,
863 	int			whichfork,
864 	xfs_ino_t		new_owner,
865 	struct list_head	*buffer_list)
866 {
867 	struct xfs_btree_cur	*cur;
868 	int			error;
869 
870 	ASSERT(tp || buffer_list);
871 	ASSERT(!(tp && buffer_list));
872 	if (whichfork == XFS_DATA_FORK)
873 		ASSERT(ip->i_d.di_format == XFS_DINODE_FMT_BTREE);
874 	else
875 		ASSERT(ip->i_d.di_aformat == XFS_DINODE_FMT_BTREE);
876 
877 	cur = xfs_bmbt_init_cursor(ip->i_mount, tp, ip, whichfork);
878 	if (!cur)
879 		return -ENOMEM;
880 
881 	error = xfs_btree_change_owner(cur, new_owner, buffer_list);
882 	xfs_btree_del_cursor(cur, error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR);
883 	return error;
884 }
885