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