]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - repair/phase7.c
libxfs: simplify xfs_trans_free_items
[thirdparty/xfsprogs-dev.git] / repair / phase7.c
CommitLineData
2bd0ea18 1/*
da23017d
NS
2 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
dfc130f3 4 *
da23017d
NS
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
2bd0ea18 7 * published by the Free Software Foundation.
dfc130f3 8 *
da23017d
NS
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
dfc130f3 13 *
da23017d
NS
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2bd0ea18
NS
17 */
18
b08338d7 19#include "xfs/libxfs.h"
2bd0ea18
NS
20#include "avl.h"
21#include "globals.h"
22#include "agheader.h"
23#include "incore.h"
24#include "protos.h"
25#include "err_protos.h"
26#include "dinode.h"
27#include "versions.h"
06fbdda9 28#include "progress.h"
2bd0ea18
NS
29
30/* dinoc is a pointer to the IN-CORE dinode core */
0f012a4c
BN
31static void
32set_nlinks(
5e656dbb 33 xfs_icdinode_t *dinoc,
0f012a4c
BN
34 xfs_ino_t ino,
35 __uint32_t nrefs,
36 int *dirty)
2bd0ea18 37{
0f012a4c
BN
38 if (dinoc->di_nlink == nrefs)
39 return;
2bd0ea18 40
0f012a4c
BN
41 if (!no_modify) {
42 *dirty = 1;
154d3b33 43 do_warn(_("resetting inode %" PRIu64 " nlinks from %u to %u\n"),
0f012a4c
BN
44 ino, dinoc->di_nlink, nrefs);
45
5f6f3660 46 ASSERT(dinoc->di_version > 1);
0f012a4c 47 dinoc->di_nlink = nrefs;
2bd0ea18 48 } else {
154d3b33
CH
49 do_warn(
50_("would have reset inode %" PRIu64 " nlinks from %u to %u\n"),
0f012a4c
BN
51 ino, dinoc->di_nlink, nrefs);
52 }
53}
54
55static void
56update_inode_nlinks(
57 xfs_mount_t *mp,
58 xfs_ino_t ino,
59 __uint32_t nlinks)
60{
61 xfs_trans_t *tp;
62 xfs_inode_t *ip;
63 int error;
64 int dirty;
48ea6cb9 65 int nres;
0f012a4c
BN
66
67 tp = libxfs_trans_alloc(mp, XFS_TRANS_REMOVE);
68
48ea6cb9 69 nres = no_modify ? 0 : 10;
12b53197 70 error = -libxfs_trans_reserve(tp, &M_RES(mp)->tr_remove, nres, 0);
0f012a4c
BN
71 ASSERT(error == 0);
72
12b53197 73 error = -libxfs_trans_iget(mp, tp, ino, 0, 0, &ip);
0f012a4c
BN
74
75 if (error) {
76 if (!no_modify)
5d1b7f0f
CH
77 do_error(
78 _("couldn't map inode %" PRIu64 ", err = %d\n"),
0f012a4c
BN
79 ino, error);
80 else {
2bd0ea18 81 do_warn(
5d1b7f0f 82 _("couldn't map inode %" PRIu64 ", err = %d, can't compare link counts\n"),
0f012a4c
BN
83 ino, error);
84 return;
85 }
86 }
87
88 dirty = 0;
89
90 /*
91 * compare and set links for all inodes
0f012a4c 92 */
6c39a3cb 93 set_nlinks(&ip->i_d, ino, nlinks, &dirty);
0f012a4c
BN
94
95 if (!dirty) {
0f012a4c
BN
96 libxfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES);
97 } else {
98 libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
99 /*
100 * no need to do a bmap finish since
101 * we're not allocating anything
102 */
103 ASSERT(error == 0);
12b53197 104 error = -libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES |
5e656dbb 105 XFS_TRANS_SYNC);
0f012a4c
BN
106
107 ASSERT(error == 0);
2bd0ea18 108 }
260c85e8 109 IRELE(ip);
2bd0ea18
NS
110}
111
112void
113phase7(xfs_mount_t *mp)
114{
115 ino_tree_node_t *irec;
2bd0ea18
NS
116 int i;
117 int j;
2bd0ea18
NS
118 __uint32_t nrefs;
119
120 if (!no_modify)
507f4e33 121 do_log(_("Phase 7 - verify and correct link counts...\n"));
2bd0ea18 122 else
507f4e33 123 do_log(_("Phase 7 - verify link counts...\n"));
2bd0ea18 124
2bd0ea18 125 /*
0f012a4c
BN
126 * for each ag, look at each inode 1 at a time. If the number of
127 * links is bad, reset it, log the inode core, commit the transaction
2bd0ea18
NS
128 */
129 for (i = 0; i < glob_agcount; i++) {
130 irec = findfirst_inode_rec(i);
131
132 while (irec != NULL) {
133 for (j = 0; j < XFS_INODES_PER_CHUNK; j++) {
134 ASSERT(is_inode_confirmed(irec, j));
135
136 if (is_inode_free(irec, j))
137 continue;
138
139 ASSERT(no_modify || is_inode_reached(irec, j));
2bd0ea18
NS
140
141 nrefs = num_inode_references(irec, j);
f4ef1178 142 ASSERT(no_modify || nrefs > 0);
2bd0ea18 143
0f012a4c
BN
144 if (get_inode_disk_nlinks(irec, j) != nrefs)
145 update_inode_nlinks(mp,
146 XFS_AGINO_TO_INO(mp, i,
147 irec->ino_startnum + j),
148 nrefs);
2bd0ea18
NS
149 }
150 irec = next_ino_rec(irec);
151 }
152 }
2bd0ea18 153}