Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.15.
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
  4 * All Rights Reserved.
  5 */
  6
  7#include "xfs.h"
  8#include "xfs_fs.h"
  9#include "xfs_shared.h"
 10#include "xfs_format.h"
 11#include "xfs_log_format.h"
 12#include "xfs_trans_resv.h"
 13#include "xfs_mount.h"
 14#include "xfs_inode.h"
 15#include "xfs_trans.h"
 16#include "xfs_inode_item.h"
 17#include "xfs_btree.h"
 18#include "xfs_bmap_btree.h"
 19#include "xfs_bmap.h"
 20#include "xfs_error.h"
 21#include "xfs_trace.h"
 22#include "xfs_da_format.h"
 23#include "xfs_da_btree.h"
 24#include "xfs_dir2_priv.h"
 25#include "xfs_attr_leaf.h"
 26
 27kmem_zone_t *xfs_ifork_zone;
 28
 29STATIC int xfs_iformat_local(xfs_inode_t *, xfs_dinode_t *, int, int);
 30STATIC int xfs_iformat_extents(xfs_inode_t *, xfs_dinode_t *, int);
 31STATIC int xfs_iformat_btree(xfs_inode_t *, xfs_dinode_t *, int);
 32
 33/*
 34 * Copy inode type and data and attr format specific information from the
 35 * on-disk inode to the in-core inode and fork structures.  For fifos, devices,
 36 * and sockets this means set i_rdev to the proper value.  For files,
 37 * directories, and symlinks this means to bring in the in-line data or extent
 38 * pointers as well as the attribute fork.  For a fork in B-tree format, only
 39 * the root is immediately brought in-core.  The rest will be read in later when
 40 * first referenced (see xfs_iread_extents()).
 41 */
 42int
 43xfs_iformat_fork(
 44	struct xfs_inode	*ip,
 45	struct xfs_dinode	*dip)
 46{
 47	struct inode		*inode = VFS_I(ip);
 48	struct xfs_attr_shortform *atp;
 49	int			size;
 50	int			error = 0;
 51	xfs_fsize_t             di_size;
 52
 53	switch (inode->i_mode & S_IFMT) {
 54	case S_IFIFO:
 55	case S_IFCHR:
 56	case S_IFBLK:
 57	case S_IFSOCK:
 58		ip->i_d.di_size = 0;
 59		inode->i_rdev = xfs_to_linux_dev_t(xfs_dinode_get_rdev(dip));
 60		break;
 61
 62	case S_IFREG:
 63	case S_IFLNK:
 64	case S_IFDIR:
 65		switch (dip->di_format) {
 66		case XFS_DINODE_FMT_LOCAL:
 67			di_size = be64_to_cpu(dip->di_size);
 68			size = (int)di_size;
 69			error = xfs_iformat_local(ip, dip, XFS_DATA_FORK, size);
 70			break;
 71		case XFS_DINODE_FMT_EXTENTS:
 72			error = xfs_iformat_extents(ip, dip, XFS_DATA_FORK);
 73			break;
 74		case XFS_DINODE_FMT_BTREE:
 75			error = xfs_iformat_btree(ip, dip, XFS_DATA_FORK);
 76			break;
 77		default:
 78			return -EFSCORRUPTED;
 79		}
 80		break;
 81
 82	default:
 83		return -EFSCORRUPTED;
 84	}
 85	if (error)
 86		return error;
 87
 88	if (xfs_is_reflink_inode(ip)) {
 89		ASSERT(ip->i_cowfp == NULL);
 90		xfs_ifork_init_cow(ip);
 91	}
 92
 93	if (!XFS_DFORK_Q(dip))
 94		return 0;
 95
 96	ASSERT(ip->i_afp == NULL);
 97	ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, KM_NOFS);
 98
 99	switch (dip->di_aformat) {
100	case XFS_DINODE_FMT_LOCAL:
101		atp = (xfs_attr_shortform_t *)XFS_DFORK_APTR(dip);
102		size = be16_to_cpu(atp->hdr.totsize);
103
104		error = xfs_iformat_local(ip, dip, XFS_ATTR_FORK, size);
105		break;
106	case XFS_DINODE_FMT_EXTENTS:
107		error = xfs_iformat_extents(ip, dip, XFS_ATTR_FORK);
108		break;
109	case XFS_DINODE_FMT_BTREE:
110		error = xfs_iformat_btree(ip, dip, XFS_ATTR_FORK);
111		break;
112	default:
113		error = -EFSCORRUPTED;
114		break;
115	}
116	if (error) {
117		kmem_zone_free(xfs_ifork_zone, ip->i_afp);
118		ip->i_afp = NULL;
119		if (ip->i_cowfp)
120			kmem_zone_free(xfs_ifork_zone, ip->i_cowfp);
121		ip->i_cowfp = NULL;
122		xfs_idestroy_fork(ip, XFS_DATA_FORK);
123	}
124	return error;
125}
126
127void
128xfs_init_local_fork(
129	struct xfs_inode	*ip,
130	int			whichfork,
131	const void		*data,
132	int			size)
133{
134	struct xfs_ifork	*ifp = XFS_IFORK_PTR(ip, whichfork);
135	int			mem_size = size, real_size = 0;
136	bool			zero_terminate;
137
138	/*
139	 * If we are using the local fork to store a symlink body we need to
140	 * zero-terminate it so that we can pass it back to the VFS directly.
141	 * Overallocate the in-memory fork by one for that and add a zero
142	 * to terminate it below.
143	 */
144	zero_terminate = S_ISLNK(VFS_I(ip)->i_mode);
145	if (zero_terminate)
146		mem_size++;
147
148	if (size) {
149		real_size = roundup(mem_size, 4);
150		ifp->if_u1.if_data = kmem_alloc(real_size, KM_NOFS);
151		memcpy(ifp->if_u1.if_data, data, size);
152		if (zero_terminate)
153			ifp->if_u1.if_data[size] = '\0';
154	} else {
155		ifp->if_u1.if_data = NULL;
156	}
157
158	ifp->if_bytes = size;
159	ifp->if_flags &= ~(XFS_IFEXTENTS | XFS_IFBROOT);
160	ifp->if_flags |= XFS_IFINLINE;
161}
162
163/*
164 * The file is in-lined in the on-disk inode.
165 */
166STATIC int
167xfs_iformat_local(
168	xfs_inode_t	*ip,
169	xfs_dinode_t	*dip,
170	int		whichfork,
171	int		size)
172{
173	/*
174	 * If the size is unreasonable, then something
175	 * is wrong and we just bail out rather than crash in
176	 * kmem_alloc() or memcpy() below.
177	 */
178	if (unlikely(size > XFS_DFORK_SIZE(dip, ip->i_mount, whichfork))) {
179		xfs_warn(ip->i_mount,
180	"corrupt inode %Lu (bad size %d for local fork, size = %d).",
181			(unsigned long long) ip->i_ino, size,
182			XFS_DFORK_SIZE(dip, ip->i_mount, whichfork));
183		xfs_inode_verifier_error(ip, -EFSCORRUPTED,
184				"xfs_iformat_local", dip, sizeof(*dip),
185				__this_address);
186		return -EFSCORRUPTED;
187	}
188
189	xfs_init_local_fork(ip, whichfork, XFS_DFORK_PTR(dip, whichfork), size);
190	return 0;
191}
192
193/*
194 * The file consists of a set of extents all of which fit into the on-disk
195 * inode.
196 */
197STATIC int
198xfs_iformat_extents(
199	struct xfs_inode	*ip,
200	struct xfs_dinode	*dip,
201	int			whichfork)
202{
203	struct xfs_mount	*mp = ip->i_mount;
204	struct xfs_ifork	*ifp = XFS_IFORK_PTR(ip, whichfork);
205	int			state = xfs_bmap_fork_to_state(whichfork);
206	int			nex = XFS_DFORK_NEXTENTS(dip, whichfork);
207	int			size = nex * sizeof(xfs_bmbt_rec_t);
208	struct xfs_iext_cursor	icur;
209	struct xfs_bmbt_rec	*dp;
210	struct xfs_bmbt_irec	new;
211	int			i;
212
213	/*
214	 * If the number of extents is unreasonable, then something is wrong and
215	 * we just bail out rather than crash in kmem_alloc() or memcpy() below.
216	 */
217	if (unlikely(size < 0 || size > XFS_DFORK_SIZE(dip, mp, whichfork))) {
218		xfs_warn(ip->i_mount, "corrupt inode %Lu ((a)extents = %d).",
219			(unsigned long long) ip->i_ino, nex);
220		xfs_inode_verifier_error(ip, -EFSCORRUPTED,
221				"xfs_iformat_extents(1)", dip, sizeof(*dip),
222				__this_address);
223		return -EFSCORRUPTED;
224	}
225
226	ifp->if_bytes = 0;
227	ifp->if_u1.if_root = NULL;
228	ifp->if_height = 0;
229	if (size) {
230		dp = (xfs_bmbt_rec_t *) XFS_DFORK_PTR(dip, whichfork);
231
232		xfs_iext_first(ifp, &icur);
233		for (i = 0; i < nex; i++, dp++) {
234			xfs_failaddr_t	fa;
235
236			xfs_bmbt_disk_get_all(dp, &new);
237			fa = xfs_bmap_validate_extent(ip, whichfork, &new);
238			if (fa) {
239				xfs_inode_verifier_error(ip, -EFSCORRUPTED,
240						"xfs_iformat_extents(2)",
241						dp, sizeof(*dp), fa);
242				return -EFSCORRUPTED;
243			}
244
245			xfs_iext_insert(ip, &icur, &new, state);
246			trace_xfs_read_extent(ip, &icur, state, _THIS_IP_);
247			xfs_iext_next(ifp, &icur);
248		}
249	}
250	ifp->if_flags |= XFS_IFEXTENTS;
251	return 0;
252}
253
254/*
255 * The file has too many extents to fit into
256 * the inode, so they are in B-tree format.
257 * Allocate a buffer for the root of the B-tree
258 * and copy the root into it.  The i_extents
259 * field will remain NULL until all of the
260 * extents are read in (when they are needed).
261 */
262STATIC int
263xfs_iformat_btree(
264	xfs_inode_t		*ip,
265	xfs_dinode_t		*dip,
266	int			whichfork)
267{
268	struct xfs_mount	*mp = ip->i_mount;
269	xfs_bmdr_block_t	*dfp;
270	struct xfs_ifork	*ifp;
271	/* REFERENCED */
272	int			nrecs;
273	int			size;
274	int			level;
275
276	ifp = XFS_IFORK_PTR(ip, whichfork);
277	dfp = (xfs_bmdr_block_t *)XFS_DFORK_PTR(dip, whichfork);
278	size = XFS_BMAP_BROOT_SPACE(mp, dfp);
279	nrecs = be16_to_cpu(dfp->bb_numrecs);
280	level = be16_to_cpu(dfp->bb_level);
281
282	/*
283	 * blow out if -- fork has less extents than can fit in
284	 * fork (fork shouldn't be a btree format), root btree
285	 * block has more records than can fit into the fork,
286	 * or the number of extents is greater than the number of
287	 * blocks.
288	 */
289	if (unlikely(XFS_IFORK_NEXTENTS(ip, whichfork) <=
290					XFS_IFORK_MAXEXT(ip, whichfork) ||
291		     nrecs == 0 ||
292		     XFS_BMDR_SPACE_CALC(nrecs) >
293					XFS_DFORK_SIZE(dip, mp, whichfork) ||
294		     XFS_IFORK_NEXTENTS(ip, whichfork) > ip->i_d.di_nblocks) ||
295		     level == 0 || level > XFS_BTREE_MAXLEVELS) {
296		xfs_warn(mp, "corrupt inode %Lu (btree).",
297					(unsigned long long) ip->i_ino);
298		xfs_inode_verifier_error(ip, -EFSCORRUPTED,
299				"xfs_iformat_btree", dfp, size,
300				__this_address);
301		return -EFSCORRUPTED;
302	}
303
304	ifp->if_broot_bytes = size;
305	ifp->if_broot = kmem_alloc(size, KM_NOFS);
306	ASSERT(ifp->if_broot != NULL);
307	/*
308	 * Copy and convert from the on-disk structure
309	 * to the in-memory structure.
310	 */
311	xfs_bmdr_to_bmbt(ip, dfp, XFS_DFORK_SIZE(dip, ip->i_mount, whichfork),
312			 ifp->if_broot, size);
313	ifp->if_flags &= ~XFS_IFEXTENTS;
314	ifp->if_flags |= XFS_IFBROOT;
315
316	ifp->if_bytes = 0;
317	ifp->if_u1.if_root = NULL;
318	ifp->if_height = 0;
319	return 0;
320}
321
322/*
323 * Reallocate the space for if_broot based on the number of records
324 * being added or deleted as indicated in rec_diff.  Move the records
325 * and pointers in if_broot to fit the new size.  When shrinking this
326 * will eliminate holes between the records and pointers created by
327 * the caller.  When growing this will create holes to be filled in
328 * by the caller.
329 *
330 * The caller must not request to add more records than would fit in
331 * the on-disk inode root.  If the if_broot is currently NULL, then
332 * if we are adding records, one will be allocated.  The caller must also
333 * not request that the number of records go below zero, although
334 * it can go to zero.
335 *
336 * ip -- the inode whose if_broot area is changing
337 * ext_diff -- the change in the number of records, positive or negative,
338 *	 requested for the if_broot array.
339 */
340void
341xfs_iroot_realloc(
342	xfs_inode_t		*ip,
343	int			rec_diff,
344	int			whichfork)
345{
346	struct xfs_mount	*mp = ip->i_mount;
347	int			cur_max;
348	struct xfs_ifork	*ifp;
349	struct xfs_btree_block	*new_broot;
350	int			new_max;
351	size_t			new_size;
352	char			*np;
353	char			*op;
354
355	/*
356	 * Handle the degenerate case quietly.
357	 */
358	if (rec_diff == 0) {
359		return;
360	}
361
362	ifp = XFS_IFORK_PTR(ip, whichfork);
363	if (rec_diff > 0) {
364		/*
365		 * If there wasn't any memory allocated before, just
366		 * allocate it now and get out.
367		 */
368		if (ifp->if_broot_bytes == 0) {
369			new_size = XFS_BMAP_BROOT_SPACE_CALC(mp, rec_diff);
370			ifp->if_broot = kmem_alloc(new_size, KM_NOFS);
371			ifp->if_broot_bytes = (int)new_size;
372			return;
373		}
374
375		/*
376		 * If there is already an existing if_broot, then we need
377		 * to realloc() it and shift the pointers to their new
378		 * location.  The records don't change location because
379		 * they are kept butted up against the btree block header.
380		 */
381		cur_max = xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, 0);
382		new_max = cur_max + rec_diff;
383		new_size = XFS_BMAP_BROOT_SPACE_CALC(mp, new_max);
384		ifp->if_broot = kmem_realloc(ifp->if_broot, new_size,
385				KM_NOFS);
386		op = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, ifp->if_broot, 1,
387						     ifp->if_broot_bytes);
388		np = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, ifp->if_broot, 1,
389						     (int)new_size);
390		ifp->if_broot_bytes = (int)new_size;
391		ASSERT(XFS_BMAP_BMDR_SPACE(ifp->if_broot) <=
392			XFS_IFORK_SIZE(ip, whichfork));
393		memmove(np, op, cur_max * (uint)sizeof(xfs_fsblock_t));
394		return;
395	}
396
397	/*
398	 * rec_diff is less than 0.  In this case, we are shrinking the
399	 * if_broot buffer.  It must already exist.  If we go to zero
400	 * records, just get rid of the root and clear the status bit.
401	 */
402	ASSERT((ifp->if_broot != NULL) && (ifp->if_broot_bytes > 0));
403	cur_max = xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, 0);
404	new_max = cur_max + rec_diff;
405	ASSERT(new_max >= 0);
406	if (new_max > 0)
407		new_size = XFS_BMAP_BROOT_SPACE_CALC(mp, new_max);
408	else
409		new_size = 0;
410	if (new_size > 0) {
411		new_broot = kmem_alloc(new_size, KM_NOFS);
412		/*
413		 * First copy over the btree block header.
414		 */
415		memcpy(new_broot, ifp->if_broot,
416			XFS_BMBT_BLOCK_LEN(ip->i_mount));
417	} else {
418		new_broot = NULL;
419		ifp->if_flags &= ~XFS_IFBROOT;
420	}
421
422	/*
423	 * Only copy the records and pointers if there are any.
424	 */
425	if (new_max > 0) {
426		/*
427		 * First copy the records.
428		 */
429		op = (char *)XFS_BMBT_REC_ADDR(mp, ifp->if_broot, 1);
430		np = (char *)XFS_BMBT_REC_ADDR(mp, new_broot, 1);
431		memcpy(np, op, new_max * (uint)sizeof(xfs_bmbt_rec_t));
432
433		/*
434		 * Then copy the pointers.
435		 */
436		op = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, ifp->if_broot, 1,
437						     ifp->if_broot_bytes);
438		np = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, new_broot, 1,
439						     (int)new_size);
440		memcpy(np, op, new_max * (uint)sizeof(xfs_fsblock_t));
441	}
442	kmem_free(ifp->if_broot);
443	ifp->if_broot = new_broot;
444	ifp->if_broot_bytes = (int)new_size;
445	if (ifp->if_broot)
446		ASSERT(XFS_BMAP_BMDR_SPACE(ifp->if_broot) <=
447			XFS_IFORK_SIZE(ip, whichfork));
448	return;
449}
450
451
452/*
453 * This is called when the amount of space needed for if_data
454 * is increased or decreased.  The change in size is indicated by
455 * the number of bytes that need to be added or deleted in the
456 * byte_diff parameter.
457 *
458 * If the amount of space needed has decreased below the size of the
459 * inline buffer, then switch to using the inline buffer.  Otherwise,
460 * use kmem_realloc() or kmem_alloc() to adjust the size of the buffer
461 * to what is needed.
462 *
463 * ip -- the inode whose if_data area is changing
464 * byte_diff -- the change in the number of bytes, positive or negative,
465 *	 requested for the if_data array.
466 */
467void
468xfs_idata_realloc(
469	struct xfs_inode	*ip,
470	int			byte_diff,
471	int			whichfork)
472{
473	struct xfs_ifork	*ifp = XFS_IFORK_PTR(ip, whichfork);
474	int			new_size = (int)ifp->if_bytes + byte_diff;
475
476	ASSERT(new_size >= 0);
477	ASSERT(new_size <= XFS_IFORK_SIZE(ip, whichfork));
478
479	if (byte_diff == 0)
480		return;
481
482	if (new_size == 0) {
483		kmem_free(ifp->if_u1.if_data);
484		ifp->if_u1.if_data = NULL;
485		ifp->if_bytes = 0;
486		return;
487	}
488
489	/*
490	 * For inline data, the underlying buffer must be a multiple of 4 bytes
491	 * in size so that it can be logged and stay on word boundaries.
492	 * We enforce that here.
493	 */
494	ifp->if_u1.if_data = kmem_realloc(ifp->if_u1.if_data,
495			roundup(new_size, 4), KM_NOFS);
496	ifp->if_bytes = new_size;
497}
498
499void
500xfs_idestroy_fork(
501	xfs_inode_t	*ip,
502	int		whichfork)
503{
504	struct xfs_ifork	*ifp;
505
506	ifp = XFS_IFORK_PTR(ip, whichfork);
507	if (ifp->if_broot != NULL) {
508		kmem_free(ifp->if_broot);
509		ifp->if_broot = NULL;
510	}
511
512	/*
513	 * If the format is local, then we can't have an extents
514	 * array so just look for an inline data array.  If we're
515	 * not local then we may or may not have an extents list,
516	 * so check and free it up if we do.
517	 */
518	if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) {
519		if (ifp->if_u1.if_data != NULL) {
520			kmem_free(ifp->if_u1.if_data);
521			ifp->if_u1.if_data = NULL;
522		}
523	} else if ((ifp->if_flags & XFS_IFEXTENTS) && ifp->if_height) {
524		xfs_iext_destroy(ifp);
525	}
526
527	if (whichfork == XFS_ATTR_FORK) {
528		kmem_zone_free(xfs_ifork_zone, ip->i_afp);
529		ip->i_afp = NULL;
530	} else if (whichfork == XFS_COW_FORK) {
531		kmem_zone_free(xfs_ifork_zone, ip->i_cowfp);
532		ip->i_cowfp = NULL;
533	}
534}
535
536/*
537 * Convert in-core extents to on-disk form
538 *
539 * In the case of the data fork, the in-core and on-disk fork sizes can be
540 * different due to delayed allocation extents. We only copy on-disk extents
541 * here, so callers must always use the physical fork size to determine the
542 * size of the buffer passed to this routine.  We will return the size actually
543 * used.
544 */
545int
546xfs_iextents_copy(
547	struct xfs_inode	*ip,
548	struct xfs_bmbt_rec	*dp,
549	int			whichfork)
550{
551	int			state = xfs_bmap_fork_to_state(whichfork);
552	struct xfs_ifork	*ifp = XFS_IFORK_PTR(ip, whichfork);
553	struct xfs_iext_cursor	icur;
554	struct xfs_bmbt_irec	rec;
555	int			copied = 0;
556
557	ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL | XFS_ILOCK_SHARED));
558	ASSERT(ifp->if_bytes > 0);
559
560	for_each_xfs_iext(ifp, &icur, &rec) {
561		if (isnullstartblock(rec.br_startblock))
562			continue;
563		ASSERT(xfs_bmap_validate_extent(ip, whichfork, &rec) == NULL);
564		xfs_bmbt_disk_set_all(dp, &rec);
565		trace_xfs_write_extent(ip, &icur, state, _RET_IP_);
566		copied += sizeof(struct xfs_bmbt_rec);
567		dp++;
568	}
569
570	ASSERT(copied > 0);
571	ASSERT(copied <= ifp->if_bytes);
572	return copied;
573}
574
575/*
576 * Each of the following cases stores data into the same region
577 * of the on-disk inode, so only one of them can be valid at
578 * any given time. While it is possible to have conflicting formats
579 * and log flags, e.g. having XFS_ILOG_?DATA set when the fork is
580 * in EXTENTS format, this can only happen when the fork has
581 * changed formats after being modified but before being flushed.
582 * In these cases, the format always takes precedence, because the
583 * format indicates the current state of the fork.
584 */
585void
586xfs_iflush_fork(
587	xfs_inode_t		*ip,
588	xfs_dinode_t		*dip,
589	xfs_inode_log_item_t	*iip,
590	int			whichfork)
591{
592	char			*cp;
593	struct xfs_ifork	*ifp;
594	xfs_mount_t		*mp;
595	static const short	brootflag[2] =
596		{ XFS_ILOG_DBROOT, XFS_ILOG_ABROOT };
597	static const short	dataflag[2] =
598		{ XFS_ILOG_DDATA, XFS_ILOG_ADATA };
599	static const short	extflag[2] =
600		{ XFS_ILOG_DEXT, XFS_ILOG_AEXT };
601
602	if (!iip)
603		return;
604	ifp = XFS_IFORK_PTR(ip, whichfork);
605	/*
606	 * This can happen if we gave up in iformat in an error path,
607	 * for the attribute fork.
608	 */
609	if (!ifp) {
610		ASSERT(whichfork == XFS_ATTR_FORK);
611		return;
612	}
613	cp = XFS_DFORK_PTR(dip, whichfork);
614	mp = ip->i_mount;
615	switch (XFS_IFORK_FORMAT(ip, whichfork)) {
616	case XFS_DINODE_FMT_LOCAL:
617		if ((iip->ili_fields & dataflag[whichfork]) &&
618		    (ifp->if_bytes > 0)) {
619			ASSERT(ifp->if_u1.if_data != NULL);
620			ASSERT(ifp->if_bytes <= XFS_IFORK_SIZE(ip, whichfork));
621			memcpy(cp, ifp->if_u1.if_data, ifp->if_bytes);
622		}
623		break;
624
625	case XFS_DINODE_FMT_EXTENTS:
626		ASSERT((ifp->if_flags & XFS_IFEXTENTS) ||
627		       !(iip->ili_fields & extflag[whichfork]));
628		if ((iip->ili_fields & extflag[whichfork]) &&
629		    (ifp->if_bytes > 0)) {
630			ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) > 0);
631			(void)xfs_iextents_copy(ip, (xfs_bmbt_rec_t *)cp,
632				whichfork);
633		}
634		break;
635
636	case XFS_DINODE_FMT_BTREE:
637		if ((iip->ili_fields & brootflag[whichfork]) &&
638		    (ifp->if_broot_bytes > 0)) {
639			ASSERT(ifp->if_broot != NULL);
640			ASSERT(XFS_BMAP_BMDR_SPACE(ifp->if_broot) <=
641			        XFS_IFORK_SIZE(ip, whichfork));
642			xfs_bmbt_to_bmdr(mp, ifp->if_broot, ifp->if_broot_bytes,
643				(xfs_bmdr_block_t *)cp,
644				XFS_DFORK_SIZE(dip, mp, whichfork));
645		}
646		break;
647
648	case XFS_DINODE_FMT_DEV:
649		if (iip->ili_fields & XFS_ILOG_DEV) {
650			ASSERT(whichfork == XFS_DATA_FORK);
651			xfs_dinode_put_rdev(dip,
652					linux_to_xfs_dev_t(VFS_I(ip)->i_rdev));
653		}
654		break;
655
656	default:
657		ASSERT(0);
658		break;
659	}
660}
661
662/* Convert bmap state flags to an inode fork. */
663struct xfs_ifork *
664xfs_iext_state_to_fork(
665	struct xfs_inode	*ip,
666	int			state)
667{
668	if (state & BMAP_COWFORK)
669		return ip->i_cowfp;
670	else if (state & BMAP_ATTRFORK)
671		return ip->i_afp;
672	return &ip->i_df;
673}
674
675/*
676 * Initialize an inode's copy-on-write fork.
677 */
678void
679xfs_ifork_init_cow(
680	struct xfs_inode	*ip)
681{
682	if (ip->i_cowfp)
683		return;
684
685	ip->i_cowfp = kmem_zone_zalloc(xfs_ifork_zone,
686				       KM_NOFS);
687	ip->i_cowfp->if_flags = XFS_IFEXTENTS;
688	ip->i_cformat = XFS_DINODE_FMT_EXTENTS;
689	ip->i_cnextents = 0;
690}
691
692/* Default fork content verifiers. */
693struct xfs_ifork_ops xfs_default_ifork_ops = {
694	.verify_attr	= xfs_attr_shortform_verify,
695	.verify_dir	= xfs_dir2_sf_verify,
696	.verify_symlink	= xfs_symlink_shortform_verify,
697};
698
699/* Verify the inline contents of the data fork of an inode. */
700xfs_failaddr_t
701xfs_ifork_verify_data(
702	struct xfs_inode	*ip,
703	struct xfs_ifork_ops	*ops)
704{
705	/* Non-local data fork, we're done. */
706	if (ip->i_d.di_format != XFS_DINODE_FMT_LOCAL)
707		return NULL;
708
709	/* Check the inline data fork if there is one. */
710	switch (VFS_I(ip)->i_mode & S_IFMT) {
711	case S_IFDIR:
712		return ops->verify_dir(ip);
713	case S_IFLNK:
714		return ops->verify_symlink(ip);
715	default:
716		return NULL;
717	}
718}
719
720/* Verify the inline contents of the attr fork of an inode. */
721xfs_failaddr_t
722xfs_ifork_verify_attr(
723	struct xfs_inode	*ip,
724	struct xfs_ifork_ops	*ops)
725{
726	/* There has to be an attr fork allocated if aformat is local. */
727	if (ip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL)
728		return NULL;
729	if (!XFS_IFORK_PTR(ip, XFS_ATTR_FORK))
730		return __this_address;
731	return ops->verify_attr(ip);
732}