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