xref: /linux/fs/xfs/scrub/tempfile.c (revision 9a95c5bfbf02a0a7f5983280fe284a0ff0836c34)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) 2021-2024 Oracle.  All Rights Reserved.
4  * Author: Darrick J. Wong <djwong@kernel.org>
5  */
6 #include "xfs.h"
7 #include "xfs_fs.h"
8 #include "xfs_shared.h"
9 #include "xfs_format.h"
10 #include "xfs_trans_resv.h"
11 #include "xfs_mount.h"
12 #include "xfs_log_format.h"
13 #include "xfs_trans.h"
14 #include "xfs_inode.h"
15 #include "xfs_ialloc.h"
16 #include "xfs_quota.h"
17 #include "xfs_bmap.h"
18 #include "xfs_bmap_btree.h"
19 #include "xfs_trans_space.h"
20 #include "xfs_dir2.h"
21 #include "xfs_exchrange.h"
22 #include "xfs_exchmaps.h"
23 #include "xfs_defer.h"
24 #include "xfs_symlink_remote.h"
25 #include "scrub/scrub.h"
26 #include "scrub/common.h"
27 #include "scrub/repair.h"
28 #include "scrub/trace.h"
29 #include "scrub/tempfile.h"
30 #include "scrub/tempexch.h"
31 #include "scrub/xfile.h"
32 
33 /*
34  * Create a temporary file for reconstructing metadata, with the intention of
35  * atomically exchanging the temporary file's contents with the file that's
36  * being repaired.
37  */
38 int
39 xrep_tempfile_create(
40 	struct xfs_scrub	*sc,
41 	uint16_t		mode)
42 {
43 	struct xfs_mount	*mp = sc->mp;
44 	struct xfs_trans	*tp = NULL;
45 	struct xfs_dquot	*udqp = NULL;
46 	struct xfs_dquot	*gdqp = NULL;
47 	struct xfs_dquot	*pdqp = NULL;
48 	struct xfs_trans_res	*tres;
49 	struct xfs_inode	*dp = mp->m_rootip;
50 	xfs_ino_t		ino;
51 	unsigned int		resblks;
52 	bool			is_dir = S_ISDIR(mode);
53 	int			error;
54 
55 	if (xfs_is_shutdown(mp))
56 		return -EIO;
57 	if (xfs_is_readonly(mp))
58 		return -EROFS;
59 
60 	ASSERT(sc->tp == NULL);
61 	ASSERT(sc->tempip == NULL);
62 
63 	/*
64 	 * Make sure that we have allocated dquot(s) on disk.  The temporary
65 	 * inode should be completely root owned so that we don't fail due to
66 	 * quota limits.
67 	 */
68 	error = xfs_qm_vop_dqalloc(dp, GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, 0,
69 			XFS_QMOPT_QUOTALL, &udqp, &gdqp, &pdqp);
70 	if (error)
71 		return error;
72 
73 	if (is_dir) {
74 		resblks = xfs_mkdir_space_res(mp, 0);
75 		tres = &M_RES(mp)->tr_mkdir;
76 	} else {
77 		resblks = XFS_IALLOC_SPACE_RES(mp);
78 		tres = &M_RES(mp)->tr_create_tmpfile;
79 	}
80 
81 	error = xfs_trans_alloc_icreate(mp, tres, udqp, gdqp, pdqp, resblks,
82 			&tp);
83 	if (error)
84 		goto out_release_dquots;
85 
86 	/* Allocate inode, set up directory. */
87 	error = xfs_dialloc(&tp, dp->i_ino, mode, &ino);
88 	if (error)
89 		goto out_trans_cancel;
90 	error = xfs_init_new_inode(&nop_mnt_idmap, tp, dp, ino, mode, 0, 0,
91 			0, false, &sc->tempip);
92 	if (error)
93 		goto out_trans_cancel;
94 
95 	/* Change the ownership of the inode to root. */
96 	VFS_I(sc->tempip)->i_uid = GLOBAL_ROOT_UID;
97 	VFS_I(sc->tempip)->i_gid = GLOBAL_ROOT_GID;
98 	sc->tempip->i_diflags &= ~(XFS_DIFLAG_REALTIME | XFS_DIFLAG_RTINHERIT);
99 	xfs_trans_log_inode(tp, sc->tempip, XFS_ILOG_CORE);
100 
101 	/*
102 	 * Mark our temporary file as private so that LSMs and the ACL code
103 	 * don't try to add their own metadata or reason about these files.
104 	 * The file should never be exposed to userspace.
105 	 */
106 	VFS_I(sc->tempip)->i_flags |= S_PRIVATE;
107 	VFS_I(sc->tempip)->i_opflags &= ~IOP_XATTR;
108 
109 	if (is_dir) {
110 		error = xfs_dir_init(tp, sc->tempip, dp);
111 		if (error)
112 			goto out_trans_cancel;
113 	} else if (S_ISLNK(VFS_I(sc->tempip)->i_mode)) {
114 		/*
115 		 * Initialize the temporary symlink with a meaningless target
116 		 * that won't trip the verifiers.  Repair must rewrite the
117 		 * target with meaningful content before swapping with the file
118 		 * being repaired.  A single-byte target will not write a
119 		 * remote target block, so the owner is irrelevant.
120 		 */
121 		error = xfs_symlink_write_target(tp, sc->tempip,
122 				sc->tempip->i_ino, ".", 1, 0, 0);
123 		if (error)
124 			goto out_trans_cancel;
125 	}
126 
127 	/*
128 	 * Attach the dquot(s) to the inodes and modify them incore.
129 	 * These ids of the inode couldn't have changed since the new
130 	 * inode has been locked ever since it was created.
131 	 */
132 	xfs_qm_vop_create_dqattach(tp, sc->tempip, udqp, gdqp, pdqp);
133 
134 	/*
135 	 * Put our temp file on the unlinked list so it's purged automatically.
136 	 * All file-based metadata being reconstructed using this file must be
137 	 * atomically exchanged with the original file because the contents
138 	 * here will be purged when the inode is dropped or log recovery cleans
139 	 * out the unlinked list.
140 	 */
141 	error = xfs_iunlink(tp, sc->tempip);
142 	if (error)
143 		goto out_trans_cancel;
144 
145 	error = xfs_trans_commit(tp);
146 	if (error)
147 		goto out_release_inode;
148 
149 	trace_xrep_tempfile_create(sc);
150 
151 	xfs_qm_dqrele(udqp);
152 	xfs_qm_dqrele(gdqp);
153 	xfs_qm_dqrele(pdqp);
154 
155 	/* Finish setting up the incore / vfs context. */
156 	xfs_iunlock(sc->tempip, XFS_ILOCK_EXCL);
157 	xfs_setup_iops(sc->tempip);
158 	xfs_finish_inode_setup(sc->tempip);
159 
160 	sc->temp_ilock_flags = 0;
161 	return error;
162 
163 out_trans_cancel:
164 	xfs_trans_cancel(tp);
165 out_release_inode:
166 	/*
167 	 * Wait until after the current transaction is aborted to finish the
168 	 * setup of the inode and release the inode.  This prevents recursive
169 	 * transactions and deadlocks from xfs_inactive.
170 	 */
171 	if (sc->tempip) {
172 		xfs_iunlock(sc->tempip, XFS_ILOCK_EXCL);
173 		xfs_finish_inode_setup(sc->tempip);
174 		xchk_irele(sc, sc->tempip);
175 	}
176 out_release_dquots:
177 	xfs_qm_dqrele(udqp);
178 	xfs_qm_dqrele(gdqp);
179 	xfs_qm_dqrele(pdqp);
180 
181 	return error;
182 }
183 
184 /* Take IOLOCK_EXCL on the temporary file, maybe. */
185 bool
186 xrep_tempfile_iolock_nowait(
187 	struct xfs_scrub	*sc)
188 {
189 	if (xfs_ilock_nowait(sc->tempip, XFS_IOLOCK_EXCL)) {
190 		sc->temp_ilock_flags |= XFS_IOLOCK_EXCL;
191 		return true;
192 	}
193 
194 	return false;
195 }
196 
197 /*
198  * Take the temporary file's IOLOCK while holding a different inode's IOLOCK.
199  * In theory nobody else should hold the tempfile's IOLOCK, but we use trylock
200  * to avoid deadlocks and lockdep complaints.
201  */
202 int
203 xrep_tempfile_iolock_polled(
204 	struct xfs_scrub	*sc)
205 {
206 	int			error = 0;
207 
208 	while (!xrep_tempfile_iolock_nowait(sc)) {
209 		if (xchk_should_terminate(sc, &error))
210 			return error;
211 		delay(1);
212 	}
213 
214 	return 0;
215 }
216 
217 /* Release IOLOCK_EXCL on the temporary file. */
218 void
219 xrep_tempfile_iounlock(
220 	struct xfs_scrub	*sc)
221 {
222 	xfs_iunlock(sc->tempip, XFS_IOLOCK_EXCL);
223 	sc->temp_ilock_flags &= ~XFS_IOLOCK_EXCL;
224 }
225 
226 /* Prepare the temporary file for metadata updates by grabbing ILOCK_EXCL. */
227 void
228 xrep_tempfile_ilock(
229 	struct xfs_scrub	*sc)
230 {
231 	sc->temp_ilock_flags |= XFS_ILOCK_EXCL;
232 	xfs_ilock(sc->tempip, XFS_ILOCK_EXCL);
233 }
234 
235 /* Try to grab ILOCK_EXCL on the temporary file. */
236 bool
237 xrep_tempfile_ilock_nowait(
238 	struct xfs_scrub	*sc)
239 {
240 	if (xfs_ilock_nowait(sc->tempip, XFS_ILOCK_EXCL)) {
241 		sc->temp_ilock_flags |= XFS_ILOCK_EXCL;
242 		return true;
243 	}
244 
245 	return false;
246 }
247 
248 /* Unlock ILOCK_EXCL on the temporary file after an update. */
249 void
250 xrep_tempfile_iunlock(
251 	struct xfs_scrub	*sc)
252 {
253 	xfs_iunlock(sc->tempip, XFS_ILOCK_EXCL);
254 	sc->temp_ilock_flags &= ~XFS_ILOCK_EXCL;
255 }
256 
257 /*
258  * Begin the process of making changes to both the file being scrubbed and
259  * the temporary file by taking ILOCK_EXCL on both.
260  */
261 void
262 xrep_tempfile_ilock_both(
263 	struct xfs_scrub	*sc)
264 {
265 	xfs_lock_two_inodes(sc->ip, XFS_ILOCK_EXCL, sc->tempip, XFS_ILOCK_EXCL);
266 	sc->ilock_flags |= XFS_ILOCK_EXCL;
267 	sc->temp_ilock_flags |= XFS_ILOCK_EXCL;
268 }
269 
270 /* Unlock ILOCK_EXCL on both files. */
271 void
272 xrep_tempfile_iunlock_both(
273 	struct xfs_scrub	*sc)
274 {
275 	xrep_tempfile_iunlock(sc);
276 	xchk_iunlock(sc, XFS_ILOCK_EXCL);
277 }
278 
279 /* Release the temporary file. */
280 void
281 xrep_tempfile_rele(
282 	struct xfs_scrub	*sc)
283 {
284 	if (!sc->tempip)
285 		return;
286 
287 	if (sc->temp_ilock_flags) {
288 		xfs_iunlock(sc->tempip, sc->temp_ilock_flags);
289 		sc->temp_ilock_flags = 0;
290 	}
291 
292 	xchk_irele(sc, sc->tempip);
293 	sc->tempip = NULL;
294 }
295 
296 /*
297  * Make sure that the given range of the data fork of the temporary file is
298  * mapped to written blocks.  The caller must ensure that both inodes are
299  * joined to the transaction.
300  */
301 int
302 xrep_tempfile_prealloc(
303 	struct xfs_scrub	*sc,
304 	xfs_fileoff_t		off,
305 	xfs_filblks_t		len)
306 {
307 	struct xfs_bmbt_irec	map;
308 	xfs_fileoff_t		end = off + len;
309 	int			error;
310 
311 	ASSERT(sc->tempip != NULL);
312 	ASSERT(!XFS_NOT_DQATTACHED(sc->mp, sc->tempip));
313 
314 	for (; off < end; off = map.br_startoff + map.br_blockcount) {
315 		int		nmaps = 1;
316 
317 		/*
318 		 * If we have a real extent mapping this block then we're
319 		 * in ok shape.
320 		 */
321 		error = xfs_bmapi_read(sc->tempip, off, end - off, &map, &nmaps,
322 				XFS_DATA_FORK);
323 		if (error)
324 			return error;
325 		if (nmaps == 0) {
326 			ASSERT(nmaps != 0);
327 			return -EFSCORRUPTED;
328 		}
329 
330 		if (xfs_bmap_is_written_extent(&map))
331 			continue;
332 
333 		/*
334 		 * If we find a delalloc reservation then something is very
335 		 * very wrong.  Bail out.
336 		 */
337 		if (map.br_startblock == DELAYSTARTBLOCK)
338 			return -EFSCORRUPTED;
339 
340 		/*
341 		 * Make sure this block has a real zeroed extent allocated to
342 		 * it.
343 		 */
344 		nmaps = 1;
345 		error = xfs_bmapi_write(sc->tp, sc->tempip, off, end - off,
346 				XFS_BMAPI_CONVERT | XFS_BMAPI_ZERO, 0, &map,
347 				&nmaps);
348 		if (error)
349 			return error;
350 		if (nmaps != 1)
351 			return -EFSCORRUPTED;
352 
353 		trace_xrep_tempfile_prealloc(sc, XFS_DATA_FORK, &map);
354 
355 		/* Commit new extent and all deferred work. */
356 		error = xfs_defer_finish(&sc->tp);
357 		if (error)
358 			return error;
359 	}
360 
361 	return 0;
362 }
363 
364 /*
365  * Write data to each block of a file.  The given range of the tempfile's data
366  * fork must already be populated with written extents.
367  */
368 int
369 xrep_tempfile_copyin(
370 	struct xfs_scrub	*sc,
371 	xfs_fileoff_t		off,
372 	xfs_filblks_t		len,
373 	xrep_tempfile_copyin_fn	prep_fn,
374 	void			*data)
375 {
376 	LIST_HEAD(buffers_list);
377 	struct xfs_mount	*mp = sc->mp;
378 	struct xfs_buf		*bp;
379 	xfs_fileoff_t		flush_mask;
380 	xfs_fileoff_t		end = off + len;
381 	loff_t			pos = XFS_FSB_TO_B(mp, off);
382 	int			error = 0;
383 
384 	ASSERT(S_ISREG(VFS_I(sc->tempip)->i_mode));
385 
386 	/* Flush buffers to disk every 512K */
387 	flush_mask = XFS_B_TO_FSBT(mp, (1U << 19)) - 1;
388 
389 	for (; off < end; off++, pos += mp->m_sb.sb_blocksize) {
390 		struct xfs_bmbt_irec	map;
391 		int			nmaps = 1;
392 
393 		/* Read block mapping for this file block. */
394 		error = xfs_bmapi_read(sc->tempip, off, 1, &map, &nmaps, 0);
395 		if (error)
396 			goto out_err;
397 		if (nmaps == 0 || !xfs_bmap_is_written_extent(&map)) {
398 			error = -EFSCORRUPTED;
399 			goto out_err;
400 		}
401 
402 		/* Get the metadata buffer for this offset in the file. */
403 		error = xfs_trans_get_buf(sc->tp, mp->m_ddev_targp,
404 				XFS_FSB_TO_DADDR(mp, map.br_startblock),
405 				mp->m_bsize, 0, &bp);
406 		if (error)
407 			goto out_err;
408 
409 		trace_xrep_tempfile_copyin(sc, XFS_DATA_FORK, &map);
410 
411 		/* Read in a block's worth of data from the xfile. */
412 		error = prep_fn(sc, bp, data);
413 		if (error) {
414 			xfs_trans_brelse(sc->tp, bp);
415 			goto out_err;
416 		}
417 
418 		/* Queue buffer, and flush if we have too much dirty data. */
419 		xfs_buf_delwri_queue_here(bp, &buffers_list);
420 		xfs_trans_brelse(sc->tp, bp);
421 
422 		if (!(off & flush_mask)) {
423 			error = xfs_buf_delwri_submit(&buffers_list);
424 			if (error)
425 				goto out_err;
426 		}
427 	}
428 
429 	/*
430 	 * Write the new blocks to disk.  If the ordered list isn't empty after
431 	 * that, then something went wrong and we have to fail.  This should
432 	 * never happen, but we'll check anyway.
433 	 */
434 	error = xfs_buf_delwri_submit(&buffers_list);
435 	if (error)
436 		goto out_err;
437 
438 	if (!list_empty(&buffers_list)) {
439 		ASSERT(list_empty(&buffers_list));
440 		error = -EIO;
441 		goto out_err;
442 	}
443 
444 	return 0;
445 
446 out_err:
447 	xfs_buf_delwri_cancel(&buffers_list);
448 	return error;
449 }
450 
451 /*
452  * Set the temporary file's size.  Caller must join the tempfile to the scrub
453  * transaction and is responsible for adjusting block mappings as needed.
454  */
455 int
456 xrep_tempfile_set_isize(
457 	struct xfs_scrub	*sc,
458 	unsigned long long	isize)
459 {
460 	if (sc->tempip->i_disk_size == isize)
461 		return 0;
462 
463 	sc->tempip->i_disk_size = isize;
464 	i_size_write(VFS_I(sc->tempip), isize);
465 	return xrep_tempfile_roll_trans(sc);
466 }
467 
468 /*
469  * Roll a repair transaction involving the temporary file.  Caller must join
470  * both the temporary file and the file being scrubbed to the transaction.
471  * This function return with both inodes joined to a new scrub transaction,
472  * or the usual negative errno.
473  */
474 int
475 xrep_tempfile_roll_trans(
476 	struct xfs_scrub	*sc)
477 {
478 	int			error;
479 
480 	xfs_trans_log_inode(sc->tp, sc->tempip, XFS_ILOG_CORE);
481 	error = xrep_roll_trans(sc);
482 	if (error)
483 		return error;
484 
485 	xfs_trans_ijoin(sc->tp, sc->tempip, 0);
486 	return 0;
487 }
488 
489 /*
490  * Fill out the mapping exchange request in preparation for atomically
491  * committing the contents of a metadata file that we've rebuilt in the temp
492  * file.
493  */
494 STATIC int
495 xrep_tempexch_prep_request(
496 	struct xfs_scrub	*sc,
497 	int			whichfork,
498 	struct xrep_tempexch	*tx)
499 {
500 	struct xfs_exchmaps_req	*req = &tx->req;
501 
502 	memset(tx, 0, sizeof(struct xrep_tempexch));
503 
504 	/* COW forks don't exist on disk. */
505 	if (whichfork == XFS_COW_FORK) {
506 		ASSERT(0);
507 		return -EINVAL;
508 	}
509 
510 	/* Both files should have the relevant forks. */
511 	if (!xfs_ifork_ptr(sc->ip, whichfork) ||
512 	    !xfs_ifork_ptr(sc->tempip, whichfork)) {
513 		ASSERT(xfs_ifork_ptr(sc->ip, whichfork) != NULL);
514 		ASSERT(xfs_ifork_ptr(sc->tempip, whichfork) != NULL);
515 		return -EINVAL;
516 	}
517 
518 	/* Exchange all mappings in both forks. */
519 	req->ip1 = sc->tempip;
520 	req->ip2 = sc->ip;
521 	req->startoff1 = 0;
522 	req->startoff2 = 0;
523 	switch (whichfork) {
524 	case XFS_ATTR_FORK:
525 		req->flags |= XFS_EXCHMAPS_ATTR_FORK;
526 		break;
527 	case XFS_DATA_FORK:
528 		/* Always exchange sizes when exchanging data fork mappings. */
529 		req->flags |= XFS_EXCHMAPS_SET_SIZES;
530 		break;
531 	}
532 	req->blockcount = XFS_MAX_FILEOFF;
533 
534 	return 0;
535 }
536 
537 /*
538  * Fill out the mapping exchange resource estimation structures in preparation
539  * for exchanging the contents of a metadata file that we've rebuilt in the
540  * temp file.  Caller must hold IOLOCK_EXCL but not ILOCK_EXCL on both files.
541  */
542 STATIC int
543 xrep_tempexch_estimate(
544 	struct xfs_scrub	*sc,
545 	struct xrep_tempexch	*tx)
546 {
547 	struct xfs_exchmaps_req	*req = &tx->req;
548 	struct xfs_ifork	*ifp;
549 	struct xfs_ifork	*tifp;
550 	int			whichfork = xfs_exchmaps_reqfork(req);
551 	int			state = 0;
552 
553 	/*
554 	 * The exchmaps code only knows how to exchange file fork space
555 	 * mappings.  Any fork data in local format must be promoted to a
556 	 * single block before the exchange can take place.
557 	 */
558 	ifp = xfs_ifork_ptr(sc->ip, whichfork);
559 	if (ifp->if_format == XFS_DINODE_FMT_LOCAL)
560 		state |= 1;
561 
562 	tifp = xfs_ifork_ptr(sc->tempip, whichfork);
563 	if (tifp->if_format == XFS_DINODE_FMT_LOCAL)
564 		state |= 2;
565 
566 	switch (state) {
567 	case 0:
568 		/* Both files have mapped extents; use the regular estimate. */
569 		return xfs_exchrange_estimate(req);
570 	case 1:
571 		/*
572 		 * The file being repaired is in local format, but the temp
573 		 * file has mapped extents.  To perform the exchange, the file
574 		 * being repaired must have its shorform data converted to an
575 		 * ondisk block so that the forks will be in extents format.
576 		 * We need one resblk for the conversion; the number of
577 		 * exchanges is (worst case) the temporary file's extent count
578 		 * plus the block we converted.
579 		 */
580 		req->ip1_bcount = sc->tempip->i_nblocks;
581 		req->ip2_bcount = 1;
582 		req->nr_exchanges = 1 + tifp->if_nextents;
583 		req->resblks = 1;
584 		break;
585 	case 2:
586 		/*
587 		 * The temporary file is in local format, but the file being
588 		 * repaired has mapped extents.  To perform the exchange, the
589 		 * temp file must have its shortform data converted to an
590 		 * ondisk block, and the fork changed to extents format.  We
591 		 * need one resblk for the conversion; the number of exchanges
592 		 * is (worst case) the extent count of the file being repaired
593 		 * plus the block we converted.
594 		 */
595 		req->ip1_bcount = 1;
596 		req->ip2_bcount = sc->ip->i_nblocks;
597 		req->nr_exchanges = 1 + ifp->if_nextents;
598 		req->resblks = 1;
599 		break;
600 	case 3:
601 		/*
602 		 * Both forks are in local format.  To perform the exchange,
603 		 * both files must have their shortform data converted to
604 		 * fsblocks, and both forks must be converted to extents
605 		 * format.  We need two resblks for the two conversions, and
606 		 * the number of exchanges is 1 since there's only one block at
607 		 * fileoff 0.  Presumably, the caller could not exchange the
608 		 * two inode fork areas directly.
609 		 */
610 		req->ip1_bcount = 1;
611 		req->ip2_bcount = 1;
612 		req->nr_exchanges = 1;
613 		req->resblks = 2;
614 		break;
615 	}
616 
617 	return xfs_exchmaps_estimate_overhead(req);
618 }
619 
620 /*
621  * Obtain a quota reservation to make sure we don't hit EDQUOT.  We can skip
622  * this if quota enforcement is disabled or if both inodes' dquots are the
623  * same.  The qretry structure must be initialized to zeroes before the first
624  * call to this function.
625  */
626 STATIC int
627 xrep_tempexch_reserve_quota(
628 	struct xfs_scrub		*sc,
629 	const struct xrep_tempexch	*tx)
630 {
631 	struct xfs_trans		*tp = sc->tp;
632 	const struct xfs_exchmaps_req	*req = &tx->req;
633 	int64_t				ddelta, rdelta;
634 	int				error;
635 
636 	/*
637 	 * Don't bother with a quota reservation if we're not enforcing them
638 	 * or the two inodes have the same dquots.
639 	 */
640 	if (!XFS_IS_QUOTA_ON(tp->t_mountp) || req->ip1 == req->ip2 ||
641 	    (req->ip1->i_udquot == req->ip2->i_udquot &&
642 	     req->ip1->i_gdquot == req->ip2->i_gdquot &&
643 	     req->ip1->i_pdquot == req->ip2->i_pdquot))
644 		return 0;
645 
646 	/*
647 	 * Quota reservation for each file comes from two sources.  First, we
648 	 * need to account for any net gain in mapped blocks during the
649 	 * exchange.  Second, we need reservation for the gross gain in mapped
650 	 * blocks so that we don't trip over any quota block reservation
651 	 * assertions.  We must reserve the gross gain because the quota code
652 	 * subtracts from bcount the number of blocks that we unmap; it does
653 	 * not add that quantity back to the quota block reservation.
654 	 */
655 	ddelta = max_t(int64_t, 0, req->ip2_bcount - req->ip1_bcount);
656 	rdelta = max_t(int64_t, 0, req->ip2_rtbcount - req->ip1_rtbcount);
657 	error = xfs_trans_reserve_quota_nblks(tp, req->ip1,
658 			ddelta + req->ip1_bcount, rdelta + req->ip1_rtbcount,
659 			true);
660 	if (error)
661 		return error;
662 
663 	ddelta = max_t(int64_t, 0, req->ip1_bcount - req->ip2_bcount);
664 	rdelta = max_t(int64_t, 0, req->ip1_rtbcount - req->ip2_rtbcount);
665 	return xfs_trans_reserve_quota_nblks(tp, req->ip2,
666 			ddelta + req->ip2_bcount, rdelta + req->ip2_rtbcount,
667 			true);
668 }
669 
670 /*
671  * Prepare an existing transaction for an atomic file contents exchange.
672  *
673  * This function fills out the mapping exchange request and resource estimation
674  * structures in preparation for exchanging the contents of a metadata file
675  * that has been rebuilt in the temp file.  Next, it reserves space and quota
676  * for the transaction.
677  *
678  * The caller must hold ILOCK_EXCL of the scrub target file and the temporary
679  * file.  The caller must join both inodes to the transaction with no unlock
680  * flags, and is responsible for dropping both ILOCKs when appropriate.  Only
681  * use this when those ILOCKs cannot be dropped.
682  */
683 int
684 xrep_tempexch_trans_reserve(
685 	struct xfs_scrub	*sc,
686 	int			whichfork,
687 	struct xrep_tempexch	*tx)
688 {
689 	int			error;
690 
691 	ASSERT(sc->tp != NULL);
692 	xfs_assert_ilocked(sc->ip, XFS_ILOCK_EXCL);
693 	xfs_assert_ilocked(sc->tempip, XFS_ILOCK_EXCL);
694 
695 	error = xrep_tempexch_prep_request(sc, whichfork, tx);
696 	if (error)
697 		return error;
698 
699 	error = xfs_exchmaps_estimate(&tx->req);
700 	if (error)
701 		return error;
702 
703 	error = xfs_trans_reserve_more(sc->tp, tx->req.resblks, 0);
704 	if (error)
705 		return error;
706 
707 	return xrep_tempexch_reserve_quota(sc, tx);
708 }
709 
710 /*
711  * Create a new transaction for a file contents exchange.
712  *
713  * This function fills out the mapping excahange request and resource
714  * estimation structures in preparation for exchanging the contents of a
715  * metadata file that has been rebuilt in the temp file.  Next, it reserves
716  * space, takes ILOCK_EXCL of both inodes, joins them to the transaction and
717  * reserves quota for the transaction.
718  *
719  * The caller is responsible for dropping both ILOCKs when appropriate.
720  */
721 int
722 xrep_tempexch_trans_alloc(
723 	struct xfs_scrub	*sc,
724 	int			whichfork,
725 	struct xrep_tempexch	*tx)
726 {
727 	unsigned int		flags = 0;
728 	int			error;
729 
730 	ASSERT(sc->tp == NULL);
731 	ASSERT(xfs_has_exchange_range(sc->mp));
732 
733 	error = xrep_tempexch_prep_request(sc, whichfork, tx);
734 	if (error)
735 		return error;
736 
737 	error = xrep_tempexch_estimate(sc, tx);
738 	if (error)
739 		return error;
740 
741 	if (xfs_has_lazysbcount(sc->mp))
742 		flags |= XFS_TRANS_RES_FDBLKS;
743 
744 	error = xfs_trans_alloc(sc->mp, &M_RES(sc->mp)->tr_itruncate,
745 			tx->req.resblks, 0, flags, &sc->tp);
746 	if (error)
747 		return error;
748 
749 	sc->temp_ilock_flags |= XFS_ILOCK_EXCL;
750 	sc->ilock_flags |= XFS_ILOCK_EXCL;
751 	xfs_exchrange_ilock(sc->tp, sc->ip, sc->tempip);
752 
753 	return xrep_tempexch_reserve_quota(sc, tx);
754 }
755 
756 /*
757  * Exchange file mappings (and hence file contents) between the file being
758  * repaired and the temporary file.  Returns with both inodes locked and joined
759  * to a clean scrub transaction.
760  */
761 int
762 xrep_tempexch_contents(
763 	struct xfs_scrub	*sc,
764 	struct xrep_tempexch	*tx)
765 {
766 	int			error;
767 
768 	ASSERT(xfs_has_exchange_range(sc->mp));
769 
770 	xfs_exchange_mappings(sc->tp, &tx->req);
771 	error = xfs_defer_finish(&sc->tp);
772 	if (error)
773 		return error;
774 
775 	/*
776 	 * If we exchanged the ondisk sizes of two metadata files, we must
777 	 * exchanged the incore sizes as well.
778 	 */
779 	if (tx->req.flags & XFS_EXCHMAPS_SET_SIZES) {
780 		loff_t	temp;
781 
782 		temp = i_size_read(VFS_I(sc->ip));
783 		i_size_write(VFS_I(sc->ip), i_size_read(VFS_I(sc->tempip)));
784 		i_size_write(VFS_I(sc->tempip), temp);
785 	}
786 
787 	return 0;
788 }
789 
790 /*
791  * Write local format data from one of the temporary file's forks into the same
792  * fork of file being repaired, and exchange the file sizes, if appropriate.
793  * Caller must ensure that the file being repaired has enough fork space to
794  * hold all the bytes.
795  */
796 void
797 xrep_tempfile_copyout_local(
798 	struct xfs_scrub	*sc,
799 	int			whichfork)
800 {
801 	struct xfs_ifork	*temp_ifp;
802 	struct xfs_ifork	*ifp;
803 	unsigned int		ilog_flags = XFS_ILOG_CORE;
804 
805 	temp_ifp = xfs_ifork_ptr(sc->tempip, whichfork);
806 	ifp = xfs_ifork_ptr(sc->ip, whichfork);
807 
808 	ASSERT(temp_ifp != NULL);
809 	ASSERT(ifp != NULL);
810 	ASSERT(temp_ifp->if_format == XFS_DINODE_FMT_LOCAL);
811 	ASSERT(ifp->if_format == XFS_DINODE_FMT_LOCAL);
812 
813 	switch (whichfork) {
814 	case XFS_DATA_FORK:
815 		ASSERT(sc->tempip->i_disk_size <=
816 					xfs_inode_data_fork_size(sc->ip));
817 		break;
818 	case XFS_ATTR_FORK:
819 		ASSERT(sc->tempip->i_forkoff >= sc->ip->i_forkoff);
820 		break;
821 	default:
822 		ASSERT(0);
823 		return;
824 	}
825 
826 	/* Recreate @sc->ip's incore fork (ifp) with data from temp_ifp. */
827 	xfs_idestroy_fork(ifp);
828 	xfs_init_local_fork(sc->ip, whichfork, temp_ifp->if_data,
829 			temp_ifp->if_bytes);
830 
831 	if (whichfork == XFS_DATA_FORK) {
832 		i_size_write(VFS_I(sc->ip), i_size_read(VFS_I(sc->tempip)));
833 		sc->ip->i_disk_size = sc->tempip->i_disk_size;
834 	}
835 
836 	ilog_flags |= xfs_ilog_fdata(whichfork);
837 	xfs_trans_log_inode(sc->tp, sc->ip, ilog_flags);
838 }
839 
840 /* Decide if a given XFS inode is a temporary file for a repair. */
841 bool
842 xrep_is_tempfile(
843 	const struct xfs_inode	*ip)
844 {
845 	const struct inode	*inode = &ip->i_vnode;
846 
847 	if (IS_PRIVATE(inode) && !(inode->i_opflags & IOP_XATTR))
848 		return true;
849 
850 	return false;
851 }
852