]>
git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - repair/phase4.c
2 * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
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
7 * published by the Free Software Foundation.
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.
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
27 #include "err_protos.h"
36 * null out quota inode fields in sb if they point to non-existent inodes.
37 * this isn't as redundant as it looks since it's possible that the sb field
38 * might be set but the imap and inode(s) agree that the inode is
39 * free in which case they'd never be cleared so the fields wouldn't
40 * be cleared by process_dinode().
43 quotino_check(xfs_mount_t
*mp
)
45 ino_tree_node_t
*irec
;
47 if (mp
->m_sb
.sb_uquotino
!= NULLFSINO
&& mp
->m_sb
.sb_uquotino
!= 0) {
48 if (verify_inum(mp
, mp
->m_sb
.sb_uquotino
))
51 irec
= find_inode_rec(mp
,
52 XFS_INO_TO_AGNO(mp
, mp
->m_sb
.sb_uquotino
),
53 XFS_INO_TO_AGINO(mp
, mp
->m_sb
.sb_uquotino
));
55 if (irec
== NULL
|| is_inode_free(irec
,
56 mp
->m_sb
.sb_uquotino
- irec
->ino_startnum
)) {
57 mp
->m_sb
.sb_uquotino
= NULLFSINO
;
63 if (mp
->m_sb
.sb_gquotino
!= NULLFSINO
&& mp
->m_sb
.sb_gquotino
!= 0) {
64 if (verify_inum(mp
, mp
->m_sb
.sb_gquotino
))
67 irec
= find_inode_rec(mp
,
68 XFS_INO_TO_AGNO(mp
, mp
->m_sb
.sb_gquotino
),
69 XFS_INO_TO_AGINO(mp
, mp
->m_sb
.sb_gquotino
));
71 if (irec
== NULL
|| is_inode_free(irec
,
72 mp
->m_sb
.sb_gquotino
- irec
->ino_startnum
)) {
73 mp
->m_sb
.sb_gquotino
= NULLFSINO
;
79 if (mp
->m_sb
.sb_pquotino
!= NULLFSINO
&& mp
->m_sb
.sb_pquotino
!= 0) {
80 if (verify_inum(mp
, mp
->m_sb
.sb_pquotino
))
83 irec
= find_inode_rec(mp
,
84 XFS_INO_TO_AGNO(mp
, mp
->m_sb
.sb_pquotino
),
85 XFS_INO_TO_AGINO(mp
, mp
->m_sb
.sb_pquotino
));
87 if (irec
== NULL
|| is_inode_free(irec
,
88 mp
->m_sb
.sb_pquotino
- irec
->ino_startnum
)) {
89 mp
->m_sb
.sb_pquotino
= NULLFSINO
;
97 quota_sb_check(xfs_mount_t
*mp
)
100 * if the sb says we have quotas and we lost both,
101 * signal a superblock downgrade. that will cause
102 * the quota flags to get zeroed. (if we only lost
103 * one quota inode, do nothing and complain later.)
105 * if the sb says we have quotas but we didn't start out
106 * with any quota inodes, signal a superblock downgrade.
108 * The sb downgrades are so that older systems can mount
111 * if the sb says we don't have quotas but it looks like
112 * we do have quota inodes, then signal a superblock upgrade.
114 * if the sb says we don't have quotas and we have no
115 * quota inodes, then leave will enough alone.
119 (mp
->m_sb
.sb_uquotino
== NULLFSINO
|| mp
->m_sb
.sb_uquotino
== 0) &&
120 (mp
->m_sb
.sb_gquotino
== NULLFSINO
|| mp
->m_sb
.sb_gquotino
== 0) &&
121 (mp
->m_sb
.sb_pquotino
== NULLFSINO
|| mp
->m_sb
.sb_pquotino
== 0)) {
124 } else if (!verify_inum(mp
, mp
->m_sb
.sb_uquotino
) &&
125 !verify_inum(mp
, mp
->m_sb
.sb_gquotino
) &&
126 !verify_inum(mp
, mp
->m_sb
.sb_pquotino
)) {
138 wait_for_inode_prefetch(arg
);
139 do_log(_(" - agno = %d\n"), agno
);
140 process_aginodes(wq
->mp
, arg
, agno
, 0, 1, 0);
141 cleanup_inode_prefetch(arg
);
144 * now recycle the per-AG duplicate extent records
146 release_dup_extent_tree(agno
);
153 do_inode_prefetch(mp
, ag_stride
, process_ag_func
, true, false);
158 phase4(xfs_mount_t
*mp
)
160 ino_tree_node_t
*irec
;
162 xfs_rtblock_t rt_start
;
166 xfs_agblock_t ag_end
;
168 int ag_hdr_len
= 4 * mp
->m_sb
.sb_sectsize
;
172 ag_hdr_block
= howmany(ag_hdr_len
, mp
->m_sb
.sb_blocksize
);
174 do_log(_("Phase 4 - check for duplicate blocks...\n"));
175 do_log(_(" - setting up duplicate extent list...\n"));
177 set_progress_msg(PROG_FMT_DUP_EXTENT
, (__uint64_t
) glob_agcount
);
179 irec
= find_inode_rec(mp
, XFS_INO_TO_AGNO(mp
, mp
->m_sb
.sb_rootino
),
180 XFS_INO_TO_AGINO(mp
, mp
->m_sb
.sb_rootino
));
183 * we always have a root inode, even if it's free...
184 * if the root is free, forget it, lost+found is already gone
186 if (is_inode_free(irec
, 0) || !inode_isadir(irec
, 0)) {
189 do_warn(_("root inode would be lost\n"));
191 do_warn(_("root inode lost\n"));
194 for (i
= 0; i
< mp
->m_sb
.sb_agcount
; i
++) {
195 ag_end
= (i
< mp
->m_sb
.sb_agcount
- 1) ? mp
->m_sb
.sb_agblocks
:
196 mp
->m_sb
.sb_dblocks
-
197 (xfs_rfsblock_t
) mp
->m_sb
.sb_agblocks
* i
;
200 * set up duplicate extent list for this ag
202 for (j
= ag_hdr_block
; j
< ag_end
; j
+= blen
) {
203 bstate
= get_bmap_ext(i
, j
, ag_end
, &blen
);
208 _("unknown block state, ag %d, block %d\n"),
210 /* fall through .. */
220 add_dup_extent(i
, j
, blen
);
225 PROG_RPT_INC(prog_rpt_done
[i
], 1);
230 * initialize realtime bitmap
235 for (bno
= 0; bno
< mp
->m_sb
.sb_rextents
; bno
++) {
236 bstate
= get_rtbmap(bno
);
241 _("unknown rt extent state, extent %" PRIu64
"\n"),
243 /* fall through .. */
255 * add extent and reset extent state
257 add_rt_dup_extent(rt_start
, rt_len
);
266 } else if (rt_len
== MAXEXTLEN
) {
270 add_rt_dup_extent(rt_start
, rt_len
);
280 * catch tail-case, extent hitting the end of the ag
283 add_rt_dup_extent(rt_start
, rt_len
);
286 * initialize bitmaps for all AGs
290 do_log(_(" - check for inodes claiming duplicate blocks...\n"));
291 set_progress_msg(PROG_FMT_DUP_BLOCKS
, (__uint64_t
) mp
->m_sb
.sb_icount
);
294 * ok, now process the inodes -- signal 2-pass check per inode.
295 * first pass checks if the inode conflicts with a known
296 * duplicate extent. if so, the inode is cleared and second
297 * pass is skipped. second pass sets the block bitmap
298 * for all blocks claimed by the inode. directory
299 * and attribute processing is turned OFF since we did that
300 * already in phase 3.
306 * free up memory used to track trealtime duplicate extents
309 free_rt_dup_extent_tree(mp
);
312 * ensure consistency of quota inode pointers in superblock,
313 * make sure they point to real inodes