orphanage.c 16 KB

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