brintos

brintos / linux-shallow public Read only

0
0
Text · 21.1 KiB · 1158ca4 Raw
819 lines · c
1// SPDX-License-Identifier: GPL-2.02/*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#include "xfs_types.h"27#include "xfs_errortag.h"28#include "xfs_health.h"29#include "xfs_symlink_remote.h"30 31struct kmem_cache *xfs_ifork_cache;32 33void34xfs_init_local_fork(35	struct xfs_inode	*ip,36	int			whichfork,37	const void		*data,38	int64_t			size)39{40	struct xfs_ifork	*ifp = xfs_ifork_ptr(ip, whichfork);41	int			mem_size = size;42	bool			zero_terminate;43 44	/*45	 * If we are using the local fork to store a symlink body we need to46	 * zero-terminate it so that we can pass it back to the VFS directly.47	 * Overallocate the in-memory fork by one for that and add a zero48	 * to terminate it below.49	 */50	zero_terminate = S_ISLNK(VFS_I(ip)->i_mode);51	if (zero_terminate)52		mem_size++;53 54	if (size) {55		char *new_data = kmalloc(mem_size,56				GFP_KERNEL | __GFP_NOLOCKDEP | __GFP_NOFAIL);57 58		memcpy(new_data, data, size);59		if (zero_terminate)60			new_data[size] = '\0';61 62		ifp->if_data = new_data;63	} else {64		ifp->if_data = NULL;65	}66 67	ifp->if_bytes = size;68}69 70/*71 * The file is in-lined in the on-disk inode.72 */73STATIC int74xfs_iformat_local(75	struct xfs_inode	*ip,76	struct xfs_dinode	*dip,77	int			whichfork,78	int			size)79{80	/*81	 * If the size is unreasonable, then something82	 * is wrong and we just bail out rather than crash in83	 * kmalloc() or memcpy() below.84	 */85	if (unlikely(size > XFS_DFORK_SIZE(dip, ip->i_mount, whichfork))) {86		xfs_warn(ip->i_mount,87	"corrupt inode %llu (bad size %d for local fork, size = %zd).",88			(unsigned long long) ip->i_ino, size,89			XFS_DFORK_SIZE(dip, ip->i_mount, whichfork));90		xfs_inode_verifier_error(ip, -EFSCORRUPTED,91				"xfs_iformat_local", dip, sizeof(*dip),92				__this_address);93		xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);94		return -EFSCORRUPTED;95	}96 97	xfs_init_local_fork(ip, whichfork, XFS_DFORK_PTR(dip, whichfork), size);98	return 0;99}100 101/*102 * The file consists of a set of extents all of which fit into the on-disk103 * inode.104 */105STATIC int106xfs_iformat_extents(107	struct xfs_inode	*ip,108	struct xfs_dinode	*dip,109	int			whichfork)110{111	struct xfs_mount	*mp = ip->i_mount;112	struct xfs_ifork	*ifp = xfs_ifork_ptr(ip, whichfork);113	int			state = xfs_bmap_fork_to_state(whichfork);114	xfs_extnum_t		nex = xfs_dfork_nextents(dip, whichfork);115	int			size = nex * sizeof(xfs_bmbt_rec_t);116	struct xfs_iext_cursor	icur;117	struct xfs_bmbt_rec	*dp;118	struct xfs_bmbt_irec	new;119	int			i;120 121	/*122	 * If the number of extents is unreasonable, then something is wrong and123	 * we just bail out rather than crash in kmalloc() or memcpy() below.124	 */125	if (unlikely(size < 0 || size > XFS_DFORK_SIZE(dip, mp, whichfork))) {126		xfs_warn(ip->i_mount, "corrupt inode %llu ((a)extents = %llu).",127			ip->i_ino, nex);128		xfs_inode_verifier_error(ip, -EFSCORRUPTED,129				"xfs_iformat_extents(1)", dip, sizeof(*dip),130				__this_address);131		xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);132		return -EFSCORRUPTED;133	}134 135	ifp->if_bytes = 0;136	ifp->if_data = NULL;137	ifp->if_height = 0;138	if (size) {139		dp = (xfs_bmbt_rec_t *) XFS_DFORK_PTR(dip, whichfork);140 141		xfs_iext_first(ifp, &icur);142		for (i = 0; i < nex; i++, dp++) {143			xfs_failaddr_t	fa;144 145			xfs_bmbt_disk_get_all(dp, &new);146			fa = xfs_bmap_validate_extent(ip, whichfork, &new);147			if (fa) {148				xfs_inode_verifier_error(ip, -EFSCORRUPTED,149						"xfs_iformat_extents(2)",150						dp, sizeof(*dp), fa);151				xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);152				return xfs_bmap_complain_bad_rec(ip, whichfork,153						fa, &new);154			}155 156			xfs_iext_insert(ip, &icur, &new, state);157			trace_xfs_read_extent(ip, &icur, state, _THIS_IP_);158			xfs_iext_next(ifp, &icur);159		}160	}161	return 0;162}163 164/*165 * The file has too many extents to fit into166 * the inode, so they are in B-tree format.167 * Allocate a buffer for the root of the B-tree168 * and copy the root into it.  The i_extents169 * field will remain NULL until all of the170 * extents are read in (when they are needed).171 */172STATIC int173xfs_iformat_btree(174	struct xfs_inode	*ip,175	struct xfs_dinode	*dip,176	int			whichfork)177{178	struct xfs_mount	*mp = ip->i_mount;179	xfs_bmdr_block_t	*dfp;180	struct xfs_ifork	*ifp;181	/* REFERENCED */182	int			nrecs;183	int			size;184	int			level;185 186	ifp = xfs_ifork_ptr(ip, whichfork);187	dfp = (xfs_bmdr_block_t *)XFS_DFORK_PTR(dip, whichfork);188	size = xfs_bmap_broot_space(mp, dfp);189	nrecs = be16_to_cpu(dfp->bb_numrecs);190	level = be16_to_cpu(dfp->bb_level);191 192	/*193	 * blow out if -- fork has less extents than can fit in194	 * fork (fork shouldn't be a btree format), root btree195	 * block has more records than can fit into the fork,196	 * or the number of extents is greater than the number of197	 * blocks.198	 */199	if (unlikely(ifp->if_nextents <= XFS_IFORK_MAXEXT(ip, whichfork) ||200		     nrecs == 0 ||201		     xfs_bmdr_space_calc(nrecs) >202					XFS_DFORK_SIZE(dip, mp, whichfork) ||203		     ifp->if_nextents > ip->i_nblocks) ||204		     level == 0 || level > XFS_BM_MAXLEVELS(mp, whichfork)) {205		xfs_warn(mp, "corrupt inode %llu (btree).",206					(unsigned long long) ip->i_ino);207		xfs_inode_verifier_error(ip, -EFSCORRUPTED,208				"xfs_iformat_btree", dfp, size,209				__this_address);210		xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);211		return -EFSCORRUPTED;212	}213 214	ifp->if_broot_bytes = size;215	ifp->if_broot = kmalloc(size,216				GFP_KERNEL | __GFP_NOLOCKDEP | __GFP_NOFAIL);217	ASSERT(ifp->if_broot != NULL);218	/*219	 * Copy and convert from the on-disk structure220	 * to the in-memory structure.221	 */222	xfs_bmdr_to_bmbt(ip, dfp, XFS_DFORK_SIZE(dip, ip->i_mount, whichfork),223			 ifp->if_broot, size);224 225	ifp->if_bytes = 0;226	ifp->if_data = NULL;227	ifp->if_height = 0;228	return 0;229}230 231int232xfs_iformat_data_fork(233	struct xfs_inode	*ip,234	struct xfs_dinode	*dip)235{236	struct inode		*inode = VFS_I(ip);237	int			error;238 239	/*240	 * Initialize the extent count early, as the per-format routines may241	 * depend on it.  Use release semantics to set needextents /after/ we242	 * set the format. This ensures that we can use acquire semantics on243	 * needextents in xfs_need_iread_extents() and be guaranteed to see a244	 * valid format value after that load.245	 */246	ip->i_df.if_format = dip->di_format;247	ip->i_df.if_nextents = xfs_dfork_data_extents(dip);248	smp_store_release(&ip->i_df.if_needextents,249			   ip->i_df.if_format == XFS_DINODE_FMT_BTREE ? 1 : 0);250 251	switch (inode->i_mode & S_IFMT) {252	case S_IFIFO:253	case S_IFCHR:254	case S_IFBLK:255	case S_IFSOCK:256		ip->i_disk_size = 0;257		inode->i_rdev = xfs_to_linux_dev_t(xfs_dinode_get_rdev(dip));258		return 0;259	case S_IFREG:260	case S_IFLNK:261	case S_IFDIR:262		switch (ip->i_df.if_format) {263		case XFS_DINODE_FMT_LOCAL:264			error = xfs_iformat_local(ip, dip, XFS_DATA_FORK,265					be64_to_cpu(dip->di_size));266			if (!error)267				error = xfs_ifork_verify_local_data(ip);268			return error;269		case XFS_DINODE_FMT_EXTENTS:270			return xfs_iformat_extents(ip, dip, XFS_DATA_FORK);271		case XFS_DINODE_FMT_BTREE:272			return xfs_iformat_btree(ip, dip, XFS_DATA_FORK);273		default:274			xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__,275					dip, sizeof(*dip), __this_address);276			xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);277			return -EFSCORRUPTED;278		}279		break;280	default:281		xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__, dip,282				sizeof(*dip), __this_address);283		xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);284		return -EFSCORRUPTED;285	}286}287 288static uint16_t289xfs_dfork_attr_shortform_size(290	struct xfs_dinode		*dip)291{292	struct xfs_attr_sf_hdr		*sf = XFS_DFORK_APTR(dip);293 294	return be16_to_cpu(sf->totsize);295}296 297void298xfs_ifork_init_attr(299	struct xfs_inode	*ip,300	enum xfs_dinode_fmt	format,301	xfs_extnum_t		nextents)302{303	/*304	 * Initialize the extent count early, as the per-format routines may305	 * depend on it.  Use release semantics to set needextents /after/ we306	 * set the format. This ensures that we can use acquire semantics on307	 * needextents in xfs_need_iread_extents() and be guaranteed to see a308	 * valid format value after that load.309	 */310	ip->i_af.if_format = format;311	ip->i_af.if_nextents = nextents;312	smp_store_release(&ip->i_af.if_needextents,313			   ip->i_af.if_format == XFS_DINODE_FMT_BTREE ? 1 : 0);314}315 316void317xfs_ifork_zap_attr(318	struct xfs_inode	*ip)319{320	xfs_idestroy_fork(&ip->i_af);321	memset(&ip->i_af, 0, sizeof(struct xfs_ifork));322	ip->i_af.if_format = XFS_DINODE_FMT_EXTENTS;323}324 325int326xfs_iformat_attr_fork(327	struct xfs_inode	*ip,328	struct xfs_dinode	*dip)329{330	xfs_extnum_t		naextents = xfs_dfork_attr_extents(dip);331	int			error = 0;332 333	/*334	 * Initialize the extent count early, as the per-format routines may335	 * depend on it.336	 */337	xfs_ifork_init_attr(ip, dip->di_aformat, naextents);338 339	switch (ip->i_af.if_format) {340	case XFS_DINODE_FMT_LOCAL:341		error = xfs_iformat_local(ip, dip, XFS_ATTR_FORK,342				xfs_dfork_attr_shortform_size(dip));343		if (!error)344			error = xfs_ifork_verify_local_attr(ip);345		break;346	case XFS_DINODE_FMT_EXTENTS:347		error = xfs_iformat_extents(ip, dip, XFS_ATTR_FORK);348		break;349	case XFS_DINODE_FMT_BTREE:350		error = xfs_iformat_btree(ip, dip, XFS_ATTR_FORK);351		break;352	default:353		xfs_inode_verifier_error(ip, error, __func__, dip,354				sizeof(*dip), __this_address);355		xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);356		error = -EFSCORRUPTED;357		break;358	}359 360	if (error)361		xfs_ifork_zap_attr(ip);362	return error;363}364 365/*366 * Reallocate the space for if_broot based on the number of records367 * being added or deleted as indicated in rec_diff.  Move the records368 * and pointers in if_broot to fit the new size.  When shrinking this369 * will eliminate holes between the records and pointers created by370 * the caller.  When growing this will create holes to be filled in371 * by the caller.372 *373 * The caller must not request to add more records than would fit in374 * the on-disk inode root.  If the if_broot is currently NULL, then375 * if we are adding records, one will be allocated.  The caller must also376 * not request that the number of records go below zero, although377 * it can go to zero.378 *379 * ip -- the inode whose if_broot area is changing380 * ext_diff -- the change in the number of records, positive or negative,381 *	 requested for the if_broot array.382 */383void384xfs_iroot_realloc(385	xfs_inode_t		*ip,386	int			rec_diff,387	int			whichfork)388{389	struct xfs_mount	*mp = ip->i_mount;390	int			cur_max;391	struct xfs_ifork	*ifp;392	struct xfs_btree_block	*new_broot;393	int			new_max;394	size_t			new_size;395	char			*np;396	char			*op;397 398	/*399	 * Handle the degenerate case quietly.400	 */401	if (rec_diff == 0) {402		return;403	}404 405	ifp = xfs_ifork_ptr(ip, whichfork);406	if (rec_diff > 0) {407		/*408		 * If there wasn't any memory allocated before, just409		 * allocate it now and get out.410		 */411		if (ifp->if_broot_bytes == 0) {412			new_size = xfs_bmap_broot_space_calc(mp, rec_diff);413			ifp->if_broot = kmalloc(new_size,414						GFP_KERNEL | __GFP_NOFAIL);415			ifp->if_broot_bytes = (int)new_size;416			return;417		}418 419		/*420		 * If there is already an existing if_broot, then we need421		 * to realloc() it and shift the pointers to their new422		 * location.  The records don't change location because423		 * they are kept butted up against the btree block header.424		 */425		cur_max = xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, false);426		new_max = cur_max + rec_diff;427		new_size = xfs_bmap_broot_space_calc(mp, new_max);428		ifp->if_broot = krealloc(ifp->if_broot, new_size,429					 GFP_KERNEL | __GFP_NOFAIL);430		op = (char *)xfs_bmap_broot_ptr_addr(mp, ifp->if_broot, 1,431						     ifp->if_broot_bytes);432		np = (char *)xfs_bmap_broot_ptr_addr(mp, ifp->if_broot, 1,433						     (int)new_size);434		ifp->if_broot_bytes = (int)new_size;435		ASSERT(xfs_bmap_bmdr_space(ifp->if_broot) <=436			xfs_inode_fork_size(ip, whichfork));437		memmove(np, op, cur_max * (uint)sizeof(xfs_fsblock_t));438		return;439	}440 441	/*442	 * rec_diff is less than 0.  In this case, we are shrinking the443	 * if_broot buffer.  It must already exist.  If we go to zero444	 * records, just get rid of the root and clear the status bit.445	 */446	ASSERT((ifp->if_broot != NULL) && (ifp->if_broot_bytes > 0));447	cur_max = xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, false);448	new_max = cur_max + rec_diff;449	ASSERT(new_max >= 0);450	if (new_max > 0)451		new_size = xfs_bmap_broot_space_calc(mp, new_max);452	else453		new_size = 0;454	if (new_size > 0) {455		new_broot = kmalloc(new_size, GFP_KERNEL | __GFP_NOFAIL);456		/*457		 * First copy over the btree block header.458		 */459		memcpy(new_broot, ifp->if_broot,460			xfs_bmbt_block_len(ip->i_mount));461	} else {462		new_broot = NULL;463	}464 465	/*466	 * Only copy the keys and pointers if there are any.467	 */468	if (new_max > 0) {469		/*470		 * First copy the keys.471		 */472		op = (char *)xfs_bmbt_key_addr(mp, ifp->if_broot, 1);473		np = (char *)xfs_bmbt_key_addr(mp, new_broot, 1);474		memcpy(np, op, new_max * (uint)sizeof(xfs_bmbt_key_t));475 476		/*477		 * Then copy the pointers.478		 */479		op = (char *)xfs_bmap_broot_ptr_addr(mp, ifp->if_broot, 1,480						     ifp->if_broot_bytes);481		np = (char *)xfs_bmap_broot_ptr_addr(mp, new_broot, 1,482						     (int)new_size);483		memcpy(np, op, new_max * (uint)sizeof(xfs_fsblock_t));484	}485	kfree(ifp->if_broot);486	ifp->if_broot = new_broot;487	ifp->if_broot_bytes = (int)new_size;488	if (ifp->if_broot)489		ASSERT(xfs_bmap_bmdr_space(ifp->if_broot) <=490			xfs_inode_fork_size(ip, whichfork));491	return;492}493 494 495/*496 * This is called when the amount of space needed for if_data497 * is increased or decreased.  The change in size is indicated by498 * the number of bytes that need to be added or deleted in the499 * byte_diff parameter.500 *501 * If the amount of space needed has decreased below the size of the502 * inline buffer, then switch to using the inline buffer.  Otherwise,503 * use krealloc() or kmalloc() to adjust the size of the buffer504 * to what is needed.505 *506 * ip -- the inode whose if_data area is changing507 * byte_diff -- the change in the number of bytes, positive or negative,508 *	 requested for the if_data array.509 */510void *511xfs_idata_realloc(512	struct xfs_inode	*ip,513	int64_t			byte_diff,514	int			whichfork)515{516	struct xfs_ifork	*ifp = xfs_ifork_ptr(ip, whichfork);517	int64_t			new_size = ifp->if_bytes + byte_diff;518 519	ASSERT(new_size >= 0);520	ASSERT(new_size <= xfs_inode_fork_size(ip, whichfork));521 522	if (byte_diff) {523		ifp->if_data = krealloc(ifp->if_data, new_size,524					GFP_KERNEL | __GFP_NOFAIL);525		if (new_size == 0)526			ifp->if_data = NULL;527		ifp->if_bytes = new_size;528	}529 530	return ifp->if_data;531}532 533/* Free all memory and reset a fork back to its initial state. */534void535xfs_idestroy_fork(536	struct xfs_ifork	*ifp)537{538	if (ifp->if_broot != NULL) {539		kfree(ifp->if_broot);540		ifp->if_broot = NULL;541	}542 543	switch (ifp->if_format) {544	case XFS_DINODE_FMT_LOCAL:545		kfree(ifp->if_data);546		ifp->if_data = NULL;547		break;548	case XFS_DINODE_FMT_EXTENTS:549	case XFS_DINODE_FMT_BTREE:550		if (ifp->if_height)551			xfs_iext_destroy(ifp);552		break;553	}554}555 556/*557 * Convert in-core extents to on-disk form558 *559 * In the case of the data fork, the in-core and on-disk fork sizes can be560 * different due to delayed allocation extents. We only copy on-disk extents561 * here, so callers must always use the physical fork size to determine the562 * size of the buffer passed to this routine.  We will return the size actually563 * used.564 */565int566xfs_iextents_copy(567	struct xfs_inode	*ip,568	struct xfs_bmbt_rec	*dp,569	int			whichfork)570{571	int			state = xfs_bmap_fork_to_state(whichfork);572	struct xfs_ifork	*ifp = xfs_ifork_ptr(ip, whichfork);573	struct xfs_iext_cursor	icur;574	struct xfs_bmbt_irec	rec;575	int64_t			copied = 0;576 577	xfs_assert_ilocked(ip, XFS_ILOCK_EXCL | XFS_ILOCK_SHARED);578	ASSERT(ifp->if_bytes > 0);579 580	for_each_xfs_iext(ifp, &icur, &rec) {581		if (isnullstartblock(rec.br_startblock))582			continue;583		ASSERT(xfs_bmap_validate_extent(ip, whichfork, &rec) == NULL);584		xfs_bmbt_disk_set_all(dp, &rec);585		trace_xfs_write_extent(ip, &icur, state, _RET_IP_);586		copied += sizeof(struct xfs_bmbt_rec);587		dp++;588	}589 590	ASSERT(copied > 0);591	ASSERT(copied <= ifp->if_bytes);592	return copied;593}594 595/*596 * Each of the following cases stores data into the same region597 * of the on-disk inode, so only one of them can be valid at598 * any given time. While it is possible to have conflicting formats599 * and log flags, e.g. having XFS_ILOG_?DATA set when the fork is600 * in EXTENTS format, this can only happen when the fork has601 * changed formats after being modified but before being flushed.602 * In these cases, the format always takes precedence, because the603 * format indicates the current state of the fork.604 */605void606xfs_iflush_fork(607	struct xfs_inode	*ip,608	struct xfs_dinode	*dip,609	struct xfs_inode_log_item *iip,610	int			whichfork)611{612	char			*cp;613	struct xfs_ifork	*ifp;614	xfs_mount_t		*mp;615	static const short	brootflag[2] =616		{ XFS_ILOG_DBROOT, XFS_ILOG_ABROOT };617	static const short	dataflag[2] =618		{ XFS_ILOG_DDATA, XFS_ILOG_ADATA };619	static const short	extflag[2] =620		{ XFS_ILOG_DEXT, XFS_ILOG_AEXT };621 622	if (!iip)623		return;624	ifp = xfs_ifork_ptr(ip, whichfork);625	/*626	 * This can happen if we gave up in iformat in an error path,627	 * for the attribute fork.628	 */629	if (!ifp) {630		ASSERT(whichfork == XFS_ATTR_FORK);631		return;632	}633	cp = XFS_DFORK_PTR(dip, whichfork);634	mp = ip->i_mount;635	switch (ifp->if_format) {636	case XFS_DINODE_FMT_LOCAL:637		if ((iip->ili_fields & dataflag[whichfork]) &&638		    (ifp->if_bytes > 0)) {639			ASSERT(ifp->if_data != NULL);640			ASSERT(ifp->if_bytes <= xfs_inode_fork_size(ip, whichfork));641			memcpy(cp, ifp->if_data, ifp->if_bytes);642		}643		break;644 645	case XFS_DINODE_FMT_EXTENTS:646		if ((iip->ili_fields & extflag[whichfork]) &&647		    (ifp->if_bytes > 0)) {648			ASSERT(ifp->if_nextents > 0);649			(void)xfs_iextents_copy(ip, (xfs_bmbt_rec_t *)cp,650				whichfork);651		}652		break;653 654	case XFS_DINODE_FMT_BTREE:655		if ((iip->ili_fields & brootflag[whichfork]) &&656		    (ifp->if_broot_bytes > 0)) {657			ASSERT(ifp->if_broot != NULL);658			ASSERT(xfs_bmap_bmdr_space(ifp->if_broot) <=659			        xfs_inode_fork_size(ip, whichfork));660			xfs_bmbt_to_bmdr(mp, ifp->if_broot, ifp->if_broot_bytes,661				(xfs_bmdr_block_t *)cp,662				XFS_DFORK_SIZE(dip, mp, whichfork));663		}664		break;665 666	case XFS_DINODE_FMT_DEV:667		if (iip->ili_fields & XFS_ILOG_DEV) {668			ASSERT(whichfork == XFS_DATA_FORK);669			xfs_dinode_put_rdev(dip,670					linux_to_xfs_dev_t(VFS_I(ip)->i_rdev));671		}672		break;673 674	default:675		ASSERT(0);676		break;677	}678}679 680/* Convert bmap state flags to an inode fork. */681struct xfs_ifork *682xfs_iext_state_to_fork(683	struct xfs_inode	*ip,684	int			state)685{686	if (state & BMAP_COWFORK)687		return ip->i_cowfp;688	else if (state & BMAP_ATTRFORK)689		return &ip->i_af;690	return &ip->i_df;691}692 693/*694 * Initialize an inode's copy-on-write fork.695 */696void697xfs_ifork_init_cow(698	struct xfs_inode	*ip)699{700	if (ip->i_cowfp)701		return;702 703	ip->i_cowfp = kmem_cache_zalloc(xfs_ifork_cache,704				GFP_KERNEL | __GFP_NOLOCKDEP | __GFP_NOFAIL);705	ip->i_cowfp->if_format = XFS_DINODE_FMT_EXTENTS;706}707 708/* Verify the inline contents of the data fork of an inode. */709int710xfs_ifork_verify_local_data(711	struct xfs_inode	*ip)712{713	xfs_failaddr_t		fa = NULL;714 715	switch (VFS_I(ip)->i_mode & S_IFMT) {716	case S_IFDIR: {717		struct xfs_mount	*mp = ip->i_mount;718		struct xfs_ifork	*ifp = xfs_ifork_ptr(ip, XFS_DATA_FORK);719		struct xfs_dir2_sf_hdr	*sfp = ifp->if_data;720 721		fa = xfs_dir2_sf_verify(mp, sfp, ifp->if_bytes);722		break;723	}724	case S_IFLNK: {725		struct xfs_ifork	*ifp = xfs_ifork_ptr(ip, XFS_DATA_FORK);726 727		fa = xfs_symlink_shortform_verify(ifp->if_data, ifp->if_bytes);728		break;729	}730	default:731		break;732	}733 734	if (fa) {735		xfs_inode_verifier_error(ip, -EFSCORRUPTED, "data fork",736				ip->i_df.if_data, ip->i_df.if_bytes, fa);737		return -EFSCORRUPTED;738	}739 740	return 0;741}742 743/* Verify the inline contents of the attr fork of an inode. */744int745xfs_ifork_verify_local_attr(746	struct xfs_inode	*ip)747{748	struct xfs_ifork	*ifp = &ip->i_af;749	xfs_failaddr_t		fa;750 751	if (!xfs_inode_has_attr_fork(ip)) {752		fa = __this_address;753	} else {754		struct xfs_ifork		*ifp = &ip->i_af;755 756		ASSERT(ifp->if_format == XFS_DINODE_FMT_LOCAL);757		fa = xfs_attr_shortform_verify(ifp->if_data, ifp->if_bytes);758	}759	if (fa) {760		xfs_inode_verifier_error(ip, -EFSCORRUPTED, "attr fork",761				ifp->if_data, ifp->if_bytes, fa);762		return -EFSCORRUPTED;763	}764 765	return 0;766}767 768/*769 * Check if the inode fork supports adding nr_to_add more extents.770 *771 * If it doesn't but we can upgrade it to large extent counters, do the upgrade.772 * If we can't upgrade or are already using big counters but still can't fit the773 * additional extents, return -EFBIG.774 */775int776xfs_iext_count_extend(777	struct xfs_trans	*tp,778	struct xfs_inode	*ip,779	int			whichfork,780	uint			nr_to_add)781{782	struct xfs_mount	*mp = ip->i_mount;783	bool			has_large =784		xfs_inode_has_large_extent_counts(ip);785	struct xfs_ifork	*ifp = xfs_ifork_ptr(ip, whichfork);786	uint64_t		nr_exts;787 788	ASSERT(nr_to_add <= XFS_MAX_EXTCNT_UPGRADE_NR);789 790	if (whichfork == XFS_COW_FORK)791		return 0;792 793	/* no point in upgrading if if_nextents overflows */794	nr_exts = ifp->if_nextents + nr_to_add;795	if (nr_exts < ifp->if_nextents)796		return -EFBIG;797 798	if (XFS_TEST_ERROR(false, mp, XFS_ERRTAG_REDUCE_MAX_IEXTENTS) &&799	    nr_exts > 10)800		return -EFBIG;801 802	if (nr_exts > xfs_iext_max_nextents(has_large, whichfork)) {803		if (has_large || !xfs_has_large_extent_counts(mp))804			return -EFBIG;805		ip->i_diflags2 |= XFS_DIFLAG2_NREXT64;806		xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);807	}808	return 0;809}810 811/* Decide if a file mapping is on the realtime device or not. */812bool813xfs_ifork_is_realtime(814	struct xfs_inode	*ip,815	int			whichfork)816{817	return XFS_IS_REALTIME_INODE(ip) && whichfork != XFS_ATTR_FORK;818}819