xref: /linux/fs/xfs/scrub/orphanage.c (revision f0100363d8c374bd8e9ea7c9ba02744f0b802ca4)
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_trans_space.h"
18 #include "xfs_dir2.h"
19 #include "xfs_icache.h"
20 #include "xfs_bmap.h"
21 #include "xfs_bmap_btree.h"
22 #include "xfs_parent.h"
23 #include "xfs_attr_sf.h"
24 #include "scrub/scrub.h"
25 #include "scrub/common.h"
26 #include "scrub/repair.h"
27 #include "scrub/trace.h"
28 #include "scrub/orphanage.h"
29 #include "scrub/readdir.h"
30 
31 #include <linux/namei.h>
32 
33 /*
34  * The Orphanage
35  * =============
36  *
37  * If the directory tree is damaged, children of that directory become
38  * inaccessible via that file path.  If a child has no other parents, the file
39  * is said to be orphaned.  xfs_repair fixes this situation by creating a
40  * orphanage directory (specifically, /lost+found) and creating a directory
41  * entry pointing to the orphaned file.
42  *
43  * Online repair follows this tactic by creating a root-owned /lost+found
44  * directory if one does not exist.  If an orphan is found, it will move that
45  * files into orphanage.
46  */
47 
48 /* Make the orphanage owned by root. */
49 STATIC int
xrep_chown_orphanage(struct xfs_scrub * sc,struct xfs_inode * dp)50 xrep_chown_orphanage(
51 	struct xfs_scrub	*sc,
52 	struct xfs_inode	*dp)
53 {
54 	struct xfs_trans	*tp;
55 	struct xfs_mount	*mp = sc->mp;
56 	struct xfs_dquot	*udqp = NULL, *gdqp = NULL, *pdqp = NULL;
57 	struct xfs_dquot	*oldu = NULL, *oldg = NULL, *oldp = NULL;
58 	struct inode		*inode = VFS_I(dp);
59 	int			error;
60 
61 	error = xfs_qm_vop_dqalloc(dp, GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, 0,
62 			XFS_QMOPT_QUOTALL, &udqp, &gdqp, &pdqp);
63 	if (error)
64 		return error;
65 
66 	error = xfs_trans_alloc_ichange(dp, udqp, gdqp, pdqp, true, &tp);
67 	if (error)
68 		goto out_dqrele;
69 
70 	/*
71 	 * Always clear setuid/setgid/sticky on the orphanage since we don't
72 	 * normally want that functionality on this directory and xfs_repair
73 	 * doesn't create it this way either.  Leave the other access bits
74 	 * unchanged.
75 	 */
76 	inode->i_mode &= ~(S_ISUID | S_ISGID | S_ISVTX);
77 
78 	/*
79 	 * Change the ownerships and register quota modifications
80 	 * in the transaction.
81 	 */
82 	if (!uid_eq(inode->i_uid, GLOBAL_ROOT_UID)) {
83 		if (XFS_IS_UQUOTA_ON(mp))
84 			oldu = xfs_qm_vop_chown(tp, dp, &dp->i_udquot, udqp);
85 		inode->i_uid = GLOBAL_ROOT_UID;
86 	}
87 	if (!gid_eq(inode->i_gid, GLOBAL_ROOT_GID)) {
88 		if (XFS_IS_GQUOTA_ON(mp))
89 			oldg = xfs_qm_vop_chown(tp, dp, &dp->i_gdquot, gdqp);
90 		inode->i_gid = GLOBAL_ROOT_GID;
91 	}
92 	if (dp->i_projid != 0) {
93 		if (XFS_IS_PQUOTA_ON(mp))
94 			oldp = xfs_qm_vop_chown(tp, dp, &dp->i_pdquot, pdqp);
95 		dp->i_projid = 0;
96 	}
97 
98 	dp->i_diflags &= ~(XFS_DIFLAG_REALTIME | XFS_DIFLAG_RTINHERIT);
99 	xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE);
100 
101 	XFS_STATS_INC(mp, xs_ig_attrchg);
102 
103 	if (xfs_has_wsync(mp))
104 		xfs_trans_set_sync(tp);
105 	error = xfs_trans_commit(tp);
106 
107 	xfs_qm_dqrele(oldu);
108 	xfs_qm_dqrele(oldg);
109 	xfs_qm_dqrele(oldp);
110 
111 out_dqrele:
112 	xfs_qm_dqrele(udqp);
113 	xfs_qm_dqrele(gdqp);
114 	xfs_qm_dqrele(pdqp);
115 	return error;
116 }
117 
118 #define ORPHANAGE	"lost+found"
119 
120 /* Create the orphanage directory, and set sc->orphanage to it. */
121 int
xrep_orphanage_create(struct xfs_scrub * sc)122 xrep_orphanage_create(
123 	struct xfs_scrub	*sc)
124 {
125 	struct xfs_mount	*mp = sc->mp;
126 	struct dentry		*root_dentry, *orphanage_dentry;
127 	struct inode		*root_inode = VFS_I(sc->mp->m_rootip);
128 	struct inode		*orphanage_inode;
129 	int			error;
130 
131 	if (xfs_is_shutdown(mp))
132 		return -EIO;
133 	if (xfs_is_readonly(mp)) {
134 		sc->orphanage = NULL;
135 		return 0;
136 	}
137 
138 	ASSERT(sc->tp == NULL);
139 	ASSERT(sc->orphanage == NULL);
140 
141 	/* Find the dentry for the root directory... */
142 	root_dentry = d_find_alias(root_inode);
143 	if (!root_dentry) {
144 		error = -EFSCORRUPTED;
145 		goto out;
146 	}
147 
148 	/* ...which is a directory, right? */
149 	if (!d_is_dir(root_dentry)) {
150 		error = -EFSCORRUPTED;
151 		goto out_dput_root;
152 	}
153 
154 	/* Try to find the orphanage directory. */
155 	orphanage_dentry = start_creating_noperm(root_dentry, &QSTR(ORPHANAGE));
156 	if (IS_ERR(orphanage_dentry)) {
157 		error = PTR_ERR(orphanage_dentry);
158 		goto out_dput_root;
159 	}
160 
161 	/*
162 	 * Nothing found?  Call mkdir to create the orphanage.  Create the
163 	 * directory without other-user access because we're live and someone
164 	 * could have been relying partly on minimal access to a parent
165 	 * directory to control access to a file we put in here.
166 	 */
167 	if (d_really_is_negative(orphanage_dentry)) {
168 		orphanage_dentry = vfs_mkdir(&nop_mnt_idmap, root_inode,
169 					     orphanage_dentry, 0750, NULL);
170 		error = PTR_ERR(orphanage_dentry);
171 		if (IS_ERR(orphanage_dentry))
172 			goto out_dput_orphanage;
173 	}
174 
175 	/* Not a directory? Bail out. */
176 	if (!d_is_dir(orphanage_dentry)) {
177 		error = -ENOTDIR;
178 		goto out_dput_orphanage;
179 	}
180 
181 	/*
182 	 * Grab a reference to the orphanage.  This /should/ succeed since
183 	 * we hold the root directory locked and therefore nobody can delete
184 	 * the orphanage.
185 	 */
186 	orphanage_inode = igrab(d_inode(orphanage_dentry));
187 	if (!orphanage_inode) {
188 		error = -ENOENT;
189 		goto out_dput_orphanage;
190 	}
191 
192 	/* Make sure the orphanage is owned by root. */
193 	error = xrep_chown_orphanage(sc, XFS_I(orphanage_inode));
194 	if (error)
195 		goto out_rele_orphanage;
196 
197 	/* Stash the reference for later and bail out. */
198 	sc->orphanage = XFS_I(orphanage_inode);
199 	sc->orphanage_ilock_flags = 0;
200 	orphanage_inode = NULL;
201 
202 out_rele_orphanage:
203 	if (orphanage_inode)
204 		xchk_irele(sc, XFS_I(orphanage_inode));
205 out_dput_orphanage:
206 	end_creating(orphanage_dentry);
207 out_dput_root:
208 	dput(root_dentry);
209 out:
210 	return error;
211 }
212 
213 void
xrep_orphanage_ilock(struct xfs_scrub * sc,unsigned int ilock_flags)214 xrep_orphanage_ilock(
215 	struct xfs_scrub	*sc,
216 	unsigned int		ilock_flags)
217 {
218 	sc->orphanage_ilock_flags |= ilock_flags;
219 	xfs_ilock(sc->orphanage, ilock_flags);
220 }
221 
222 bool
xrep_orphanage_ilock_nowait(struct xfs_scrub * sc,unsigned int ilock_flags)223 xrep_orphanage_ilock_nowait(
224 	struct xfs_scrub	*sc,
225 	unsigned int		ilock_flags)
226 {
227 	if (xfs_ilock_nowait(sc->orphanage, ilock_flags)) {
228 		sc->orphanage_ilock_flags |= ilock_flags;
229 		return true;
230 	}
231 
232 	return false;
233 }
234 
235 void
xrep_orphanage_iunlock(struct xfs_scrub * sc,unsigned int ilock_flags)236 xrep_orphanage_iunlock(
237 	struct xfs_scrub	*sc,
238 	unsigned int		ilock_flags)
239 {
240 	xfs_iunlock(sc->orphanage, ilock_flags);
241 	sc->orphanage_ilock_flags &= ~ilock_flags;
242 }
243 
244 /* Grab the IOLOCK of the orphanage and sc->ip. */
245 int
xrep_orphanage_iolock_two(struct xfs_scrub * sc)246 xrep_orphanage_iolock_two(
247 	struct xfs_scrub	*sc)
248 {
249 	int			error = 0;
250 
251 	while (true) {
252 		if (xchk_should_terminate(sc, &error))
253 			return error;
254 
255 		/*
256 		 * Normal XFS takes the IOLOCK before grabbing a transaction.
257 		 * Scrub holds a transaction, which means that we can't block
258 		 * on either IOLOCK.
259 		 */
260 		if (xrep_orphanage_ilock_nowait(sc, XFS_IOLOCK_EXCL)) {
261 			if (xchk_ilock_nowait(sc, XFS_IOLOCK_EXCL))
262 				break;
263 			xrep_orphanage_iunlock(sc, XFS_IOLOCK_EXCL);
264 		}
265 		delay(1);
266 	}
267 
268 	return 0;
269 }
270 
271 /* Release the orphanage. */
272 void
xrep_orphanage_rele(struct xfs_scrub * sc)273 xrep_orphanage_rele(
274 	struct xfs_scrub	*sc)
275 {
276 	if (!sc->orphanage)
277 		return;
278 
279 	if (sc->orphanage_ilock_flags)
280 		xfs_iunlock(sc->orphanage, sc->orphanage_ilock_flags);
281 
282 	xchk_irele(sc, sc->orphanage);
283 	sc->orphanage = NULL;
284 }
285 
286 /* Adoption moves a file into /lost+found */
287 
288 /* Can the orphanage adopt @sc->ip? */
289 bool
xrep_orphanage_can_adopt(struct xfs_scrub * sc)290 xrep_orphanage_can_adopt(
291 	struct xfs_scrub	*sc)
292 {
293 	ASSERT(sc->ip != NULL);
294 
295 	if (!sc->orphanage)
296 		return false;
297 	if (sc->ip == sc->orphanage)
298 		return false;
299 	if (xchk_inode_is_sb_rooted(sc->ip))
300 		return false;
301 	if (xfs_is_internal_inode(sc->ip))
302 		return false;
303 	return true;
304 }
305 
306 /*
307  * Create a new transaction to send a child to the orphanage.
308  *
309  * Allocate a new transaction with sufficient disk space to handle the
310  * adoption, take ILOCK_EXCL of the orphanage and sc->ip, joins them to the
311  * transaction, and reserve quota to reparent the latter.  Caller must hold the
312  * IOLOCK of the orphanage and sc->ip.
313  */
314 int
xrep_adoption_trans_alloc(struct xfs_scrub * sc,struct xrep_adoption * adopt)315 xrep_adoption_trans_alloc(
316 	struct xfs_scrub	*sc,
317 	struct xrep_adoption	*adopt)
318 {
319 	struct xfs_mount	*mp = sc->mp;
320 	unsigned int		child_blkres = 0;
321 	int			error;
322 
323 	ASSERT(sc->tp == NULL);
324 	ASSERT(sc->ip != NULL);
325 	ASSERT(sc->orphanage != NULL);
326 	ASSERT(sc->ilock_flags & XFS_IOLOCK_EXCL);
327 	ASSERT(sc->orphanage_ilock_flags & XFS_IOLOCK_EXCL);
328 	ASSERT(!(sc->ilock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)));
329 	ASSERT(!(sc->orphanage_ilock_flags &
330 				(XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)));
331 
332 	/* Compute the worst case space reservation that we need. */
333 	adopt->sc = sc;
334 	adopt->orphanage_blkres = xfs_link_space_res(mp, MAXNAMELEN);
335 	if (S_ISDIR(VFS_I(sc->ip)->i_mode))
336 		child_blkres = xfs_rename_space_res(mp, 0, false,
337 						    xfs_name_dotdot.len, false);
338 	if (xfs_has_parent(mp))
339 		child_blkres += XFS_ADDAFORK_SPACE_RES(mp);
340 	adopt->child_blkres = child_blkres;
341 
342 	/*
343 	 * Allocate a transaction to link the child into the parent, along with
344 	 * enough disk space to handle expansion of both the orphanage and the
345 	 * dotdot entry of a child directory.
346 	 */
347 	error = xfs_trans_alloc(mp, &M_RES(mp)->tr_link,
348 			adopt->orphanage_blkres + adopt->child_blkres, 0, 0,
349 			&sc->tp);
350 	if (error)
351 		return error;
352 
353 	xfs_lock_two_inodes(sc->orphanage, XFS_ILOCK_EXCL,
354 			    sc->ip, XFS_ILOCK_EXCL);
355 	sc->ilock_flags |= XFS_ILOCK_EXCL;
356 	sc->orphanage_ilock_flags |= XFS_ILOCK_EXCL;
357 
358 	xfs_trans_ijoin(sc->tp, sc->orphanage, 0);
359 	xfs_trans_ijoin(sc->tp, sc->ip, 0);
360 
361 	/*
362 	 * Reserve enough quota in the orphan directory to add the new name.
363 	 * Normally the orphanage should have user/group/project ids of zero
364 	 * and hence is not subject to quota enforcement, but we're allowed to
365 	 * exceed quota to reattach disconnected parts of the directory tree.
366 	 */
367 	error = xfs_trans_reserve_quota_nblks(sc->tp, sc->orphanage,
368 			adopt->orphanage_blkres, 0, true);
369 	if (error)
370 		goto out_cancel;
371 
372 	/*
373 	 * Reserve enough quota in the child directory to change dotdot.
374 	 * Here we're also allowed to exceed file quota to repair inconsistent
375 	 * metadata.
376 	 */
377 	if (adopt->child_blkres) {
378 		error = xfs_trans_reserve_quota_nblks(sc->tp, sc->ip,
379 				adopt->child_blkres, 0, true);
380 		if (error)
381 			goto out_cancel;
382 	}
383 
384 	return 0;
385 out_cancel:
386 	xchk_trans_cancel(sc);
387 	xrep_orphanage_iunlock(sc, XFS_ILOCK_EXCL);
388 	xchk_iunlock(sc, XFS_ILOCK_EXCL);
389 	return error;
390 }
391 
392 /*
393  * Compute the xfs_name for the directory entry that we're adding to the
394  * orphanage.  Caller must hold ILOCKs of sc->ip and the orphanage and must not
395  * reuse namebuf until the adoption completes or is dissolved.
396  */
397 int
xrep_adoption_compute_name(struct xrep_adoption * adopt,struct xfs_name * xname)398 xrep_adoption_compute_name(
399 	struct xrep_adoption	*adopt,
400 	struct xfs_name		*xname)
401 {
402 	struct xfs_scrub	*sc = adopt->sc;
403 	char			*namebuf = (void *)xname->name;
404 	xfs_ino_t		ino;
405 	unsigned int		incr = 0;
406 	int			error = 0;
407 
408 	adopt->xname = xname;
409 	xname->len = snprintf(namebuf, MAXNAMELEN, "%llu", I_INO(sc->ip));
410 	xname->type = xfs_mode_to_ftype(VFS_I(sc->ip)->i_mode);
411 
412 	/* Make sure the filename is unique in the lost+found. */
413 	error = xchk_dir_lookup(sc, sc->orphanage, xname, &ino);
414 	while (error == 0 && incr < 10000) {
415 		xname->len = snprintf(namebuf, MAXNAMELEN, "%llu.%u",
416 				I_INO(sc->ip), ++incr);
417 		error = xchk_dir_lookup(sc, sc->orphanage, xname, &ino);
418 	}
419 	if (error == 0) {
420 		/* We already have 10,000 entries in the orphanage? */
421 		return -EFSCORRUPTED;
422 	}
423 
424 	if (error != -ENOENT)
425 		return error;
426 	return 0;
427 }
428 
429 /*
430  * Make sure the dcache does not have a positive dentry for the name we've
431  * chosen.  The caller should have checked with the ondisk directory, so any
432  * discrepancy is a sign that something is seriously wrong.
433  */
434 static int
xrep_adoption_check_dcache(struct xrep_adoption * adopt)435 xrep_adoption_check_dcache(
436 	struct xrep_adoption	*adopt)
437 {
438 	struct qstr		qname = QSTR_INIT(adopt->xname->name,
439 						  adopt->xname->len);
440 	struct xfs_scrub	*sc = adopt->sc;
441 	struct dentry		*d_orphanage, *d_child;
442 	int			error = 0;
443 
444 	d_orphanage = d_find_alias(VFS_I(sc->orphanage));
445 	if (!d_orphanage)
446 		return 0;
447 
448 	d_child = try_lookup_noperm(&qname, d_orphanage);
449 	if (IS_ERR(d_child)) {
450 		dput(d_orphanage);
451 		return PTR_ERR(d_child);
452 	}
453 
454 	if (d_child) {
455 		trace_xrep_adoption_check_child(sc->mp, d_child);
456 
457 		if (d_is_positive(d_child)) {
458 			ASSERT(d_is_negative(d_child));
459 			error = -EFSCORRUPTED;
460 		}
461 
462 		dput(d_child);
463 	}
464 
465 	dput(d_orphanage);
466 	return error;
467 }
468 
469 /*
470  * Invalidate all dentries for the name that was added to the orphanage
471  * directory, and all dentries pointing to the child inode that was moved.
472  *
473  * There should not be any positive entries for the name, since we've
474  * maintained our lock on the orphanage directory.
475  */
476 static void
xrep_adoption_zap_dcache(struct xrep_adoption * adopt)477 xrep_adoption_zap_dcache(
478 	struct xrep_adoption	*adopt)
479 {
480 	struct qstr		qname = QSTR_INIT(adopt->xname->name,
481 						  adopt->xname->len);
482 	struct xfs_scrub	*sc = adopt->sc;
483 	struct dentry		*d_orphanage, *d_child;
484 
485 	/* Invalidate all dentries for the adoption name */
486 	d_orphanage = d_find_alias(VFS_I(sc->orphanage));
487 	if (!d_orphanage)
488 		return;
489 
490 	d_child = try_lookup_noperm(&qname, d_orphanage);
491 	while (!IS_ERR_OR_NULL(d_child)) {
492 		trace_xrep_adoption_invalidate_child(sc->mp, d_child);
493 
494 		ASSERT(d_is_negative(d_child));
495 		d_invalidate(d_child);
496 		dput(d_child);
497 		d_child = d_lookup(d_orphanage, &qname);
498 	}
499 
500 	dput(d_orphanage);
501 
502 	/* Invalidate all the dentries pointing down to this file. */
503 	while ((d_child = d_find_alias(VFS_I(sc->ip))) != NULL) {
504 		trace_xrep_adoption_invalidate_child(sc->mp, d_child);
505 
506 		d_invalidate(d_child);
507 		dput(d_child);
508 	}
509 }
510 
511 /*
512  * If we have to add an attr fork ahead of a parent pointer update, how much
513  * space should we ask for?
514  */
515 static inline int
xrep_adoption_attr_sizeof(const struct xrep_adoption * adopt)516 xrep_adoption_attr_sizeof(
517 	const struct xrep_adoption	*adopt)
518 {
519 	return sizeof(struct xfs_attr_sf_hdr) +
520 		xfs_attr_sf_entsize_byname(sizeof(struct xfs_parent_rec),
521 					   adopt->xname->len);
522 }
523 
524 /*
525  * Move the current file to the orphanage under the computed name.
526  *
527  * Returns with a dirty transaction so that the caller can handle any other
528  * work, such as fixing up unlinked lists or resetting link counts.
529  */
530 int
xrep_adoption_move(struct xrep_adoption * adopt)531 xrep_adoption_move(
532 	struct xrep_adoption	*adopt)
533 {
534 	struct xfs_scrub	*sc = adopt->sc;
535 	bool			isdir = S_ISDIR(VFS_I(sc->ip)->i_mode);
536 	int			error;
537 
538 	trace_xrep_adoption_reparent(sc->orphanage, adopt->xname,
539 			I_INO(sc->ip));
540 
541 	error = xrep_adoption_check_dcache(adopt);
542 	if (error)
543 		return error;
544 
545 	/*
546 	 * If this filesystem has parent pointers, ensure that the file being
547 	 * moved to the orphanage has an attribute fork.  This is required
548 	 * because the parent pointer code does not itself add attr forks.
549 	 */
550 	if (!xfs_inode_has_attr_fork(sc->ip) && xfs_has_parent(sc->mp)) {
551 		int sf_size = xrep_adoption_attr_sizeof(adopt);
552 
553 		error = xfs_bmap_add_attrfork(sc->tp, sc->ip, sf_size, true);
554 		if (error)
555 			return error;
556 	}
557 
558 	/* Create the new name in the orphanage. */
559 	error = xfs_dir_createname(sc->tp, sc->orphanage, adopt->xname,
560 			I_INO(sc->ip), adopt->orphanage_blkres);
561 	if (error)
562 		return error;
563 
564 	/*
565 	 * Bump the link count of the orphanage if we just added a
566 	 * subdirectory, and update its timestamps.
567 	 */
568 	xfs_trans_ichgtime(sc->tp, sc->orphanage,
569 			XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
570 	if (isdir)
571 		xfs_bumplink(sc->tp, sc->orphanage);
572 	xfs_trans_log_inode(sc->tp, sc->orphanage, XFS_ILOG_CORE);
573 
574 	/* Bump the link count of the child. */
575 	if (adopt->bump_child_nlink) {
576 		xfs_bumplink(sc->tp, sc->ip);
577 		xfs_trans_log_inode(sc->tp, sc->ip, XFS_ILOG_CORE);
578 	}
579 
580 	/* Replace the dotdot entry if the child is a subdirectory. */
581 	if (isdir) {
582 		error = xfs_dir_replace(sc->tp, sc->ip, &xfs_name_dotdot,
583 				I_INO(sc->orphanage), adopt->child_blkres);
584 		if (error)
585 			return error;
586 	}
587 
588 	/* Add a parent pointer from the file back to the lost+found. */
589 	if (xfs_has_parent(sc->mp)) {
590 		error = xfs_parent_addname(sc->tp, &adopt->ppargs,
591 				sc->orphanage, adopt->xname, sc->ip);
592 		if (error)
593 			return error;
594 	}
595 
596 	/*
597 	 * Notify dirent hooks that we moved the file to /lost+found, and
598 	 * finish all the deferred work so that we know the adoption is fully
599 	 * recorded in the log.
600 	 */
601 	xfs_dir_update_hook(sc->orphanage, sc->ip, 1, adopt->xname);
602 
603 	/* Remove negative dentries from the lost+found's dcache */
604 	xrep_adoption_zap_dcache(adopt);
605 	return 0;
606 }
607 
608 /*
609  * Roll to a clean scrub transaction so that we can release the orphanage,
610  * even if xrep_adoption_move was not called.
611  *
612  * Commits all the work and deferred ops attached to an adoption request and
613  * rolls to a clean scrub transaction.  On success, returns 0 with the scrub
614  * context holding a clean transaction with no inodes joined.  On failure,
615  * returns negative errno with no scrub transaction.  All inode locks are
616  * still held after this function returns.
617  */
618 int
xrep_adoption_trans_roll(struct xrep_adoption * adopt)619 xrep_adoption_trans_roll(
620 	struct xrep_adoption	*adopt)
621 {
622 	struct xfs_scrub	*sc = adopt->sc;
623 	int			error;
624 
625 	trace_xrep_adoption_trans_roll(sc->orphanage, sc->ip,
626 			!!(sc->tp->t_flags & XFS_TRANS_DIRTY));
627 
628 	/* Finish all the deferred ops to commit all repairs. */
629 	error = xrep_defer_finish(sc);
630 	if (error)
631 		return error;
632 
633 	/* Roll the transaction once more to detach the inodes. */
634 	return xfs_trans_roll(&sc->tp);
635 }
636