2 * Copyright (c) 2000-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
28 #include "err_protos.h"
33 static struct cred zerocr
;
34 static struct fsxattr zerofsx
;
35 static xfs_ino_t orphanage_ino
;
37 static struct xfs_name xfs_name_dot
= {(unsigned char *)".",
42 * Data structures used to keep track of directories where the ".."
43 * entries are updated. These must be rebuilt after the initial pass
45 typedef struct dotdot_update
{
46 struct list_head list
;
47 ino_tree_node_t
*irec
;
52 static LIST_HEAD(dotdot_update_list
);
53 static int dotdot_update
;
58 ino_tree_node_t
*irec
,
61 dotdot_update_t
*dir
= malloc(sizeof(dotdot_update_t
));
64 do_error(_("malloc failed add_dotdot_update (%zu bytes)\n"),
65 sizeof(dotdot_update_t
));
67 INIT_LIST_HEAD(&dir
->list
);
70 dir
->ino_offset
= ino_offset
;
72 list_add(&dir
->list
, &dotdot_update_list
);
76 * Data structures and routines to keep track of directory entries
77 * and whether their leaf entry has been seen. Also used for name
78 * duplicate checking and rebuilding step if required.
80 typedef struct dir_hash_ent
{
81 struct dir_hash_ent
*nextbyaddr
; /* next in addr bucket */
82 struct dir_hash_ent
*nextbyhash
; /* next in name bucket */
83 struct dir_hash_ent
*nextbyorder
; /* next in order added */
84 xfs_dahash_t hashval
; /* hash value of name */
85 __uint32_t address
; /* offset of data entry */
86 xfs_ino_t inum
; /* inode num of entry */
87 short junkit
; /* name starts with / */
88 short seen
; /* have seen leaf entry */
92 typedef struct dir_hash_tab
{
93 int size
; /* size of hash tables */
94 int names_duped
; /* 1 = ent names malloced */
95 dir_hash_ent_t
*first
; /* ptr to first added entry */
96 dir_hash_ent_t
*last
; /* ptr to last added entry */
97 dir_hash_ent_t
**byhash
; /* ptr to name hash buckets */
98 dir_hash_ent_t
**byaddr
; /* ptr to addr hash buckets */
101 #define DIR_HASH_TAB_SIZE(n) \
102 (sizeof(dir_hash_tab_t) + (sizeof(dir_hash_ent_t *) * (n) * 2))
103 #define DIR_HASH_FUNC(t,a) ((a) % (t)->size)
106 * Track the contents of the freespace table in a directory.
108 typedef struct freetab
{
109 int naents
; /* expected number of data blocks */
110 int nents
; /* number of data blocks processed */
112 xfs_dir2_data_off_t v
;
116 #define FREETAB_SIZE(n) \
117 (offsetof(freetab_t, ents) + (sizeof(struct freetab_ent) * (n)))
119 #define DIR_HASH_CK_OK 0
120 #define DIR_HASH_CK_DUPLEAF 1
121 #define DIR_HASH_CK_BADHASH 2
122 #define DIR_HASH_CK_NODATA 3
123 #define DIR_HASH_CK_NOLEAF 4
124 #define DIR_HASH_CK_BADSTALE 5
125 #define DIR_HASH_CK_TOTAL 6
128 * Need to handle CRC and validation errors specially here. If there is a
129 * validator error, re-read without the verifier so that we get a buffer we can
130 * check and repair. Re-attach the ops to the buffer after the read so that when
131 * it is rewritten the CRC is recalculated.
133 * If the buffer was not read, we return an error. If the buffer was read but
134 * had a CRC or corruption error, we reread it without the verifier and if it is
135 * read successfully we increment *crc_error and return 0. Otherwise we
136 * return the read error.
140 struct xfs_inode
*ip
,
142 xfs_daddr_t mappedbno
,
143 struct xfs_buf
**bpp
,
144 const struct xfs_buf_ops
*ops
,
150 error
= -libxfs_da_read_buf(NULL
, ip
, bno
, mappedbno
, bpp
,
153 if (error
!= EFSBADCRC
&& error
!= EFSCORRUPTED
)
156 error2
= -libxfs_da_read_buf(NULL
, ip
, bno
, mappedbno
, bpp
,
157 XFS_DATA_FORK
, NULL
);
167 * Returns 0 if the name already exists (ie. a duplicate)
172 dir_hash_tab_t
*hashtab
,
179 xfs_dahash_t hash
= 0;
185 struct xfs_name xname
;
187 ASSERT(!hashtab
->names_duped
);
193 junk
= name
[0] == '/';
194 byaddr
= DIR_HASH_FUNC(hashtab
, addr
);
198 hash
= mp
->m_dirnameops
->hashname(&xname
);
199 byhash
= DIR_HASH_FUNC(hashtab
, hash
);
202 * search hash bucket for existing name.
204 for (p
= hashtab
->byhash
[byhash
]; p
; p
= p
->nextbyhash
) {
205 if (p
->hashval
== hash
&& p
->name
.len
== namelen
) {
206 if (memcmp(p
->name
.name
, name
, namelen
) == 0) {
215 if ((p
= malloc(sizeof(*p
))) == NULL
)
216 do_error(_("malloc failed in dir_hash_add (%zu bytes)\n"),
219 p
->nextbyaddr
= hashtab
->byaddr
[byaddr
];
220 hashtab
->byaddr
[byaddr
] = p
;
222 hashtab
->last
->nextbyorder
= p
;
225 p
->nextbyorder
= NULL
;
228 if (!(p
->junkit
= junk
)) {
230 p
->nextbyhash
= hashtab
->byhash
[byhash
];
231 hashtab
->byhash
[byhash
] = p
;
242 * checks to see if any data entries are not in the leaf blocks
246 dir_hash_tab_t
*hashtab
)
251 for (i
= 0; i
< hashtab
->size
; i
++) {
252 for (p
= hashtab
->byaddr
[i
]; p
; p
= p
->nextbyaddr
) {
262 dir_hash_tab_t
*hashtab
,
266 static char *seevalstr
[DIR_HASH_CK_TOTAL
];
270 seevalstr
[DIR_HASH_CK_OK
] = _("ok");
271 seevalstr
[DIR_HASH_CK_DUPLEAF
] = _("duplicate leaf");
272 seevalstr
[DIR_HASH_CK_BADHASH
] = _("hash value mismatch");
273 seevalstr
[DIR_HASH_CK_NODATA
] = _("no data entry");
274 seevalstr
[DIR_HASH_CK_NOLEAF
] = _("no leaf entry");
275 seevalstr
[DIR_HASH_CK_BADSTALE
] = _("bad stale count");
279 if (seeval
== DIR_HASH_CK_OK
&& dir_hash_unseen(hashtab
))
280 seeval
= DIR_HASH_CK_NOLEAF
;
281 if (seeval
== DIR_HASH_CK_OK
)
283 do_warn(_("bad hash table for directory inode %" PRIu64
" (%s): "),
284 ip
->i_ino
, seevalstr
[seeval
]);
286 do_warn(_("rebuilding\n"));
288 do_warn(_("would rebuild\n"));
294 dir_hash_tab_t
*hashtab
)
300 for (i
= 0; i
< hashtab
->size
; i
++) {
301 for (p
= hashtab
->byaddr
[i
]; p
; p
= n
) {
303 if (hashtab
->names_duped
)
304 free((void *)p
->name
.name
);
311 static dir_hash_tab_t
*
315 dir_hash_tab_t
*hashtab
;
318 hsize
= size
/ (16 * 4);
323 if ((hashtab
= calloc(DIR_HASH_TAB_SIZE(hsize
), 1)) == NULL
)
324 do_error(_("calloc failed in dir_hash_init\n"));
325 hashtab
->size
= hsize
;
326 hashtab
->byhash
= (dir_hash_ent_t
**)((char *)hashtab
+
327 sizeof(dir_hash_tab_t
));
328 hashtab
->byaddr
= (dir_hash_ent_t
**)((char *)hashtab
+
329 sizeof(dir_hash_tab_t
) + sizeof(dir_hash_ent_t
*) * hsize
);
335 dir_hash_tab_t
*hashtab
,
337 xfs_dir2_dataptr_t addr
)
342 i
= DIR_HASH_FUNC(hashtab
, addr
);
343 for (p
= hashtab
->byaddr
[i
]; p
; p
= p
->nextbyaddr
) {
344 if (p
->address
!= addr
)
347 return DIR_HASH_CK_DUPLEAF
;
348 if (p
->junkit
== 0 && p
->hashval
!= hash
)
349 return DIR_HASH_CK_BADHASH
;
351 return DIR_HASH_CK_OK
;
353 return DIR_HASH_CK_NODATA
;
357 dir_hash_update_ftype(
358 dir_hash_tab_t
*hashtab
,
359 xfs_dir2_dataptr_t addr
,
365 i
= DIR_HASH_FUNC(hashtab
, addr
);
366 for (p
= hashtab
->byaddr
[i
]; p
; p
= p
->nextbyaddr
) {
367 if (p
->address
!= addr
)
369 p
->name
.type
= ftype
;
374 * checks to make sure leafs match a data entry, and that the stale
379 dir_hash_tab_t
*hashtab
,
380 xfs_dir2_leaf_entry_t
*ents
,
388 for (i
= j
= 0; i
< count
; i
++) {
389 if (be32_to_cpu(ents
[i
].address
) == XFS_DIR2_NULL_DATAPTR
) {
393 rval
= dir_hash_see(hashtab
, be32_to_cpu(ents
[i
].hashval
),
394 be32_to_cpu(ents
[i
].address
));
395 if (rval
!= DIR_HASH_CK_OK
)
398 return j
== stale
? DIR_HASH_CK_OK
: DIR_HASH_CK_BADSTALE
;
402 * Convert name pointers into locally allocated memory.
403 * This must only be done after all the entries have been added.
406 dir_hash_dup_names(dir_hash_tab_t
*hashtab
)
411 if (hashtab
->names_duped
)
414 for (p
= hashtab
->first
; p
; p
= p
->nextbyorder
) {
415 name
= malloc(p
->name
.len
);
416 memcpy(name
, p
->name
.name
, p
->name
.len
);
419 hashtab
->names_duped
= 1;
423 * Given a block number in a fork, return the next valid block number
425 * If this is the last block number then NULLFILEOFF is returned.
427 * This was originally in the kernel, but only used in xfs_repair.
431 xfs_trans_t
*tp
, /* transaction pointer */
432 xfs_inode_t
*ip
, /* incore inode */
433 xfs_fileoff_t
*bnop
, /* current block */
434 int whichfork
) /* data or attr fork */
436 xfs_fileoff_t bno
; /* current block */
437 int eof
; /* hit end of file */
438 int error
; /* error return value */
439 xfs_bmbt_irec_t got
; /* current extent value */
440 xfs_ifork_t
*ifp
; /* inode fork pointer */
441 xfs_extnum_t lastx
; /* last extent used */
442 xfs_bmbt_irec_t prev
; /* previous extent value */
444 if (XFS_IFORK_FORMAT(ip
, whichfork
) != XFS_DINODE_FMT_BTREE
&&
445 XFS_IFORK_FORMAT(ip
, whichfork
) != XFS_DINODE_FMT_EXTENTS
&&
446 XFS_IFORK_FORMAT(ip
, whichfork
) != XFS_DINODE_FMT_LOCAL
)
448 if (XFS_IFORK_FORMAT(ip
, whichfork
) == XFS_DINODE_FMT_LOCAL
) {
452 ifp
= XFS_IFORK_PTR(ip
, whichfork
);
453 if (!(ifp
->if_flags
& XFS_IFEXTENTS
) &&
454 (error
= xfs_iread_extents(tp
, ip
, whichfork
)))
457 libxfs_bmap_search_extents(ip
, bno
, whichfork
, &eof
, &lastx
,
462 *bnop
= got
.br_startoff
< bno
? bno
: got
.br_startoff
;
472 do_error(_("ran out of disk space!\n"));
474 do_error(_("xfs_trans_reserve returned %d\n"), err
);
478 mk_rbmino(xfs_mount_t
*mp
)
488 xfs_bmap_free_t flist
;
490 xfs_bmbt_irec_t map
[XFS_BMAP_MAX_NMAP
];
493 struct xfs_trans_res tres
= {0};
498 tp
= libxfs_trans_alloc(mp
, 0);
500 i
= -libxfs_trans_reserve(tp
, &tres
, 10, 0);
504 error
= -libxfs_trans_iget(mp
, tp
, mp
->m_sb
.sb_rbmino
, 0, 0, &ip
);
507 _("couldn't iget realtime bitmap inode -- error - %d\n"),
511 vers
= xfs_sb_version_hascrc(&mp
->m_sb
) ? 3 : 1;
512 memset(&ip
->i_d
, 0, xfs_icdinode_size(vers
));
514 ip
->i_d
.di_magic
= XFS_DINODE_MAGIC
;
515 ip
->i_d
.di_mode
= S_IFREG
;
516 ip
->i_d
.di_version
= vers
;
517 ip
->i_d
.di_format
= XFS_DINODE_FMT_EXTENTS
;
518 ip
->i_d
.di_aformat
= XFS_DINODE_FMT_EXTENTS
;
520 ip
->i_d
.di_nlink
= 1; /* account for sb ptr */
522 times
= XFS_ICHGTIME_CHG
| XFS_ICHGTIME_MOD
;
523 if (ip
->i_d
.di_version
== 3) {
525 ip
->i_d
.di_changecount
= 1;
527 ip
->i_d
.di_flags2
= 0;
528 ip
->i_d
.di_ino
= mp
->m_sb
.sb_rbmino
;
529 memset(&(ip
->i_d
.di_pad2
[0]), 0, sizeof(ip
->i_d
.di_pad2
));
530 platform_uuid_copy(&ip
->i_d
.di_uuid
, &mp
->m_sb
.sb_uuid
);
531 times
|= XFS_ICHGTIME_CREATE
;
533 libxfs_trans_ichgtime(tp
, ip
, times
);
538 ip
->i_df
.if_flags
= XFS_IFEXTENTS
;
539 ip
->i_df
.if_bytes
= ip
->i_df
.if_real_bytes
= 0;
540 ip
->i_df
.if_u1
.if_extents
= NULL
;
542 ip
->i_d
.di_size
= mp
->m_sb
.sb_rbmblocks
* mp
->m_sb
.sb_blocksize
;
547 libxfs_trans_log_inode(tp
, ip
, XFS_ILOG_CORE
);
548 libxfs_trans_commit(tp
);
551 * then allocate blocks for file and fill with zeroes (stolen
554 tp
= libxfs_trans_alloc(mp
, 0);
555 error
= -libxfs_trans_reserve(tp
, &tres
, mp
->m_sb
.sb_rbmblocks
+
556 (XFS_BM_MAXLEVELS(mp
, XFS_DATA_FORK
) - 1), 0);
560 libxfs_trans_ijoin(tp
, ip
, 0);
562 xfs_bmap_init(&flist
, &first
);
563 while (bno
< mp
->m_sb
.sb_rbmblocks
) {
564 nmap
= XFS_BMAP_MAX_NMAP
;
565 error
= -libxfs_bmapi_write(tp
, ip
, bno
,
566 (xfs_extlen_t
)(mp
->m_sb
.sb_rbmblocks
- bno
),
567 0, &first
, mp
->m_sb
.sb_rbmblocks
,
571 _("couldn't allocate realtime bitmap, error = %d\n"),
574 for (i
= 0, ep
= map
; i
< nmap
; i
++, ep
++) {
575 libxfs_device_zero(mp
->m_ddev_targp
,
576 XFS_FSB_TO_DADDR(mp
, ep
->br_startblock
),
577 XFS_FSB_TO_BB(mp
, ep
->br_blockcount
));
578 bno
+= ep
->br_blockcount
;
581 error
= -libxfs_bmap_finish(&tp
, &flist
, &committed
);
584 _("allocation of the realtime bitmap failed, error = %d\n"),
587 libxfs_trans_commit(tp
);
591 fill_rbmino(xfs_mount_t
*mp
)
602 struct xfs_trans_res tres
= {0};
607 tp
= libxfs_trans_alloc(mp
, 0);
609 error
= -libxfs_trans_reserve(tp
, &tres
, 10, 0);
613 error
= -libxfs_trans_iget(mp
, tp
, mp
->m_sb
.sb_rbmino
, 0, 0, &ip
);
616 _("couldn't iget realtime bitmap inode -- error - %d\n"),
621 while (bno
< mp
->m_sb
.sb_rbmblocks
) {
623 * fill the file one block at a time
626 error
= -libxfs_bmapi_write(tp
, ip
, bno
, 1, 0,
627 &first
, 1, &map
, &nmap
, NULL
);
628 if (error
|| nmap
!= 1) {
630 _("couldn't map realtime bitmap block %" PRIu64
", error = %d\n"),
634 ASSERT(map
.br_startblock
!= HOLESTARTBLOCK
);
636 error
= -libxfs_trans_read_buf(
638 XFS_FSB_TO_DADDR(mp
, map
.br_startblock
),
639 XFS_FSB_TO_BB(mp
, 1), 1, &bp
, NULL
);
643 _("can't access block %" PRIu64
" (fsbno %" PRIu64
") of realtime bitmap inode %" PRIu64
"\n"),
644 bno
, map
.br_startblock
, mp
->m_sb
.sb_rbmino
);
648 memmove(XFS_BUF_PTR(bp
), bmp
, mp
->m_sb
.sb_blocksize
);
650 libxfs_trans_log_buf(tp
, bp
, 0, mp
->m_sb
.sb_blocksize
- 1);
652 bmp
= (xfs_rtword_t
*)((intptr_t) bmp
+ mp
->m_sb
.sb_blocksize
);
656 libxfs_trans_commit(tp
);
661 fill_rsumino(xfs_mount_t
*mp
)
671 xfs_fileoff_t end_bno
;
673 struct xfs_trans_res tres
= {0};
677 end_bno
= mp
->m_rsumsize
>> mp
->m_sb
.sb_blocklog
;
679 tp
= libxfs_trans_alloc(mp
, 0);
681 error
= -libxfs_trans_reserve(tp
, &tres
, 10, 0);
685 error
= -libxfs_trans_iget(mp
, tp
, mp
->m_sb
.sb_rsumino
, 0, 0, &ip
);
688 _("couldn't iget realtime summary inode -- error - %d\n"),
693 while (bno
< end_bno
) {
695 * fill the file one block at a time
698 error
= -libxfs_bmapi_write(tp
, ip
, bno
, 1, 0,
699 &first
, 1, &map
, &nmap
, NULL
);
700 if (error
|| nmap
!= 1) {
702 _("couldn't map realtime summary inode block %" PRIu64
", error = %d\n"),
706 ASSERT(map
.br_startblock
!= HOLESTARTBLOCK
);
708 error
= -libxfs_trans_read_buf(
710 XFS_FSB_TO_DADDR(mp
, map
.br_startblock
),
711 XFS_FSB_TO_BB(mp
, 1), 1, &bp
, NULL
);
715 _("can't access block %" PRIu64
" (fsbno %" PRIu64
") of realtime summary inode %" PRIu64
"\n"),
716 bno
, map
.br_startblock
, mp
->m_sb
.sb_rsumino
);
720 memmove(XFS_BUF_PTR(bp
), smp
, mp
->m_sb
.sb_blocksize
);
722 libxfs_trans_log_buf(tp
, bp
, 0, mp
->m_sb
.sb_blocksize
- 1);
724 smp
= (xfs_suminfo_t
*)((intptr_t)smp
+ mp
->m_sb
.sb_blocksize
);
728 libxfs_trans_commit(tp
);
733 mk_rsumino(xfs_mount_t
*mp
)
744 xfs_bmap_free_t flist
;
746 xfs_bmbt_irec_t map
[XFS_BMAP_MAX_NMAP
];
749 struct xfs_trans_res tres
= {0};
754 tp
= libxfs_trans_alloc(mp
, 0);
756 i
= -libxfs_trans_reserve(tp
, &M_RES(mp
)->tr_ichange
, 10, 0);
760 error
= -libxfs_trans_iget(mp
, tp
, mp
->m_sb
.sb_rsumino
, 0, 0, &ip
);
763 _("couldn't iget realtime summary inode -- error - %d\n"),
767 vers
= xfs_sb_version_hascrc(&mp
->m_sb
) ? 3 : 1;
768 memset(&ip
->i_d
, 0, xfs_icdinode_size(vers
));
770 ip
->i_d
.di_magic
= XFS_DINODE_MAGIC
;
771 ip
->i_d
.di_mode
= S_IFREG
;
772 ip
->i_d
.di_version
= vers
;
773 ip
->i_d
.di_format
= XFS_DINODE_FMT_EXTENTS
;
774 ip
->i_d
.di_aformat
= XFS_DINODE_FMT_EXTENTS
;
776 ip
->i_d
.di_nlink
= 1; /* account for sb ptr */
778 times
= XFS_ICHGTIME_CHG
| XFS_ICHGTIME_MOD
;
779 if (ip
->i_d
.di_version
== 3) {
781 ip
->i_d
.di_changecount
= 1;
783 ip
->i_d
.di_flags2
= 0;
784 ip
->i_d
.di_ino
= mp
->m_sb
.sb_rsumino
;
785 memset(&(ip
->i_d
.di_pad2
[0]), 0, sizeof(ip
->i_d
.di_pad2
));
786 platform_uuid_copy(&ip
->i_d
.di_uuid
, &mp
->m_sb
.sb_uuid
);
787 times
|= XFS_ICHGTIME_CREATE
;
789 libxfs_trans_ichgtime(tp
, ip
, times
);
794 ip
->i_df
.if_flags
= XFS_IFEXTENTS
;
795 ip
->i_df
.if_bytes
= ip
->i_df
.if_real_bytes
= 0;
796 ip
->i_df
.if_u1
.if_extents
= NULL
;
798 ip
->i_d
.di_size
= mp
->m_rsumsize
;
803 libxfs_trans_log_inode(tp
, ip
, XFS_ILOG_CORE
);
804 libxfs_trans_commit(tp
);
807 * then allocate blocks for file and fill with zeroes (stolen
810 tp
= libxfs_trans_alloc(mp
, 0);
811 xfs_bmap_init(&flist
, &first
);
813 nsumblocks
= mp
->m_rsumsize
>> mp
->m_sb
.sb_blocklog
;
814 tres
.tr_logres
= BBTOB(128);
815 tres
.tr_logcount
= XFS_DEFAULT_PERM_LOG_COUNT
;
816 tres
.tr_logflags
= XFS_TRANS_PERM_LOG_RES
;
817 error
= -libxfs_trans_reserve(tp
, &tres
, mp
->m_sb
.sb_rbmblocks
+
818 (XFS_BM_MAXLEVELS(mp
, XFS_DATA_FORK
) - 1), 0);
822 libxfs_trans_ijoin(tp
, ip
, 0);
824 xfs_bmap_init(&flist
, &first
);
825 while (bno
< nsumblocks
) {
826 nmap
= XFS_BMAP_MAX_NMAP
;
827 error
= -libxfs_bmapi_write(tp
, ip
, bno
,
828 (xfs_extlen_t
)(nsumblocks
- bno
),
829 0, &first
, nsumblocks
, map
, &nmap
, &flist
);
832 _("couldn't allocate realtime summary inode, error = %d\n"),
835 for (i
= 0, ep
= map
; i
< nmap
; i
++, ep
++) {
836 libxfs_device_zero(mp
->m_ddev_targp
,
837 XFS_FSB_TO_DADDR(mp
, ep
->br_startblock
),
838 XFS_FSB_TO_BB(mp
, ep
->br_blockcount
));
839 bno
+= ep
->br_blockcount
;
842 error
= -libxfs_bmap_finish(&tp
, &flist
, &committed
);
845 _("allocation of the realtime summary ino failed, error = %d\n"),
848 libxfs_trans_commit(tp
);
852 * makes a new root directory.
855 mk_root_dir(xfs_mount_t
*mp
)
861 const mode_t mode
= 0755;
862 ino_tree_node_t
*irec
;
866 tp
= libxfs_trans_alloc(mp
, 0);
869 i
= -libxfs_trans_reserve(tp
, &M_RES(mp
)->tr_ichange
, 10, 0);
873 error
= -libxfs_trans_iget(mp
, tp
, mp
->m_sb
.sb_rootino
, 0, 0, &ip
);
875 do_error(_("could not iget root inode -- error - %d\n"), error
);
879 * take care of the core -- initialization from xfs_ialloc()
881 vers
= xfs_sb_version_hascrc(&mp
->m_sb
) ? 3 : 2;
882 memset(&ip
->i_d
, 0, xfs_icdinode_size(vers
));
884 ip
->i_d
.di_magic
= XFS_DINODE_MAGIC
;
885 ip
->i_d
.di_mode
= (__uint16_t
) mode
|S_IFDIR
;
886 ip
->i_d
.di_version
= vers
;
887 ip
->i_d
.di_format
= XFS_DINODE_FMT_EXTENTS
;
888 ip
->i_d
.di_aformat
= XFS_DINODE_FMT_EXTENTS
;
890 ip
->i_d
.di_nlink
= 1; /* account for . */
892 times
= XFS_ICHGTIME_CHG
| XFS_ICHGTIME_MOD
;
893 if (ip
->i_d
.di_version
== 3) {
895 ip
->i_d
.di_changecount
= 1;
897 ip
->i_d
.di_flags2
= 0;
898 ip
->i_d
.di_ino
= mp
->m_sb
.sb_rootino
;
899 memset(&(ip
->i_d
.di_pad2
[0]), 0, sizeof(ip
->i_d
.di_pad2
));
900 platform_uuid_copy(&ip
->i_d
.di_uuid
, &mp
->m_sb
.sb_uuid
);
901 times
|= XFS_ICHGTIME_CREATE
;
903 libxfs_trans_ichgtime(tp
, ip
, times
);
905 libxfs_trans_log_inode(tp
, ip
, XFS_ILOG_CORE
);
910 ip
->i_df
.if_flags
= XFS_IFEXTENTS
;
911 ip
->i_df
.if_bytes
= ip
->i_df
.if_real_bytes
= 0;
912 ip
->i_df
.if_u1
.if_extents
= NULL
;
917 * initialize the directory
919 ip
->d_ops
= mp
->m_dir_inode_ops
;
920 libxfs_dir_init(tp
, ip
, ip
);
922 libxfs_trans_commit(tp
);
924 irec
= find_inode_rec(mp
, XFS_INO_TO_AGNO(mp
, mp
->m_sb
.sb_rootino
),
925 XFS_INO_TO_AGINO(mp
, mp
->m_sb
.sb_rootino
));
926 set_inode_isadir(irec
, XFS_INO_TO_AGINO(mp
, mp
->m_sb
.sb_rootino
) -
931 * orphanage name == lost+found
934 mk_orphanage(xfs_mount_t
*mp
)
941 ino_tree_node_t
*irec
;
946 xfs_bmap_free_t flist
;
947 const int mode
= 0755;
949 struct xfs_name xname
;
952 * check for an existing lost+found first, if it exists, return
953 * its inode. Otherwise, we can create it. Bad lost+found inodes
954 * would have been cleared in phase3 and phase4.
957 if ((i
= -libxfs_iget(mp
, NULL
, mp
->m_sb
.sb_rootino
, 0, &pip
, 0)))
958 do_error(_("%d - couldn't iget root inode to obtain %s\n"),
961 xname
.name
= (unsigned char *)ORPHANAGE
;
962 xname
.len
= strlen(ORPHANAGE
);
963 xname
.type
= XFS_DIR3_FT_DIR
;
965 if (libxfs_dir_lookup(NULL
, pip
, &xname
, &ino
, NULL
) == 0)
969 * could not be found, create it
972 tp
= libxfs_trans_alloc(mp
, 0);
973 xfs_bmap_init(&flist
, &first
);
975 nres
= XFS_MKDIR_SPACE_RES(mp
, xname
.len
);
976 i
= -libxfs_trans_reserve(tp
, &M_RES(mp
)->tr_mkdir
, nres
, 0);
981 * use iget/ijoin instead of trans_iget because the ialloc
982 * wrapper can commit the transaction and start a new one
984 /* if ((i = -libxfs_iget(mp, NULL, mp->m_sb.sb_rootino, 0, &pip, 0)))
985 do_error(_("%d - couldn't iget root inode to make %s\n"),
988 error
= -libxfs_inode_alloc(&tp
, pip
, mode
|S_IFDIR
,
989 1, 0, &zerocr
, &zerofsx
, &ip
);
991 do_error(_("%s inode allocation failed %d\n"),
994 ip
->i_d
.di_nlink
++; /* account for . */
997 irec
= find_inode_rec(mp
,
998 XFS_INO_TO_AGNO(mp
, ino
),
999 XFS_INO_TO_AGINO(mp
, ino
));
1003 * This inode is allocated from a newly created inode
1004 * chunk and therefore did not exist when inode chunks
1005 * were processed in phase3. Add this group of inodes to
1006 * the entry avl tree as if they were discovered in phase3.
1008 irec
= set_inode_free_alloc(mp
, XFS_INO_TO_AGNO(mp
, ino
),
1009 XFS_INO_TO_AGINO(mp
, ino
));
1010 alloc_ex_data(irec
);
1012 for (i
= 0; i
< XFS_INODES_PER_CHUNK
; i
++)
1013 set_inode_free(irec
, i
);
1016 ino_offset
= get_inode_offset(mp
, ino
, irec
);
1019 * Mark the inode allocated to lost+found as used in the AVL tree
1020 * so it is not skipped in phase 7
1022 set_inode_used(irec
, ino_offset
);
1023 add_inode_ref(irec
, ino_offset
);
1026 * now that we know the transaction will stay around,
1027 * add the root inode to it
1029 libxfs_trans_ijoin(tp
, pip
, 0);
1032 * create the actual entry
1034 error
= -libxfs_dir_createname(tp
, pip
, &xname
, ip
->i_ino
, &first
,
1038 _("can't make %s, createname error %d\n"),
1042 * bump up the link count in the root directory to account
1043 * for .. in the new directory
1045 pip
->i_d
.di_nlink
++;
1046 add_inode_ref(find_inode_rec(mp
,
1047 XFS_INO_TO_AGNO(mp
, mp
->m_sb
.sb_rootino
),
1048 XFS_INO_TO_AGINO(mp
, mp
->m_sb
.sb_rootino
)), 0);
1052 libxfs_trans_log_inode(tp
, pip
, XFS_ILOG_CORE
);
1053 libxfs_dir_init(tp
, ip
, pip
);
1054 libxfs_trans_log_inode(tp
, ip
, XFS_ILOG_CORE
);
1056 error
= -libxfs_bmap_finish(&tp
, &flist
, &committed
);
1058 do_error(_("%s directory creation failed -- bmapf error %d\n"),
1063 libxfs_trans_commit(tp
);
1066 add_inode_reached(irec
,ino_offset
);
1072 * move a file to the orphange.
1077 xfs_ino_t ino
, /* inode # to be moved */
1078 int isa_dir
) /* 1 if inode is a directory */
1080 xfs_inode_t
*orphanage_ip
;
1081 xfs_ino_t entry_ino_num
;
1084 xfs_fsblock_t first
;
1085 xfs_bmap_free_t flist
;
1088 unsigned char fname
[MAXPATHLEN
+ 1];
1091 ino_tree_node_t
*irec
;
1093 struct xfs_name xname
;
1096 xname
.len
= snprintf((char *)fname
, sizeof(fname
), "%llu",
1097 (unsigned long long)ino
);
1099 err
= -libxfs_iget(mp
, NULL
, orphanage_ino
, 0, &orphanage_ip
, 0);
1101 do_error(_("%d - couldn't iget orphanage inode\n"), err
);
1103 * Make sure the filename is unique in the lost+found
1106 while (libxfs_dir_lookup(NULL
, orphanage_ip
, &xname
, &entry_ino_num
,
1108 xname
.len
= snprintf((char *)fname
, sizeof(fname
), "%llu.%d",
1109 (unsigned long long)ino
, ++incr
);
1111 tp
= libxfs_trans_alloc(mp
, 0);
1113 if ((err
= -libxfs_iget(mp
, NULL
, ino
, 0, &ino_p
, 0)))
1114 do_error(_("%d - couldn't iget disconnected inode\n"), err
);
1116 xname
.type
= xfs_mode_to_ftype
[(ino_p
->i_d
.di_mode
& S_IFMT
)>>S_SHIFT
];
1119 irec
= find_inode_rec(mp
, XFS_INO_TO_AGNO(mp
, orphanage_ino
),
1120 XFS_INO_TO_AGINO(mp
, orphanage_ino
));
1122 ino_offset
= XFS_INO_TO_AGINO(mp
, orphanage_ino
) -
1124 nres
= XFS_DIRENTER_SPACE_RES(mp
, fnamelen
) +
1125 XFS_DIRENTER_SPACE_RES(mp
, 2);
1126 err
= -libxfs_dir_lookup(tp
, ino_p
, &xfs_name_dotdot
,
1127 &entry_ino_num
, NULL
);
1129 ASSERT(err
== ENOENT
);
1131 err
= -libxfs_trans_reserve(tp
, &M_RES(mp
)->tr_rename
,
1135 _("space reservation failed (%d), filesystem may be out of space\n"),
1138 libxfs_trans_ijoin(tp
, orphanage_ip
, 0);
1139 libxfs_trans_ijoin(tp
, ino_p
, 0);
1141 xfs_bmap_init(&flist
, &first
);
1142 err
= -libxfs_dir_createname(tp
, orphanage_ip
, &xname
,
1143 ino
, &first
, &flist
, nres
);
1146 _("name create failed in %s (%d), filesystem may be out of space\n"),
1150 add_inode_ref(irec
, ino_offset
);
1152 orphanage_ip
->i_d
.di_nlink
++;
1153 libxfs_trans_log_inode(tp
, orphanage_ip
, XFS_ILOG_CORE
);
1155 err
= -libxfs_dir_createname(tp
, ino_p
, &xfs_name_dotdot
,
1156 orphanage_ino
, &first
, &flist
, nres
);
1159 _("creation of .. entry failed (%d), filesystem may be out of space\n"),
1162 ino_p
->i_d
.di_nlink
++;
1163 libxfs_trans_log_inode(tp
, ino_p
, XFS_ILOG_CORE
);
1165 err
= -libxfs_bmap_finish(&tp
, &flist
, &committed
);
1168 _("bmap finish failed (err - %d), filesystem may be out of space\n"),
1171 libxfs_trans_commit(tp
);
1173 err
= -libxfs_trans_reserve(tp
, &M_RES(mp
)->tr_rename
,
1177 _("space reservation failed (%d), filesystem may be out of space\n"),
1180 libxfs_trans_ijoin(tp
, orphanage_ip
, 0);
1181 libxfs_trans_ijoin(tp
, ino_p
, 0);
1183 xfs_bmap_init(&flist
, &first
);
1185 err
= -libxfs_dir_createname(tp
, orphanage_ip
, &xname
,
1186 ino
, &first
, &flist
, nres
);
1189 _("name create failed in %s (%d), filesystem may be out of space\n"),
1193 add_inode_ref(irec
, ino_offset
);
1195 orphanage_ip
->i_d
.di_nlink
++;
1196 libxfs_trans_log_inode(tp
, orphanage_ip
, XFS_ILOG_CORE
);
1199 * don't replace .. value if it already points
1200 * to us. that'll pop a libxfs/kernel ASSERT.
1202 if (entry_ino_num
!= orphanage_ino
) {
1203 err
= -libxfs_dir_replace(tp
, ino_p
,
1204 &xfs_name_dotdot
, orphanage_ino
,
1205 &first
, &flist
, nres
);
1208 _("name replace op failed (%d), filesystem may be out of space\n"),
1212 err
= -libxfs_bmap_finish(&tp
, &flist
, &committed
);
1215 _("bmap finish failed (%d), filesystem may be out of space\n"),
1218 libxfs_trans_commit(tp
);
1223 * use the remove log reservation as that's
1224 * more accurate. we're only creating the
1225 * links, we're not doing the inode allocation
1226 * also accounted for in the create
1228 nres
= XFS_DIRENTER_SPACE_RES(mp
, xname
.len
);
1229 err
= -libxfs_trans_reserve(tp
, &M_RES(mp
)->tr_remove
,
1233 _("space reservation failed (%d), filesystem may be out of space\n"),
1236 libxfs_trans_ijoin(tp
, orphanage_ip
, 0);
1237 libxfs_trans_ijoin(tp
, ino_p
, 0);
1239 xfs_bmap_init(&flist
, &first
);
1240 err
= -libxfs_dir_createname(tp
, orphanage_ip
, &xname
, ino
,
1241 &first
, &flist
, nres
);
1244 _("name create failed in %s (%d), filesystem may be out of space\n"),
1248 ino_p
->i_d
.di_nlink
= 1;
1249 libxfs_trans_log_inode(tp
, ino_p
, XFS_ILOG_CORE
);
1251 err
= -libxfs_bmap_finish(&tp
, &flist
, &committed
);
1254 _("bmap finish failed (%d), filesystem may be out of space\n"),
1257 libxfs_trans_commit(tp
);
1260 IRELE(orphanage_ip
);
1270 do_warn(msg
, iname
, ino1
, ino2
);
1273 do_warn(_(", marking entry to be junked\n"));
1277 do_warn(_(", would junk entry\n"));
1282 * Unexpected failure during the rebuild will leave the entries in
1283 * lost+found on the next run
1287 longform_dir2_rebuild(
1291 ino_tree_node_t
*irec
,
1293 dir_hash_tab_t
*hashtab
)
1298 xfs_fileoff_t lastblock
;
1299 xfs_fsblock_t firstblock
;
1300 xfs_bmap_free_t flist
;
1307 * trash directory completely and rebuild from scratch using the
1308 * name/inode pairs in the hash table
1311 do_warn(_("rebuilding directory inode %" PRIu64
"\n"), ino
);
1314 * first attempt to locate the parent inode, if it can't be
1315 * found, set it to the root inode and it'll be moved to the
1316 * orphanage later (the inode number here needs to be valid
1317 * for the libxfs_dir_init() call).
1319 pip
.i_ino
= get_inode_parent(irec
, ino_offset
);
1320 if (pip
.i_ino
== NULLFSINO
||
1321 xfs_dir_ino_validate(mp
, pip
.i_ino
))
1322 pip
.i_ino
= mp
->m_sb
.sb_rootino
;
1324 xfs_bmap_init(&flist
, &firstblock
);
1326 tp
= libxfs_trans_alloc(mp
, 0);
1327 nres
= XFS_REMOVE_SPACE_RES(mp
);
1328 error
= -libxfs_trans_reserve(tp
, &M_RES(mp
)->tr_remove
, nres
, 0);
1331 libxfs_trans_ijoin(tp
, ip
, 0);
1333 if ((error
= -libxfs_bmap_last_offset(ip
, &lastblock
, XFS_DATA_FORK
)))
1334 do_error(_("xfs_bmap_last_offset failed -- error - %d\n"),
1337 /* free all data, leaf, node and freespace blocks */
1338 error
= -libxfs_bunmapi(tp
, ip
, 0, lastblock
, XFS_BMAPI_METADATA
, 0,
1339 &firstblock
, &flist
, &done
);
1341 do_warn(_("xfs_bunmapi failed -- error - %d\n"), error
);
1342 goto out_bmap_cancel
;
1347 error
= libxfs_dir_init(tp
, ip
, &pip
);
1349 do_warn(_("xfs_dir_init failed -- error - %d\n"), error
);
1350 goto out_bmap_cancel
;
1353 error
= -libxfs_bmap_finish(&tp
, &flist
, &committed
);
1355 libxfs_trans_commit(tp
);
1357 if (ino
== mp
->m_sb
.sb_rootino
)
1358 need_root_dotdot
= 0;
1360 /* go through the hash list and re-add the inodes */
1362 for (p
= hashtab
->first
; p
; p
= p
->nextbyorder
) {
1364 if (p
->name
.name
[0] == '/' || (p
->name
.name
[0] == '.' &&
1365 (p
->name
.len
== 1 || (p
->name
.len
== 2 &&
1366 p
->name
.name
[1] == '.'))))
1369 tp
= libxfs_trans_alloc(mp
, 0);
1370 nres
= XFS_CREATE_SPACE_RES(mp
, p
->name
.len
);
1371 error
= -libxfs_trans_reserve(tp
, &M_RES(mp
)->tr_create
,
1376 libxfs_trans_ijoin(tp
, ip
, 0);
1378 xfs_bmap_init(&flist
, &firstblock
);
1379 error
= -libxfs_dir_createname(tp
, ip
, &p
->name
, p
->inum
,
1380 &firstblock
, &flist
, nres
);
1383 _("name create failed in ino %" PRIu64
" (%d), filesystem may be out of space\n"),
1385 goto out_bmap_cancel
;
1388 error
= -libxfs_bmap_finish(&tp
, &flist
, &committed
);
1391 _("bmap finish failed (%d), filesystem may be out of space\n"),
1393 goto out_bmap_cancel
;
1396 libxfs_trans_commit(tp
);
1402 libxfs_bmap_cancel(&flist
);
1403 libxfs_trans_cancel(tp
);
1409 * Kill a block in a version 2 inode.
1410 * Makes its own transaction.
1422 xfs_fsblock_t firstblock
;
1423 xfs_bmap_free_t flist
;
1427 tp
= libxfs_trans_alloc(mp
, 0);
1428 nres
= XFS_REMOVE_SPACE_RES(mp
);
1429 error
= -libxfs_trans_reserve(tp
, &M_RES(mp
)->tr_remove
, nres
, 0);
1432 libxfs_trans_ijoin(tp
, ip
, 0);
1433 libxfs_trans_bjoin(tp
, bp
);
1434 memset(&args
, 0, sizeof(args
));
1435 xfs_bmap_init(&flist
, &firstblock
);
1438 args
.firstblock
= &firstblock
;
1439 args
.flist
= &flist
;
1440 args
.whichfork
= XFS_DATA_FORK
;
1441 if (da_bno
>= mp
->m_dir_geo
->leafblk
&& da_bno
< mp
->m_dir_geo
->freeblk
)
1442 error
= -libxfs_da_shrink_inode(&args
, da_bno
, bp
);
1444 error
= -libxfs_dir2_shrink_inode(&args
,
1445 xfs_dir2_da_to_db(mp
->m_dir_geo
, da_bno
), bp
);
1447 do_error(_("shrink_inode failed inode %" PRIu64
" block %u\n"),
1449 libxfs_bmap_finish(&tp
, &flist
, &committed
);
1450 libxfs_trans_commit(tp
);
1454 * process a data block, also checks for .. entry
1455 * and corrects it to match what we think .. should be
1458 longform_dir2_entry_check_data(
1463 ino_tree_node_t
*current_irec
,
1464 int current_ino_offset
,
1465 struct xfs_buf
**bpp
,
1466 dir_hash_tab_t
*hashtab
,
1467 freetab_t
**freetabp
,
1471 xfs_dir2_dataptr_t addr
;
1472 xfs_dir2_leaf_entry_t
*blp
;
1474 xfs_dir2_block_tail_t
*btp
;
1476 struct xfs_dir2_data_hdr
*d
;
1478 xfs_dir2_data_entry_t
*dep
;
1479 xfs_dir2_data_unused_t
*dup
;
1480 struct xfs_dir2_data_free
*bf
;
1483 xfs_fsblock_t firstblock
;
1484 xfs_bmap_free_t flist
;
1485 char fname
[MAXNAMELEN
+ 1];
1490 ino_tree_node_t
*irec
;
1501 struct xfs_da_args da
= {
1508 ptr
= (char *)M_DIROPS(mp
)->data_entry_p(d
);
1510 needscan
= needlog
= 0;
1512 freetab
= *freetabp
;
1514 btp
= xfs_dir2_block_tail_p(mp
->m_dir_geo
, d
);
1515 blp
= xfs_dir2_block_leaf_p(btp
);
1516 endptr
= (char *)blp
;
1517 if (endptr
> (char *)btp
)
1518 endptr
= (char *)btp
;
1519 if (xfs_sb_version_hascrc(&mp
->m_sb
))
1520 wantmagic
= XFS_DIR3_BLOCK_MAGIC
;
1522 wantmagic
= XFS_DIR2_BLOCK_MAGIC
;
1524 endptr
= (char *)d
+ mp
->m_dir_geo
->blksize
;
1525 if (xfs_sb_version_hascrc(&mp
->m_sb
))
1526 wantmagic
= XFS_DIR3_DATA_MAGIC
;
1528 wantmagic
= XFS_DIR2_DATA_MAGIC
;
1530 db
= xfs_dir2_da_to_db(mp
->m_dir_geo
, da_bno
);
1532 /* check for data block beyond expected end */
1533 if (freetab
->naents
<= db
) {
1534 struct freetab_ent e
;
1536 *freetabp
= freetab
= realloc(freetab
, FREETAB_SIZE(db
+ 1));
1538 do_error(_("realloc failed in %s (%zu bytes)\n"),
1539 __func__
, FREETAB_SIZE(db
+ 1));
1543 for (i
= freetab
->naents
; i
< db
; i
++)
1544 freetab
->ents
[i
] = e
;
1545 freetab
->naents
= db
+ 1;
1548 /* check the data block */
1549 while (ptr
< endptr
) {
1551 /* check for freespace */
1552 dup
= (xfs_dir2_data_unused_t
*)ptr
;
1553 if (XFS_DIR2_DATA_FREE_TAG
== be16_to_cpu(dup
->freetag
)) {
1555 /* check for invalid freespace length */
1556 if (ptr
+ be16_to_cpu(dup
->length
) > endptr
||
1557 be16_to_cpu(dup
->length
) == 0 ||
1558 (be16_to_cpu(dup
->length
) &
1559 (XFS_DIR2_DATA_ALIGN
- 1)))
1562 /* check for invalid tag */
1563 if (be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup
)) !=
1564 (char *)dup
- (char *)d
)
1567 /* check for block with no data entries */
1568 if ((ptr
== (char *)M_DIROPS(mp
)->data_entry_p(d
)) &&
1569 (ptr
+ be16_to_cpu(dup
->length
) >= endptr
)) {
1575 /* continue at the end of the freespace */
1576 ptr
+= be16_to_cpu(dup
->length
);
1581 /* validate data entry size */
1582 dep
= (xfs_dir2_data_entry_t
*)ptr
;
1583 if (ptr
+ M_DIROPS(mp
)->data_entsize(dep
->namelen
) > endptr
)
1585 if (be16_to_cpu(*M_DIROPS(mp
)->data_entry_tag_p(dep
)) !=
1586 (char *)dep
- (char *)d
)
1588 ptr
+= M_DIROPS(mp
)->data_entsize(dep
->namelen
);
1591 /* did we find an empty or corrupt block? */
1592 if (ptr
!= endptr
) {
1595 _("empty data block %u in directory inode %" PRIu64
": "),
1599 ("corrupt block %u in directory inode %" PRIu64
": "),
1603 do_warn(_("junking block\n"));
1604 dir2_kill_block(mp
, ip
, da_bno
, bp
);
1606 do_warn(_("would junk block\n"));
1609 freetab
->ents
[db
].v
= NULLDATAOFF
;
1614 /* update number of data blocks processed */
1615 if (freetab
->nents
< db
+ 1)
1616 freetab
->nents
= db
+ 1;
1618 tp
= libxfs_trans_alloc(mp
, 0);
1619 error
= -libxfs_trans_reserve(tp
, &M_RES(mp
)->tr_remove
, 0, 0);
1623 libxfs_trans_ijoin(tp
, ip
, 0);
1624 libxfs_trans_bjoin(tp
, bp
);
1625 libxfs_trans_bhold(tp
, bp
);
1626 xfs_bmap_init(&flist
, &firstblock
);
1627 if (be32_to_cpu(d
->magic
) != wantmagic
) {
1629 _("bad directory block magic # %#x for directory inode %" PRIu64
" block %d: "),
1630 be32_to_cpu(d
->magic
), ip
->i_ino
, da_bno
);
1632 do_warn(_("fixing magic # to %#x\n"), wantmagic
);
1633 d
->magic
= cpu_to_be32(wantmagic
);
1636 do_warn(_("would fix magic # to %#x\n"), wantmagic
);
1639 ptr
= (char *)M_DIROPS(mp
)->data_entry_p(d
);
1641 * look at each entry. reference inode pointed to by each
1642 * entry in the incore inode tree.
1643 * if not a directory, set reached flag, increment link count
1644 * if a directory and reached, mark entry as to be deleted.
1645 * if a directory, check to see if recorded parent
1646 * matches current inode #,
1647 * if so, then set reached flag, increment link count
1648 * of current and child dir inodes, push the child
1649 * directory inode onto the directory stack.
1650 * if current inode != parent, then mark entry to be deleted.
1652 while (ptr
< endptr
) {
1653 dup
= (xfs_dir2_data_unused_t
*)ptr
;
1654 if (be16_to_cpu(dup
->freetag
) == XFS_DIR2_DATA_FREE_TAG
) {
1657 _("directory inode %" PRIu64
" block %u has consecutive free entries: "),
1661 do_warn(_("joining together\n"));
1662 len
= be16_to_cpu(dup
->length
);
1663 libxfs_dir2_data_use_free(&da
, bp
, dup
,
1664 ptr
- (char *)d
, len
, &needlog
,
1666 libxfs_dir2_data_make_free(&da
, bp
,
1667 ptr
- (char *)d
, len
, &needlog
,
1670 do_warn(_("would join together\n"));
1672 ptr
+= be16_to_cpu(dup
->length
);
1676 addr
= xfs_dir2_db_off_to_dataptr(mp
->m_dir_geo
, db
,
1678 dep
= (xfs_dir2_data_entry_t
*)ptr
;
1679 ptr
+= M_DIROPS(mp
)->data_entsize(dep
->namelen
);
1680 inum
= be64_to_cpu(dep
->inumber
);
1683 * skip bogus entries (leading '/'). they'll be deleted
1684 * later. must still log it, else we leak references to
1687 if (dep
->name
[0] == '/') {
1690 libxfs_dir2_data_log_entry(&da
, bp
, dep
);
1694 memmove(fname
, dep
->name
, dep
->namelen
);
1695 fname
[dep
->namelen
] = '\0';
1696 ASSERT(inum
!= NULLFSINO
);
1698 irec
= find_inode_rec(mp
, XFS_INO_TO_AGNO(mp
, inum
),
1699 XFS_INO_TO_AGINO(mp
, inum
));
1703 _("entry \"%s\" in directory inode %" PRIu64
" points to non-existent inode %" PRIu64
""),
1704 fname
, ip
->i_ino
, inum
)) {
1706 libxfs_dir2_data_log_entry(&da
, bp
, dep
);
1710 ino_offset
= XFS_INO_TO_AGINO(mp
, inum
) - irec
->ino_startnum
;
1713 * if it's a free inode, blow out the entry.
1714 * by now, any inode that we think is free
1717 if (is_inode_free(irec
, ino_offset
)) {
1720 _("entry \"%s\" in directory inode %" PRIu64
" points to free inode %" PRIu64
),
1721 fname
, ip
->i_ino
, inum
)) {
1723 libxfs_dir2_data_log_entry(&da
, bp
, dep
);
1729 * check if this inode is lost+found dir in the root
1731 if (inum
== mp
->m_sb
.sb_rootino
&& strcmp(fname
, ORPHANAGE
) == 0) {
1733 * if it's not a directory, trash it
1735 if (!inode_isadir(irec
, ino_offset
)) {
1738 _("%s (ino %" PRIu64
") in root (%" PRIu64
") is not a directory"),
1739 ORPHANAGE
, inum
, ip
->i_ino
)) {
1741 libxfs_dir2_data_log_entry(&da
, bp
, dep
);
1746 * if this is a dup, it will be picked up below,
1747 * otherwise, mark it as the orphanage for later.
1750 orphanage_ino
= inum
;
1754 * check for duplicate names in directory.
1756 if (!dir_hash_add(mp
, hashtab
, addr
, inum
, dep
->namelen
,
1757 dep
->name
, M_DIROPS(mp
)->data_get_ftype(dep
))) {
1760 _("entry \"%s\" (ino %" PRIu64
") in dir %" PRIu64
" is a duplicate name"),
1761 fname
, inum
, ip
->i_ino
)) {
1763 libxfs_dir2_data_log_entry(&da
, bp
, dep
);
1765 if (inum
== orphanage_ino
)
1771 * if just scanning to rebuild a directory due to a ".."
1772 * update, just continue
1778 * skip the '..' entry since it's checked when the
1779 * directory is reached by something else. if it never
1780 * gets reached, it'll be moved to the orphanage and we'll
1781 * take care of it then. If it doesn't exist at all, the
1782 * directory needs to be rebuilt first before being added
1785 if (dep
->namelen
== 2 && dep
->name
[0] == '.' &&
1786 dep
->name
[1] == '.') {
1788 /* ".." should be in the first block */
1791 _("entry \"%s\" (ino %" PRIu64
") in dir %" PRIu64
" is not in the the first block"), fname
,
1794 libxfs_dir2_data_log_entry(&da
, bp
, dep
);
1799 ASSERT(no_modify
|| !verify_inum(mp
, inum
));
1801 * special case the . entry. we know there's only one
1802 * '.' and only '.' points to itself because bogus entries
1803 * got trashed in phase 3 if there were > 1.
1804 * bump up link count for '.' but don't set reached
1805 * until we're actually reached by another directory
1806 * '..' is already accounted for or will be taken care
1807 * of when directory is moved to orphanage.
1809 if (ip
->i_ino
== inum
) {
1810 ASSERT(dep
->name
[0] == '.' && dep
->namelen
== 1);
1811 add_inode_ref(current_irec
, current_ino_offset
);
1813 dep
!= M_DIROPS(mp
)->data_entry_p(d
)) {
1814 /* "." should be the first entry */
1817 _("entry \"%s\" in dir %" PRIu64
" is not the first entry"),
1818 fname
, inum
, ip
->i_ino
)) {
1820 libxfs_dir2_data_log_entry(&da
, bp
, dep
);
1827 * skip entries with bogus inumbers if we're in no modify mode
1829 if (no_modify
&& verify_inum(mp
, inum
))
1832 /* validate ftype field if supported */
1833 if (xfs_sb_version_hasftype(&mp
->m_sb
)) {
1834 __uint8_t dir_ftype
;
1835 __uint8_t ino_ftype
;
1837 dir_ftype
= M_DIROPS(mp
)->data_get_ftype(dep
);
1838 ino_ftype
= get_inode_ftype(irec
, ino_offset
);
1840 if (dir_ftype
!= ino_ftype
) {
1843 _("would fix ftype mismatch (%d/%d) in directory/child inode %" PRIu64
"/%" PRIu64
"\n"),
1844 dir_ftype
, ino_ftype
,
1848 _("fixing ftype mismatch (%d/%d) in directory/child inode %" PRIu64
"/%" PRIu64
"\n"),
1849 dir_ftype
, ino_ftype
,
1851 M_DIROPS(mp
)->data_put_ftype(dep
,
1853 libxfs_dir2_data_log_entry(&da
, bp
, dep
);
1854 dir_hash_update_ftype(hashtab
, addr
,
1861 * check easy case first, regular inode, just bump
1862 * the link count and continue
1864 if (!inode_isadir(irec
, ino_offset
)) {
1865 add_inode_reached(irec
, ino_offset
);
1868 parent
= get_inode_parent(irec
, ino_offset
);
1869 ASSERT(parent
!= 0);
1872 * bump up the link counts in parent and child
1873 * directory but if the link doesn't agree with
1874 * the .. in the child, blow out the entry.
1875 * if the directory has already been reached,
1876 * blow away the entry also.
1878 if (is_inode_reached(irec
, ino_offset
)) {
1881 _("entry \"%s\" in dir %" PRIu64
" points to an already connected directory inode %" PRIu64
"\n"),
1882 fname
, ip
->i_ino
, inum
);
1883 } else if (parent
== ip
->i_ino
) {
1884 add_inode_reached(irec
, ino_offset
);
1885 add_inode_ref(current_irec
, current_ino_offset
);
1886 } else if (parent
== NULLFSINO
) {
1887 /* ".." was missing, but this entry refers to it,
1888 so, set it as the parent and mark for rebuild */
1890 _("entry \"%s\" in dir ino %" PRIu64
" doesn't have a .. entry, will set it in ino %" PRIu64
".\n"),
1891 fname
, ip
->i_ino
, inum
);
1892 set_inode_parent(irec
, ino_offset
, ip
->i_ino
);
1893 add_inode_reached(irec
, ino_offset
);
1894 add_inode_ref(current_irec
, current_ino_offset
);
1895 add_dotdot_update(XFS_INO_TO_AGNO(mp
, inum
), irec
,
1900 _("entry \"%s\" in dir inode %" PRIu64
" inconsistent with .. value (%" PRIu64
") in ino %" PRIu64
"\n"),
1901 fname
, ip
->i_ino
, parent
, inum
);
1904 if (inum
== orphanage_ino
)
1909 libxfs_dir2_data_log_entry(&da
, bp
, dep
);
1912 _("\twill clear entry \"%s\"\n"),
1915 do_warn(_("\twould clear entry \"%s\"\n"),
1920 *num_illegal
+= nbad
;
1922 libxfs_dir2_data_freescan(mp
->m_dir_geo
, M_DIROPS(mp
), d
, &i
);
1924 libxfs_dir2_data_log_header(&da
, bp
);
1925 libxfs_bmap_finish(&tp
, &flist
, &committed
);
1926 libxfs_trans_commit(tp
);
1928 /* record the largest free space in the freetab for later checking */
1929 bf
= M_DIROPS(mp
)->data_bestfree_p(d
);
1930 freetab
->ents
[db
].v
= be16_to_cpu(bf
[0].length
);
1931 freetab
->ents
[db
].s
= 0;
1934 /* check v5 metadata */
1936 __check_dir3_header(
1937 struct xfs_mount
*mp
,
1946 if (be64_to_cpu(owner
) != ino
) {
1948 _("expected owner inode %" PRIu64
", got %llu, directory block %" PRIu64
"\n"),
1949 ino
, be64_to_cpu(owner
), bp
->b_bn
);
1952 /* verify block number */
1953 if (be64_to_cpu(blkno
) != bp
->b_bn
) {
1955 _("expected block %" PRIu64
", got %llu, directory inode %" PRIu64
"\n"),
1956 bp
->b_bn
, be64_to_cpu(blkno
), ino
);
1960 if (platform_uuid_compare(uuid
, &mp
->m_sb
.sb_uuid
) != 0) {
1962 _("wrong FS UUID, directory inode %" PRIu64
" block %" PRIu64
"\n"),
1972 struct xfs_mount
*mp
,
1976 struct xfs_da3_blkinfo
*info
= bp
->b_addr
;
1978 return __check_dir3_header(mp
, bp
, ino
, info
->owner
, info
->blkno
,
1984 struct xfs_mount
*mp
,
1988 struct xfs_dir3_blk_hdr
*info
= bp
->b_addr
;
1990 return __check_dir3_header(mp
, bp
, ino
, info
->owner
, info
->blkno
,
1995 * Check contents of leaf-form block.
1998 longform_dir2_check_leaf(
2001 dir_hash_tab_t
*hashtab
,
2009 xfs_dir2_leaf_t
*leaf
;
2010 xfs_dir2_leaf_tail_t
*ltp
;
2012 struct xfs_dir2_leaf_entry
*ents
;
2013 struct xfs_dir3_icleaf_hdr leafhdr
;
2017 da_bno
= mp
->m_dir_geo
->leafblk
;
2018 error
= dir_read_buf(ip
, da_bno
, -1, &bp
, &xfs_dir3_leaf1_buf_ops
,
2020 if (error
== EFSBADCRC
|| error
== EFSCORRUPTED
|| fixit
) {
2022 _("leaf block %u for directory inode %" PRIu64
" bad CRC\n"),
2027 _("can't read block %u for directory inode %" PRIu64
", error %d\n"),
2028 da_bno
, ip
->i_ino
, error
);
2033 M_DIROPS(mp
)->leaf_hdr_from_disk(&leafhdr
, leaf
);
2034 ents
= M_DIROPS(mp
)->leaf_ents_p(leaf
);
2035 ltp
= xfs_dir2_leaf_tail_p(mp
->m_dir_geo
, leaf
);
2036 bestsp
= xfs_dir2_leaf_bests_p(ltp
);
2037 if (!(leafhdr
.magic
== XFS_DIR2_LEAF1_MAGIC
||
2038 leafhdr
.magic
== XFS_DIR3_LEAF1_MAGIC
) ||
2039 leafhdr
.forw
|| leafhdr
.back
||
2040 leafhdr
.count
< leafhdr
.stale
||
2042 M_DIROPS(mp
)->leaf_max_ents(mp
->m_dir_geo
) ||
2043 (char *)&ents
[leafhdr
.count
] > (char *)bestsp
) {
2045 _("leaf block %u for directory inode %" PRIu64
" bad header\n"),
2051 if (leafhdr
.magic
== XFS_DIR3_LEAF1_MAGIC
) {
2052 error
= check_da3_header(mp
, bp
, ip
->i_ino
);
2059 seeval
= dir_hash_see_all(hashtab
, ents
, leafhdr
.count
, leafhdr
.stale
);
2060 if (dir_hash_check(hashtab
, ip
, seeval
)) {
2064 badtail
= freetab
->nents
!= be32_to_cpu(ltp
->bestcount
);
2065 for (i
= 0; !badtail
&& i
< be32_to_cpu(ltp
->bestcount
); i
++) {
2066 freetab
->ents
[i
].s
= 1;
2067 badtail
= freetab
->ents
[i
].v
!= be16_to_cpu(bestsp
[i
]);
2071 _("leaf block %u for directory inode %" PRIu64
" bad tail\n"),
2081 * Check contents of the node blocks (leaves)
2082 * Looks for matching hash values for the data entries.
2085 longform_dir2_check_node(
2088 dir_hash_tab_t
*hashtab
,
2094 xfs_dir2_free_t
*free
;
2096 xfs_dir2_leaf_t
*leaf
;
2097 xfs_fileoff_t next_da_bno
;
2100 struct xfs_dir2_leaf_entry
*ents
;
2101 struct xfs_dir3_icleaf_hdr leafhdr
;
2102 struct xfs_dir3_icfree_hdr freehdr
;
2107 for (da_bno
= mp
->m_dir_geo
->leafblk
, next_da_bno
= 0;
2108 next_da_bno
!= NULLFILEOFF
&& da_bno
< mp
->m_dir_geo
->freeblk
;
2109 da_bno
= (xfs_dablk_t
)next_da_bno
) {
2110 next_da_bno
= da_bno
+ mp
->m_dir_geo
->fsbcount
- 1;
2111 if (bmap_next_offset(NULL
, ip
, &next_da_bno
, XFS_DATA_FORK
))
2115 * we need to use the da3 node verifier here as it handles the
2116 * fact that reading the leaf hash tree blocks can return either
2117 * leaf or node blocks and calls the correct verifier. If we get
2118 * a node block, then we'll skip it below based on a magic
2121 error
= dir_read_buf(ip
, da_bno
, -1, &bp
,
2122 &xfs_da3_node_buf_ops
, &fixit
);
2125 _("can't read leaf block %u for directory inode %" PRIu64
", error %d\n"),
2126 da_bno
, ip
->i_ino
, error
);
2130 M_DIROPS(mp
)->leaf_hdr_from_disk(&leafhdr
, leaf
);
2131 ents
= M_DIROPS(mp
)->leaf_ents_p(leaf
);
2132 if (!(leafhdr
.magic
== XFS_DIR2_LEAFN_MAGIC
||
2133 leafhdr
.magic
== XFS_DIR3_LEAFN_MAGIC
||
2134 leafhdr
.magic
== XFS_DA_NODE_MAGIC
||
2135 leafhdr
.magic
== XFS_DA3_NODE_MAGIC
)) {
2137 _("unknown magic number %#x for block %u in directory inode %" PRIu64
"\n"),
2138 leafhdr
.magic
, da_bno
, ip
->i_ino
);
2143 /* check v5 metadata */
2144 if (leafhdr
.magic
== XFS_DIR3_LEAFN_MAGIC
||
2145 leafhdr
.magic
== XFS_DA3_NODE_MAGIC
) {
2146 error
= check_da3_header(mp
, bp
, ip
->i_ino
);
2154 if (leafhdr
.magic
== XFS_DA_NODE_MAGIC
||
2155 leafhdr
.magic
== XFS_DA3_NODE_MAGIC
) {
2161 * If there's a validator error, we need to ensure that we got
2162 * the right ops on the buffer for when we write it back out.
2164 bp
->b_ops
= &xfs_dir3_leafn_buf_ops
;
2165 if (leafhdr
.count
> M_DIROPS(mp
)->leaf_max_ents(mp
->m_dir_geo
) ||
2166 leafhdr
.count
< leafhdr
.stale
) {
2168 _("leaf block %u for directory inode %" PRIu64
" bad header\n"),
2173 seeval
= dir_hash_see_all(hashtab
, ents
,
2174 leafhdr
.count
, leafhdr
.stale
);
2176 if (seeval
!= DIR_HASH_CK_OK
)
2179 if (dir_hash_check(hashtab
, ip
, seeval
))
2182 for (da_bno
= mp
->m_dir_geo
->freeblk
, next_da_bno
= 0;
2183 next_da_bno
!= NULLFILEOFF
;
2184 da_bno
= (xfs_dablk_t
)next_da_bno
) {
2185 next_da_bno
= da_bno
+ mp
->m_dir_geo
->fsbcount
- 1;
2186 if (bmap_next_offset(NULL
, ip
, &next_da_bno
, XFS_DATA_FORK
))
2189 error
= dir_read_buf(ip
, da_bno
, -1, &bp
,
2190 &xfs_dir3_free_buf_ops
, &fixit
);
2193 _("can't read freespace block %u for directory inode %" PRIu64
", error %d\n"),
2194 da_bno
, ip
->i_ino
, error
);
2198 M_DIROPS(mp
)->free_hdr_from_disk(&freehdr
, free
);
2199 bests
= M_DIROPS(mp
)->free_bests_p(free
);
2200 fdb
= xfs_dir2_da_to_db(mp
->m_dir_geo
, da_bno
);
2201 if (!(freehdr
.magic
== XFS_DIR2_FREE_MAGIC
||
2202 freehdr
.magic
== XFS_DIR3_FREE_MAGIC
) ||
2204 (fdb
- xfs_dir2_byte_to_db(mp
->m_dir_geo
, XFS_DIR2_FREE_OFFSET
)) *
2205 M_DIROPS(mp
)->free_max_bests(mp
->m_dir_geo
) ||
2206 freehdr
.nvalid
< freehdr
.nused
) {
2208 _("free block %u for directory inode %" PRIu64
" bad header\n"),
2214 if (freehdr
.magic
== XFS_DIR3_FREE_MAGIC
) {
2215 error
= check_dir3_header(mp
, bp
, ip
->i_ino
);
2221 for (i
= used
= 0; i
< freehdr
.nvalid
; i
++) {
2222 if (i
+ freehdr
.firstdb
>= freetab
->nents
||
2223 freetab
->ents
[i
+ freehdr
.firstdb
].v
!=
2224 be16_to_cpu(bests
[i
])) {
2226 _("free block %u entry %i for directory ino %" PRIu64
" bad\n"),
2227 da_bno
, i
, ip
->i_ino
);
2231 used
+= be16_to_cpu(bests
[i
]) != NULLDATAOFF
;
2232 freetab
->ents
[i
+ freehdr
.firstdb
].s
= 1;
2234 if (used
!= freehdr
.nused
) {
2236 _("free block %u for directory inode %" PRIu64
" bad nused\n"),
2243 for (i
= 0; i
< freetab
->nents
; i
++) {
2244 if ((freetab
->ents
[i
].s
== 0) &&
2245 (freetab
->ents
[i
].v
!= NULLDATAOFF
)) {
2247 _("missing freetab entry %u for directory inode %" PRIu64
"\n"),
2256 * If a directory is corrupt, we need to read in as many entries as possible,
2257 * destroy the entry and create a new one with recovered name/inode pairs.
2258 * (ie. get libxfs to do all the grunt work)
2261 longform_dir2_entry_check(xfs_mount_t
*mp
,
2266 ino_tree_node_t
*irec
,
2268 dir_hash_tab_t
*hashtab
)
2270 struct xfs_buf
**bplist
;
2277 xfs_fileoff_t next_da_bno
;
2281 struct xfs_da_args args
;
2284 freetab
= malloc(FREETAB_SIZE(ip
->i_d
.di_size
/ mp
->m_dir_geo
->blksize
));
2286 do_error(_("malloc failed in %s (%" PRId64
" bytes)\n"),
2288 FREETAB_SIZE(ip
->i_d
.di_size
/ mp
->m_dir_geo
->blksize
));
2291 freetab
->naents
= ip
->i_d
.di_size
/ mp
->m_dir_geo
->blksize
;
2293 for (i
= 0; i
< freetab
->naents
; i
++) {
2294 freetab
->ents
[i
].v
= NULLDATAOFF
;
2295 freetab
->ents
[i
].s
= 0;
2297 num_bps
= freetab
->naents
;
2298 bplist
= calloc(num_bps
, sizeof(struct xfs_buf
*));
2300 do_error(_("calloc failed in %s (%zu bytes)\n"),
2301 __func__
, num_bps
* sizeof(struct xfs_buf
*));
2303 /* is this a block, leaf, or node directory? */
2305 args
.geo
= mp
->m_dir_geo
;
2306 libxfs_dir2_isblock(&args
, &isblock
);
2307 libxfs_dir2_isleaf(&args
, &isleaf
);
2309 /* check directory "data" blocks (ie. name/inode pairs) */
2310 for (da_bno
= 0, next_da_bno
= 0;
2311 next_da_bno
!= NULLFILEOFF
&& da_bno
< mp
->m_dir_geo
->leafblk
;
2312 da_bno
= (xfs_dablk_t
)next_da_bno
) {
2313 const struct xfs_buf_ops
*ops
;
2315 struct xfs_dir2_data_hdr
*d
;
2317 next_da_bno
= da_bno
+ mp
->m_dir_geo
->fsbcount
- 1;
2318 if (bmap_next_offset(NULL
, ip
, &next_da_bno
, XFS_DATA_FORK
)) {
2320 * if this is the first block, there isn't anything we
2321 * can recover so we just trash it.
2330 db
= xfs_dir2_da_to_db(mp
->m_dir_geo
, da_bno
);
2331 if (db
>= num_bps
) {
2332 /* more data blocks than expected */
2334 bplist
= realloc(bplist
, num_bps
* sizeof(struct xfs_buf
*));
2336 do_error(_("realloc failed in %s (%zu bytes)\n"),
2338 num_bps
* sizeof(struct xfs_buf
*));
2342 ops
= &xfs_dir3_block_buf_ops
;
2344 ops
= &xfs_dir3_data_buf_ops
;
2346 error
= dir_read_buf(ip
, da_bno
, -1, &bplist
[db
], ops
, &fixit
);
2349 _("can't read data block %u for directory inode %" PRIu64
" error %d\n"),
2350 da_bno
, ino
, error
);
2354 * we try to read all "data" blocks, but if we are in
2355 * block form and we fail, there isn't anything else to
2356 * read, and nothing we can do but trash it.
2365 /* check v5 metadata */
2366 d
= bplist
[db
]->b_addr
;
2367 if (be32_to_cpu(d
->magic
) == XFS_DIR3_BLOCK_MAGIC
||
2368 be32_to_cpu(d
->magic
) == XFS_DIR3_DATA_MAGIC
) {
2369 struct xfs_buf
*bp
= bplist
[db
];
2371 error
= check_dir3_header(mp
, bp
, ino
);
2378 longform_dir2_entry_check_data(mp
, ip
, num_illegal
, need_dot
,
2379 irec
, ino_offset
, &bplist
[db
], hashtab
,
2380 &freetab
, da_bno
, isblock
);
2382 fixit
|= (*num_illegal
!= 0) || dir2_is_badino(ino
) || *need_dot
;
2384 if (!dotdot_update
) {
2385 /* check btree and freespace */
2387 struct xfs_dir2_data_hdr
*block
;
2388 xfs_dir2_block_tail_t
*btp
;
2389 xfs_dir2_leaf_entry_t
*blp
;
2391 block
= bplist
[0]->b_addr
;
2392 btp
= xfs_dir2_block_tail_p(mp
->m_dir_geo
, block
);
2393 blp
= xfs_dir2_block_leaf_p(btp
);
2394 seeval
= dir_hash_see_all(hashtab
, blp
,
2395 be32_to_cpu(btp
->count
),
2396 be32_to_cpu(btp
->stale
));
2397 if (dir_hash_check(hashtab
, ip
, seeval
))
2399 } else if (isleaf
) {
2400 fixit
|= longform_dir2_check_leaf(mp
, ip
, hashtab
,
2403 fixit
|= longform_dir2_check_node(mp
, ip
, hashtab
,
2408 if (!no_modify
&& (fixit
|| dotdot_update
)) {
2409 dir_hash_dup_names(hashtab
);
2410 for (i
= 0; i
< num_bps
; i
++)
2412 libxfs_putbuf(bplist
[i
]);
2413 longform_dir2_rebuild(mp
, ino
, ip
, irec
, ino_offset
, hashtab
);
2417 for (i
= 0; i
< num_bps
; i
++)
2419 libxfs_putbuf(bplist
[i
]);
2427 * shortform directory v2 processing routines -- entry verification and
2428 * bad entry deletion (pruning).
2430 static struct xfs_dir2_sf_entry
*
2431 shortform_dir2_junk(
2432 struct xfs_mount
*mp
,
2433 struct xfs_dir2_sf_hdr
*sfp
,
2434 struct xfs_dir2_sf_entry
*sfep
,
2441 struct xfs_dir2_sf_entry
*next_sfep
;
2445 if (lino
== orphanage_ino
)
2448 next_elen
= M_DIROPS(mp
)->sf_entsize(sfp
, sfep
->namelen
);
2449 next_sfep
= M_DIROPS(mp
)->sf_nextentry(sfp
, sfep
);
2452 * if we are just checking, simply return the pointer to the next entry
2453 * here so that the checking loop can continue.
2456 do_warn(_("would junk entry\n"));
2461 * now move all the remaining entries down over the junked entry and
2462 * clear the newly unused bytes at the tail of the directory region.
2464 next_len
= *max_size
- ((intptr_t)next_sfep
- (intptr_t)sfp
);
2465 *max_size
-= next_elen
;
2466 *bytes_deleted
+= next_elen
;
2468 memmove(sfep
, next_sfep
, next_len
);
2469 memset((void *)((intptr_t)sfep
+ next_len
), 0, next_elen
);
2474 * WARNING: drop the index i by one so it matches the decremented count
2475 * for accurate comparisons in the loop test
2480 do_warn(_("junking entry\n"));
2487 shortform_dir2_entry_check(xfs_mount_t
*mp
,
2491 ino_tree_node_t
*current_irec
,
2492 int current_ino_offset
,
2493 dir_hash_tab_t
*hashtab
)
2497 struct xfs_dir2_sf_hdr
*sfp
;
2498 struct xfs_dir2_sf_entry
*sfep
;
2499 struct xfs_dir2_sf_entry
*next_sfep
;
2500 struct xfs_ifork
*ifp
;
2501 struct ino_tree_node
*irec
;
2508 char fname
[MAXNAMELEN
+ 1];
2512 sfp
= (struct xfs_dir2_sf_hdr
*) ifp
->if_u1
.if_data
;
2516 max_size
= ifp
->if_bytes
;
2517 ASSERT(ip
->i_d
.di_size
<= ifp
->if_bytes
);
2520 * if just rebuild a directory due to a "..", update and return
2522 if (dotdot_update
) {
2523 parent
= get_inode_parent(current_irec
, current_ino_offset
);
2526 _("would set .. in sf dir inode %" PRIu64
" to %" PRIu64
"\n"),
2530 _("setting .. in sf dir inode %" PRIu64
" to %" PRIu64
"\n"),
2532 M_DIROPS(mp
)->sf_put_parent_ino(sfp
, parent
);
2539 * no '.' entry in shortform dirs, just bump up ref count by 1
2540 * '..' was already (or will be) accounted for and checked when
2541 * the directory is reached or will be taken care of when the
2542 * directory is moved to orphanage.
2544 add_inode_ref(current_irec
, current_ino_offset
);
2547 * Initialise i8 counter -- the parent inode number counts as well.
2549 i8
= M_DIROPS(mp
)->sf_get_parent_ino(sfp
) > XFS_DIR2_MAX_SHORT_INUM
;
2552 * now run through entries, stop at first bad entry, don't need
2553 * to skip over '..' since that's encoded in its own field and
2554 * no need to worry about '.' since it doesn't exist.
2556 sfep
= next_sfep
= xfs_dir2_sf_firstentry(sfp
);
2558 for (i
= 0; i
< sfp
->count
&& max_size
>
2559 (intptr_t)next_sfep
- (intptr_t)sfp
;
2560 sfep
= next_sfep
, i
++) {
2563 lino
= M_DIROPS(mp
)->sf_get_ino(sfp
, sfep
);
2565 namelen
= sfep
->namelen
;
2567 ASSERT(no_modify
|| namelen
> 0);
2569 if (no_modify
&& namelen
== 0) {
2571 * if we're really lucky, this is
2572 * the last entry in which case we
2573 * can use the dir size to set the
2574 * namelen value. otherwise, forget
2575 * it because we're not going to be
2576 * able to find the next entry.
2580 if (i
== sfp
->count
- 1) {
2581 namelen
= ip
->i_d
.di_size
-
2582 ((intptr_t) &sfep
->name
[0] -
2586 * don't process the rest of the directory,
2587 * break out of processing loop
2591 } else if (no_modify
&& (intptr_t) sfep
- (intptr_t) sfp
+
2592 + M_DIROPS(mp
)->sf_entsize(sfp
, sfep
->namelen
)
2593 > ip
->i_d
.di_size
) {
2596 if (i
== sfp
->count
- 1) {
2597 namelen
= ip
->i_d
.di_size
-
2598 ((intptr_t) &sfep
->name
[0] -
2602 * don't process the rest of the directory,
2603 * break out of processing loop
2609 memmove(fname
, sfep
->name
, sfep
->namelen
);
2610 fname
[sfep
->namelen
] = '\0';
2612 ASSERT(no_modify
|| (lino
!= NULLFSINO
&& lino
!= 0));
2613 ASSERT(no_modify
|| !verify_inum(mp
, lino
));
2616 * Also skip entries with bogus inode numbers if we're
2617 * in no modify mode.
2620 if (no_modify
&& verify_inum(mp
, lino
)) {
2621 next_sfep
= M_DIROPS(mp
)->sf_nextentry(sfp
, sfep
);
2625 irec
= find_inode_rec(mp
, XFS_INO_TO_AGNO(mp
, lino
),
2626 XFS_INO_TO_AGINO(mp
, lino
));
2630 _("entry \"%s\" in shortform directory %" PRIu64
" references non-existent inode %" PRIu64
"\n"),
2632 next_sfep
= shortform_dir2_junk(mp
, sfp
, sfep
, lino
,
2633 &max_size
, &i
, &bytes_deleted
,
2638 ino_offset
= XFS_INO_TO_AGINO(mp
, lino
) - irec
->ino_startnum
;
2641 * if it's a free inode, blow out the entry.
2642 * by now, any inode that we think is free
2645 if (is_inode_free(irec
, ino_offset
)) {
2647 _("entry \"%s\" in shortform directory inode %" PRIu64
" points to free inode %" PRIu64
"\n"),
2649 next_sfep
= shortform_dir2_junk(mp
, sfp
, sfep
, lino
,
2650 &max_size
, &i
, &bytes_deleted
,
2655 * check if this inode is lost+found dir in the root
2657 if (ino
== mp
->m_sb
.sb_rootino
&& strcmp(fname
, ORPHANAGE
) == 0) {
2659 * if it's not a directory, trash it
2661 if (!inode_isadir(irec
, ino_offset
)) {
2663 _("%s (ino %" PRIu64
") in root (%" PRIu64
") is not a directory"),
2664 ORPHANAGE
, lino
, ino
);
2665 next_sfep
= shortform_dir2_junk(mp
, sfp
, sfep
,
2666 lino
, &max_size
, &i
,
2667 &bytes_deleted
, ino_dirty
);
2671 * if this is a dup, it will be picked up below,
2672 * otherwise, mark it as the orphanage for later.
2675 orphanage_ino
= lino
;
2678 * check for duplicate names in directory.
2680 if (!dir_hash_add(mp
, hashtab
, (xfs_dir2_dataptr_t
)
2681 (sfep
- xfs_dir2_sf_firstentry(sfp
)),
2682 lino
, sfep
->namelen
, sfep
->name
,
2683 M_DIROPS(mp
)->sf_get_ftype(sfep
))) {
2685 _("entry \"%s\" (ino %" PRIu64
") in dir %" PRIu64
" is a duplicate name"),
2687 next_sfep
= shortform_dir2_junk(mp
, sfp
, sfep
, lino
,
2688 &max_size
, &i
, &bytes_deleted
,
2693 if (!inode_isadir(irec
, ino_offset
)) {
2695 * check easy case first, regular inode, just bump
2698 add_inode_reached(irec
, ino_offset
);
2700 parent
= get_inode_parent(irec
, ino_offset
);
2703 * bump up the link counts in parent and child.
2704 * directory but if the link doesn't agree with
2705 * the .. in the child, blow out the entry
2707 if (is_inode_reached(irec
, ino_offset
)) {
2709 _("entry \"%s\" in directory inode %" PRIu64
2710 " references already connected inode %" PRIu64
".\n"),
2712 next_sfep
= shortform_dir2_junk(mp
, sfp
, sfep
,
2713 lino
, &max_size
, &i
,
2714 &bytes_deleted
, ino_dirty
);
2716 } else if (parent
== ino
) {
2717 add_inode_reached(irec
, ino_offset
);
2718 add_inode_ref(current_irec
, current_ino_offset
);
2719 } else if (parent
== NULLFSINO
) {
2720 /* ".." was missing, but this entry refers to it,
2721 so, set it as the parent and mark for rebuild */
2723 _("entry \"%s\" in dir ino %" PRIu64
" doesn't have a .. entry, will set it in ino %" PRIu64
".\n"),
2725 set_inode_parent(irec
, ino_offset
, ino
);
2726 add_inode_reached(irec
, ino_offset
);
2727 add_inode_ref(current_irec
, current_ino_offset
);
2728 add_dotdot_update(XFS_INO_TO_AGNO(mp
, lino
),
2732 _("entry \"%s\" in directory inode %" PRIu64
2733 " not consistent with .. value (%" PRIu64
2734 ") in inode %" PRIu64
",\n"),
2735 fname
, ino
, parent
, lino
);
2736 next_sfep
= shortform_dir2_junk(mp
, sfp
, sfep
,
2737 lino
, &max_size
, &i
,
2738 &bytes_deleted
, ino_dirty
);
2743 /* validate ftype field if supported */
2744 if (xfs_sb_version_hasftype(&mp
->m_sb
)) {
2745 __uint8_t dir_ftype
;
2746 __uint8_t ino_ftype
;
2748 dir_ftype
= M_DIROPS(mp
)->sf_get_ftype(sfep
);
2749 ino_ftype
= get_inode_ftype(irec
, ino_offset
);
2751 if (dir_ftype
!= ino_ftype
) {
2754 _("would fix ftype mismatch (%d/%d) in directory/child inode %" PRIu64
"/%" PRIu64
"\n"),
2755 dir_ftype
, ino_ftype
,
2759 _("fixing ftype mismatch (%d/%d) in directory/child inode %" PRIu64
"/%" PRIu64
"\n"),
2760 dir_ftype
, ino_ftype
,
2762 M_DIROPS(mp
)->sf_put_ftype(sfep
,
2764 dir_hash_update_ftype(hashtab
,
2765 (xfs_dir2_dataptr_t
)(sfep
- xfs_dir2_sf_firstentry(sfp
)),
2772 if (lino
> XFS_DIR2_MAX_SHORT_INUM
)
2776 * go onto next entry - we have to take entries with bad namelen
2777 * into account in no modify mode since we calculate size based
2780 ASSERT(no_modify
|| bad_sfnamelen
== 0);
2781 next_sfep
= (struct xfs_dir2_sf_entry
*)((intptr_t)sfep
+
2783 ? M_DIROPS(mp
)->sf_entsize(sfp
, namelen
)
2784 : M_DIROPS(mp
)->sf_entsize(sfp
, sfep
->namelen
)));
2787 if (sfp
->i8count
!= i8
) {
2789 do_warn(_("would fix i8count in inode %" PRIu64
"\n"),
2793 struct xfs_dir2_sf_entry
*tmp_sfep
;
2795 tmp_sfep
= next_sfep
;
2796 process_sf_dir2_fixi8(mp
, sfp
, &tmp_sfep
);
2798 (intptr_t)next_sfep
-
2800 next_sfep
= tmp_sfep
;
2804 do_warn(_("fixing i8count in inode %" PRIu64
"\n"),
2810 * sync up sizes if required
2812 if (*ino_dirty
&& bytes_deleted
> 0) {
2814 libxfs_idata_realloc(ip
, -bytes_deleted
, XFS_DATA_FORK
);
2815 ip
->i_d
.di_size
-= bytes_deleted
;
2818 if (ip
->i_d
.di_size
!= ip
->i_df
.if_bytes
) {
2819 ASSERT(ip
->i_df
.if_bytes
== (xfs_fsize_t
)
2820 ((intptr_t) next_sfep
- (intptr_t) sfp
));
2821 ip
->i_d
.di_size
= (xfs_fsize_t
)
2822 ((intptr_t) next_sfep
- (intptr_t) sfp
);
2824 _("setting size to %" PRId64
" bytes to reflect junked entries\n"),
2831 * processes all reachable inodes in directories
2836 xfs_agnumber_t agno
,
2837 ino_tree_node_t
*irec
,
2841 xfs_bmap_free_t flist
;
2842 xfs_fsblock_t first
;
2845 dir_hash_tab_t
*hashtab
;
2846 int need_dot
, committed
;
2847 int dirty
, num_illegal
, error
, nres
;
2849 ino
= XFS_AGINO_TO_INO(mp
, agno
, irec
->ino_startnum
+ ino_offset
);
2852 * open up directory inode, check all entries,
2853 * then call prune_dir_entries to remove all
2854 * remaining illegal directory entries.
2857 ASSERT(!is_inode_refchecked(irec
, ino_offset
) || dotdot_update
);
2859 error
= -libxfs_iget(mp
, NULL
, ino
, 0, &ip
, 0);
2863 _("couldn't map inode %" PRIu64
", err = %d\n"),
2867 _("couldn't map inode %" PRIu64
", err = %d\n"),
2870 * see below for what we're doing if this
2871 * is root. Why do we need to do this here?
2872 * to ensure that the root doesn't show up
2873 * as being disconnected in the no_modify case.
2875 if (mp
->m_sb
.sb_rootino
== ino
) {
2876 add_inode_reached(irec
, 0);
2877 add_inode_ref(irec
, 0);
2881 add_inode_refchecked(irec
, 0);
2885 need_dot
= dirty
= num_illegal
= 0;
2887 if (mp
->m_sb
.sb_rootino
== ino
) {
2889 * mark root inode reached and bump up
2890 * link count for root inode to account
2891 * for '..' entry since the root inode is
2892 * never reached by a parent. we know
2893 * that root's '..' is always good --
2894 * guaranteed by phase 3 and/or below.
2896 add_inode_reached(irec
, ino_offset
);
2899 add_inode_refchecked(irec
, ino_offset
);
2901 hashtab
= dir_hash_init(ip
->i_d
.di_size
);
2904 * look for bogus entries
2906 switch (ip
->i_d
.di_format
) {
2907 case XFS_DINODE_FMT_EXTENTS
:
2908 case XFS_DINODE_FMT_BTREE
:
2910 * also check for missing '.' in longform dirs.
2911 * missing .. entries are added if required when
2912 * the directory is connected to lost+found. but
2913 * we need to create '.' entries here.
2915 longform_dir2_entry_check(mp
, ino
, ip
,
2916 &num_illegal
, &need_dot
,
2921 case XFS_DINODE_FMT_LOCAL
:
2922 tp
= libxfs_trans_alloc(mp
, 0);
2924 * using the remove reservation is overkill
2925 * since at most we'll only need to log the
2926 * inode but it's easier than wedging a
2927 * new define in ourselves.
2929 nres
= no_modify
? 0 : XFS_REMOVE_SPACE_RES(mp
);
2930 error
= -libxfs_trans_reserve(tp
, &M_RES(mp
)->tr_remove
,
2935 libxfs_trans_ijoin(tp
, ip
, 0);
2937 shortform_dir2_entry_check(mp
, ino
, ip
, &dirty
,
2941 ASSERT(dirty
== 0 || (dirty
&& !no_modify
));
2943 libxfs_trans_log_inode(tp
, ip
,
2944 XFS_ILOG_CORE
| XFS_ILOG_DDATA
);
2945 libxfs_trans_commit(tp
);
2947 libxfs_trans_cancel(tp
);
2954 dir_hash_done(hashtab
);
2957 * if we have to create a .. for /, do it now *before*
2958 * we delete the bogus entries, otherwise the directory
2959 * could transform into a shortform dir which would
2960 * probably cause the simulation to choke. Even
2961 * if the illegal entries get shifted around, it's ok
2962 * because the entries are structurally intact and in
2963 * in hash-value order so the simulation won't get confused
2964 * if it has to move them around.
2966 if (!no_modify
&& need_root_dotdot
&& ino
== mp
->m_sb
.sb_rootino
) {
2967 ASSERT(ip
->i_d
.di_format
!= XFS_DINODE_FMT_LOCAL
);
2969 do_warn(_("recreating root directory .. entry\n"));
2971 tp
= libxfs_trans_alloc(mp
, 0);
2974 nres
= XFS_MKDIR_SPACE_RES(mp
, 2);
2975 error
= -libxfs_trans_reserve(tp
, &M_RES(mp
)->tr_mkdir
, nres
, 0);
2979 libxfs_trans_ijoin(tp
, ip
, 0);
2981 xfs_bmap_init(&flist
, &first
);
2983 error
= -libxfs_dir_createname(tp
, ip
, &xfs_name_dotdot
,
2984 ip
->i_ino
, &first
, &flist
, nres
);
2987 _("can't make \"..\" entry in root inode %" PRIu64
", createname error %d\n"), ino
, error
);
2989 libxfs_trans_log_inode(tp
, ip
, XFS_ILOG_CORE
);
2991 error
= -libxfs_bmap_finish(&tp
, &flist
, &committed
);
2993 libxfs_trans_commit(tp
);
2995 need_root_dotdot
= 0;
2996 } else if (need_root_dotdot
&& ino
== mp
->m_sb
.sb_rootino
) {
2997 do_warn(_("would recreate root directory .. entry\n"));
3001 * if we need to create the '.' entry, do so only if
3002 * the directory is a longform dir. if it's been
3003 * turned into a shortform dir, then the inode is ok
3004 * since shortform dirs have no '.' entry and the inode
3005 * has already been committed by prune_lf_dir_entry().
3009 * bump up our link count but don't
3010 * bump up the inode link count. chances
3011 * are good that even though we lost '.'
3012 * the inode link counts reflect '.' so
3013 * leave the inode link count alone and if
3014 * it turns out to be wrong, we'll catch
3017 add_inode_ref(irec
, ino_offset
);
3021 _("would create missing \".\" entry in dir ino %" PRIu64
"\n"),
3023 } else if (ip
->i_d
.di_format
!= XFS_DINODE_FMT_LOCAL
) {
3025 * need to create . entry in longform dir.
3028 _("creating missing \".\" entry in dir ino %" PRIu64
"\n"), ino
);
3030 tp
= libxfs_trans_alloc(mp
, 0);
3033 nres
= XFS_MKDIR_SPACE_RES(mp
, 1);
3034 error
= -libxfs_trans_reserve(tp
, &M_RES(mp
)->tr_mkdir
,
3039 libxfs_trans_ijoin(tp
, ip
, 0);
3041 xfs_bmap_init(&flist
, &first
);
3043 error
= -libxfs_dir_createname(tp
, ip
, &xfs_name_dot
,
3044 ip
->i_ino
, &first
, &flist
, nres
);
3047 _("can't make \".\" entry in dir ino %" PRIu64
", createname error %d\n"),
3050 libxfs_trans_log_inode(tp
, ip
, XFS_ILOG_CORE
);
3052 error
= -libxfs_bmap_finish(&tp
, &flist
, &committed
);
3054 libxfs_trans_commit(tp
);
3061 * mark realtime bitmap and summary inodes as reached.
3062 * quota inode will be marked here as well
3065 mark_standalone_inodes(xfs_mount_t
*mp
)
3067 ino_tree_node_t
*irec
;
3070 irec
= find_inode_rec(mp
, XFS_INO_TO_AGNO(mp
, mp
->m_sb
.sb_rbmino
),
3071 XFS_INO_TO_AGINO(mp
, mp
->m_sb
.sb_rbmino
));
3073 ASSERT(irec
!= NULL
);
3075 offset
= XFS_INO_TO_AGINO(mp
, mp
->m_sb
.sb_rbmino
) -
3078 add_inode_reached(irec
, offset
);
3080 irec
= find_inode_rec(mp
, XFS_INO_TO_AGNO(mp
, mp
->m_sb
.sb_rsumino
),
3081 XFS_INO_TO_AGINO(mp
, mp
->m_sb
.sb_rsumino
));
3083 offset
= XFS_INO_TO_AGINO(mp
, mp
->m_sb
.sb_rsumino
) -
3086 ASSERT(irec
!= NULL
);
3088 add_inode_reached(irec
, offset
);
3091 if (mp
->m_sb
.sb_uquotino
3092 && mp
->m_sb
.sb_uquotino
!= NULLFSINO
) {
3093 irec
= find_inode_rec(mp
, XFS_INO_TO_AGNO(mp
,
3094 mp
->m_sb
.sb_uquotino
),
3095 XFS_INO_TO_AGINO(mp
, mp
->m_sb
.sb_uquotino
));
3096 offset
= XFS_INO_TO_AGINO(mp
, mp
->m_sb
.sb_uquotino
)
3097 - irec
->ino_startnum
;
3098 add_inode_reached(irec
, offset
);
3100 if (mp
->m_sb
.sb_gquotino
3101 && mp
->m_sb
.sb_gquotino
!= NULLFSINO
) {
3102 irec
= find_inode_rec(mp
, XFS_INO_TO_AGNO(mp
,
3103 mp
->m_sb
.sb_gquotino
),
3104 XFS_INO_TO_AGINO(mp
, mp
->m_sb
.sb_gquotino
));
3105 offset
= XFS_INO_TO_AGINO(mp
, mp
->m_sb
.sb_gquotino
)
3106 - irec
->ino_startnum
;
3107 add_inode_reached(irec
, offset
);
3109 if (mp
->m_sb
.sb_pquotino
3110 && mp
->m_sb
.sb_pquotino
!= NULLFSINO
) {
3111 irec
= find_inode_rec(mp
, XFS_INO_TO_AGNO(mp
,
3112 mp
->m_sb
.sb_pquotino
),
3113 XFS_INO_TO_AGINO(mp
, mp
->m_sb
.sb_pquotino
));
3114 offset
= XFS_INO_TO_AGINO(mp
, mp
->m_sb
.sb_pquotino
)
3115 - irec
->ino_startnum
;
3116 add_inode_reached(irec
, offset
);
3122 check_for_orphaned_inodes(
3124 xfs_agnumber_t agno
,
3125 ino_tree_node_t
*irec
)
3130 for (i
= 0; i
< XFS_INODES_PER_CHUNK
; i
++) {
3131 ASSERT(is_inode_confirmed(irec
, i
));
3132 if (is_inode_free(irec
, i
))
3135 if (is_inode_reached(irec
, i
))
3138 ASSERT(inode_isadir(irec
, i
) ||
3139 num_inode_references(irec
, i
) == 0);
3141 ino
= XFS_AGINO_TO_INO(mp
, agno
, i
+ irec
->ino_startnum
);
3142 if (inode_isadir(irec
, i
))
3143 do_warn(_("disconnected dir inode %" PRIu64
", "), ino
);
3145 do_warn(_("disconnected inode %" PRIu64
", "), ino
);
3148 orphanage_ino
= mk_orphanage(mp
);
3149 do_warn(_("moving to %s\n"), ORPHANAGE
);
3150 mv_orphanage(mp
, ino
, inode_isadir(irec
, i
));
3152 do_warn(_("would move to %s\n"), ORPHANAGE
);
3155 * for read-only case, even though the inode isn't
3156 * really reachable, set the flag (and bump our link
3157 * count) anyway to fool phase 7
3159 add_inode_reached(irec
, i
);
3166 xfs_agnumber_t agno
,
3169 ino_tree_node_t
*irec
;
3171 prefetch_args_t
*pf_args
= arg
;
3173 wait_for_inode_prefetch(pf_args
);
3176 do_log(_(" - agno = %d\n"), agno
);
3178 for (irec
= findfirst_inode_rec(agno
); irec
; irec
= next_ino_rec(irec
)) {
3179 if (irec
->ino_isa_dir
== 0)
3183 sem_post(&pf_args
->ra_count
);
3185 sem_getvalue(&pf_args
->ra_count
, &i
);
3187 "processing inode chunk %p in AG %d (sem count = %d)",
3192 for (i
= 0; i
< XFS_INODES_PER_CHUNK
; i
++) {
3193 if (inode_isadir(irec
, i
))
3194 process_dir_inode(wq
->mp
, agno
, irec
, i
);
3197 cleanup_inode_prefetch(pf_args
);
3201 update_missing_dotdot_entries(
3204 dotdot_update_t
*dir
;
3207 * these entries parents were updated, rebuild them again
3208 * set dotdot_update flag so processing routines do not count links
3211 while (!list_empty(&dotdot_update_list
)) {
3212 dir
= list_entry(dotdot_update_list
.prev
, struct dotdot_update
,
3214 list_del(&dir
->list
);
3215 process_dir_inode(mp
, dir
->agno
, dir
->irec
, dir
->ino_offset
);
3222 struct xfs_mount
*mp
)
3224 do_inode_prefetch(mp
, 0, traverse_function
, false, true);
3228 phase6(xfs_mount_t
*mp
)
3230 ino_tree_node_t
*irec
;
3233 memset(&zerocr
, 0, sizeof(struct cred
));
3234 memset(&zerofsx
, 0, sizeof(struct fsxattr
));
3237 do_log(_("Phase 6 - check inode connectivity...\n"));
3239 incore_ext_teardown(mp
);
3241 add_ino_ex_data(mp
);
3244 * verify existence of root directory - if we have to
3245 * make one, it's ok for the incore data structs not to
3246 * know about it since everything about it (and the other
3247 * inodes in its chunk if a new chunk was created) are ok
3249 if (need_root_inode
) {
3251 do_warn(_("reinitializing root directory\n"));
3253 need_root_inode
= 0;
3254 need_root_dotdot
= 0;
3256 do_warn(_("would reinitialize root directory\n"));
3262 do_warn(_("reinitializing realtime bitmap inode\n"));
3266 do_warn(_("would reinitialize realtime bitmap inode\n"));
3272 do_warn(_("reinitializing realtime summary inode\n"));
3276 do_warn(_("would reinitialize realtime summary inode\n"));
3282 _(" - resetting contents of realtime bitmap and summary inodes\n"));
3283 if (fill_rbmino(mp
)) {
3285 _("Warning: realtime bitmap may be inconsistent\n"));
3288 if (fill_rsumino(mp
)) {
3290 _("Warning: realtime bitmap may be inconsistent\n"));
3294 mark_standalone_inodes(mp
);
3296 do_log(_(" - traversing filesystem ...\n"));
3298 irec
= find_inode_rec(mp
, XFS_INO_TO_AGNO(mp
, mp
->m_sb
.sb_rootino
),
3299 XFS_INO_TO_AGINO(mp
, mp
->m_sb
.sb_rootino
));
3302 * we always have a root inode, even if it's free...
3303 * if the root is free, forget it, lost+found is already gone
3305 if (is_inode_free(irec
, 0) || !inode_isadir(irec
, 0)) {
3306 need_root_inode
= 1;
3310 * then process all inodes by walking incore inode tree
3315 * any directories that had updated ".." entries, rebuild them now
3317 update_missing_dotdot_entries(mp
);
3319 do_log(_(" - traversal finished ...\n"));
3320 do_log(_(" - moving disconnected inodes to %s ...\n"),
3324 * move all disconnected inodes to the orphanage
3326 for (i
= 0; i
< glob_agcount
; i
++) {
3327 irec
= findfirst_inode_rec(i
);
3328 while (irec
!= NULL
) {
3329 check_for_orphaned_inodes(mp
, i
, irec
);
3330 irec
= next_ino_rec(irec
);