xref: /linux/fs/xfs/scrub/tempfile.c (revision 546b928da0427b0d6c663cbb992bd7bfa9ac7971)
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 static inline unsigned int
xrep_tempexch_estimate_sf_resblks(struct xfs_scrub * sc,int whichfork)653 xrep_tempexch_estimate_sf_resblks(
654 	struct xfs_scrub	*sc,
655 	int			whichfork)
656 {
657 	/* repairing a symlink target */
658 	if (S_ISLNK(VFS_I(sc->ip)->i_mode) && whichfork == XFS_DATA_FORK)
659 		return 1;
660 
661 	/* everything else is a directory or an xattr structure */
662 	return xfs_dabuf_nfsb(sc->mp, whichfork);
663 }
664 
665 /*
666  * Fill out the mapping exchange resource estimation structures in preparation
667  * for exchanging the contents of a metadata file that we've rebuilt in the
668  * temp file.  Caller must hold IOLOCK_EXCL but not ILOCK_EXCL on both files.
669  */
670 STATIC int
xrep_tempexch_estimate(struct xfs_scrub * sc,struct xrep_tempexch * tx)671 xrep_tempexch_estimate(
672 	struct xfs_scrub	*sc,
673 	struct xrep_tempexch	*tx)
674 {
675 	struct xfs_exchmaps_req	*req = &tx->req;
676 	struct xfs_ifork	*ifp;
677 	struct xfs_ifork	*tifp;
678 	int			whichfork = xfs_exchmaps_reqfork(req);
679 	unsigned int		sf_resblks =
680 		xrep_tempexch_estimate_sf_resblks(sc, whichfork);
681 	int			state = 0;
682 
683 	/*
684 	 * The exchmaps code only knows how to exchange file fork space
685 	 * mappings.  Any fork data in local format must be promoted to a
686 	 * single block before the exchange can take place.
687 	 */
688 	ifp = xfs_ifork_ptr(sc->ip, whichfork);
689 	if (ifp->if_format == XFS_DINODE_FMT_LOCAL)
690 		state |= 1;
691 
692 	tifp = xfs_ifork_ptr(sc->tempip, whichfork);
693 	if (tifp->if_format == XFS_DINODE_FMT_LOCAL)
694 		state |= 2;
695 
696 	switch (state) {
697 	case 0:
698 		/* Both files have mapped extents; use the regular estimate. */
699 		return xfs_exchrange_estimate(req);
700 	case 1:
701 		/*
702 		 * The file being repaired is in local format, but the temp
703 		 * file has mapped extents.  To perform the exchange, the file
704 		 * being repaired must have its shorform data converted to an
705 		 * ondisk block so that the forks will be in extents format.
706 		 * We need one resblk for the conversion; the number of
707 		 * exchanges is (worst case) the temporary file's extent count
708 		 * plus the block we converted.
709 		 */
710 		req->ip1_bcount = sc->tempip->i_nblocks;
711 		req->ip2_bcount = sf_resblks;
712 		req->nr_exchanges = 1 + tifp->if_nextents;
713 		req->resblks = sf_resblks;
714 		break;
715 	case 2:
716 		/*
717 		 * The temporary file is in local format, but the file being
718 		 * repaired has mapped extents.  To perform the exchange, the
719 		 * temp file must have its shortform data converted to an
720 		 * ondisk block, and the fork changed to extents format.  We
721 		 * need one resblk for the conversion; the number of exchanges
722 		 * is (worst case) the extent count of the file being repaired
723 		 * plus the block we converted.
724 		 */
725 		req->ip1_bcount = sf_resblks;
726 		req->ip2_bcount = sc->ip->i_nblocks;
727 		req->nr_exchanges = 1 + ifp->if_nextents;
728 		req->resblks = sf_resblks;
729 		break;
730 	case 3:
731 		/*
732 		 * Both forks are in local format.  To perform the exchange,
733 		 * both files must have their shortform data converted to
734 		 * fsblocks, and both forks must be converted to extents
735 		 * format.  We need two resblks for the two conversions, and
736 		 * the number of exchanges is 1 since there's only one block at
737 		 * fileoff 0.  Presumably, the caller could not exchange the
738 		 * two inode fork areas directly.
739 		 */
740 		req->ip1_bcount = sf_resblks;
741 		req->ip2_bcount = sf_resblks;
742 		req->nr_exchanges = 1;
743 		req->resblks = 2 * sf_resblks;
744 		break;
745 	}
746 
747 	return xfs_exchmaps_estimate_overhead(req);
748 }
749 
750 /*
751  * Obtain a quota reservation to make sure we don't hit EDQUOT.  We can skip
752  * this if quota enforcement is disabled or if both inodes' dquots are the
753  * same.  The qretry structure must be initialized to zeroes before the first
754  * call to this function.
755  */
756 STATIC int
xrep_tempexch_reserve_quota(struct xfs_scrub * sc,const struct xrep_tempexch * tx)757 xrep_tempexch_reserve_quota(
758 	struct xfs_scrub		*sc,
759 	const struct xrep_tempexch	*tx)
760 {
761 	struct xfs_trans		*tp = sc->tp;
762 	const struct xfs_exchmaps_req	*req = &tx->req;
763 	int64_t				ddelta, rdelta;
764 	int				error;
765 
766 	/*
767 	 * Don't bother with a quota reservation if we're not enforcing them
768 	 * or the two inodes have the same dquots.
769 	 */
770 	if (!XFS_IS_QUOTA_ON(tp->t_mountp) || req->ip1 == req->ip2 ||
771 	    xfs_is_metadir_inode(req->ip1) ||
772 	    (req->ip1->i_udquot == req->ip2->i_udquot &&
773 	     req->ip1->i_gdquot == req->ip2->i_gdquot &&
774 	     req->ip1->i_pdquot == req->ip2->i_pdquot))
775 		return 0;
776 
777 	/*
778 	 * Quota reservation for each file comes from two sources.  First, we
779 	 * need to account for any net gain in mapped blocks during the
780 	 * exchange.  Second, we need reservation for the gross gain in mapped
781 	 * blocks so that we don't trip over any quota block reservation
782 	 * assertions.  We must reserve the gross gain because the quota code
783 	 * subtracts from bcount the number of blocks that we unmap; it does
784 	 * not add that quantity back to the quota block reservation.
785 	 */
786 	ddelta = max_t(int64_t, 0, req->ip2_bcount - req->ip1_bcount);
787 	rdelta = max_t(int64_t, 0, req->ip2_rtbcount - req->ip1_rtbcount);
788 	error = xfs_trans_reserve_quota_nblks(tp, req->ip1,
789 			ddelta + req->ip1_bcount, rdelta + req->ip1_rtbcount,
790 			true);
791 	if (error)
792 		return error;
793 
794 	ddelta = max_t(int64_t, 0, req->ip1_bcount - req->ip2_bcount);
795 	rdelta = max_t(int64_t, 0, req->ip1_rtbcount - req->ip2_rtbcount);
796 	return xfs_trans_reserve_quota_nblks(tp, req->ip2,
797 			ddelta + req->ip2_bcount, rdelta + req->ip2_rtbcount,
798 			true);
799 }
800 
801 /*
802  * Prepare an existing transaction for an atomic file contents exchange.
803  *
804  * This function fills out the mapping exchange request and resource estimation
805  * structures in preparation for exchanging the contents of a metadata file
806  * that has been rebuilt in the temp file.  Next, it reserves space and quota
807  * for the transaction.
808  *
809  * The caller must hold ILOCK_EXCL of the scrub target file and the temporary
810  * file.  The caller must join both inodes to the transaction with no unlock
811  * flags, and is responsible for dropping both ILOCKs when appropriate.  Only
812  * use this when those ILOCKs cannot be dropped.
813  */
814 int
xrep_tempexch_trans_reserve(struct xfs_scrub * sc,int whichfork,xfs_fileoff_t off,xfs_filblks_t len,struct xrep_tempexch * tx)815 xrep_tempexch_trans_reserve(
816 	struct xfs_scrub	*sc,
817 	int			whichfork,
818 	xfs_fileoff_t		off,
819 	xfs_filblks_t		len,
820 	struct xrep_tempexch	*tx)
821 {
822 	int			error;
823 
824 	ASSERT(sc->tp != NULL);
825 	xfs_assert_ilocked(sc->ip, XFS_ILOCK_EXCL);
826 	xfs_assert_ilocked(sc->tempip, XFS_ILOCK_EXCL);
827 
828 	error = xrep_tempexch_prep_request(sc, whichfork, off, len, tx);
829 	if (error)
830 		return error;
831 
832 	error = xfs_exchmaps_estimate(&tx->req);
833 	if (error)
834 		return error;
835 
836 	error = xfs_trans_reserve_more(sc->tp, tx->req.resblks, 0);
837 	if (error)
838 		return error;
839 
840 	return xrep_tempexch_reserve_quota(sc, tx);
841 }
842 
843 /*
844  * Create a new transaction for a file contents exchange.
845  *
846  * This function fills out the mapping excahange request and resource
847  * estimation structures in preparation for exchanging the contents of a
848  * metadata file that has been rebuilt in the temp file.  Next, it reserves
849  * space, takes ILOCK_EXCL of both inodes, joins them to the transaction and
850  * reserves quota for the transaction.
851  *
852  * The caller is responsible for dropping both ILOCKs when appropriate.
853  */
854 int
xrep_tempexch_trans_alloc(struct xfs_scrub * sc,int whichfork,struct xrep_tempexch * tx)855 xrep_tempexch_trans_alloc(
856 	struct xfs_scrub	*sc,
857 	int			whichfork,
858 	struct xrep_tempexch	*tx)
859 {
860 	unsigned int		flags = 0;
861 	int			error;
862 
863 	ASSERT(sc->tp == NULL);
864 	ASSERT(xfs_has_exchange_range(sc->mp));
865 
866 	error = xrep_tempexch_prep_request(sc, whichfork, 0, XFS_MAX_FILEOFF,
867 			tx);
868 	if (error)
869 		return error;
870 
871 	error = xrep_tempexch_estimate(sc, tx);
872 	if (error)
873 		return error;
874 
875 	if (xfs_has_lazysbcount(sc->mp))
876 		flags |= XFS_TRANS_RES_FDBLKS;
877 
878 	error = xfs_trans_alloc(sc->mp, &M_RES(sc->mp)->tr_itruncate,
879 			tx->req.resblks, 0, flags, &sc->tp);
880 	if (error)
881 		return error;
882 
883 	sc->temp_ilock_flags |= XFS_ILOCK_EXCL;
884 	sc->ilock_flags |= XFS_ILOCK_EXCL;
885 	xfs_exchrange_ilock(sc->tp, sc->ip, sc->tempip);
886 
887 	return xrep_tempexch_reserve_quota(sc, tx);
888 }
889 
890 /*
891  * Exchange file mappings (and hence file contents) between the file being
892  * repaired and the temporary file.  Returns with both inodes locked and joined
893  * to a clean scrub transaction.
894  */
895 int
xrep_tempexch_contents(struct xfs_scrub * sc,struct xrep_tempexch * tx)896 xrep_tempexch_contents(
897 	struct xfs_scrub	*sc,
898 	struct xrep_tempexch	*tx)
899 {
900 	int			error;
901 
902 	ASSERT(xfs_has_exchange_range(sc->mp));
903 
904 	xfs_exchange_mappings(sc->tp, &tx->req);
905 	error = xfs_defer_finish(&sc->tp);
906 	if (error)
907 		return error;
908 
909 	/*
910 	 * If we exchanged the ondisk sizes of two metadata files, we must
911 	 * exchanged the incore sizes as well.
912 	 */
913 	if (tx->req.flags & XFS_EXCHMAPS_SET_SIZES) {
914 		loff_t	temp;
915 
916 		temp = i_size_read(VFS_I(sc->ip));
917 		i_size_write(VFS_I(sc->ip), i_size_read(VFS_I(sc->tempip)));
918 		i_size_write(VFS_I(sc->tempip), temp);
919 	}
920 
921 	return 0;
922 }
923 
924 /*
925  * Write local format data from one of the temporary file's forks into the same
926  * fork of file being repaired, and exchange the file sizes, if appropriate.
927  * Caller must ensure that the file being repaired has enough fork space to
928  * hold all the bytes.
929  */
930 void
xrep_tempfile_copyout_local(struct xfs_scrub * sc,int whichfork)931 xrep_tempfile_copyout_local(
932 	struct xfs_scrub	*sc,
933 	int			whichfork)
934 {
935 	struct xfs_ifork	*temp_ifp;
936 	struct xfs_ifork	*ifp;
937 	unsigned int		ilog_flags = XFS_ILOG_CORE;
938 
939 	temp_ifp = xfs_ifork_ptr(sc->tempip, whichfork);
940 	ifp = xfs_ifork_ptr(sc->ip, whichfork);
941 
942 	ASSERT(temp_ifp != NULL);
943 	ASSERT(ifp != NULL);
944 	ASSERT(temp_ifp->if_format == XFS_DINODE_FMT_LOCAL);
945 	ASSERT(ifp->if_format == XFS_DINODE_FMT_LOCAL);
946 
947 	switch (whichfork) {
948 	case XFS_DATA_FORK:
949 		ASSERT(sc->tempip->i_disk_size <=
950 					xfs_inode_data_fork_size(sc->ip));
951 		break;
952 	case XFS_ATTR_FORK:
953 		ASSERT(sc->tempip->i_forkoff >= sc->ip->i_forkoff);
954 		break;
955 	default:
956 		ASSERT(0);
957 		return;
958 	}
959 
960 	/* Recreate @sc->ip's incore fork (ifp) with data from temp_ifp. */
961 	xfs_idestroy_fork(ifp);
962 	xfs_init_local_fork(sc->ip, whichfork, temp_ifp->if_data,
963 			temp_ifp->if_bytes);
964 
965 	if (whichfork == XFS_DATA_FORK) {
966 		i_size_write(VFS_I(sc->ip), i_size_read(VFS_I(sc->tempip)));
967 		sc->ip->i_disk_size = sc->tempip->i_disk_size;
968 	}
969 
970 	ilog_flags |= xfs_ilog_fdata(whichfork);
971 	xfs_trans_log_inode(sc->tp, sc->ip, ilog_flags);
972 }
973 
974 /* Decide if a given XFS inode is a temporary file for a repair. */
975 bool
xrep_is_tempfile(const struct xfs_inode * ip)976 xrep_is_tempfile(
977 	const struct xfs_inode	*ip)
978 {
979 	const struct inode	*inode = &ip->i_vnode;
980 	struct xfs_mount	*mp = ip->i_mount;
981 
982 	/*
983 	 * Files in the metadata directory tree also have S_PRIVATE set and
984 	 * IOP_XATTR unset, so we must distinguish them separately.  We (ab)use
985 	 * the IRECOVERY flag to mark temporary metadir inodes knowing that the
986 	 * end of log recovery clears IRECOVERY, so the only ones that can
987 	 * exist during online repair are the ones we create.
988 	 */
989 	if (xfs_has_metadir(mp) && (ip->i_diflags2 & XFS_DIFLAG2_METADATA))
990 		return __xfs_iflags_test(ip, XFS_IRECOVERY);
991 
992 	if (IS_PRIVATE(inode) && !(inode->i_opflags & IOP_XATTR))
993 		return true;
994 
995 	return false;
996 }
997