Lines Matching +full:tp +full:- +full:link

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (c) 2021-2024 Oracle. All Rights Reserved.
43 * Online repair follows this tactic by creating a root-owned /lost+found
54 struct xfs_trans *tp; in xrep_chown_orphanage() local
55 struct xfs_mount *mp = sc->mp; in xrep_chown_orphanage()
66 error = xfs_trans_alloc_ichange(dp, udqp, gdqp, pdqp, true, &tp); in xrep_chown_orphanage()
76 inode->i_mode &= ~(S_ISUID | S_ISGID | S_ISVTX); in xrep_chown_orphanage()
82 if (!uid_eq(inode->i_uid, GLOBAL_ROOT_UID)) { in xrep_chown_orphanage()
84 oldu = xfs_qm_vop_chown(tp, dp, &dp->i_udquot, udqp); in xrep_chown_orphanage()
85 inode->i_uid = GLOBAL_ROOT_UID; in xrep_chown_orphanage()
87 if (!gid_eq(inode->i_gid, GLOBAL_ROOT_GID)) { in xrep_chown_orphanage()
89 oldg = xfs_qm_vop_chown(tp, dp, &dp->i_gdquot, gdqp); in xrep_chown_orphanage()
90 inode->i_gid = GLOBAL_ROOT_GID; in xrep_chown_orphanage()
92 if (dp->i_projid != 0) { in xrep_chown_orphanage()
94 oldp = xfs_qm_vop_chown(tp, dp, &dp->i_pdquot, pdqp); in xrep_chown_orphanage()
95 dp->i_projid = 0; in xrep_chown_orphanage()
98 dp->i_diflags &= ~(XFS_DIFLAG_REALTIME | XFS_DIFLAG_RTINHERIT); in xrep_chown_orphanage()
99 xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE); in xrep_chown_orphanage()
104 xfs_trans_set_sync(tp); in xrep_chown_orphanage()
105 error = xfs_trans_commit(tp); in xrep_chown_orphanage()
120 /* Create the orphanage directory, and set sc->orphanage to it. */
125 struct xfs_mount *mp = sc->mp; in xrep_orphanage_create()
127 struct inode *root_inode = VFS_I(sc->mp->m_rootip); in xrep_orphanage_create()
132 return -EIO; in xrep_orphanage_create()
134 sc->orphanage = NULL; in xrep_orphanage_create()
138 ASSERT(sc->tp == NULL); in xrep_orphanage_create()
139 ASSERT(sc->orphanage == NULL); in xrep_orphanage_create()
144 error = -EFSCORRUPTED; in xrep_orphanage_create()
150 error = -EFSCORRUPTED; in xrep_orphanage_create()
165 * directory without other-user access because we're live and someone in xrep_orphanage_create()
178 error = -ENOTDIR; in xrep_orphanage_create()
189 error = -ENOENT; in xrep_orphanage_create()
199 sc->orphanage = XFS_I(orphanage_inode); in xrep_orphanage_create()
200 sc->orphanage_ilock_flags = 0; in xrep_orphanage_create()
205 inode_unlock(VFS_I(sc->mp->m_rootip)); in xrep_orphanage_create()
217 sc->orphanage_ilock_flags |= ilock_flags; in xrep_orphanage_ilock()
218 xfs_ilock(sc->orphanage, ilock_flags); in xrep_orphanage_ilock()
226 if (xfs_ilock_nowait(sc->orphanage, ilock_flags)) { in xrep_orphanage_ilock_nowait()
227 sc->orphanage_ilock_flags |= ilock_flags; in xrep_orphanage_ilock_nowait()
239 xfs_iunlock(sc->orphanage, ilock_flags); in xrep_orphanage_iunlock()
240 sc->orphanage_ilock_flags &= ~ilock_flags; in xrep_orphanage_iunlock()
243 /* Grab the IOLOCK of the orphanage and sc->ip. */
275 if (!sc->orphanage) in xrep_orphanage_rele()
278 if (sc->orphanage_ilock_flags) in xrep_orphanage_rele()
279 xfs_iunlock(sc->orphanage, sc->orphanage_ilock_flags); in xrep_orphanage_rele()
281 xchk_irele(sc, sc->orphanage); in xrep_orphanage_rele()
282 sc->orphanage = NULL; in xrep_orphanage_rele()
287 /* Can the orphanage adopt @sc->ip? */
292 ASSERT(sc->ip != NULL); in xrep_orphanage_can_adopt()
294 if (!sc->orphanage) in xrep_orphanage_can_adopt()
296 if (sc->ip == sc->orphanage) in xrep_orphanage_can_adopt()
298 if (xfs_internal_inum(sc->mp, sc->ip->i_ino)) in xrep_orphanage_can_adopt()
307 * adoption, take ILOCK_EXCL of the orphanage and sc->ip, joins them to the
309 * IOLOCK of the orphanage and sc->ip.
316 struct xfs_mount *mp = sc->mp; in xrep_adoption_trans_alloc()
320 ASSERT(sc->tp == NULL); in xrep_adoption_trans_alloc()
321 ASSERT(sc->ip != NULL); in xrep_adoption_trans_alloc()
322 ASSERT(sc->orphanage != NULL); in xrep_adoption_trans_alloc()
323 ASSERT(sc->ilock_flags & XFS_IOLOCK_EXCL); in xrep_adoption_trans_alloc()
324 ASSERT(sc->orphanage_ilock_flags & XFS_IOLOCK_EXCL); in xrep_adoption_trans_alloc()
325 ASSERT(!(sc->ilock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL))); in xrep_adoption_trans_alloc()
326 ASSERT(!(sc->orphanage_ilock_flags & in xrep_adoption_trans_alloc()
330 adopt->sc = sc; in xrep_adoption_trans_alloc()
331 adopt->orphanage_blkres = xfs_link_space_res(mp, MAXNAMELEN); in xrep_adoption_trans_alloc()
332 if (S_ISDIR(VFS_I(sc->ip)->i_mode)) in xrep_adoption_trans_alloc()
337 adopt->child_blkres = child_blkres; in xrep_adoption_trans_alloc()
340 * Allocate a transaction to link the child into the parent, along with in xrep_adoption_trans_alloc()
344 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_link, in xrep_adoption_trans_alloc()
345 adopt->orphanage_blkres + adopt->child_blkres, 0, 0, in xrep_adoption_trans_alloc()
346 &sc->tp); in xrep_adoption_trans_alloc()
350 xfs_lock_two_inodes(sc->orphanage, XFS_ILOCK_EXCL, in xrep_adoption_trans_alloc()
351 sc->ip, XFS_ILOCK_EXCL); in xrep_adoption_trans_alloc()
352 sc->ilock_flags |= XFS_ILOCK_EXCL; in xrep_adoption_trans_alloc()
353 sc->orphanage_ilock_flags |= XFS_ILOCK_EXCL; in xrep_adoption_trans_alloc()
355 xfs_trans_ijoin(sc->tp, sc->orphanage, 0); in xrep_adoption_trans_alloc()
356 xfs_trans_ijoin(sc->tp, sc->ip, 0); in xrep_adoption_trans_alloc()
364 error = xfs_trans_reserve_quota_nblks(sc->tp, sc->orphanage, in xrep_adoption_trans_alloc()
365 adopt->orphanage_blkres, 0, true); in xrep_adoption_trans_alloc()
374 if (adopt->child_blkres) { in xrep_adoption_trans_alloc()
375 error = xfs_trans_reserve_quota_nblks(sc->tp, sc->ip, in xrep_adoption_trans_alloc()
376 adopt->child_blkres, 0, true); in xrep_adoption_trans_alloc()
391 * orphanage. Caller must hold ILOCKs of sc->ip and the orphanage and must not
399 struct xfs_scrub *sc = adopt->sc; in xrep_adoption_compute_name()
400 char *namebuf = (void *)xname->name; in xrep_adoption_compute_name()
405 adopt->xname = xname; in xrep_adoption_compute_name()
406 xname->len = snprintf(namebuf, MAXNAMELEN, "%llu", sc->ip->i_ino); in xrep_adoption_compute_name()
407 xname->type = xfs_mode_to_ftype(VFS_I(sc->ip)->i_mode); in xrep_adoption_compute_name()
410 error = xchk_dir_lookup(sc, sc->orphanage, xname, &ino); in xrep_adoption_compute_name()
412 xname->len = snprintf(namebuf, MAXNAMELEN, "%llu.%u", in xrep_adoption_compute_name()
413 sc->ip->i_ino, ++incr); in xrep_adoption_compute_name()
414 error = xchk_dir_lookup(sc, sc->orphanage, xname, &ino); in xrep_adoption_compute_name()
418 return -EFSCORRUPTED; in xrep_adoption_compute_name()
421 if (error != -ENOENT) in xrep_adoption_compute_name()
435 struct qstr qname = QSTR_INIT(adopt->xname->name, in xrep_adoption_check_dcache()
436 adopt->xname->len); in xrep_adoption_check_dcache()
437 struct xfs_scrub *sc = adopt->sc; in xrep_adoption_check_dcache()
441 d_orphanage = d_find_alias(VFS_I(sc->orphanage)); in xrep_adoption_check_dcache()
447 trace_xrep_adoption_check_child(sc->mp, d_child); in xrep_adoption_check_dcache()
451 error = -EFSCORRUPTED; in xrep_adoption_check_dcache()
472 struct qstr qname = QSTR_INIT(adopt->xname->name, in xrep_adoption_zap_dcache()
473 adopt->xname->len); in xrep_adoption_zap_dcache()
474 struct xfs_scrub *sc = adopt->sc; in xrep_adoption_zap_dcache()
478 d_orphanage = d_find_alias(VFS_I(sc->orphanage)); in xrep_adoption_zap_dcache()
484 trace_xrep_adoption_invalidate_child(sc->mp, d_child); in xrep_adoption_zap_dcache()
495 while ((d_child = d_find_alias(VFS_I(sc->ip))) != NULL) { in xrep_adoption_zap_dcache()
496 trace_xrep_adoption_invalidate_child(sc->mp, d_child); in xrep_adoption_zap_dcache()
513 adopt->xname->len); in xrep_adoption_attr_sizeof()
520 * work, such as fixing up unlinked lists or resetting link counts.
526 struct xfs_scrub *sc = adopt->sc; in xrep_adoption_move()
527 bool isdir = S_ISDIR(VFS_I(sc->ip)->i_mode); in xrep_adoption_move()
530 trace_xrep_adoption_reparent(sc->orphanage, adopt->xname, in xrep_adoption_move()
531 sc->ip->i_ino); in xrep_adoption_move()
542 if (!xfs_inode_has_attr_fork(sc->ip) && xfs_has_parent(sc->mp)) { in xrep_adoption_move()
545 error = xfs_bmap_add_attrfork(sc->tp, sc->ip, sf_size, true); in xrep_adoption_move()
551 error = xfs_dir_createname(sc->tp, sc->orphanage, adopt->xname, in xrep_adoption_move()
552 sc->ip->i_ino, adopt->orphanage_blkres); in xrep_adoption_move()
557 * Bump the link count of the orphanage if we just added a in xrep_adoption_move()
560 xfs_trans_ichgtime(sc->tp, sc->orphanage, in xrep_adoption_move()
563 xfs_bumplink(sc->tp, sc->orphanage); in xrep_adoption_move()
564 xfs_trans_log_inode(sc->tp, sc->orphanage, XFS_ILOG_CORE); in xrep_adoption_move()
566 /* Bump the link count of the child. */ in xrep_adoption_move()
567 if (adopt->bump_child_nlink) { in xrep_adoption_move()
568 xfs_bumplink(sc->tp, sc->ip); in xrep_adoption_move()
569 xfs_trans_log_inode(sc->tp, sc->ip, XFS_ILOG_CORE); in xrep_adoption_move()
574 error = xfs_dir_replace(sc->tp, sc->ip, &xfs_name_dotdot, in xrep_adoption_move()
575 sc->orphanage->i_ino, adopt->child_blkres); in xrep_adoption_move()
581 if (xfs_has_parent(sc->mp)) { in xrep_adoption_move()
582 error = xfs_parent_addname(sc->tp, &adopt->ppargs, in xrep_adoption_move()
583 sc->orphanage, adopt->xname, sc->ip); in xrep_adoption_move()
593 xfs_dir_update_hook(sc->orphanage, sc->ip, 1, adopt->xname); in xrep_adoption_move()
614 struct xfs_scrub *sc = adopt->sc; in xrep_adoption_trans_roll()
617 trace_xrep_adoption_trans_roll(sc->orphanage, sc->ip, in xrep_adoption_trans_roll()
618 !!(sc->tp->t_flags & XFS_TRANS_DIRTY)); in xrep_adoption_trans_roll()
626 return xfs_trans_roll(&sc->tp); in xrep_adoption_trans_roll()