]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - repair/phase4.c
Merge whitespace changes over
[thirdparty/xfsprogs-dev.git] / repair / phase4.c
CommitLineData
2bd0ea18 1/*
0d3e0b37 2 * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
dfc130f3 3 *
2bd0ea18
NS
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as
6 * published by the Free Software Foundation.
dfc130f3 7 *
2bd0ea18
NS
8 * This program is distributed in the hope that it would be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
dfc130f3 11 *
2bd0ea18
NS
12 * Further, this software is distributed without any warranty that it is
13 * free of the rightful claim of any third person regarding infringement
14 * or the like. Any license provided herein, whether implied or
15 * otherwise, applies only to this software file. Patent licenses, if
16 * any, provided herein do not apply to combinations of this program with
17 * other software, or any other product whatsoever.
dfc130f3 18 *
2bd0ea18
NS
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write the Free Software Foundation, Inc., 59
21 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
dfc130f3 22 *
2bd0ea18
NS
23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
dfc130f3
RC
25 *
26 * http://www.sgi.com
27 *
28 * For further information regarding this notice, see:
29 *
2bd0ea18
NS
30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
31 */
32
33#include <libxfs.h>
34#include "avl.h"
35#include "globals.h"
36#include "agheader.h"
37#include "incore.h"
38#include "protos.h"
39#include "err_protos.h"
40#include "dinode.h"
41#include "dir.h"
42#include "bmap.h"
43#include "versions.h"
44#include "dir2.h"
45
46
47/* ARGSUSED */
48int
49lf_block_delete_orphanage(xfs_mount_t *mp,
50 xfs_ino_t ino,
51 xfs_dir_leafblock_t *leaf,
52 int *dirty,
53 xfs_buf_t *rootino_bp,
54 int *rbuf_dirty)
55{
56 xfs_dir_leaf_entry_t *entry;
57 xfs_dinode_t *dino;
58 xfs_buf_t *bp;
59 ino_tree_node_t *irec;
60 xfs_ino_t lino;
61 xfs_dir_leaf_name_t *namest;
62 xfs_agino_t agino;
63 xfs_agnumber_t agno;
64 xfs_agino_t root_agino;
65 xfs_agnumber_t root_agno;
66 int i;
67 int ino_offset;
68 int ino_dirty;
69 int use_rbuf;
70 int len;
71 char fname[MAXNAMELEN + 1];
72 int res;
73
74 entry = &leaf->entries[0];
75 *dirty = 0;
76 use_rbuf = 0;
77 res = 0;
78 root_agno = XFS_INO_TO_AGNO(mp, mp->m_sb.sb_rootino);
79 root_agino = XFS_INO_TO_AGINO(mp, mp->m_sb.sb_rootino);
80
81 for (i = 0; i < INT_GET(leaf->hdr.count, ARCH_CONVERT); entry++, i++) {
82 namest = XFS_DIR_LEAF_NAMESTRUCT(leaf,
83 INT_GET(entry->nameidx, ARCH_CONVERT));
84 XFS_DIR_SF_GET_DIRINO_ARCH(&namest->inumber, &lino, ARCH_CONVERT);
85 bcopy(namest->name, fname, entry->namelen);
86 fname[entry->namelen] = '\0';
87
88 if (fname[0] != '/' && !strcmp(fname, ORPHANAGE)) {
89 agino = XFS_INO_TO_AGINO(mp, lino);
90 agno = XFS_INO_TO_AGNO(mp, lino);
91
92 old_orphanage_ino = lino;
93
94 irec = find_inode_rec(agno, agino);
95
96 /*
97 * if the orphange inode is in the tree,
98 * get it, clear it, and mark it free.
99 * the inodes in the orphanage will get
100 * reattached to the new orphanage.
101 */
102 if (irec != NULL) {
103 ino_offset = agino - irec->ino_startnum;
104
105 /*
106 * check if we have to use the root inode
107 * buffer or read one in ourselves. Note
108 * that the root inode is always the first
109 * inode of the chunk that it's in so there
110 * are two possible cases where lost+found
111 * might be in the same buffer as the root
112 * inode. One case is a large block
113 * filesystem where the two inodes are
114 * in different inode chunks but wind
115 * up in the same block (multiple chunks
116 * per block) and the second case (one or
117 * more blocks per chunk) is where the two
118 * inodes are in the same chunk. Note that
119 * inodes are allocated on disk in units
120 * of MAX(XFS_INODES_PER_CHUNK,sb_inopblock).
121 */
122 if (XFS_INO_TO_FSB(mp, mp->m_sb.sb_rootino)
123 == XFS_INO_TO_FSB(mp, lino) ||
124 (agno == root_agno &&
125 agino < root_agino + XFS_INODES_PER_CHUNK)) {
126 use_rbuf = 1;
127 bp = rootino_bp;
128 dino = XFS_MAKE_IPTR(mp, bp, agino -
129 XFS_INO_TO_AGINO(mp,
130 mp->m_sb.sb_rootino));
131 } else {
132 len = (int)XFS_FSB_TO_BB(mp,
133 MAX(1, XFS_INODES_PER_CHUNK/
134 inodes_per_block));
135 bp = libxfs_readbuf(mp->m_dev,
136 XFS_AGB_TO_DADDR(mp, agno,
137 XFS_AGINO_TO_AGBNO(mp,
138 irec->ino_startnum)),
139 len, 0);
140 if (!bp)
507f4e33
NS
141 do_error(
142 _("couldn't read %s inode %llu\n"),
2bd0ea18
NS
143 ORPHANAGE, lino);
144
145 /*
146 * get the agbno containing the first
147 * inode in the chunk. In multi-block
148 * chunks, this gets us the offset
149 * relative to the beginning of a
150 * properly aligned buffer. In
151 * multi-chunk blocks, this gets us
152 * the correct block number. Then
153 * turn the block number back into
154 * an agino and calculate the offset
155 * from there to feed to make the iptr.
156 * the last term in effect rounds down
157 * to the first agino in the buffer.
158 */
159 dino = XFS_MAKE_IPTR(mp, bp,
160 agino - XFS_OFFBNO_TO_AGINO(mp,
161 XFS_AGINO_TO_AGBNO(mp,
162 irec->ino_startnum),
163 0));
164 }
165
507f4e33
NS
166 do_warn(
167 _(" - clearing existing \"%s\" inode\n"),
2bd0ea18
NS
168 ORPHANAGE);
169
170 ino_dirty = clear_dinode(mp, dino, lino);
171
172 if (!use_rbuf) {
173 ASSERT(ino_dirty == 0 ||
27527004 174 (ino_dirty && !no_modify));
2bd0ea18
NS
175
176 if (ino_dirty && !no_modify)
177 libxfs_writebuf(bp, 0);
178 else
179 libxfs_putbuf(bp);
180 } else {
181 if (ino_dirty)
182 *rbuf_dirty = 1;
183 }
dfc130f3 184
2bd0ea18
NS
185 if (inode_isadir(irec, ino_offset))
186 clear_inode_isadir(irec, ino_offset);
187
188 set_inode_free(irec, ino_offset);
189 }
190
191 /*
192 * regardless of whether the inode num is good or
193 * bad, mark the entry to be junked so the
194 * createname in phase 6 will succeed.
195 */
196 namest->name[0] = '/';
197 *dirty = 1;
507f4e33
NS
198 do_warn(
199 _(" - marking entry \"%s\" to be deleted\n"),
200 fname);
2bd0ea18
NS
201 res++;
202 }
203 }
204
205 return(res);
206}
207
208int
209longform_delete_orphanage(xfs_mount_t *mp,
210 xfs_ino_t ino,
211 xfs_dinode_t *dino,
212 xfs_buf_t *rootino_bp,
213 int *rbuf_dirty)
214{
215 xfs_dir_leafblock_t *leaf;
216 xfs_buf_t *bp;
217 xfs_dfsbno_t fsbno;
218 xfs_dablk_t da_bno;
219 int dirty;
220 int res;
221
222 da_bno = 0;
223 *rbuf_dirty = 0;
224
507f4e33
NS
225 if ((fsbno = get_first_dblock_fsbno(mp, ino, dino)) == NULLDFSBNO)
226 do_error(
227 _("couldn't map first leaf block of directory inode %llu\n"), ino);
2bd0ea18
NS
228
229 /*
230 * cycle through the entire directory looking to delete
231 * every "lost+found" entry. make sure to catch duplicate
232 * entries.
233 *
234 * We could probably speed this up by doing a smarter lookup
235 * to get us to the first block that contains the hashvalue
236 * of "lost+found" but what the heck. that would require a
237 * double lookup for each level. and how big can '/' get???
238 * It's probably not worth it.
239 */
240 res = 0;
241
242 do {
65d2c755
NS
243 if (fsbno == NULLDFSBNO)
244 break;
2bd0ea18
NS
245 bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, fsbno),
246 XFS_FSB_TO_BB(mp, 1), 0);
507f4e33
NS
247 if (!bp)
248 do_error(_("can't read block %u (fsbno %llu) for "
249 "directory inode %llu\n"),
250 da_bno, fsbno, ino);
2bd0ea18
NS
251
252 leaf = (xfs_dir_leafblock_t *)XFS_BUF_PTR(bp);
253
507f4e33
NS
254 if (INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) !=
255 XFS_DIR_LEAF_MAGIC)
256 do_error(_("bad magic # (0x%x) for directory "
257 "leaf block (bno %u fsbno %llu)\n"),
2bd0ea18
NS
258 INT_GET(leaf->hdr.info.magic, ARCH_CONVERT),
259 da_bno, fsbno);
2bd0ea18
NS
260
261 da_bno = INT_GET(leaf->hdr.info.forw, ARCH_CONVERT);
262
263 res += lf_block_delete_orphanage(mp, ino, leaf, &dirty,
264 rootino_bp, rbuf_dirty);
265
27527004 266 ASSERT(dirty == 0 || (dirty && !no_modify));
2bd0ea18
NS
267
268 if (dirty && !no_modify)
269 libxfs_writebuf(bp, 0);
270 else
271 libxfs_putbuf(bp);
272
273 if (da_bno != 0)
274 fsbno = get_bmapi(mp, dino, ino, da_bno, XFS_DATA_FORK);
275
276 } while (da_bno != 0);
277
278 return(res);
279}
280
281/*
282 * returns 1 if a deletion happened, 0 otherwise.
283 */
284/* ARGSUSED */
285int
286shortform_delete_orphanage(xfs_mount_t *mp,
287 xfs_ino_t ino,
288 xfs_dinode_t *root_dino,
289 xfs_buf_t *rootino_bp,
290 int *ino_dirty)
291{
292 xfs_dir_shortform_t *sf;
293 xfs_dinode_t *dino;
294 xfs_dir_sf_entry_t *sf_entry, *next_sfe, *tmp_sfe;
295 xfs_buf_t *bp;
296 xfs_ino_t lino;
297 xfs_agino_t agino;
298 xfs_agino_t root_agino;
299 int max_size;
300 xfs_agnumber_t agno;
301 xfs_agnumber_t root_agno;
302 int ino_dir_size;
303 ino_tree_node_t *irec;
304 int ino_offset;
305 int i;
306 int dirty;
307 int tmp_len;
308 int tmp_elen;
309 int len;
310 int use_rbuf;
311 char fname[MAXNAMELEN + 1];
312 int res;
313
314 sf = &root_dino->di_u.di_dirsf;
315 *ino_dirty = 0;
316 res = 0;
317 irec = NULL;
318 ino_dir_size = INT_GET(root_dino->di_core.di_size, ARCH_CONVERT);
319 max_size = XFS_DFORK_DSIZE_ARCH(root_dino, mp, ARCH_CONVERT);
320 use_rbuf = 0;
321 root_agno = XFS_INO_TO_AGNO(mp, mp->m_sb.sb_rootino);
322 root_agino = XFS_INO_TO_AGINO(mp, mp->m_sb.sb_rootino);
323
324 /*
325 * run through entries looking for "lost+found".
326 */
327 sf_entry = next_sfe = &sf->list[0];
328 for (i = 0; i < INT_GET(sf->hdr.count, ARCH_CONVERT) && ino_dir_size >
329 (__psint_t)next_sfe - (__psint_t)sf; i++) {
330 tmp_sfe = NULL;
331 sf_entry = next_sfe;
507f4e33
NS
332 XFS_DIR_SF_GET_DIRINO_ARCH(&sf_entry->inumber,
333 &lino, ARCH_CONVERT);
2bd0ea18
NS
334 bcopy(sf_entry->name, fname, sf_entry->namelen);
335 fname[sf_entry->namelen] = '\0';
336
337 if (!strcmp(ORPHANAGE, fname)) {
338 agno = XFS_INO_TO_AGNO(mp, lino);
339 agino = XFS_INO_TO_AGINO(mp, lino);
340
341 irec = find_inode_rec(agno, agino);
342
343 /*
344 * if the orphange inode is in the tree,
345 * get it, clear it, and mark it free.
346 * the inodes in the orphanage will get
347 * reattached to the new orphanage.
348 */
349 if (irec != NULL) {
507f4e33
NS
350 do_warn(
351 _(" - clearing existing \"%s\" inode\n"),
2bd0ea18
NS
352 ORPHANAGE);
353
354 ino_offset = agino - irec->ino_startnum;
355
356 /*
357 * check if we have to use the root inode
358 * buffer or read one in ourselves. Note
359 * that the root inode is always the first
360 * inode of the chunk that it's in so there
361 * are two possible cases where lost+found
362 * might be in the same buffer as the root
363 * inode. One case is a large block
364 * filesystem where the two inodes are
365 * in different inode chunks but wind
366 * up in the same block (multiple chunks
367 * per block) and the second case (one or
368 * more blocks per chunk) is where the two
369 * inodes are in the same chunk. Note that
370 * inodes are allocated on disk in units
371 * of MAX(XFS_INODES_PER_CHUNK,sb_inopblock).
372 */
373 if (XFS_INO_TO_FSB(mp, mp->m_sb.sb_rootino)
374 == XFS_INO_TO_FSB(mp, lino) ||
375 (agno == root_agno &&
376 agino < root_agino + XFS_INODES_PER_CHUNK)) {
377 use_rbuf = 1;
378 bp = rootino_bp;
379
380 dino = XFS_MAKE_IPTR(mp, bp, agino -
381 XFS_INO_TO_AGINO(mp,
382 mp->m_sb.sb_rootino));
383 } else {
384 len = (int)XFS_FSB_TO_BB(mp,
385 MAX(1, XFS_INODES_PER_CHUNK/
386 inodes_per_block));
387 bp = libxfs_readbuf(mp->m_dev,
388 XFS_AGB_TO_DADDR(mp, agno,
389 XFS_AGINO_TO_AGBNO(mp,
390 irec->ino_startnum)),
391 len, 0);
392 if (!bp)
507f4e33
NS
393 do_error(
394 _("could not read %s inode %llu\n"),
395 ORPHANAGE, lino);
396
2bd0ea18
NS
397 /*
398 * get the agbno containing the first
399 * inode in the chunk. In multi-block
400 * chunks, this gets us the offset
401 * relative to the beginning of a
402 * properly aligned buffer. In
403 * multi-chunk blocks, this gets us
404 * the correct block number. Then
405 * turn the block number back into
406 * an agino and calculate the offset
407 * from there to feed to make the iptr.
408 * the last term in effect rounds down
409 * to the first agino in the buffer.
410 */
411 dino = XFS_MAKE_IPTR(mp, bp,
412 agino - XFS_OFFBNO_TO_AGINO(mp,
413 XFS_AGINO_TO_AGBNO(mp,
414 irec->ino_startnum),
415 0));
416 }
417
418 dirty = clear_dinode(mp, dino, lino);
419
27527004 420 ASSERT(dirty == 0 || (dirty && !no_modify));
2bd0ea18
NS
421
422 /*
423 * if we read the lost+found inode in to
424 * it, get rid of it here. if the lost+found
425 * inode is in the root inode buffer, the
426 * buffer will be marked dirty anyway since
427 * the lost+found entry in the root inode is
428 * also being deleted which makes the root
429 * inode buffer automatically dirty.
430 */
431 if (!use_rbuf) {
432 dino = NULL;
433 if (dirty && !no_modify)
434 libxfs_writebuf(bp, 0);
435 else
436 libxfs_putbuf(bp);
437 }
438
439 if (inode_isadir(irec, ino_offset))
440 clear_inode_isadir(irec, ino_offset);
441
442 set_inode_free(irec, ino_offset);
443 }
444
507f4e33 445 do_warn(_(" - deleting existing \"%s\" entry\n"),
2bd0ea18
NS
446 ORPHANAGE);
447
448 /*
449 * note -- exactly the same deletion code as in
450 * process_shortform_dir()
451 */
452 tmp_elen = XFS_DIR_SF_ENTSIZE_BYENTRY(sf_entry);
507f4e33
NS
453 INT_MOD(root_dino->di_core.di_size, ARCH_CONVERT,
454 -(tmp_elen));
2bd0ea18
NS
455
456 tmp_sfe = (xfs_dir_sf_entry_t *)
457 ((__psint_t) sf_entry + tmp_elen);
458 tmp_len = max_size - ((__psint_t) tmp_sfe
459 - (__psint_t) sf);
460
461 memmove(sf_entry, tmp_sfe, tmp_len);
462
463 INT_MOD(sf->hdr.count, ARCH_CONVERT, -1);
464
465 bzero((void *) ((__psint_t) sf_entry + tmp_len),
466 tmp_elen);
467
468 /*
469 * set the tmp value to the current
470 * pointer so we'll process the entry
471 * we just moved up
472 */
473 tmp_sfe = sf_entry;
474
475 /*
476 * WARNING: drop the index i by one
477 * so it matches the decremented count for
478 * accurate comparisons in the loop test.
479 * mark root inode as dirty to make deletion
480 * permanent.
481 */
482 i--;
483
484 *ino_dirty = 1;
485 res++;
486
487 }
488 next_sfe = (tmp_sfe == NULL)
489 ? (xfs_dir_sf_entry_t *) ((__psint_t) sf_entry +
490 XFS_DIR_SF_ENTSIZE_BYENTRY(sf_entry))
491 : tmp_sfe;
492 }
493
494 return(res);
495}
496
497/* ARGSUSED */
498int
499lf2_block_delete_orphanage(xfs_mount_t *mp,
500 xfs_ino_t ino,
501 xfs_dir2_data_t *data,
502 int *dirty,
503 xfs_buf_t *rootino_bp,
504 int *rbuf_dirty)
505{
506 xfs_dinode_t *dino;
507 xfs_buf_t *bp;
508 ino_tree_node_t *irec;
509 xfs_ino_t lino;
510 xfs_agino_t agino;
511 xfs_agnumber_t agno;
512 xfs_agino_t root_agino;
513 xfs_agnumber_t root_agno;
514 int ino_offset;
515 int ino_dirty;
516 int use_rbuf;
517 int len;
518 char fname[MAXNAMELEN + 1];
519 int res;
520 char *ptr;
521 char *endptr;
522 xfs_dir2_block_tail_t *btp;
523 xfs_dir2_data_entry_t *dep;
524 xfs_dir2_data_unused_t *dup;
525
526 ptr = (char *)data->u;
527 if (INT_GET(data->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC) {
528 btp = XFS_DIR2_BLOCK_TAIL_P(mp, (xfs_dir2_block_t *)data);
529 endptr = (char *)XFS_DIR2_BLOCK_LEAF_P_ARCH(btp, ARCH_CONVERT);
530 } else
531 endptr = (char *)data + mp->m_dirblksize;
532 *dirty = 0;
533 use_rbuf = 0;
534 res = 0;
535 root_agno = XFS_INO_TO_AGNO(mp, mp->m_sb.sb_rootino);
536 root_agino = XFS_INO_TO_AGINO(mp, mp->m_sb.sb_rootino);
537
538 while (ptr < endptr) {
539 dup = (xfs_dir2_data_unused_t *)ptr;
507f4e33
NS
540 if (INT_GET(dup->freetag, ARCH_CONVERT) ==
541 XFS_DIR2_DATA_FREE_TAG) {
2bd0ea18
NS
542 if (ptr + INT_GET(dup->length, ARCH_CONVERT) > endptr ||
543 INT_GET(dup->length, ARCH_CONVERT) == 0 ||
544 (INT_GET(dup->length, ARCH_CONVERT) &
545 (XFS_DIR2_DATA_ALIGN - 1)))
546 break;
547 ptr += INT_GET(dup->length, ARCH_CONVERT);
548 continue;
549 }
550 dep = (xfs_dir2_data_entry_t *)ptr;
551 lino = INT_GET(dep->inumber, ARCH_CONVERT);
552 bcopy(dep->name, fname, dep->namelen);
553 fname[dep->namelen] = '\0';
554
555 if (fname[0] != '/' && !strcmp(fname, ORPHANAGE)) {
556 agino = XFS_INO_TO_AGINO(mp, lino);
557 agno = XFS_INO_TO_AGNO(mp, lino);
558
559 old_orphanage_ino = lino;
560
561 irec = find_inode_rec(agno, agino);
562
563 /*
564 * if the orphange inode is in the tree,
565 * get it, clear it, and mark it free.
566 * the inodes in the orphanage will get
567 * reattached to the new orphanage.
568 */
569 if (irec != NULL) {
570 ino_offset = agino - irec->ino_startnum;
571
572 /*
573 * check if we have to use the root inode
574 * buffer or read one in ourselves. Note
575 * that the root inode is always the first
576 * inode of the chunk that it's in so there
577 * are two possible cases where lost+found
578 * might be in the same buffer as the root
579 * inode. One case is a large block
580 * filesystem where the two inodes are
581 * in different inode chunks but wind
582 * up in the same block (multiple chunks
583 * per block) and the second case (one or
584 * more blocks per chunk) is where the two
585 * inodes are in the same chunk. Note that
586 * inodes are allocated on disk in units
587 * of MAX(XFS_INODES_PER_CHUNK,sb_inopblock).
588 */
589 if (XFS_INO_TO_FSB(mp, mp->m_sb.sb_rootino)
590 == XFS_INO_TO_FSB(mp, lino) ||
591 (agno == root_agno &&
592 agino < root_agino + XFS_INODES_PER_CHUNK)) {
593 use_rbuf = 1;
594 bp = rootino_bp;
595 dino = XFS_MAKE_IPTR(mp, bp, agino -
596 XFS_INO_TO_AGINO(mp,
597 mp->m_sb.sb_rootino));
598 } else {
599 len = (int)XFS_FSB_TO_BB(mp,
600 MAX(1, XFS_INODES_PER_CHUNK/
601 inodes_per_block));
602 bp = libxfs_readbuf(mp->m_dev,
603 XFS_AGB_TO_DADDR(mp, agno,
604 XFS_AGINO_TO_AGBNO(mp,
605 irec->ino_startnum)),
606 len, 0);
607 if (!bp)
507f4e33
NS
608 do_error(
609 _("couldn't read %s inode %llu\n"),
2bd0ea18
NS
610 ORPHANAGE, lino);
611
612 /*
613 * get the agbno containing the first
614 * inode in the chunk. In multi-block
615 * chunks, this gets us the offset
616 * relative to the beginning of a
617 * properly aligned buffer. In
618 * multi-chunk blocks, this gets us
619 * the correct block number. Then
620 * turn the block number back into
621 * an agino and calculate the offset
622 * from there to feed to make the iptr.
623 * the last term in effect rounds down
624 * to the first agino in the buffer.
625 */
626 dino = XFS_MAKE_IPTR(mp, bp,
627 agino - XFS_OFFBNO_TO_AGINO(mp,
628 XFS_AGINO_TO_AGBNO(mp,
629 irec->ino_startnum),
630 0));
631 }
632
507f4e33
NS
633 do_warn(
634 _(" - clearing existing \"%s\" inode\n"),
2bd0ea18
NS
635 ORPHANAGE);
636
637 ino_dirty = clear_dinode(mp, dino, lino);
638
639 if (!use_rbuf) {
640 ASSERT(ino_dirty == 0 ||
27527004 641 (ino_dirty && !no_modify));
2bd0ea18
NS
642
643 if (ino_dirty && !no_modify)
644 libxfs_writebuf(bp, 0);
645 else
646 libxfs_putbuf(bp);
647 } else {
648 if (ino_dirty)
649 *rbuf_dirty = 1;
650 }
dfc130f3 651
2bd0ea18
NS
652 if (inode_isadir(irec, ino_offset))
653 clear_inode_isadir(irec, ino_offset);
654
655 set_inode_free(irec, ino_offset);
656
657 }
658
659 /*
660 * regardless of whether the inode num is good or
661 * bad, mark the entry to be junked so the
662 * createname in phase 6 will succeed.
663 */
664 dep->name[0] = '/';
665 *dirty = 1;
666 do_warn(
507f4e33
NS
667 _(" - marking entry \"%s\" to be deleted\n"),
668 fname);
2bd0ea18
NS
669 res++;
670 }
671 ptr += XFS_DIR2_DATA_ENTSIZE(dep->namelen);
672 }
673
674 return(res);
675}
676
677int
678longform2_delete_orphanage(xfs_mount_t *mp,
679 xfs_ino_t ino,
680 xfs_dinode_t *dino,
681 xfs_buf_t *rootino_bp,
682 int *rbuf_dirty)
683{
684 xfs_dir2_data_t *data;
685 xfs_dabuf_t *bp;
686 xfs_dfsbno_t fsbno;
687 xfs_dablk_t da_bno;
688 int dirty;
689 int res;
690 bmap_ext_t *bmp;
691 int i;
692
693 da_bno = 0;
694 *rbuf_dirty = 0;
695 fsbno = NULLDFSBNO;
696 bmp = malloc(mp->m_dirblkfsbs * sizeof(*bmp));
507f4e33 697 if (!bmp)
2bd0ea18 698 do_error(
507f4e33 699 _("malloc failed (%u bytes) in longform2_delete_orphanage, ino %llu\n"),
2bd0ea18 700 mp->m_dirblkfsbs * sizeof(*bmp), ino);
2bd0ea18
NS
701
702 /*
703 * cycle through the entire directory looking to delete
704 * every "lost+found" entry. make sure to catch duplicate
705 * entries.
706 *
707 * We could probably speed this up by doing a smarter lookup
708 * to get us to the first block that contains the hashvalue
709 * of "lost+found" but what the heck. that would require a
710 * double lookup for each level. and how big can '/' get???
711 * It's probably not worth it.
712 */
713 res = 0;
714
715 for (da_bno = 0;
716 da_bno < XFS_B_TO_FSB(mp, INT_GET(dino->di_core.di_size, ARCH_CONVERT));
717 da_bno += mp->m_dirblkfsbs) {
718 for (i = 0; i < mp->m_dirblkfsbs; i++) {
719 fsbno = get_bmapi(mp, dino, ino, da_bno + i,
720 XFS_DATA_FORK);
721 if (fsbno == NULLDFSBNO)
722 break;
723 bmp[i].startoff = da_bno + i;
724 bmp[i].startblock = fsbno;
725 bmp[i].blockcount = 1;
726 bmp[i].flag = 0;
727 }
728 if (fsbno == NULLDFSBNO)
729 continue;
730 bp = da_read_buf(mp, mp->m_dirblkfsbs, bmp);
507f4e33 731 if (bp == NULL)
2bd0ea18 732 do_error(
507f4e33
NS
733 _("can't read block %u (fsbno %llu) for directory inode %llu\n"),
734 da_bno, bmp[0].startblock, ino);
2bd0ea18
NS
735
736 data = (xfs_dir2_data_t *)bp->data;
737
507f4e33
NS
738 if (INT_GET(data->hdr.magic, ARCH_CONVERT) !=
739 XFS_DIR2_DATA_MAGIC &&
740 INT_GET(data->hdr.magic, ARCH_CONVERT) !=
741 XFS_DIR2_BLOCK_MAGIC)
2bd0ea18 742 do_error(
507f4e33
NS
743 _("bad magic # (0x%x) for directory data block (bno %u fsbno %llu)\n"),
744 INT_GET(data->hdr.magic, ARCH_CONVERT),
745 da_bno, bmp[0].startblock);
2bd0ea18
NS
746
747 res += lf2_block_delete_orphanage(mp, ino, data, &dirty,
748 rootino_bp, rbuf_dirty);
749
27527004 750 ASSERT(dirty == 0 || (dirty && !no_modify));
2bd0ea18
NS
751
752 if (dirty && !no_modify)
753 da_bwrite(mp, bp);
754 else
755 da_brelse(bp);
756 }
757 free(bmp);
758
759 return(res);
760}
761
762/*
763 * returns 1 if a deletion happened, 0 otherwise.
764 */
765/* ARGSUSED */
766int
767shortform2_delete_orphanage(xfs_mount_t *mp,
768 xfs_ino_t ino,
769 xfs_dinode_t *root_dino,
770 xfs_buf_t *rootino_bp,
771 int *ino_dirty)
772{
773 xfs_dir2_sf_t *sf;
774 xfs_dinode_t *dino;
775 xfs_dir2_sf_entry_t *sf_entry, *next_sfe, *tmp_sfe;
776 xfs_buf_t *bp;
777 xfs_ino_t lino;
778 xfs_agino_t agino;
779 xfs_agino_t root_agino;
780 int max_size;
781 xfs_agnumber_t agno;
782 xfs_agnumber_t root_agno;
783 int ino_dir_size;
784 ino_tree_node_t *irec;
785 int ino_offset;
786 int i;
787 int dirty;
788 int tmp_len;
789 int tmp_elen;
790 int len;
791 int use_rbuf;
792 char fname[MAXNAMELEN + 1];
793 int res;
794
795 sf = &root_dino->di_u.di_dir2sf;
796 *ino_dirty = 0;
797 irec = NULL;
798 ino_dir_size = INT_GET(root_dino->di_core.di_size, ARCH_CONVERT);
799 max_size = XFS_DFORK_DSIZE_ARCH(root_dino, mp, ARCH_CONVERT);
800 use_rbuf = 0;
801 res = 0;
802 root_agno = XFS_INO_TO_AGNO(mp, mp->m_sb.sb_rootino);
803 root_agino = XFS_INO_TO_AGINO(mp, mp->m_sb.sb_rootino);
804
805 /*
806 * run through entries looking for "lost+found".
807 */
808 sf_entry = next_sfe = XFS_DIR2_SF_FIRSTENTRY(sf);
809 for (i = 0; i < INT_GET(sf->hdr.count, ARCH_CONVERT) && ino_dir_size >
810 (__psint_t)next_sfe - (__psint_t)sf; i++) {
811 tmp_sfe = NULL;
812 sf_entry = next_sfe;
813 lino = XFS_DIR2_SF_GET_INUMBER_ARCH(sf,
814 XFS_DIR2_SF_INUMBERP(sf_entry), ARCH_CONVERT);
815 bcopy(sf_entry->name, fname, sf_entry->namelen);
816 fname[sf_entry->namelen] = '\0';
817
818 if (!strcmp(ORPHANAGE, fname)) {
819 agno = XFS_INO_TO_AGNO(mp, lino);
820 agino = XFS_INO_TO_AGINO(mp, lino);
821
822 irec = find_inode_rec(agno, agino);
823
824 /*
825 * if the orphange inode is in the tree,
826 * get it, clear it, and mark it free.
827 * the inodes in the orphanage will get
828 * reattached to the new orphanage.
829 */
830 if (irec != NULL) {
507f4e33
NS
831 do_warn(
832 _(" - clearing existing \"%s\" inode\n"),
2bd0ea18
NS
833 ORPHANAGE);
834
835 ino_offset = agino - irec->ino_startnum;
836
837 /*
838 * check if we have to use the root inode
839 * buffer or read one in ourselves. Note
840 * that the root inode is always the first
841 * inode of the chunk that it's in so there
842 * are two possible cases where lost+found
843 * might be in the same buffer as the root
844 * inode. One case is a large block
845 * filesystem where the two inodes are
846 * in different inode chunks but wind
847 * up in the same block (multiple chunks
848 * per block) and the second case (one or
849 * more blocks per chunk) is where the two
850 * inodes are in the same chunk. Note that
851 * inodes are allocated on disk in units
852 * of MAX(XFS_INODES_PER_CHUNK,sb_inopblock).
853 */
854 if (XFS_INO_TO_FSB(mp, mp->m_sb.sb_rootino)
855 == XFS_INO_TO_FSB(mp, lino) ||
856 (agno == root_agno &&
857 agino < root_agino + XFS_INODES_PER_CHUNK)) {
858 use_rbuf = 1;
859 bp = rootino_bp;
860
861 dino = XFS_MAKE_IPTR(mp, bp, agino -
862 XFS_INO_TO_AGINO(mp,
863 mp->m_sb.sb_rootino));
864 } else {
865 len = (int)XFS_FSB_TO_BB(mp,
866 MAX(1, XFS_INODES_PER_CHUNK/
867 inodes_per_block));
868 bp = libxfs_readbuf(mp->m_dev,
869 XFS_AGB_TO_DADDR(mp, agno,
870 XFS_AGINO_TO_AGBNO(mp,
871 irec->ino_startnum)),
872 len, 0);
873 if (!bp)
507f4e33
NS
874 do_error(
875 _("could not read %s inode %llu\n"),
876 ORPHANAGE, lino);
877
2bd0ea18
NS
878 /*
879 * get the agbno containing the first
880 * inode in the chunk. In multi-block
881 * chunks, this gets us the offset
882 * relative to the beginning of a
883 * properly aligned buffer. In
884 * multi-chunk blocks, this gets us
885 * the correct block number. Then
886 * turn the block number back into
887 * an agino and calculate the offset
888 * from there to feed to make the iptr.
889 * the last term in effect rounds down
890 * to the first agino in the buffer.
891 */
892 dino = XFS_MAKE_IPTR(mp, bp,
893 agino - XFS_OFFBNO_TO_AGINO(mp,
894 XFS_AGINO_TO_AGBNO(mp,
895 irec->ino_startnum),
896 0));
897 }
898
899 dirty = clear_dinode(mp, dino, lino);
900
27527004 901 ASSERT(dirty == 0 || (dirty && !no_modify));
2bd0ea18
NS
902
903 /*
904 * if we read the lost+found inode in to
905 * it, get rid of it here. if the lost+found
906 * inode is in the root inode buffer, the
907 * buffer will be marked dirty anyway since
908 * the lost+found entry in the root inode is
909 * also being deleted which makes the root
910 * inode buffer automatically dirty.
911 */
912 if (!use_rbuf) {
913 dino = NULL;
914 if (dirty && !no_modify)
915 libxfs_writebuf(bp, 0);
916 else
917 libxfs_putbuf(bp);
918 }
dfc130f3 919
2bd0ea18
NS
920
921 if (inode_isadir(irec, ino_offset))
922 clear_inode_isadir(irec, ino_offset);
923
924 set_inode_free(irec, ino_offset);
925 }
926
507f4e33 927 do_warn(_(" - deleting existing \"%s\" entry\n"),
2bd0ea18
NS
928 ORPHANAGE);
929
930 /*
931 * note -- exactly the same deletion code as in
932 * process_shortform_dir()
933 */
934 tmp_elen = XFS_DIR2_SF_ENTSIZE_BYENTRY(sf, sf_entry);
507f4e33
NS
935 INT_MOD(root_dino->di_core.di_size, ARCH_CONVERT,
936 -(tmp_elen));
2bd0ea18
NS
937
938 tmp_sfe = (xfs_dir2_sf_entry_t *)
939 ((__psint_t) sf_entry + tmp_elen);
940 tmp_len = max_size - ((__psint_t) tmp_sfe
941 - (__psint_t) sf);
942
943 memmove(sf_entry, tmp_sfe, tmp_len);
944
945 INT_MOD(sf->hdr.count, ARCH_CONVERT, -1);
946 if (lino > XFS_DIR2_MAX_SHORT_INUM)
947 sf->hdr.i8count--;
948
949 bzero((void *) ((__psint_t) sf_entry + tmp_len),
950 tmp_elen);
951
952 /*
953 * set the tmp value to the current
954 * pointer so we'll process the entry
955 * we just moved up
956 */
957 tmp_sfe = sf_entry;
958
959 /*
960 * WARNING: drop the index i by one
961 * so it matches the decremented count for
962 * accurate comparisons in the loop test.
963 * mark root inode as dirty to make deletion
964 * permanent.
965 */
966 i--;
967
968 *ino_dirty = 1;
969
970 res++;
971 }
972 next_sfe = (tmp_sfe == NULL)
973 ? (xfs_dir2_sf_entry_t *) ((__psint_t) sf_entry +
974 XFS_DIR2_SF_ENTSIZE_BYENTRY(sf, sf_entry))
975 : tmp_sfe;
976 }
977
978 return(res);
979}
980
981void
982delete_orphanage(xfs_mount_t *mp)
983{
984 xfs_ino_t ino;
985 xfs_dinode_t *dino;
986 xfs_buf_t *dbp;
987 int dirty, res, len;
988
989 ASSERT(!no_modify);
990
991 dbp = NULL;
992 dirty = res = 0;
993 ino = mp->m_sb.sb_rootino;
994
995 /*
996 * we know the root is in use or we wouldn't be here
997 */
998 len = (int)XFS_FSB_TO_BB(mp,
999 MAX(1, XFS_INODES_PER_CHUNK/inodes_per_block));
1000 dbp = libxfs_readbuf(mp->m_dev,
1001 XFS_FSB_TO_DADDR(mp, XFS_INO_TO_FSB(mp, ino)), len, 0);
507f4e33
NS
1002 if (!dbp)
1003 do_error(_("could not read buffer for root inode %llu "
1004 "(daddr %lld, size %d)\n"), ino,
2bd0ea18
NS
1005 XFS_FSB_TO_DADDR(mp, XFS_INO_TO_FSB(mp, ino)),
1006 XFS_FSB_TO_BB(mp, 1));
2bd0ea18
NS
1007
1008 /*
1009 * we also know that the root inode is always the first inode
1010 * allocated in the system, therefore it'll be at the beginning
1011 * of the root inode chunk
1012 */
1013 dino = XFS_MAKE_IPTR(mp, dbp, 0);
1014
1015 switch (dino->di_core.di_format) {
1016 case XFS_DINODE_FMT_EXTENTS:
1017 case XFS_DINODE_FMT_BTREE:
1018 if (XFS_SB_VERSION_HASDIRV2(&mp->m_sb))
1019 res = longform2_delete_orphanage(mp, ino, dino, dbp,
1020 &dirty);
1021 else
1022 res = longform_delete_orphanage(mp, ino, dino, dbp,
1023 &dirty);
1024 break;
1025 case XFS_DINODE_FMT_LOCAL:
1026 if (XFS_SB_VERSION_HASDIRV2(&mp->m_sb))
1027 res = shortform2_delete_orphanage(mp, ino, dino, dbp,
1028 &dirty);
1029 else
1030 res = shortform_delete_orphanage(mp, ino, dino, dbp,
1031 &dirty);
3079c6c0 1032 ASSERT((res == 0 && dirty == 0) || (res > 0 && dirty == 1));
2bd0ea18
NS
1033 break;
1034 default:
1035 break;
1036 }
1037
1038 if (res) {
1039 switch (dino->di_core.di_version) {
1040 case XFS_DINODE_VERSION_1:
3079c6c0 1041 INT_MOD(dino->di_core.di_onlink, ARCH_CONVERT, -res);
2bd0ea18
NS
1042 INT_SET(dino->di_core.di_nlink, ARCH_CONVERT,
1043 INT_GET(dino->di_core.di_onlink, ARCH_CONVERT));
1044 break;
1045 case XFS_DINODE_VERSION_2:
3079c6c0 1046 INT_MOD(dino->di_core.di_nlink, ARCH_CONVERT, -res);
2bd0ea18
NS
1047 break;
1048 default:
507f4e33 1049 do_error(_("unknown version #%d in root inode\n"),
2bd0ea18
NS
1050 dino->di_core.di_version);
1051 }
1052
1053 dirty = 1;
1054 }
1055
1056 if (dirty)
1057 libxfs_writebuf(dbp, 0);
1058 else
1059 libxfs_putbuf(dbp);
1060}
1061
1062/*
1063 * null out quota inode fields in sb if they point to non-existent inodes.
1064 * this isn't as redundant as it looks since it's possible that the sb field
1065 * might be set but the imap and inode(s) agree that the inode is
1066 * free in which case they'd never be cleared so the fields wouldn't
1067 * be cleared by process_dinode().
1068 */
1069void
1070quotino_check(xfs_mount_t *mp)
1071{
1072 ino_tree_node_t *irec;
1073
1074 if (mp->m_sb.sb_uquotino != NULLFSINO && mp->m_sb.sb_uquotino != 0) {
1075 irec = find_inode_rec(XFS_INO_TO_AGNO(mp, mp->m_sb.sb_uquotino),
1076 XFS_INO_TO_AGINO(mp, mp->m_sb.sb_uquotino));
1077
1078 if (irec == NULL || is_inode_free(irec,
1079 mp->m_sb.sb_uquotino - irec->ino_startnum)) {
1080 mp->m_sb.sb_uquotino = NULLFSINO;
1081 lost_uquotino = 1;
1082 } else
1083 lost_uquotino = 0;
1084 }
1085
b36eef04
NS
1086 if (mp->m_sb.sb_gquotino != NULLFSINO && mp->m_sb.sb_gquotino != 0) {
1087 irec = find_inode_rec(XFS_INO_TO_AGNO(mp, mp->m_sb.sb_gquotino),
1088 XFS_INO_TO_AGINO(mp, mp->m_sb.sb_gquotino));
2bd0ea18
NS
1089
1090 if (irec == NULL || is_inode_free(irec,
b36eef04
NS
1091 mp->m_sb.sb_gquotino - irec->ino_startnum)) {
1092 mp->m_sb.sb_gquotino = NULLFSINO;
1093 lost_gquotino = 1;
2bd0ea18 1094 } else
b36eef04 1095 lost_gquotino = 0;
2bd0ea18
NS
1096 }
1097}
1098
1099void
1100quota_sb_check(xfs_mount_t *mp)
1101{
1102 /*
1103 * if the sb says we have quotas and we lost both,
1104 * signal a superblock downgrade. that will cause
1105 * the quota flags to get zeroed. (if we only lost
1106 * one quota inode, do nothing and complain later.)
1107 *
1108 * if the sb says we have quotas but we didn't start out
1109 * with any quota inodes, signal a superblock downgrade.
1110 *
1111 * The sb downgrades are so that older systems can mount
1112 * the filesystem.
1113 *
1114 * if the sb says we don't have quotas but it looks like
1115 * we do have quota inodes, then signal a superblock upgrade.
1116 *
1117 * if the sb says we don't have quotas and we have no
1118 * quota inodes, then leave will enough alone.
1119 */
1120
1121 if (fs_quotas &&
1122 (mp->m_sb.sb_uquotino == NULLFSINO || mp->m_sb.sb_uquotino == 0) &&
b36eef04 1123 (mp->m_sb.sb_gquotino == NULLFSINO || mp->m_sb.sb_gquotino == 0)) {
2bd0ea18
NS
1124 lost_quotas = 1;
1125 fs_quotas = 0;
1126 } else if (!verify_inum(mp, mp->m_sb.sb_uquotino) &&
b36eef04 1127 !verify_inum(mp, mp->m_sb.sb_gquotino)) {
2bd0ea18
NS
1128 fs_quotas = 1;
1129 }
1130}
1131
1132
1133void
1134phase4(xfs_mount_t *mp)
1135{
1136 ino_tree_node_t *irec;
1137 xfs_drtbno_t bno;
1138 xfs_drtbno_t rt_start;
1139 xfs_extlen_t rt_len;
1140 xfs_agnumber_t i;
1141 xfs_agblock_t j;
1142 xfs_agblock_t ag_end;
1143 xfs_agblock_t extent_start;
1144 xfs_extlen_t extent_len;
1145 int ag_hdr_len = 4 * mp->m_sb.sb_sectsize;
1146 int ag_hdr_block;
1147 int bstate;
1148 int count_bcnt_extents(xfs_agnumber_t agno);
1149 int count_bno_extents(xfs_agnumber_t agno);
dfc130f3 1150
2bd0ea18
NS
1151 ag_hdr_block = howmany(ag_hdr_len, mp->m_sb.sb_blocksize);
1152
507f4e33
NS
1153 do_log(_("Phase 4 - check for duplicate blocks...\n"));
1154 do_log(_(" - setting up duplicate extent list...\n"));
2bd0ea18
NS
1155
1156 irec = find_inode_rec(XFS_INO_TO_AGNO(mp, mp->m_sb.sb_rootino),
1157 XFS_INO_TO_AGINO(mp, mp->m_sb.sb_rootino));
1158
1159 /*
1160 * we always have a root inode, even if it's free...
1161 * if the root is free, forget it, lost+found is already gone
1162 */
1163 if (is_inode_free(irec, 0) || !inode_isadir(irec, 0)) {
1164 need_root_inode = 1;
1165 if (no_modify)
507f4e33 1166 do_warn(_("root inode would be lost\n"));
2bd0ea18 1167 else
507f4e33 1168 do_warn(_("root inode lost\n"));
2bd0ea18
NS
1169 }
1170
1171 /*
1172 * have to delete lost+found first so that blocks used
1173 * by lost+found don't show up as used
1174 */
1175 if (!no_modify) {
507f4e33 1176 do_log(_(" - clear lost+found (if it exists) ...\n"));
2bd0ea18
NS
1177 if (!need_root_inode)
1178 delete_orphanage(mp);
1179 }
1180
1181 for (i = 0; i < mp->m_sb.sb_agcount; i++) {
1182 ag_end = (i < mp->m_sb.sb_agcount - 1) ? mp->m_sb.sb_agblocks :
1183 mp->m_sb.sb_dblocks -
1184 (xfs_drfsbno_t) mp->m_sb.sb_agblocks * i;
1185 extent_start = extent_len = 0;
1186 /*
1187 * set up duplicate extent list for this ag
1188 */
1189 for (j = ag_hdr_block; j < ag_end; j++) {
1190
1191 bstate = get_agbno_state(mp, i, j);
1192
1193 switch (bstate) {
1194 case XR_E_BAD_STATE:
1195 default:
507f4e33
NS
1196 do_warn(
1197 _("unknown block state, ag %d, block %d\n"),
2bd0ea18
NS
1198 i, j);
1199 /* fall through .. */
1200 case XR_E_UNKNOWN:
1201 case XR_E_FREE1:
1202 case XR_E_FREE:
1203 case XR_E_INUSE:
1204 case XR_E_INUSE_FS:
1205 case XR_E_INO:
1206 case XR_E_FS_MAP:
1207 if (extent_start == 0)
1208 continue;
1209 else {
1210 /*
1211 * add extent and reset extent state
1212 */
1213 add_dup_extent(i, extent_start,
1214 extent_len);
1215 extent_start = 0;
1216 extent_len = 0;
1217 }
1218 break;
1219 case XR_E_MULT:
1220 if (extent_start == 0) {
1221 extent_start = j;
1222 extent_len = 1;
1223 } else if (extent_len == MAXEXTLEN) {
1224 add_dup_extent(i, extent_start,
1225 extent_len);
1226 extent_start = j;
1227 extent_len = 1;
1228 } else
1229 extent_len++;
1230 break;
1231 }
1232 }
1233 /*
1234 * catch tail-case, extent hitting the end of the ag
1235 */
1236 if (extent_start != 0)
1237 add_dup_extent(i, extent_start, extent_len);
1238 }
1239
1240 /*
1241 * initialize realtime bitmap
1242 */
1243 rt_start = 0;
1244 rt_len = 0;
1245
1246 for (bno = 0; bno < mp->m_sb.sb_rextents; bno++) {
1247
1248 bstate = get_rtbno_state(mp, bno);
1249
1250 switch (bstate) {
1251 case XR_E_BAD_STATE:
1252 default:
507f4e33
NS
1253 do_warn(_("unknown rt extent state, extent %llu\n"),
1254 bno);
2bd0ea18
NS
1255 /* fall through .. */
1256 case XR_E_UNKNOWN:
1257 case XR_E_FREE1:
1258 case XR_E_FREE:
1259 case XR_E_INUSE:
1260 case XR_E_INUSE_FS:
1261 case XR_E_INO:
1262 case XR_E_FS_MAP:
1263 if (rt_start == 0)
1264 continue;
1265 else {
1266 /*
1267 * add extent and reset extent state
1268 */
1269 add_rt_dup_extent(rt_start, rt_len);
1270 rt_start = 0;
1271 rt_len = 0;
1272 }
1273 break;
1274 case XR_E_MULT:
1275 if (rt_start == 0) {
1276 rt_start = bno;
1277 rt_len = 1;
1278 } else if (rt_len == MAXEXTLEN) {
1279 /*
1280 * large extent case
1281 */
1282 add_rt_dup_extent(rt_start, rt_len);
1283 rt_start = bno;
1284 rt_len = 1;
1285 } else
1286 rt_len++;
1287 break;
1288 }
1289 }
1290
1291 /*
1292 * catch tail-case, extent hitting the end of the ag
1293 */
1294 if (rt_start != 0)
1295 add_rt_dup_extent(rt_start, rt_len);
1296
1297 /*
1298 * initialize bitmaps for all AGs
1299 */
1300 for (i = 0; i < mp->m_sb.sb_agcount; i++) {
1301 ag_end = (i < mp->m_sb.sb_agcount - 1) ? mp->m_sb.sb_agblocks :
1302 mp->m_sb.sb_dblocks -
1303 (xfs_drfsbno_t) mp->m_sb.sb_agblocks * i;
1304 /*
1305 * now reset the bitmap for all ags
1306 */
df10f12a 1307 bzero(ba_bmap[i], roundup(mp->m_sb.sb_agblocks/(NBBY/XR_BB),
2bd0ea18
NS
1308 sizeof(__uint64_t)));
1309 for (j = 0; j < ag_hdr_block; j++)
1310 set_agbno_state(mp, i, j, XR_E_INUSE_FS);
1311 }
1312 set_bmap_rt(mp->m_sb.sb_rextents);
1313 set_bmap_log(mp);
1314 set_bmap_fs(mp);
1315
507f4e33 1316 do_log(_(" - check for inodes claiming duplicate blocks...\n"));
2bd0ea18
NS
1317 for (i = 0; i < mp->m_sb.sb_agcount; i++) {
1318 /*
1319 * ok, now process the inodes -- signal 2-pass check per inode.
1320 * first pass checks if the inode conflicts with a known
1321 * duplicate extent. if so, the inode is cleared and second
1322 * pass is skipped. second pass sets the block bitmap
1323 * for all blocks claimed by the inode. directory
dfc130f3 1324 * and attribute processing is turned OFF since we did that
2bd0ea18
NS
1325 * already in phase 3.
1326 */
507f4e33 1327 do_log(_(" - agno = %d\n"), i);
2bd0ea18
NS
1328 process_aginodes(mp, i, 0, 1, 0);
1329
1330 /*
1331 * now recycle the per-AG duplicate extent records
1332 */
1333 release_dup_extent_tree(i);
1334 }
1335
1336 /*
1337 * free up memory used to track trealtime duplicate extents
1338 */
1339 if (rt_start != 0)
1340 free_rt_dup_extent_tree(mp);
1341
1342 /*
1343 * ensure consistency of quota inode pointers in superblock,
1344 * make sure they point to real inodes
1345 */
1346 quotino_check(mp);
1347 quota_sb_check(mp);
1348}