]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - repair/phase7.c
libxfs: remove libxfs_trans_iget
[thirdparty/xfsprogs-dev.git] / repair / phase7.c
CommitLineData
959ef981 1// SPDX-License-Identifier: GPL-2.0
2bd0ea18 2/*
da23017d
NS
3 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
4 * All Rights Reserved.
2bd0ea18
NS
5 */
6
6b803e5a 7#include "libxfs.h"
2bd0ea18
NS
8#include "avl.h"
9#include "globals.h"
10#include "agheader.h"
11#include "incore.h"
12#include "protos.h"
13#include "err_protos.h"
14#include "dinode.h"
15#include "versions.h"
06fbdda9 16#include "progress.h"
e161d4a8 17#include "threads.h"
2bd0ea18 18
0f012a4c
BN
19static void
20update_inode_nlinks(
21 xfs_mount_t *mp,
22 xfs_ino_t ino,
14f8b681 23 uint32_t nlinks)
0f012a4c
BN
24{
25 xfs_trans_t *tp;
26 xfs_inode_t *ip;
27 int error;
28 int dirty;
48ea6cb9 29 int nres;
0f012a4c 30
48ea6cb9 31 nres = no_modify ? 0 : 10;
9074815c 32 error = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_remove, nres, 0, 0, &tp);
0f012a4c
BN
33 ASSERT(error == 0);
34
e2dd0e1c 35 error = -libxfs_iget(mp, tp, ino, 0, &ip, &xfs_default_ifork_ops);
0f012a4c
BN
36 if (error) {
37 if (!no_modify)
5d1b7f0f
CH
38 do_error(
39 _("couldn't map inode %" PRIu64 ", err = %d\n"),
0f012a4c
BN
40 ino, error);
41 else {
2bd0ea18 42 do_warn(
5d1b7f0f 43 _("couldn't map inode %" PRIu64 ", err = %d, can't compare link counts\n"),
0f012a4c
BN
44 ino, error);
45 return;
46 }
47 }
48
49 dirty = 0;
50
bcbe04c1
DC
51 /* compare and set links if they differ. */
52 if (VFS_I(ip)->i_nlink != nlinks) {
53 if (!no_modify) {
54 do_warn(
55 _("resetting inode %" PRIu64 " nlinks from %u to %u\n"),
56 ino, VFS_I(ip)->i_nlink, nlinks);
57 set_nlink(VFS_I(ip), nlinks);
58 dirty = 1;
59 } else {
60 do_warn(
61 _("would have reset inode %" PRIu64 " nlinks from %u to %u\n"),
62 ino, VFS_I(ip)->i_nlink, nlinks);
63 }
64 }
0f012a4c
BN
65
66 if (!dirty) {
3d7434fe 67 libxfs_trans_cancel(tp);
0f012a4c 68 } else {
e2dd0e1c 69 libxfs_trans_ijoin(tp, ip, 0);
0f012a4c
BN
70 libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
71 /*
72 * no need to do a bmap finish since
73 * we're not allocating anything
74 */
75 ASSERT(error == 0);
de5a3f46 76 error = -libxfs_trans_commit(tp);
0f012a4c
BN
77
78 ASSERT(error == 0);
2bd0ea18 79 }
31845e4c 80 libxfs_irele(ip);
2bd0ea18
NS
81}
82
e161d4a8
DC
83/*
84 * for each ag, look at each inode 1 at a time. If the number of
85 * links is bad, reset it, log the inode core, commit the transaction
86 */
87static void
88do_link_updates(
62843f36 89 struct workqueue *wq,
e161d4a8
DC
90 xfs_agnumber_t agno,
91 void *arg)
2bd0ea18 92{
62843f36 93 struct xfs_mount *mp = wq->wq_ctx;
2bd0ea18 94 ino_tree_node_t *irec;
2bd0ea18 95 int j;
14f8b681 96 uint32_t nrefs;
2bd0ea18 97
e161d4a8
DC
98 for (irec = findfirst_inode_rec(agno); irec;
99 irec = next_ino_rec(irec)) {
100 for (j = 0; j < XFS_INODES_PER_CHUNK; j++) {
101 ASSERT(is_inode_confirmed(irec, j));
102
103 if (is_inode_free(irec, j))
104 continue;
105
106 ASSERT(no_modify || is_inode_reached(irec, j));
107
108 nrefs = num_inode_references(irec, j);
109 ASSERT(no_modify || nrefs > 0);
110
111 if (get_inode_disk_nlinks(irec, j) != nrefs)
62843f36
DW
112 update_inode_nlinks(wq->wq_ctx,
113 XFS_AGINO_TO_INO(mp, agno,
e161d4a8
DC
114 irec->ino_startnum + j),
115 nrefs);
116 }
117 }
118
119 PROG_RPT_INC(prog_rpt_done[agno], 1);
120}
121
122void
123phase7(
124 struct xfs_mount *mp,
125 int scan_threads)
126{
62843f36 127 struct workqueue wq;
e161d4a8
DC
128 int agno;
129
2bd0ea18 130 if (!no_modify)
507f4e33 131 do_log(_("Phase 7 - verify and correct link counts...\n"));
2bd0ea18 132 else
507f4e33 133 do_log(_("Phase 7 - verify link counts...\n"));
2bd0ea18 134
14f8b681 135 set_progress_msg(PROGRESS_FMT_CORR_LINK, (uint64_t) glob_agcount);
2bd0ea18 136
e161d4a8 137 create_work_queue(&wq, mp, scan_threads);
2bd0ea18 138
e161d4a8
DC
139 for (agno = 0; agno < mp->m_sb.sb_agcount; agno++)
140 queue_work(&wq, do_link_updates, agno, NULL);
2bd0ea18 141
e161d4a8 142 destroy_work_queue(&wq);
2bd0ea18 143
e161d4a8 144 print_final_rpt();
2bd0ea18 145}