Linux Audio

Check our new training course

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