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