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
26 #include "dir_stack.h"
28 #include "err_protos.h"
33 static struct cred zerocr
;
34 static struct fsxattr zerofsx
;
35 static int orphanage_entered
;
38 * Data structures and routines to keep track of directory entries
39 * and whether their leaf entry has been seen
41 typedef struct dir_hash_ent
{
42 struct dir_hash_ent
*next
; /* pointer to next entry */
43 xfs_dir2_leaf_entry_t ent
; /* address and hash value */
44 short junkit
; /* name starts with / */
45 short seen
; /* have seen leaf entry */
48 typedef struct dir_hash_tab
{
49 int size
; /* size of hash table */
50 dir_hash_ent_t
*tab
[1];/* actual hash table, variable size */
52 #define DIR_HASH_TAB_SIZE(n) \
53 (offsetof(dir_hash_tab_t, tab) + (sizeof(dir_hash_ent_t *) * (n)))
54 #define DIR_HASH_FUNC(t,a) ((a) % (t)->size)
57 * Track the contents of the freespace table in a directory.
59 typedef struct freetab
{
60 int naents
; /* expected number of data blocks */
61 int nents
; /* number of data blocks processed */
63 xfs_dir2_data_off_t v
;
67 #define FREETAB_SIZE(n) \
68 (offsetof(freetab_t, ents) + (sizeof(struct freetab_ent) * (n)))
70 #define DIR_HASH_CK_OK 0
71 #define DIR_HASH_CK_DUPLEAF 1
72 #define DIR_HASH_CK_BADHASH 2
73 #define DIR_HASH_CK_NODATA 3
74 #define DIR_HASH_CK_NOLEAF 4
75 #define DIR_HASH_CK_BADSTALE 5
76 #define DIR_HASH_CK_TOTAL 6
80 dir_hash_tab_t
*hashtab
,
82 xfs_dir2_dataptr_t addr
,
88 i
= DIR_HASH_FUNC(hashtab
, addr
);
89 if ((p
= malloc(sizeof(*p
))) == NULL
)
90 do_error(_("malloc failed in dir_hash_add (%u bytes)\n"),
92 p
->next
= hashtab
->tab
[i
];
94 if (!(p
->junkit
= junk
))
95 p
->ent
.hashval
= hash
;
96 p
->ent
.address
= addr
;
102 dir_hash_tab_t
*hashtab
)
107 for (i
= 0; i
< hashtab
->size
; i
++) {
108 for (p
= hashtab
->tab
[i
]; p
; p
= p
->next
) {
118 dir_hash_tab_t
*hashtab
,
122 static char *seevalstr
[DIR_HASH_CK_TOTAL
];
126 seevalstr
[DIR_HASH_CK_OK
] = _("ok");
127 seevalstr
[DIR_HASH_CK_DUPLEAF
] = _("duplicate leaf");
128 seevalstr
[DIR_HASH_CK_BADHASH
] = _("hash value mismatch");
129 seevalstr
[DIR_HASH_CK_NODATA
] = _("no data entry");
130 seevalstr
[DIR_HASH_CK_NOLEAF
] = _("no leaf entry");
131 seevalstr
[DIR_HASH_CK_BADSTALE
] = _("bad stale count");
135 if (seeval
== DIR_HASH_CK_OK
&& dir_hash_unseen(hashtab
))
136 seeval
= DIR_HASH_CK_NOLEAF
;
137 if (seeval
== DIR_HASH_CK_OK
)
139 do_warn(_("bad hash table for directory inode %llu (%s): "),
140 ip
->i_ino
, seevalstr
[seeval
]);
142 do_warn(_("rebuilding\n"));
144 do_warn(_("would rebuild\n"));
150 dir_hash_tab_t
*hashtab
)
156 for (i
= 0; i
< hashtab
->size
; i
++) {
157 for (p
= hashtab
->tab
[i
]; p
; p
= n
) {
165 static dir_hash_tab_t
*
169 dir_hash_tab_t
*hashtab
;
172 hsize
= size
/ (16 * 4);
177 if ((hashtab
= calloc(DIR_HASH_TAB_SIZE(hsize
), 1)) == NULL
)
178 do_error(_("calloc failed in dir_hash_init\n"));
179 hashtab
->size
= hsize
;
185 dir_hash_tab_t
*hashtab
,
187 xfs_dir2_dataptr_t addr
)
192 i
= DIR_HASH_FUNC(hashtab
, addr
);
193 for (p
= hashtab
->tab
[i
]; p
; p
= p
->next
) {
194 if (p
->ent
.address
!= addr
)
197 return DIR_HASH_CK_DUPLEAF
;
198 if (p
->junkit
== 0 && p
->ent
.hashval
!= hash
)
199 return DIR_HASH_CK_BADHASH
;
201 return DIR_HASH_CK_OK
;
203 return DIR_HASH_CK_NODATA
;
208 dir_hash_tab_t
*hashtab
,
209 xfs_dir2_leaf_entry_t
*ents
,
217 for (i
= j
= 0; i
< count
; i
++) {
218 if (INT_GET(ents
[i
].address
, ARCH_CONVERT
) == XFS_DIR2_NULL_DATAPTR
) {
222 rval
= dir_hash_see(hashtab
, INT_GET(ents
[i
].hashval
, ARCH_CONVERT
), INT_GET(ents
[i
].address
, ARCH_CONVERT
));
223 if (rval
!= DIR_HASH_CK_OK
)
226 return j
== stale
? DIR_HASH_CK_OK
: DIR_HASH_CK_BADSTALE
;
231 * Version 1 or 2 directory routine wrappers
234 dir_init(xfs_mount_t
*mp
, xfs_trans_t
*tp
, xfs_inode_t
*dp
, xfs_inode_t
*pdp
)
236 if (XFS_SB_VERSION_HASDIRV2(&mp
->m_sb
))
237 libxfs_dir2_init(tp
, dp
, pdp
);
239 libxfs_dir_init(tp
, dp
, pdp
);
243 dir_createname(xfs_mount_t
*mp
, xfs_trans_t
*tp
, xfs_inode_t
*pip
,
244 char *name
, int namelen
, xfs_ino_t inum
, xfs_fsblock_t
*first
,
245 xfs_bmap_free_t
*flist
, xfs_extlen_t total
)
247 if (XFS_SB_VERSION_HASDIRV2(&mp
->m_sb
))
248 return libxfs_dir2_createname(tp
, pip
, name
, namelen
,
249 inum
, first
, flist
, total
);
251 return libxfs_dir_createname(tp
, pip
, name
, namelen
,
252 inum
, first
, flist
, total
);
256 dir_lookup(xfs_mount_t
*mp
, xfs_trans_t
*tp
, xfs_inode_t
*dp
, char *name
,
257 int namelen
, xfs_ino_t
*inum
)
259 if (XFS_SB_VERSION_HASDIRV2(&mp
->m_sb
))
260 return libxfs_dir2_lookup(tp
, dp
, name
, namelen
, inum
);
262 return libxfs_dir_lookup(tp
, dp
, name
, namelen
, inum
);
266 dir_replace(xfs_mount_t
*mp
, xfs_trans_t
*tp
, xfs_inode_t
*dp
, char *name
,
267 int namelen
, xfs_ino_t inum
, xfs_fsblock_t
*firstblock
,
268 xfs_bmap_free_t
*flist
, xfs_extlen_t total
)
270 if (XFS_SB_VERSION_HASDIRV2(&mp
->m_sb
))
271 return libxfs_dir2_replace(tp
, dp
, name
, namelen
, inum
,
272 firstblock
, flist
, total
);
274 return libxfs_dir_replace(tp
, dp
, name
, namelen
, inum
,
275 firstblock
, flist
, total
);
279 dir_removename(xfs_mount_t
*mp
, xfs_trans_t
*tp
, xfs_inode_t
*dp
, char *name
,
280 int namelen
, xfs_ino_t inum
, xfs_fsblock_t
*firstblock
,
281 xfs_bmap_free_t
*flist
, xfs_extlen_t total
)
283 if (XFS_SB_VERSION_HASDIRV2(&mp
->m_sb
))
284 return libxfs_dir2_removename(tp
, dp
, name
, namelen
, inum
,
285 firstblock
, flist
, total
);
287 return libxfs_dir_removename(tp
, dp
, name
, namelen
, inum
,
288 firstblock
, flist
, total
);
292 dir_bogus_removename(xfs_mount_t
*mp
, xfs_trans_t
*tp
, xfs_inode_t
*dp
,
293 char *name
, xfs_fsblock_t
*firstblock
, xfs_bmap_free_t
*flist
,
294 xfs_extlen_t total
, xfs_dahash_t hashval
, int namelen
)
296 if (XFS_SB_VERSION_HASDIRV2(&mp
->m_sb
))
297 return libxfs_dir2_bogus_removename(tp
, dp
, name
, firstblock
,
298 flist
, total
, hashval
, namelen
);
300 return libxfs_dir_bogus_removename(tp
, dp
, name
, firstblock
,
301 flist
, total
, hashval
, namelen
);
310 do_error(_("ran out of disk space!\n"));
312 do_error(_("xfs_trans_reserve returned %d\n"), err
);
316 mk_rbmino(xfs_mount_t
*mp
)
326 xfs_bmap_free_t flist
;
328 xfs_bmbt_irec_t map
[XFS_BMAP_MAX_NMAP
];
333 tp
= libxfs_trans_alloc(mp
, 0);
335 if ((i
= libxfs_trans_reserve(tp
, 10, 0, 0, 0, 0)))
338 error
= libxfs_trans_iget(mp
, tp
, mp
->m_sb
.sb_rbmino
, 0, 0, &ip
);
341 _("couldn't iget realtime bitmap inode -- error - %d\n"),
345 bzero(&ip
->i_d
, sizeof(xfs_dinode_core_t
));
347 ip
->i_d
.di_magic
= XFS_DINODE_MAGIC
;
348 ip
->i_d
.di_mode
= S_IFREG
;
349 ip
->i_d
.di_version
= XFS_DINODE_VERSION_1
;
350 ip
->i_d
.di_format
= XFS_DINODE_FMT_EXTENTS
;
351 ip
->i_d
.di_aformat
= XFS_DINODE_FMT_EXTENTS
;
353 ip
->i_d
.di_nlink
= 1; /* account for sb ptr */
358 ip
->i_df
.if_flags
= XFS_IFEXTENTS
;
359 ip
->i_df
.if_bytes
= ip
->i_df
.if_real_bytes
= 0;
360 ip
->i_df
.if_u1
.if_extents
= NULL
;
362 ip
->i_d
.di_size
= mp
->m_sb
.sb_rbmblocks
* mp
->m_sb
.sb_blocksize
;
367 libxfs_trans_log_inode(tp
, ip
, XFS_ILOG_CORE
);
368 libxfs_trans_ihold(tp
, ip
);
369 libxfs_trans_commit(tp
, XFS_TRANS_RELEASE_LOG_RES
|XFS_TRANS_SYNC
, NULL
);
372 * then allocate blocks for file and fill with zeroes (stolen
375 tp
= libxfs_trans_alloc(mp
, 0);
376 if ((error
= libxfs_trans_reserve(tp
, mp
->m_sb
.sb_rbmblocks
+
377 (XFS_BM_MAXLEVELS(mp
, XFS_DATA_FORK
) - 1), 0, 0, 0, 0)))
380 libxfs_trans_ijoin(tp
, ip
, 0);
382 XFS_BMAP_INIT(&flist
, &first
);
383 while (bno
< mp
->m_sb
.sb_rbmblocks
) {
384 nmap
= XFS_BMAP_MAX_NMAP
;
385 error
= libxfs_bmapi(tp
, ip
, bno
,
386 (xfs_extlen_t
)(mp
->m_sb
.sb_rbmblocks
- bno
),
387 XFS_BMAPI_WRITE
, &first
, mp
->m_sb
.sb_rbmblocks
,
391 _("couldn't allocate realtime bitmap, error = %d\n"),
394 for (i
= 0, ep
= map
; i
< nmap
; i
++, ep
++) {
395 libxfs_device_zero(mp
->m_dev
,
396 XFS_FSB_TO_DADDR(mp
, ep
->br_startblock
),
397 XFS_FSB_TO_BB(mp
, ep
->br_blockcount
));
398 bno
+= ep
->br_blockcount
;
401 error
= libxfs_bmap_finish(&tp
, &flist
, first
, &committed
);
404 _("allocation of the realtime bitmap failed, error = %d\n"),
407 libxfs_trans_commit(tp
, XFS_TRANS_RELEASE_LOG_RES
|XFS_TRANS_SYNC
, 0);
411 fill_rbmino(xfs_mount_t
*mp
)
426 tp
= libxfs_trans_alloc(mp
, 0);
428 if ((error
= libxfs_trans_reserve(tp
, 10, 0, 0, 0, 0)))
431 error
= libxfs_trans_iget(mp
, tp
, mp
->m_sb
.sb_rbmino
, 0, 0, &ip
);
434 _("couldn't iget realtime bitmap inode -- error - %d\n"),
438 while (bno
< mp
->m_sb
.sb_rbmblocks
) {
440 * fill the file one block at a time
443 error
= libxfs_bmapi(tp
, ip
, bno
, 1, XFS_BMAPI_WRITE
,
444 &first
, 1, &map
, &nmap
, NULL
);
445 if (error
|| nmap
!= 1) {
447 _("couldn't map realtime bitmap block %llu, error = %d\n"),
451 ASSERT(map
.br_startblock
!= HOLESTARTBLOCK
);
453 error
= libxfs_trans_read_buf(
455 XFS_FSB_TO_DADDR(mp
, map
.br_startblock
),
456 XFS_FSB_TO_BB(mp
, 1), 1, &bp
);
460 _("can't access block %llu (fsbno %llu) of realtime bitmap inode %llu\n"),
461 bno
, map
.br_startblock
, mp
->m_sb
.sb_rbmino
);
465 bcopy(bmp
, XFS_BUF_PTR(bp
), mp
->m_sb
.sb_blocksize
);
467 libxfs_trans_log_buf(tp
, bp
, 0, mp
->m_sb
.sb_blocksize
- 1);
469 bmp
= (xfs_rtword_t
*)((__psint_t
) bmp
+ mp
->m_sb
.sb_blocksize
);
473 libxfs_trans_commit(tp
, XFS_TRANS_RELEASE_LOG_RES
|XFS_TRANS_SYNC
, 0);
478 fill_rsumino(xfs_mount_t
*mp
)
488 xfs_dfiloff_t end_bno
;
493 end_bno
= mp
->m_rsumsize
>> mp
->m_sb
.sb_blocklog
;
495 tp
= libxfs_trans_alloc(mp
, 0);
497 if ((error
= libxfs_trans_reserve(tp
, 10, 0, 0, 0, 0)))
500 error
= libxfs_trans_iget(mp
, tp
, mp
->m_sb
.sb_rsumino
, 0, 0, &ip
);
503 _("couldn't iget realtime summary inode -- error - %d\n"),
507 while (bno
< end_bno
) {
509 * fill the file one block at a time
512 error
= libxfs_bmapi(tp
, ip
, bno
, 1, XFS_BMAPI_WRITE
,
513 &first
, 1, &map
, &nmap
, NULL
);
514 if (error
|| nmap
!= 1) {
516 _("couldn't map realtime summary inode block %llu, error = %d\n"),
520 ASSERT(map
.br_startblock
!= HOLESTARTBLOCK
);
522 error
= libxfs_trans_read_buf(
524 XFS_FSB_TO_DADDR(mp
, map
.br_startblock
),
525 XFS_FSB_TO_BB(mp
, 1), 1, &bp
);
529 _("can't access block %llu (fsbno %llu) of realtime summary inode %llu\n"),
530 bno
, map
.br_startblock
, mp
->m_sb
.sb_rsumino
);
534 bcopy(smp
, XFS_BUF_PTR(bp
), mp
->m_sb
.sb_blocksize
);
536 libxfs_trans_log_buf(tp
, bp
, 0, mp
->m_sb
.sb_blocksize
- 1);
538 smp
= (xfs_suminfo_t
*)((__psint_t
)smp
+ mp
->m_sb
.sb_blocksize
);
542 libxfs_trans_commit(tp
, XFS_TRANS_RELEASE_LOG_RES
|XFS_TRANS_SYNC
, 0);
547 mk_rsumino(xfs_mount_t
*mp
)
558 xfs_bmap_free_t flist
;
560 xfs_bmbt_irec_t map
[XFS_BMAP_MAX_NMAP
];
565 tp
= libxfs_trans_alloc(mp
, 0);
567 if ((i
= libxfs_trans_reserve(tp
, 10, XFS_ICHANGE_LOG_RES(mp
), 0,
568 XFS_TRANS_PERM_LOG_RES
, XFS_MKDIR_LOG_COUNT
)))
571 error
= libxfs_trans_iget(mp
, tp
, mp
->m_sb
.sb_rsumino
, 0, 0, &ip
);
574 _("couldn't iget realtime summary inode -- error - %d\n"),
578 bzero(&ip
->i_d
, sizeof(xfs_dinode_core_t
));
580 ip
->i_d
.di_magic
= XFS_DINODE_MAGIC
;
581 ip
->i_d
.di_mode
= S_IFREG
;
582 ip
->i_d
.di_version
= XFS_DINODE_VERSION_1
;
583 ip
->i_d
.di_format
= XFS_DINODE_FMT_EXTENTS
;
584 ip
->i_d
.di_aformat
= XFS_DINODE_FMT_EXTENTS
;
586 ip
->i_d
.di_nlink
= 1; /* account for sb ptr */
591 ip
->i_df
.if_flags
= XFS_IFEXTENTS
;
592 ip
->i_df
.if_bytes
= ip
->i_df
.if_real_bytes
= 0;
593 ip
->i_df
.if_u1
.if_extents
= NULL
;
595 ip
->i_d
.di_size
= mp
->m_rsumsize
;
600 libxfs_trans_log_inode(tp
, ip
, XFS_ILOG_CORE
);
601 libxfs_trans_ihold(tp
, ip
);
602 libxfs_trans_commit(tp
, XFS_TRANS_RELEASE_LOG_RES
|XFS_TRANS_SYNC
, 0);
605 * then allocate blocks for file and fill with zeroes (stolen
608 tp
= libxfs_trans_alloc(mp
, 0);
609 XFS_BMAP_INIT(&flist
, &first
);
611 nsumblocks
= mp
->m_rsumsize
>> mp
->m_sb
.sb_blocklog
;
612 if ((error
= libxfs_trans_reserve(tp
,
613 mp
->m_sb
.sb_rbmblocks
+
614 (XFS_BM_MAXLEVELS(mp
, XFS_DATA_FORK
) - 1),
615 BBTOB(128), 0, XFS_TRANS_PERM_LOG_RES
,
616 XFS_DEFAULT_PERM_LOG_COUNT
)))
619 libxfs_trans_ijoin(tp
, ip
, 0);
621 XFS_BMAP_INIT(&flist
, &first
);
622 while (bno
< nsumblocks
) {
623 nmap
= XFS_BMAP_MAX_NMAP
;
624 error
= libxfs_bmapi(tp
, ip
, bno
,
625 (xfs_extlen_t
)(nsumblocks
- bno
),
626 XFS_BMAPI_WRITE
, &first
, nsumblocks
,
630 _("couldn't allocate realtime summary inode, error = %d\n"),
633 for (i
= 0, ep
= map
; i
< nmap
; i
++, ep
++) {
634 libxfs_device_zero(mp
->m_dev
,
635 XFS_FSB_TO_DADDR(mp
, ep
->br_startblock
),
636 XFS_FSB_TO_BB(mp
, ep
->br_blockcount
));
637 bno
+= ep
->br_blockcount
;
640 error
= libxfs_bmap_finish(&tp
, &flist
, first
, &committed
);
643 _("allocation of the realtime summary ino failed, error = %d\n"),
646 libxfs_trans_commit(tp
, XFS_TRANS_RELEASE_LOG_RES
|XFS_TRANS_SYNC
, 0);
650 * makes a new root directory.
653 mk_root_dir(xfs_mount_t
*mp
)
659 const mode_t mode
= 0755;
661 tp
= libxfs_trans_alloc(mp
, 0);
664 if ((i
= libxfs_trans_reserve(tp
, 10, XFS_ICHANGE_LOG_RES(mp
), 0,
665 XFS_TRANS_PERM_LOG_RES
, XFS_MKDIR_LOG_COUNT
)))
668 error
= libxfs_trans_iget(mp
, tp
, mp
->m_sb
.sb_rootino
, 0, 0, &ip
);
670 do_error(_("could not iget root inode -- error - %d\n"), error
);
674 * take care of the core -- initialization from xfs_ialloc()
676 bzero(&ip
->i_d
, sizeof(xfs_dinode_core_t
));
678 ip
->i_d
.di_magic
= XFS_DINODE_MAGIC
;
679 ip
->i_d
.di_mode
= (__uint16_t
) mode
|S_IFDIR
;
680 ip
->i_d
.di_version
= XFS_DINODE_VERSION_1
;
681 ip
->i_d
.di_format
= XFS_DINODE_FMT_EXTENTS
;
682 ip
->i_d
.di_aformat
= XFS_DINODE_FMT_EXTENTS
;
684 ip
->i_d
.di_nlink
= 1; /* account for . */
686 libxfs_trans_log_inode(tp
, ip
, XFS_ILOG_CORE
);
691 ip
->i_df
.if_flags
= XFS_IFEXTENTS
;
692 ip
->i_df
.if_bytes
= ip
->i_df
.if_real_bytes
= 0;
693 ip
->i_df
.if_u1
.if_extents
= NULL
;
698 * initialize the directory
700 dir_init(mp
, tp
, ip
, ip
);
702 libxfs_trans_commit(tp
, XFS_TRANS_RELEASE_LOG_RES
|XFS_TRANS_SYNC
, 0);
706 * orphanage name == lost+found
709 mk_orphanage(xfs_mount_t
*mp
)
719 xfs_bmap_free_t flist
;
720 const int mode
= 0755;
723 tp
= libxfs_trans_alloc(mp
, 0);
724 XFS_BMAP_INIT(&flist
, &first
);
726 nres
= XFS_MKDIR_SPACE_RES(mp
, strlen(ORPHANAGE
));
727 if ((i
= libxfs_trans_reserve(tp
, nres
, XFS_MKDIR_LOG_RES(mp
), 0,
728 XFS_TRANS_PERM_LOG_RES
, XFS_MKDIR_LOG_COUNT
)))
732 * use iget/ijoin instead of trans_iget because the ialloc
733 * wrapper can commit the transaction and start a new one
735 if ((i
= libxfs_iget(mp
, NULL
, mp
->m_sb
.sb_rootino
, 0, &pip
, 0)))
736 do_error(_("%d - couldn't iget root inode to make %s\n"),
739 error
= libxfs_inode_alloc(&tp
, pip
, mode
|S_IFDIR
,
740 1, 0, &zerocr
, &zerofsx
, &ip
);
742 do_error(_("%s inode allocation failed %d\n"),
745 ip
->i_d
.di_nlink
++; /* account for . */
748 * now that we know the transaction will stay around,
749 * add the root inode to it
751 libxfs_trans_ijoin(tp
, pip
, 0);
754 * create the actual entry
756 if ((error
= dir_createname(mp
, tp
, pip
, ORPHANAGE
,
757 strlen(ORPHANAGE
), ip
->i_ino
, &first
, &flist
, nres
))) {
759 _("can't make %s, createname error %d, will try later\n"),
761 orphanage_entered
= 0;
763 orphanage_entered
= 1;
766 * bump up the link count in the root directory to account
767 * for .. in the new directory
771 libxfs_trans_log_inode(tp
, pip
, XFS_ILOG_CORE
);
772 dir_init(mp
, tp
, ip
, pip
);
773 libxfs_trans_log_inode(tp
, ip
, XFS_ILOG_CORE
);
775 error
= libxfs_bmap_finish(&tp
, &flist
, first
, &committed
);
777 do_error(_("%s directory creation failed -- bmapf error %d\n"),
783 libxfs_trans_commit(tp
, XFS_TRANS_RELEASE_LOG_RES
|XFS_TRANS_SYNC
, 0);
785 /* need libxfs_iput here? - nathans TODO - possible memory leak? */
791 * move a file to the orphange. the orphanage is guaranteed
792 * at this point to only have file in it whose name == file inode #
795 mv_orphanage(xfs_mount_t
*mp
,
796 xfs_ino_t dir_ino
, /* orphange inode # */
797 xfs_ino_t ino
, /* inode # to be moved */
798 int isa_dir
) /* 1 if inode is a directory */
800 xfs_ino_t entry_ino_num
;
801 xfs_inode_t
*dir_ino_p
;
805 xfs_bmap_free_t flist
;
808 char fname
[MAXPATHLEN
+ 1];
811 snprintf(fname
, sizeof(fname
), "%llu", (unsigned long long)ino
);
813 if ((err
= libxfs_iget(mp
, NULL
, dir_ino
, 0, &dir_ino_p
, 0)))
814 do_error(_("%d - couldn't iget orphanage inode\n"), err
);
816 tp
= libxfs_trans_alloc(mp
, 0);
818 if ((err
= libxfs_iget(mp
, NULL
, ino
, 0, &ino_p
, 0)))
819 do_error(_("%d - couldn't iget disconnected inode\n"), err
);
822 nres
= XFS_DIRENTER_SPACE_RES(mp
, strlen(fname
)) +
823 XFS_DIRENTER_SPACE_RES(mp
, 2);
824 if ((err
= dir_lookup(mp
, tp
, ino_p
, "..", 2,
826 ASSERT(err
== ENOENT
);
828 if ((err
= libxfs_trans_reserve(tp
, nres
,
829 XFS_RENAME_LOG_RES(mp
), 0,
830 XFS_TRANS_PERM_LOG_RES
,
831 XFS_RENAME_LOG_COUNT
)))
833 _("space reservation failed (%d), filesystem may be out of space\n"),
836 libxfs_trans_ijoin(tp
, dir_ino_p
, 0);
837 libxfs_trans_ijoin(tp
, ino_p
, 0);
839 XFS_BMAP_INIT(&flist
, &first
);
840 if ((err
= dir_createname(mp
, tp
, dir_ino_p
, fname
,
841 strlen(fname
), ino
, &first
,
844 _("name create failed in %s (%d), filesystem may be out of space\n"),
847 dir_ino_p
->i_d
.di_nlink
++;
848 libxfs_trans_log_inode(tp
, dir_ino_p
, XFS_ILOG_CORE
);
850 if ((err
= dir_createname(mp
, tp
, ino_p
, "..", 2,
851 dir_ino
, &first
, &flist
, nres
)))
853 _("creation of .. entry failed (%d), filesystem may be out of space\n"),
856 ino_p
->i_d
.di_nlink
++;
857 libxfs_trans_log_inode(tp
, ino_p
, XFS_ILOG_CORE
);
859 if ((err
= libxfs_bmap_finish(&tp
, &flist
, first
, &committed
)))
861 _("bmap finish failed (err - %d), filesystem may be out of space\n"),
864 libxfs_trans_commit(tp
,
865 XFS_TRANS_RELEASE_LOG_RES
|XFS_TRANS_SYNC
, 0);
867 if ((err
= libxfs_trans_reserve(tp
, nres
,
868 XFS_RENAME_LOG_RES(mp
), 0,
869 XFS_TRANS_PERM_LOG_RES
,
870 XFS_RENAME_LOG_COUNT
)))
872 _("space reservation failed (%d), filesystem may be out of space\n"),
875 libxfs_trans_ijoin(tp
, dir_ino_p
, 0);
876 libxfs_trans_ijoin(tp
, ino_p
, 0);
878 XFS_BMAP_INIT(&flist
, &first
);
880 if ((err
= dir_createname(mp
, tp
, dir_ino_p
, fname
,
881 strlen(fname
), ino
, &first
,
884 _("name create failed in %s (%d), filesystem may be out of space\n"),
887 dir_ino_p
->i_d
.di_nlink
++;
888 libxfs_trans_log_inode(tp
, dir_ino_p
, XFS_ILOG_CORE
);
891 * don't replace .. value if it already points
892 * to us. that'll pop a libxfs/kernel ASSERT.
894 if (entry_ino_num
!= dir_ino
) {
895 if ((err
= dir_replace(mp
, tp
, ino_p
, "..",
899 _("name replace op failed (%d), filesystem may be out of space\n"),
903 if ((err
= libxfs_bmap_finish(&tp
, &flist
, first
,
906 _("bmap finish failed (%d), filesystem may be out of space\n"),
909 libxfs_trans_commit(tp
,
910 XFS_TRANS_RELEASE_LOG_RES
|XFS_TRANS_SYNC
, 0);
914 * use the remove log reservation as that's
915 * more accurate. we're only creating the
916 * links, we're not doing the inode allocation
917 * also accounted for in the create
919 nres
= XFS_DIRENTER_SPACE_RES(mp
, strlen(fname
));
920 if ((err
= libxfs_trans_reserve(tp
, nres
, XFS_REMOVE_LOG_RES(mp
), 0,
921 XFS_TRANS_PERM_LOG_RES
, XFS_REMOVE_LOG_COUNT
)))
923 _("space reservation failed (%d), filesystem may be out of space\n"),
926 libxfs_trans_ijoin(tp
, dir_ino_p
, 0);
927 libxfs_trans_ijoin(tp
, ino_p
, 0);
929 XFS_BMAP_INIT(&flist
, &first
);
930 if ((err
= dir_createname(mp
, tp
, dir_ino_p
, fname
,
931 strlen(fname
), ino
, &first
, &flist
, nres
)))
933 _("name create failed in %s (%d), filesystem may be out of space\n"),
937 ino_p
->i_d
.di_nlink
= 1;
938 libxfs_trans_log_inode(tp
, ino_p
, XFS_ILOG_CORE
);
940 if ((err
= libxfs_bmap_finish(&tp
, &flist
, first
, &committed
)))
942 _("bmap finish failed (%d), filesystem may be out of space\n"),
945 libxfs_trans_commit(tp
, XFS_TRANS_RELEASE_LOG_RES
|XFS_TRANS_SYNC
, 0);
950 * like get_first_dblock_fsbno only it uses the simulation code instead
953 * Returns the fsbno of the first (leftmost) block in the directory leaf.
954 * sets *bno to the directory block # corresponding to the returned fsbno.
957 map_first_dblock_fsbno(xfs_mount_t
*mp
,
962 xfs_fsblock_t fblock
;
963 xfs_da_intnode_t
*node
;
972 xfs_fsblock_t fblock2
;
975 * traverse down left-side of tree until we hit the
976 * left-most leaf block setting up the btree cursor along
983 fblock
= NULLFSBLOCK
;
987 error
= libxfs_bmapi(NULL
, ip
, (xfs_fileoff_t
) da_bno
, 1,
988 XFS_BMAPI_METADATA
, &fblock
, 0,
990 if (error
|| nmap
!= 1) {
993 _("can't map block %d in %s inode %llu, xfs_bmapi returns %d, nmap = %d\n"),
994 da_bno
, ftype
, ino
, error
, nmap
);
997 _("can't map block %d in %s inode %llu, xfs_bmapi returns %d, nmap = %d\n"),
998 da_bno
, ftype
, ino
, error
, nmap
);
1003 if ((fsbno
= map
.br_startblock
) == HOLESTARTBLOCK
) {
1005 do_error(_("block %d in %s ino %llu doesn't exist\n"),
1006 da_bno
, ftype
, ino
);
1008 do_warn(_("block %d in %s ino %llu doesn't exist\n"),
1009 da_bno
, ftype
, ino
);
1014 if (ip
->i_d
.di_size
<= XFS_LBSIZE(mp
))
1017 if (XFS_SB_VERSION_HASDIRV2(&mp
->m_sb
))
1021 fblock2
= NULLFSBLOCK
;
1022 prefetch_p6_dir1(mp
, ino
, ip
, 0, &fblock2
);
1027 * walk down left side of btree, release buffers as you
1028 * go. if the root block is a leaf (single-level btree),
1033 bp
= libxfs_readbuf(mp
->m_dev
, XFS_FSB_TO_DADDR(mp
, fsbno
),
1034 XFS_FSB_TO_BB(mp
, 1), 0);
1038 _("can't read block %u (fsbno %llu) for directory inode %llu\n"),
1039 da_bno
, fsbno
, ino
);
1043 node
= (xfs_da_intnode_t
*)XFS_BUF_PTR(bp
);
1045 if (INT_GET(node
->hdr
.info
.magic
, ARCH_CONVERT
) != XFS_DA_NODE_MAGIC
) {
1048 _("bad dir/attr magic number in inode %llu, file bno = %u, fsbno = %llu\n"),
1049 ino
, da_bno
, fsbno
);
1054 i
= INT_GET(node
->hdr
.level
, ARCH_CONVERT
);
1056 da_bno
= INT_GET(node
->btree
[0].before
, ARCH_CONVERT
);
1062 error
= libxfs_bmapi(NULL
, ip
, (xfs_fileoff_t
) da_bno
, 1,
1063 XFS_BMAPI_METADATA
, &fblock
, 0,
1065 if (error
|| nmap
!= 1) {
1068 _("can't map block %d in %s ino %llu, xfs_bmapi returns %d, nmap = %d\n"),
1069 da_bno
, ftype
, ino
, error
, nmap
);
1072 _("can't map block %d in %s ino %llu, xfs_bmapi returns %d, nmap = %d\n"),
1073 da_bno
, ftype
, ino
, error
, nmap
);
1077 if ((fsbno
= map
.br_startblock
) == HOLESTARTBLOCK
) {
1080 _("block %d in %s inode %llu doesn't exist\n"),
1081 da_bno
, ftype
, ino
);
1084 _("block %d in %s inode %llu doesn't exist\n"),
1085 da_bno
, ftype
, ino
);
1098 * scan longform directory and prune first bad entry. returns 1 if
1099 * it had to remove something, 0 if it made it all the way through
1100 * the directory. prune_lf_dir_entry does all the necessary bmap calls.
1102 * hashval is an in/out -- starting hashvalue in, hashvalue of the
1103 * deleted entry (if there was one) out
1105 * this routine can NOT be called if running in no modify mode
1108 prune_lf_dir_entry(xfs_mount_t
*mp
, xfs_ino_t ino
, xfs_inode_t
*ip
,
1109 xfs_dahash_t
*hashval
)
1116 xfs_bmap_free_t free_list
;
1117 xfs_fsblock_t first_block
;
1119 xfs_dir_leaf_name_t
*namest
;
1120 xfs_dir_leafblock_t
*leaf
;
1121 xfs_dir_leaf_entry_t
*entry
;
1124 xfs_fsblock_t fblock
;
1127 xfs_bmbt_irec_t map
;
1128 char fname
[MAXNAMELEN
+ 1];
1133 * ok, this is kind of a schizoid routine. we use our
1134 * internal bmapi routines to walk the directory. when
1135 * we find a bogus entry, we release the buffer so
1136 * the simulation code doesn't deadlock and use the
1137 * sim code to remove the entry. That will cause an
1138 * extra bmap traversal to map the block but I think
1139 * that's preferable to hacking the bogus removename
1140 * function to be really different and then trying to
1141 * maintain both versions as time goes on.
1143 * first, grab the dinode and find the right leaf block.
1150 fblock
= NULLFSBLOCK
;
1152 fsbno
= map_first_dblock_fsbno(mp
, ino
, ip
, &da_bno
);
1155 * now go foward along the leaves of the btree looking
1156 * for an entry beginning with '/'
1159 bp
= libxfs_readbuf(mp
->m_dev
, XFS_FSB_TO_DADDR(mp
, fsbno
),
1160 XFS_FSB_TO_BB(mp
, 1), 0);
1164 _("can't read directory inode %llu (leaf) block %u (fsbno %llu)\n"),
1165 ino
, da_bno
, fsbno
);
1169 leaf
= (xfs_dir_leafblock_t
*)XFS_BUF_PTR(bp
);
1170 ASSERT(INT_GET(leaf
->hdr
.info
.magic
, ARCH_CONVERT
) == XFS_DIR_LEAF_MAGIC
);
1171 entry
= &leaf
->entries
[0];
1173 for (index
= -1, i
= 0;
1174 i
< INT_GET(leaf
->hdr
.count
, ARCH_CONVERT
) && index
== -1;
1176 namest
= XFS_DIR_LEAF_NAMESTRUCT(leaf
, INT_GET(entry
->nameidx
, ARCH_CONVERT
));
1177 if (namest
->name
[0] != '/')
1184 * if we got a bogus entry, exit loop with a pointer to
1185 * the leaf block buffer. otherwise, keep trying blocks
1187 da_bno
= INT_GET(leaf
->hdr
.info
.forw
, ARCH_CONVERT
);
1196 * map next leaf block unless we've run out
1200 error
= libxfs_bmapi(NULL
, ip
,
1201 (xfs_fileoff_t
) da_bno
, 1,
1202 XFS_BMAPI_METADATA
, &fblock
, 0,
1204 if (error
|| nmap
!= 1)
1206 _("can't map block %d in directory %llu, xfs_bmapi returns %d, nmap = %d\n"),
1207 da_bno
, ino
, error
, nmap
);
1208 if ((fsbno
= map
.br_startblock
)
1209 == HOLESTARTBLOCK
) {
1211 _("%s ino %llu block %d doesn't exist\n"),
1212 ftype
, ino
, da_bno
);
1216 } while (da_bno
!= 0 && index
== -1);
1219 * if we hit the edge of the tree with no bad entries, we're done
1220 * and the buffer was released.
1222 if (da_bno
== 0 && index
== -1)
1226 ASSERT(entry
== &leaf
->entries
[index
]);
1227 ASSERT(namest
== XFS_DIR_LEAF_NAMESTRUCT(leaf
,
1228 INT_GET(entry
->nameidx
, ARCH_CONVERT
)));
1231 * snag the info we need out of the directory then release all buffers
1233 bcopy(namest
->name
, fname
, entry
->namelen
);
1234 fname
[entry
->namelen
] = '\0';
1235 *hashval
= INT_GET(entry
->hashval
, ARCH_CONVERT
);
1236 namelen
= entry
->namelen
;
1241 * ok, now the hard part, blow away the index'th entry in this block
1243 * allocate a remove transaction for it. that's not quite true since
1244 * we're only messing with one inode, not two but...
1247 tp
= libxfs_trans_alloc(mp
, XFS_TRANS_REMOVE
);
1249 nres
= XFS_REMOVE_SPACE_RES(mp
);
1250 error
= libxfs_trans_reserve(tp
, nres
, XFS_REMOVE_LOG_RES(mp
),
1251 0, XFS_TRANS_PERM_LOG_RES
,
1252 XFS_REMOVE_LOG_COUNT
);
1256 libxfs_trans_ijoin(tp
, ip
, 0);
1257 libxfs_trans_ihold(tp
, ip
);
1259 XFS_BMAP_INIT(&free_list
, &first_block
);
1261 error
= dir_bogus_removename(mp
, tp
, ip
, fname
,
1262 &first_block
, &free_list
, nres
, *hashval
, namelen
);
1266 _("couldn't remove bogus entry \"%s\" in\n\tdirectory inode %llu, errno = %d\n"),
1271 error
= libxfs_bmap_finish(&tp
, &free_list
, first_block
, &committed
);
1275 libxfs_trans_commit(tp
, XFS_TRANS_RELEASE_LOG_RES
|XFS_TRANS_SYNC
, 0);
1281 * process a leaf block, also checks for .. entry
1282 * and corrects it to match what we think .. should be
1285 lf_block_dir_entry_check(xfs_mount_t
*mp
,
1287 xfs_dir_leafblock_t
*leaf
,
1292 ino_tree_node_t
*current_irec
,
1293 int current_ino_offset
)
1295 xfs_dir_leaf_entry_t
*entry
;
1296 ino_tree_node_t
*irec
;
1299 xfs_dir_leaf_name_t
*namest
;
1304 char fname
[MAXNAMELEN
+ 1];
1306 entry
= &leaf
->entries
[0];
1311 * look at each entry. reference inode pointed to by each
1312 * entry in the incore inode tree.
1313 * if not a directory, set reached flag, increment link count
1314 * if a directory and reached, mark entry as to be deleted.
1315 * if a directory, check to see if recorded parent
1316 * matches current inode #,
1317 * if so, then set reached flag, increment link count
1318 * of current and child dir inodes, push the child
1319 * directory inode onto the directory stack.
1320 * if current inode != parent, then mark entry to be deleted.
1324 for (i
= 0; i
< INT_GET(leaf
->hdr
.count
, ARCH_CONVERT
); entry
++, i
++) {
1326 * snag inode #, update link counts, and make sure
1327 * this isn't a loop if the child is a directory
1329 namest
= XFS_DIR_LEAF_NAMESTRUCT(leaf
, INT_GET(entry
->nameidx
, ARCH_CONVERT
));
1332 * skip bogus entries (leading '/'). they'll be deleted
1335 if (namest
->name
[0] == '/') {
1342 XFS_DIR_SF_GET_DIRINO(&namest
->inumber
, &lino
);
1343 bcopy(namest
->name
, fname
, entry
->namelen
);
1344 fname
[entry
->namelen
] = '\0';
1346 ASSERT(lino
!= NULLFSINO
);
1349 * skip the '..' entry since it's checked when the
1350 * directory is reached by something else. if it never
1351 * gets reached, it'll be moved to the orphanage and we'll
1352 * take care of it then.
1354 if (entry
->namelen
== 2 && namest
->name
[0] == '.' &&
1355 namest
->name
[1] == '.') {
1358 ASSERT(no_modify
|| !verify_inum(mp
, lino
));
1361 * special case the . entry. we know there's only one
1362 * '.' and only '.' points to itself because bogus entries
1363 * got trashed in phase 3 if there were > 1.
1364 * bump up link count for '.' but don't set reached
1365 * until we're actually reached by another directory
1366 * '..' is already accounted for or will be taken care
1367 * of when directory is moved to orphanage.
1370 ASSERT(namest
->name
[0] == '.' && entry
->namelen
== 1);
1371 add_inode_ref(current_irec
, current_ino_offset
);
1377 * special case the "lost+found" entry if pointing
1378 * to where we think lost+found should be. if that's
1379 * the case, that's the one we created in phase 6.
1380 * just skip it. no need to process it and it's ..
1381 * link is already accounted for.
1384 if (lino
== orphanage_ino
&& strcmp(fname
, ORPHANAGE
) == 0)
1388 * skip entries with bogus inumbers if we're in no modify mode
1390 if (no_modify
&& verify_inum(mp
, lino
))
1394 * ok, now handle the rest of the cases besides '.' and '..'
1396 irec
= find_inode_rec(XFS_INO_TO_AGNO(mp
, lino
),
1397 XFS_INO_TO_AGINO(mp
, lino
));
1402 _("entry \"%s\" in dir inode %llu points to non-existent inode, "),
1406 namest
->name
[0] = '/';
1408 do_warn(_("marking entry to be junked\n"));
1410 do_warn(_("would junk entry\n"));
1416 ino_offset
= XFS_INO_TO_AGINO(mp
, lino
) - irec
->ino_startnum
;
1419 * if it's a free inode, blow out the entry.
1420 * by now, any inode that we think is free
1423 if (is_inode_free(irec
, ino_offset
)) {
1425 * don't complain if this entry points to the old
1426 * and now-free lost+found inode
1428 if (verbose
|| no_modify
|| lino
!= old_orphanage_ino
)
1430 _("entry \"%s\" in dir inode %llu points to free inode %llu"),
1435 if (verbose
|| lino
!= old_orphanage_ino
)
1437 _(", marking entry to be junked\n"));
1441 namest
->name
[0] = '/';
1444 do_warn(_(", would junk entry\n"));
1451 * check easy case first, regular inode, just bump
1452 * the link count and continue
1454 if (!inode_isadir(irec
, ino_offset
)) {
1455 add_inode_reached(irec
, ino_offset
);
1459 parent
= get_inode_parent(irec
, ino_offset
);
1460 ASSERT(parent
!= 0);
1463 * bump up the link counts in parent and child
1464 * directory but if the link doesn't agree with
1465 * the .. in the child, blow out the entry.
1466 * if the directory has already been reached,
1467 * blow away the entry also.
1469 if (is_inode_reached(irec
, ino_offset
)) {
1472 _("entry \"%s\" in dir %llu points to an already connected dir inode %llu,\n"),
1474 } else if (parent
== ino
) {
1475 add_inode_reached(irec
, ino_offset
);
1476 add_inode_ref(current_irec
, current_ino_offset
);
1478 if (!is_inode_refchecked(lino
, irec
, ino_offset
))
1479 push_dir(stack
, lino
);
1483 _("entry \"%s\" in dir ino %llu not consistent with .. value (%llu) in ino %llu,\n"),
1484 fname
, ino
, parent
, lino
);
1492 namest
->name
[0] = '/';
1494 if (verbose
|| lino
!= old_orphanage_ino
)
1496 _("\twill clear entry \"%s\"\n"),
1499 do_warn(_("\twould clear entry \"%s\"\n"),
1505 *num_illegal
+= nbad
;
1509 * succeeds or dies, inode never gets dirtied since all changes
1510 * happen in file blocks. the inode size and other core info
1511 * is already correct, it's just the leaf entries that get altered.
1514 longform_dir_entry_check(xfs_mount_t
*mp
,
1520 ino_tree_node_t
*irec
,
1523 xfs_dir_leafblock_t
*leaf
;
1526 xfs_fsblock_t fblock
;
1532 xfs_bmbt_irec_t map
;
1536 fblock
= NULLFSBLOCK
;
1540 fsbno
= map_first_dblock_fsbno(mp
, ino
, ip
, &da_bno
);
1542 if (fsbno
== NULLDFSBNO
&& no_modify
) {
1543 do_warn(_("cannot map block 0 of directory inode %llu\n"), ino
);
1548 ASSERT(fsbno
!= NULLDFSBNO
);
1551 bp
= libxfs_readbuf(mp
->m_dev
, XFS_FSB_TO_DADDR(mp
, fsbno
),
1552 XFS_FSB_TO_BB(mp
, 1), 0);
1556 _("can't read block %u (fsbno %llu) for directory inode %llu\n"),
1557 da_bno
, fsbno
, ino
);
1561 leaf
= (xfs_dir_leafblock_t
*)XFS_BUF_PTR(bp
);
1563 da_bno
= INT_GET(leaf
->hdr
.info
.forw
, ARCH_CONVERT
);
1565 if (INT_GET(leaf
->hdr
.info
.magic
, ARCH_CONVERT
) !=
1566 XFS_DIR_LEAF_MAGIC
) {
1569 _("bad magic # (0x%x) for dir ino %llu leaf block (bno %u fsbno %llu)\n"),
1570 INT_GET(leaf
->hdr
.info
.magic
,
1572 ino
, da_bno
, fsbno
);
1576 * this block's bad but maybe the
1577 * forward pointer is good...
1585 lf_block_dir_entry_check(mp
, ino
, leaf
, &dirty
,
1586 num_illegal
, need_dot
, stack
,
1589 ASSERT(dirty
== 0 || (dirty
&& !no_modify
));
1591 if (dirty
&& !no_modify
)
1592 libxfs_writebuf(bp
, 0);
1599 error
= libxfs_bmapi(NULL
, ip
, (xfs_fileoff_t
)da_bno
, 1,
1600 XFS_BMAPI_METADATA
, &fblock
, 0,
1602 if (error
|| nmap
!= 1) {
1605 _("can't map leaf block %d in dir %llu, xfs_bmapi returns %d, nmap = %d\n"),
1606 da_bno
, ino
, error
, nmap
);
1609 _("can't map leaf block %d in dir %llu, xfs_bmapi returns %d, nmap = %d\n"),
1610 da_bno
, ino
, error
, nmap
);
1614 if ((fsbno
= map
.br_startblock
) == HOLESTARTBLOCK
) {
1617 _("block %d in %s ino %llu doesn't exist\n"),
1618 da_bno
, ftype
, ino
);
1621 _("block %d in %s ino %llu doesn't exist\n"),
1622 da_bno
, ftype
, ino
);
1627 } while (da_bno
!= 0);
1631 * Kill a block in a version 2 inode.
1632 * Makes its own transaction.
1644 xfs_fsblock_t firstblock
;
1645 xfs_bmap_free_t flist
;
1649 tp
= libxfs_trans_alloc(mp
, 0);
1650 nres
= XFS_REMOVE_SPACE_RES(mp
);
1651 error
= libxfs_trans_reserve(tp
, nres
, XFS_REMOVE_LOG_RES(mp
), 0,
1652 XFS_TRANS_PERM_LOG_RES
, XFS_REMOVE_LOG_COUNT
);
1655 libxfs_trans_ijoin(tp
, ip
, 0);
1656 libxfs_trans_ihold(tp
, ip
);
1657 libxfs_da_bjoin(tp
, bp
);
1658 bzero(&args
, sizeof(args
));
1659 XFS_BMAP_INIT(&flist
, &firstblock
);
1662 args
.firstblock
= &firstblock
;
1663 args
.flist
= &flist
;
1664 args
.whichfork
= XFS_DATA_FORK
;
1665 if (da_bno
>= mp
->m_dirleafblk
&& da_bno
< mp
->m_dirfreeblk
)
1666 error
= libxfs_da_shrink_inode(&args
, da_bno
, bp
);
1668 error
= libxfs_dir2_shrink_inode(&args
,
1669 XFS_DIR2_DA_TO_DB(mp
, da_bno
), bp
);
1671 do_error(_("shrink_inode failed inode %llu block %u\n"),
1673 libxfs_bmap_finish(&tp
, &flist
, firstblock
, &committed
);
1674 libxfs_trans_commit(tp
, 0, 0);
1678 * process a data block, also checks for .. entry
1679 * and corrects it to match what we think .. should be
1682 longform_dir2_entry_check_data(
1688 ino_tree_node_t
*current_irec
,
1689 int current_ino_offset
,
1691 dir_hash_tab_t
*hashtab
,
1692 freetab_t
**freetabp
,
1696 xfs_dir2_dataptr_t addr
;
1697 xfs_dir2_leaf_entry_t
*blp
;
1699 xfs_dir2_block_tail_t
*btp
;
1703 xfs_dir2_data_entry_t
*dep
;
1704 xfs_dir2_data_unused_t
*dup
;
1707 xfs_fsblock_t firstblock
;
1708 xfs_bmap_free_t flist
;
1709 char fname
[MAXNAMELEN
+ 1];
1713 ino_tree_node_t
*irec
;
1729 needscan
= needlog
= 0;
1731 freetab
= *freetabp
;
1733 btp
= XFS_DIR2_BLOCK_TAIL_P(mp
, (xfs_dir2_block_t
*)d
);
1734 blp
= XFS_DIR2_BLOCK_LEAF_P(btp
);
1735 endptr
= (char *)blp
;
1736 if (endptr
> (char *)btp
)
1737 endptr
= (char *)btp
;
1738 wantmagic
= XFS_DIR2_BLOCK_MAGIC
;
1740 endptr
= (char *)d
+ mp
->m_dirblksize
;
1741 wantmagic
= XFS_DIR2_DATA_MAGIC
;
1743 db
= XFS_DIR2_DA_TO_DB(mp
, da_bno
);
1745 /* check for data block beyond expected end */
1746 if (freetab
->naents
<= db
) {
1747 struct freetab_ent e
;
1749 *freetabp
= freetab
= realloc(freetab
, FREETAB_SIZE(db
+ 1));
1752 _("realloc failed in longform_dir2_entry_check_data (%u bytes)\n"),
1753 FREETAB_SIZE(db
+ 1));
1757 for (i
= freetab
->naents
; i
< db
; i
++)
1758 freetab
->ents
[i
] = e
;
1759 freetab
->naents
= db
+ 1;
1762 /* check the data block */
1763 while (ptr
< endptr
) {
1765 /* check for freespace */
1766 dup
= (xfs_dir2_data_unused_t
*)ptr
;
1767 if (XFS_DIR2_DATA_FREE_TAG
==
1768 INT_GET(dup
->freetag
, ARCH_CONVERT
)) {
1770 /* check for invalid freespace length */
1771 if (ptr
+ INT_GET(dup
->length
, ARCH_CONVERT
) > endptr
||
1772 INT_GET(dup
->length
, ARCH_CONVERT
) == 0 ||
1773 (INT_GET(dup
->length
, ARCH_CONVERT
) &
1774 (XFS_DIR2_DATA_ALIGN
- 1)))
1777 /* check for invalid tag */
1778 if (INT_GET(*XFS_DIR2_DATA_UNUSED_TAG_P(dup
),
1779 ARCH_CONVERT
) != (char *)dup
- (char *)d
)
1782 /* check for block with no data entries */
1783 if ((ptr
== (char *)d
->u
) &&
1784 (ptr
+ INT_GET(dup
->length
, ARCH_CONVERT
) >=
1791 /* continue at the end of the freespace */
1792 ptr
+= INT_GET(dup
->length
, ARCH_CONVERT
);
1797 /* validate data entry size */
1798 dep
= (xfs_dir2_data_entry_t
*)ptr
;
1799 if (ptr
+ XFS_DIR2_DATA_ENTSIZE(dep
->namelen
) > endptr
)
1801 if (INT_GET(*XFS_DIR2_DATA_ENTRY_TAG_P(dep
), ARCH_CONVERT
) !=
1802 (char *)dep
- (char *)d
)
1804 ptr
+= XFS_DIR2_DATA_ENTSIZE(dep
->namelen
);
1807 /* did we find an empty or corrupt block? */
1808 if (ptr
!= endptr
) {
1811 _("empty data block %u in directory inode %llu: "),
1814 do_warn(_("corrupt block %u in directory inode %llu: "),
1818 do_warn(_("junking block\n"));
1819 dir2_kill_block(mp
, ip
, da_bno
, bp
);
1821 do_warn(_("would junk block\n"));
1822 libxfs_da_brelse(NULL
, bp
);
1824 freetab
->ents
[db
].v
= NULLDATAOFF
;
1829 /* update number of data blocks processed */
1830 if (freetab
->nents
< db
+ 1)
1831 freetab
->nents
= db
+ 1;
1833 tp
= libxfs_trans_alloc(mp
, 0);
1834 error
= libxfs_trans_reserve(tp
, 0, XFS_REMOVE_LOG_RES(mp
), 0,
1835 XFS_TRANS_PERM_LOG_RES
, XFS_REMOVE_LOG_COUNT
);
1838 libxfs_trans_ijoin(tp
, ip
, 0);
1839 libxfs_trans_ihold(tp
, ip
);
1840 libxfs_da_bjoin(tp
, bp
);
1842 libxfs_da_bhold(tp
, bp
);
1843 XFS_BMAP_INIT(&flist
, &firstblock
);
1844 if (INT_GET(d
->hdr
.magic
, ARCH_CONVERT
) != wantmagic
) {
1845 do_warn(_("bad directory block magic # %#x for directory inode "
1847 INT_GET(d
->hdr
.magic
, ARCH_CONVERT
), ip
->i_ino
, da_bno
);
1849 do_warn(_("fixing magic # to %#x\n"), wantmagic
);
1850 INT_SET(d
->hdr
.magic
, ARCH_CONVERT
, wantmagic
);
1853 do_warn(_("would fix magic # to %#x\n"), wantmagic
);
1858 * look at each entry. reference inode pointed to by each
1859 * entry in the incore inode tree.
1860 * if not a directory, set reached flag, increment link count
1861 * if a directory and reached, mark entry as to be deleted.
1862 * if a directory, check to see if recorded parent
1863 * matches current inode #,
1864 * if so, then set reached flag, increment link count
1865 * of current and child dir inodes, push the child
1866 * directory inode onto the directory stack.
1867 * if current inode != parent, then mark entry to be deleted.
1869 while (ptr
< endptr
) {
1870 dup
= (xfs_dir2_data_unused_t
*)ptr
;
1871 if (INT_GET(dup
->freetag
, ARCH_CONVERT
) ==
1872 XFS_DIR2_DATA_FREE_TAG
) {
1874 do_warn(_("directory inode %llu block %u has "
1875 "consecutive free entries: "),
1878 do_warn(_("joining together\n"));
1879 len
= INT_GET(dup
->length
, ARCH_CONVERT
);
1880 libxfs_dir2_data_use_free(tp
, bp
, dup
,
1881 ptr
- (char *)d
, len
, &needlog
,
1883 libxfs_dir2_data_make_free(tp
, bp
,
1884 ptr
- (char *)d
, len
, &needlog
,
1887 do_warn(_("would join together\n"));
1889 ptr
+= INT_GET(dup
->length
, ARCH_CONVERT
);
1893 addr
= XFS_DIR2_DB_OFF_TO_DATAPTR(mp
, db
, ptr
- (char *)d
);
1894 dep
= (xfs_dir2_data_entry_t
*)ptr
;
1895 ptr
+= XFS_DIR2_DATA_ENTSIZE(dep
->namelen
);
1897 dir_hash_add(hashtab
,
1898 libxfs_da_hashname((uchar_t
*)dep
->name
, dep
->namelen
),
1899 addr
, dep
->name
[0] == '/');
1901 * skip bogus entries (leading '/'). they'll be deleted
1902 * later. must still log it, else we leak references to
1905 if (dep
->name
[0] == '/') {
1908 libxfs_dir2_data_log_entry(tp
, bp
, dep
);
1912 bcopy(dep
->name
, fname
, dep
->namelen
);
1913 fname
[dep
->namelen
] = '\0';
1914 ASSERT(INT_GET(dep
->inumber
, ARCH_CONVERT
) != NULLFSINO
);
1916 * skip the '..' entry since it's checked when the
1917 * directory is reached by something else. if it never
1918 * gets reached, it'll be moved to the orphanage and we'll
1919 * take care of it then.
1921 if (dep
->namelen
== 2 && dep
->name
[0] == '.' &&
1922 dep
->name
[1] == '.')
1924 ASSERT(no_modify
|| !verify_inum(mp
, INT_GET(dep
->inumber
, ARCH_CONVERT
)));
1926 * special case the . entry. we know there's only one
1927 * '.' and only '.' points to itself because bogus entries
1928 * got trashed in phase 3 if there were > 1.
1929 * bump up link count for '.' but don't set reached
1930 * until we're actually reached by another directory
1931 * '..' is already accounted for or will be taken care
1932 * of when directory is moved to orphanage.
1934 if (ip
->i_ino
== INT_GET(dep
->inumber
, ARCH_CONVERT
)) {
1935 ASSERT(dep
->name
[0] == '.' && dep
->namelen
== 1);
1936 add_inode_ref(current_irec
, current_ino_offset
);
1941 * special case the "lost+found" entry if pointing
1942 * to where we think lost+found should be. if that's
1943 * the case, that's the one we created in phase 6.
1944 * just skip it. no need to process it and it's ..
1945 * link is already accounted for.
1947 if (INT_GET(dep
->inumber
, ARCH_CONVERT
) == orphanage_ino
&&
1948 strcmp(fname
, ORPHANAGE
) == 0)
1951 * skip entries with bogus inumbers if we're in no modify mode
1954 verify_inum(mp
, INT_GET(dep
->inumber
, ARCH_CONVERT
)))
1957 * ok, now handle the rest of the cases besides '.' and '..'
1959 irec
= find_inode_rec(
1961 INT_GET(dep
->inumber
, ARCH_CONVERT
)),
1962 XFS_INO_TO_AGINO(mp
,
1963 INT_GET(dep
->inumber
, ARCH_CONVERT
)));
1966 do_warn(_("entry \"%s\" in directory inode %llu points "
1967 "to non-existent inode, "),
1971 libxfs_dir2_data_log_entry(tp
, bp
, dep
);
1972 do_warn(_("marking entry to be junked\n"));
1974 do_warn(_("would junk entry\n"));
1978 ino_offset
= XFS_INO_TO_AGINO(mp
,
1979 INT_GET(dep
->inumber
, ARCH_CONVERT
)) -
1982 * if it's a free inode, blow out the entry.
1983 * by now, any inode that we think is free
1986 if (is_inode_free(irec
, ino_offset
)) {
1988 * don't complain if this entry points to the old
1989 * and now-free lost+found inode
1991 if (verbose
|| no_modify
||
1992 INT_GET(dep
->inumber
, ARCH_CONVERT
) !=
1995 _("entry \"%s\" in directory inode %llu points to free inode %llu"),
1997 INT_GET(dep
->inumber
, ARCH_CONVERT
));
2001 INT_GET(dep
->inumber
, ARCH_CONVERT
) !=
2004 _(", marking entry to be junked\n"));
2008 libxfs_dir2_data_log_entry(tp
, bp
, dep
);
2010 do_warn(_(", would junk entry\n"));
2015 * check easy case first, regular inode, just bump
2016 * the link count and continue
2018 if (!inode_isadir(irec
, ino_offset
)) {
2019 add_inode_reached(irec
, ino_offset
);
2022 parent
= get_inode_parent(irec
, ino_offset
);
2023 ASSERT(parent
!= 0);
2025 * bump up the link counts in parent and child
2026 * directory but if the link doesn't agree with
2027 * the .. in the child, blow out the entry.
2028 * if the directory has already been reached,
2029 * blow away the entry also.
2031 if (is_inode_reached(irec
, ino_offset
)) {
2034 _("entry \"%s\" in dir %llu points to an already connected directory inode %llu,\n"),
2036 INT_GET(dep
->inumber
, ARCH_CONVERT
));
2037 } else if (parent
== ip
->i_ino
) {
2038 add_inode_reached(irec
, ino_offset
);
2039 add_inode_ref(current_irec
, current_ino_offset
);
2040 if (!is_inode_refchecked(
2041 INT_GET(dep
->inumber
, ARCH_CONVERT
), irec
,
2044 INT_GET(dep
->inumber
, ARCH_CONVERT
));
2048 _("entry \"%s\" in dir inode %llu inconsistent with .. value (%llu) in ino %llu,\n"),
2049 fname
, ip
->i_ino
, parent
,
2050 INT_GET(dep
->inumber
, ARCH_CONVERT
));
2057 libxfs_dir2_data_log_entry(tp
, bp
, dep
);
2059 INT_GET(dep
->inumber
, ARCH_CONVERT
) !=
2062 _("\twill clear entry \"%s\"\n"),
2065 do_warn(_("\twould clear entry \"%s\"\n"),
2070 *num_illegal
+= nbad
;
2072 libxfs_dir2_data_freescan(mp
, d
, &needlog
, NULL
);
2074 libxfs_dir2_data_log_header(tp
, bp
);
2075 else if (!isblock
&& !nbad
)
2076 libxfs_da_brelse(tp
, bp
);
2077 libxfs_bmap_finish(&tp
, &flist
, firstblock
, &committed
);
2078 libxfs_trans_commit(tp
, 0, 0);
2079 freetab
->ents
[db
].v
= INT_GET(d
->hdr
.bestfree
[0].length
, ARCH_CONVERT
);
2080 freetab
->ents
[db
].s
= 0;
2084 * Check contents of leaf-form block.
2087 longform_dir2_check_leaf(
2090 dir_hash_tab_t
*hashtab
,
2094 xfs_dir2_data_off_t
*bestsp
;
2098 xfs_dir2_leaf_t
*leaf
;
2099 xfs_dir2_leaf_tail_t
*ltp
;
2102 da_bno
= mp
->m_dirleafblk
;
2103 if (libxfs_da_read_bufr(NULL
, ip
, da_bno
, -1, &bp
, XFS_DATA_FORK
)) {
2104 do_error(_("can't read block %u for directory inode %llu\n"),
2109 ltp
= XFS_DIR2_LEAF_TAIL_P(mp
, leaf
);
2110 bestsp
= XFS_DIR2_LEAF_BESTS_P(ltp
);
2111 if (INT_GET(leaf
->hdr
.info
.magic
, ARCH_CONVERT
) !=
2112 XFS_DIR2_LEAF1_MAGIC
||
2113 INT_GET(leaf
->hdr
.info
.forw
, ARCH_CONVERT
) ||
2114 INT_GET(leaf
->hdr
.info
.back
, ARCH_CONVERT
) ||
2115 INT_GET(leaf
->hdr
.count
, ARCH_CONVERT
) <
2116 INT_GET(leaf
->hdr
.stale
, ARCH_CONVERT
) ||
2117 INT_GET(leaf
->hdr
.count
, ARCH_CONVERT
) >
2118 XFS_DIR2_MAX_LEAF_ENTS(mp
) ||
2119 (char *)&leaf
->ents
[INT_GET(leaf
->hdr
.count
, ARCH_CONVERT
)] >
2122 _("leaf block %u for directory inode %llu bad header\n"),
2124 libxfs_da_brelse(NULL
, bp
);
2127 seeval
= dir_hash_see_all(hashtab
, leaf
->ents
,
2128 INT_GET(leaf
->hdr
.count
, ARCH_CONVERT
),
2129 INT_GET(leaf
->hdr
.stale
, ARCH_CONVERT
));
2130 if (dir_hash_check(hashtab
, ip
, seeval
)) {
2131 libxfs_da_brelse(NULL
, bp
);
2134 badtail
= freetab
->nents
!= INT_GET(ltp
->bestcount
, ARCH_CONVERT
);
2135 for (i
= 0; !badtail
&& i
< INT_GET(ltp
->bestcount
, ARCH_CONVERT
); i
++) {
2136 freetab
->ents
[i
].s
= 1;
2137 badtail
= freetab
->ents
[i
].v
!= INT_GET(bestsp
[i
], ARCH_CONVERT
);
2140 do_warn(_("leaf block %u for directory inode %llu bad tail\n"),
2142 libxfs_da_brelse(NULL
, bp
);
2145 libxfs_da_brelse(NULL
, bp
);
2150 * Check contents of the node blocks (leaves)
2151 * Looks for matching hash values for the data entries.
2154 longform_dir2_check_node(
2157 dir_hash_tab_t
*hashtab
,
2163 xfs_dir2_free_t
*free
;
2165 xfs_dir2_leaf_t
*leaf
;
2166 xfs_fileoff_t next_da_bno
;
2170 for (da_bno
= mp
->m_dirleafblk
, next_da_bno
= 0;
2171 next_da_bno
!= NULLFILEOFF
&& da_bno
< mp
->m_dirfreeblk
;
2172 da_bno
= (xfs_dablk_t
)next_da_bno
) {
2173 next_da_bno
= da_bno
+ mp
->m_dirblkfsbs
- 1;
2174 if (libxfs_bmap_next_offset(NULL
, ip
, &next_da_bno
, XFS_DATA_FORK
))
2176 if (libxfs_da_read_bufr(NULL
, ip
, da_bno
, -1, &bp
,
2179 _("can't read block %u for directory inode %llu\n"),
2184 if (INT_GET(leaf
->hdr
.info
.magic
, ARCH_CONVERT
) !=
2185 XFS_DIR2_LEAFN_MAGIC
) {
2186 if (INT_GET(leaf
->hdr
.info
.magic
, ARCH_CONVERT
) ==
2187 XFS_DA_NODE_MAGIC
) {
2188 libxfs_da_brelse(NULL
, bp
);
2191 do_warn(_("unknown magic number %#x for block %u in "
2192 "directory inode %llu\n"),
2193 INT_GET(leaf
->hdr
.info
.magic
, ARCH_CONVERT
),
2195 libxfs_da_brelse(NULL
, bp
);
2198 if (INT_GET(leaf
->hdr
.count
, ARCH_CONVERT
) <
2199 INT_GET(leaf
->hdr
.stale
, ARCH_CONVERT
) ||
2200 INT_GET(leaf
->hdr
.count
, ARCH_CONVERT
) >
2201 XFS_DIR2_MAX_LEAF_ENTS(mp
)) {
2202 do_warn(_("leaf block %u for directory inode %llu bad "
2205 libxfs_da_brelse(NULL
, bp
);
2208 seeval
= dir_hash_see_all(hashtab
, leaf
->ents
, INT_GET(leaf
->hdr
.count
, ARCH_CONVERT
),
2209 INT_GET(leaf
->hdr
.stale
, ARCH_CONVERT
));
2210 libxfs_da_brelse(NULL
, bp
);
2211 if (seeval
!= DIR_HASH_CK_OK
)
2214 if (dir_hash_check(hashtab
, ip
, seeval
))
2216 for (da_bno
= mp
->m_dirfreeblk
, next_da_bno
= 0;
2217 next_da_bno
!= NULLFILEOFF
;
2218 da_bno
= (xfs_dablk_t
)next_da_bno
) {
2219 next_da_bno
= da_bno
+ mp
->m_dirblkfsbs
- 1;
2220 if (libxfs_bmap_next_offset(NULL
, ip
, &next_da_bno
, XFS_DATA_FORK
))
2222 if (libxfs_da_read_bufr(NULL
, ip
, da_bno
, -1, &bp
,
2224 do_error(_("can't read block %u for directory inode "
2230 fdb
= XFS_DIR2_DA_TO_DB(mp
, da_bno
);
2231 if (INT_GET(free
->hdr
.magic
, ARCH_CONVERT
) !=
2232 XFS_DIR2_FREE_MAGIC
||
2233 INT_GET(free
->hdr
.firstdb
, ARCH_CONVERT
) !=
2234 (fdb
- XFS_DIR2_FREE_FIRSTDB(mp
)) *
2235 XFS_DIR2_MAX_FREE_BESTS(mp
) ||
2236 INT_GET(free
->hdr
.nvalid
, ARCH_CONVERT
) <
2237 INT_GET(free
->hdr
.nused
, ARCH_CONVERT
)) {
2238 do_warn(_("free block %u for directory inode %llu bad "
2241 libxfs_da_brelse(NULL
, bp
);
2244 for (i
= used
= 0; i
< INT_GET(free
->hdr
.nvalid
, ARCH_CONVERT
); i
++) {
2245 if (i
+ INT_GET(free
->hdr
.firstdb
, ARCH_CONVERT
) >=
2247 freetab
->ents
[i
+ INT_GET(free
->hdr
.firstdb
,
2249 INT_GET(free
->bests
[i
], ARCH_CONVERT
)) {
2251 _("free block %u entry %i for directory ino %llu bad\n"),
2252 da_bno
, i
, ip
->i_ino
);
2253 libxfs_da_brelse(NULL
, bp
);
2256 used
+= INT_GET(free
->bests
[i
], ARCH_CONVERT
) != NULLDATAOFF
;
2257 freetab
->ents
[i
+ INT_GET(free
->hdr
.firstdb
, ARCH_CONVERT
)].s
= 1;
2259 if (used
!= INT_GET(free
->hdr
.nused
, ARCH_CONVERT
)) {
2260 do_warn(_("free block %u for directory inode %llu bad "
2263 libxfs_da_brelse(NULL
, bp
);
2266 libxfs_da_brelse(NULL
, bp
);
2268 for (i
= 0; i
< freetab
->nents
; i
++) {
2269 if ((freetab
->ents
[i
].s
== 0) &&
2270 (freetab
->ents
[i
].v
!= NULLDATAOFF
)) {
2271 do_warn(_("missing freetab entry %u for "
2272 "directory inode %llu\n"),
2281 * Rebuild a directory: set up.
2282 * Turn it into a node-format directory with no contents in the
2283 * upper area. Also has correct freespace blocks.
2286 longform_dir2_rebuild_setup(
2294 xfs_dir2_data_t
*data
= NULL
;
2299 xfs_fsblock_t firstblock
;
2300 xfs_bmap_free_t flist
;
2301 xfs_dir2_free_t
*free
;
2306 xfs_dir2_leaf_t
*leaf
;
2310 /* read first directory block */
2311 tp
= libxfs_trans_alloc(mp
, 0);
2312 nres
= XFS_DAENTER_SPACE_RES(mp
, XFS_DATA_FORK
);
2313 error
= libxfs_trans_reserve(tp
,
2314 nres
, XFS_CREATE_LOG_RES(mp
), 0, XFS_TRANS_PERM_LOG_RES
,
2315 XFS_CREATE_LOG_COUNT
);
2318 libxfs_trans_ijoin(tp
, ip
, 0);
2319 libxfs_trans_ihold(tp
, ip
);
2320 XFS_BMAP_INIT(&flist
, &firstblock
);
2321 if (libxfs_da_read_buf(tp
, ip
, mp
->m_dirdatablk
, -2, &dbp
,
2323 do_error(_("can't read block %u for directory inode %llu\n"),
2324 mp
->m_dirdatablk
, ino
);
2331 /* check for block format directory */
2333 INT_GET((data
)->hdr
.magic
, ARCH_CONVERT
) == XFS_DIR2_BLOCK_MAGIC
) {
2334 xfs_dir2_block_t
*block
;
2335 xfs_dir2_leaf_entry_t
*blp
;
2336 xfs_dir2_block_tail_t
*btp
;
2340 /* convert directory block from block format to data format */
2341 INT_SET(data
->hdr
.magic
, ARCH_CONVERT
, XFS_DIR2_DATA_MAGIC
);
2343 /* construct freelist */
2344 block
= (xfs_dir2_block_t
*)data
;
2345 btp
= XFS_DIR2_BLOCK_TAIL_P(mp
, block
);
2346 blp
= XFS_DIR2_BLOCK_LEAF_P(btp
);
2347 needlog
= needscan
= 0;
2348 libxfs_dir2_data_make_free(tp
, dbp
, (char *)blp
- (char *)block
,
2349 (char *)block
+ mp
->m_dirblksize
- (char *)blp
,
2350 &needlog
, &needscan
);
2352 libxfs_dir2_data_freescan(mp
, data
, &needlog
, NULL
);
2353 libxfs_da_log_buf(tp
, dbp
, 0, mp
->m_dirblksize
- 1);
2355 libxfs_da_brelse(tp
, dbp
);
2358 /* allocate blocks for btree */
2359 bzero(&args
, sizeof(args
));
2362 args
.whichfork
= XFS_DATA_FORK
;
2363 args
.firstblock
= &firstblock
;
2364 args
.flist
= &flist
;
2366 if ((error
= libxfs_da_grow_inode(&args
, &lblkno
)) ||
2367 (error
= libxfs_da_get_buf(tp
, ip
, lblkno
, -1, &lbp
, XFS_DATA_FORK
))) {
2368 do_error(_("can't add btree block to directory inode %llu\n"),
2373 bzero(leaf
, mp
->m_dirblksize
);
2374 INT_SET(leaf
->hdr
.info
.magic
, ARCH_CONVERT
, XFS_DIR2_LEAFN_MAGIC
);
2375 libxfs_da_log_buf(tp
, lbp
, 0, mp
->m_dirblksize
- 1);
2376 libxfs_bmap_finish(&tp
, &flist
, firstblock
, &committed
);
2377 libxfs_trans_commit(tp
, 0, 0);
2379 for (i
= 0; i
< freetab
->nents
; i
+= XFS_DIR2_MAX_FREE_BESTS(mp
)) {
2380 tp
= libxfs_trans_alloc(mp
, 0);
2381 nres
= XFS_DAENTER_SPACE_RES(mp
, XFS_DATA_FORK
);
2382 error
= libxfs_trans_reserve(tp
,
2383 nres
, XFS_CREATE_LOG_RES(mp
), 0, XFS_TRANS_PERM_LOG_RES
,
2384 XFS_CREATE_LOG_COUNT
);
2387 libxfs_trans_ijoin(tp
, ip
, 0);
2388 libxfs_trans_ihold(tp
, ip
);
2389 XFS_BMAP_INIT(&flist
, &firstblock
);
2390 bzero(&args
, sizeof(args
));
2393 args
.whichfork
= XFS_DATA_FORK
;
2394 args
.firstblock
= &firstblock
;
2395 args
.flist
= &flist
;
2397 if ((error
= libxfs_dir2_grow_inode(&args
, XFS_DIR2_FREE_SPACE
,
2399 (error
= libxfs_da_get_buf(tp
, ip
, XFS_DIR2_DB_TO_DA(mp
, fbno
),
2400 -1, &fbp
, XFS_DATA_FORK
))) {
2401 do_error(_("can't add free block to directory inode "
2407 bzero(free
, mp
->m_dirblksize
);
2408 INT_SET(free
->hdr
.magic
, ARCH_CONVERT
, XFS_DIR2_FREE_MAGIC
);
2409 INT_SET(free
->hdr
.firstdb
, ARCH_CONVERT
, i
);
2410 INT_SET(free
->hdr
.nvalid
, ARCH_CONVERT
, XFS_DIR2_MAX_FREE_BESTS(mp
));
2411 if (i
+ INT_GET(free
->hdr
.nvalid
, ARCH_CONVERT
) > freetab
->nents
)
2412 INT_SET(free
->hdr
.nvalid
, ARCH_CONVERT
, freetab
->nents
- i
);
2413 for (j
= 0; j
< INT_GET(free
->hdr
.nvalid
, ARCH_CONVERT
); j
++) {
2414 INT_SET(free
->bests
[j
], ARCH_CONVERT
, freetab
->ents
[i
+ j
].v
);
2415 if (INT_GET(free
->bests
[j
], ARCH_CONVERT
) != NULLDATAOFF
)
2416 INT_MOD(free
->hdr
.nused
, ARCH_CONVERT
, +1);
2418 libxfs_da_log_buf(tp
, fbp
, 0, mp
->m_dirblksize
- 1);
2419 libxfs_bmap_finish(&tp
, &flist
, firstblock
, &committed
);
2420 libxfs_trans_commit(tp
, 0, 0);
2425 * Rebuild the entries from a single data block.
2428 longform_dir2_rebuild_data(
2435 xfs_dir2_block_tail_t
*btp
;
2437 xfs_dir2_data_t
*data
;
2439 xfs_dir2_data_entry_t
*dep
;
2440 xfs_dir2_data_unused_t
*dup
;
2443 xfs_dir2_free_t
*fblock
;
2447 xfs_fsblock_t firstblock
;
2448 xfs_bmap_free_t flist
;
2455 if (libxfs_da_read_buf(NULL
, ip
, da_bno
, da_bno
== 0 ? -2 : -1, &bp
,
2457 do_error(_("can't read block %u for directory inode %llu\n"),
2461 if (da_bno
== 0 && bp
== NULL
)
2463 * The block was punched out.
2467 dbno
= XFS_DIR2_DA_TO_DB(mp
, da_bno
);
2468 fdb
= XFS_DIR2_DB_TO_FDB(mp
, dbno
);
2469 if (libxfs_da_read_buf(NULL
, ip
, XFS_DIR2_DB_TO_DA(mp
, fdb
), -1, &fbp
,
2471 do_error(_("can't read block %u for directory inode %llu\n"),
2472 XFS_DIR2_DB_TO_DA(mp
, fdb
), ino
);
2475 data
= malloc(mp
->m_dirblksize
);
2478 _("malloc failed in longform_dir2_rebuild_data (%u bytes)\n"),
2482 bcopy(bp
->data
, data
, mp
->m_dirblksize
);
2483 ptr
= (char *)data
->u
;
2484 if (INT_GET(data
->hdr
.magic
, ARCH_CONVERT
) == XFS_DIR2_BLOCK_MAGIC
) {
2485 btp
= XFS_DIR2_BLOCK_TAIL_P(mp
, (xfs_dir2_block_t
*)data
);
2486 endptr
= (char *)XFS_DIR2_BLOCK_LEAF_P(btp
);
2488 endptr
= (char *)data
+ mp
->m_dirblksize
;
2490 fi
= XFS_DIR2_DB_TO_FDINDEX(mp
, dbno
);
2491 tp
= libxfs_trans_alloc(mp
, 0);
2492 error
= libxfs_trans_reserve(tp
, 0, XFS_CREATE_LOG_RES(mp
), 0,
2493 XFS_TRANS_PERM_LOG_RES
, XFS_CREATE_LOG_COUNT
);
2496 libxfs_trans_ijoin(tp
, ip
, 0);
2497 libxfs_trans_ihold(tp
, ip
);
2498 libxfs_da_bjoin(tp
, bp
);
2499 libxfs_da_bhold(tp
, bp
);
2500 libxfs_da_bjoin(tp
, fbp
);
2501 libxfs_da_bhold(tp
, fbp
);
2502 XFS_BMAP_INIT(&flist
, &firstblock
);
2503 needlog
= needscan
= 0;
2504 bzero(((xfs_dir2_data_t
*)(bp
->data
))->hdr
.bestfree
,
2505 sizeof(data
->hdr
.bestfree
));
2506 libxfs_dir2_data_make_free(tp
, bp
, (xfs_dir2_data_aoff_t
)sizeof(data
->hdr
),
2507 mp
->m_dirblksize
- sizeof(data
->hdr
), &needlog
, &needscan
);
2508 ASSERT(needscan
== 0);
2509 libxfs_dir2_data_log_header(tp
, bp
);
2510 INT_SET(fblock
->bests
[fi
], ARCH_CONVERT
,
2511 INT_GET(((xfs_dir2_data_t
*)(bp
->data
))->hdr
.bestfree
[0].length
, ARCH_CONVERT
));
2512 libxfs_dir2_free_log_bests(tp
, fbp
, fi
, fi
);
2513 libxfs_bmap_finish(&tp
, &flist
, firstblock
, &committed
);
2514 libxfs_trans_commit(tp
, 0, 0);
2516 while (ptr
< endptr
) {
2517 dup
= (xfs_dir2_data_unused_t
*)ptr
;
2518 if (INT_GET(dup
->freetag
, ARCH_CONVERT
) == XFS_DIR2_DATA_FREE_TAG
) {
2519 ptr
+= INT_GET(dup
->length
, ARCH_CONVERT
);
2522 dep
= (xfs_dir2_data_entry_t
*)ptr
;
2523 ptr
+= XFS_DIR2_DATA_ENTSIZE(dep
->namelen
);
2524 if (dep
->name
[0] == '/')
2526 tp
= libxfs_trans_alloc(mp
, 0);
2527 nres
= XFS_CREATE_SPACE_RES(mp
, dep
->namelen
);
2528 error
= libxfs_trans_reserve(tp
, nres
, XFS_CREATE_LOG_RES(mp
), 0,
2529 XFS_TRANS_PERM_LOG_RES
, XFS_CREATE_LOG_COUNT
);
2532 libxfs_trans_ijoin(tp
, ip
, 0);
2533 libxfs_trans_ihold(tp
, ip
);
2534 libxfs_da_bjoin(tp
, bp
);
2535 libxfs_da_bhold(tp
, bp
);
2536 libxfs_da_bjoin(tp
, fbp
);
2537 libxfs_da_bhold(tp
, fbp
);
2538 XFS_BMAP_INIT(&flist
, &firstblock
);
2539 error
= dir_createname(mp
, tp
, ip
, (char *)dep
->name
,
2540 dep
->namelen
, INT_GET(dep
->inumber
, ARCH_CONVERT
),
2541 &firstblock
, &flist
, nres
);
2543 libxfs_bmap_finish(&tp
, &flist
, firstblock
, &committed
);
2544 libxfs_trans_commit(tp
, 0, 0);
2546 libxfs_da_brelse(NULL
, bp
);
2547 libxfs_da_brelse(NULL
, fbp
);
2552 * Finish the rebuild of a directory.
2553 * Stuff / in and then remove it, this forces the directory to end
2554 * up in the right format.
2557 longform_dir2_rebuild_finish(
2564 xfs_fsblock_t firstblock
;
2565 xfs_bmap_free_t flist
;
2569 tp
= libxfs_trans_alloc(mp
, 0);
2570 nres
= XFS_CREATE_SPACE_RES(mp
, 1);
2571 error
= libxfs_trans_reserve(tp
, nres
, XFS_CREATE_LOG_RES(mp
), 0,
2572 XFS_TRANS_PERM_LOG_RES
, XFS_CREATE_LOG_COUNT
);
2575 libxfs_trans_ijoin(tp
, ip
, 0);
2576 libxfs_trans_ihold(tp
, ip
);
2577 XFS_BMAP_INIT(&flist
, &firstblock
);
2578 error
= dir_createname(mp
, tp
, ip
, "/", 1, ino
,
2579 &firstblock
, &flist
, nres
);
2581 libxfs_bmap_finish(&tp
, &flist
, firstblock
, &committed
);
2582 libxfs_trans_commit(tp
, 0, 0);
2584 /* could kill trailing empty data blocks here */
2586 tp
= libxfs_trans_alloc(mp
, 0);
2587 nres
= XFS_REMOVE_SPACE_RES(mp
);
2588 error
= libxfs_trans_reserve(tp
, nres
, XFS_REMOVE_LOG_RES(mp
), 0,
2589 XFS_TRANS_PERM_LOG_RES
, XFS_REMOVE_LOG_COUNT
);
2592 libxfs_trans_ijoin(tp
, ip
, 0);
2593 libxfs_trans_ihold(tp
, ip
);
2594 XFS_BMAP_INIT(&flist
, &firstblock
);
2595 error
= dir_removename(mp
, tp
, ip
, "/", 1, ino
,
2596 &firstblock
, &flist
, nres
);
2598 libxfs_bmap_finish(&tp
, &flist
, firstblock
, &committed
);
2599 libxfs_trans_commit(tp
, 0, 0);
2603 * Rebuild a directory.
2604 * Remove all the non-data blocks.
2605 * Re-initialize to (empty) node form.
2606 * Loop over the data blocks reinserting each entry.
2607 * Force the directory into the right format.
2610 longform_dir2_rebuild(
2620 xfs_fileoff_t next_da_bno
;
2622 do_warn(_("rebuilding directory inode %llu\n"), ino
);
2624 /* kill leaf blocks */
2625 for (da_bno
= mp
->m_dirleafblk
, next_da_bno
= isblock
? NULLFILEOFF
: 0;
2626 next_da_bno
!= NULLFILEOFF
;
2627 da_bno
= (xfs_dablk_t
)next_da_bno
) {
2628 next_da_bno
= da_bno
+ mp
->m_dirblkfsbs
- 1;
2629 if (libxfs_bmap_next_offset(NULL
, ip
, &next_da_bno
, XFS_DATA_FORK
))
2631 if (libxfs_da_get_buf(NULL
, ip
, da_bno
, -1, &bp
, XFS_DATA_FORK
)) {
2632 do_error(_("can't get block %u for directory inode "
2637 dir2_kill_block(mp
, ip
, da_bno
, bp
);
2640 /* rebuild empty btree and freelist */
2641 longform_dir2_rebuild_setup(mp
, ino
, ip
, freetab
);
2643 /* rebuild directory */
2644 for (da_bno
= mp
->m_dirdatablk
, next_da_bno
= 0;
2645 da_bno
< mp
->m_dirleafblk
&& next_da_bno
!= NULLFILEOFF
;
2646 da_bno
= (xfs_dablk_t
)next_da_bno
) {
2647 next_da_bno
= da_bno
+ mp
->m_dirblkfsbs
- 1;
2648 if (libxfs_bmap_next_offset(NULL
, ip
, &next_da_bno
, XFS_DATA_FORK
))
2650 longform_dir2_rebuild_data(mp
, ino
, ip
, da_bno
);
2653 /* put the directory in the appropriate on-disk format */
2654 longform_dir2_rebuild_finish(mp
, ino
, ip
);
2659 * succeeds or dies, inode never gets dirtied since all changes
2660 * happen in file blocks. the inode size and other core info
2661 * is already correct, it's just the leaf entries that get altered.
2662 * XXX above comment is wrong for v2 - need to see why it matters
2665 longform_dir2_entry_check(xfs_mount_t
*mp
,
2671 ino_tree_node_t
*irec
,
2674 xfs_dir2_block_t
*block
;
2675 xfs_dir2_leaf_entry_t
*blp
;
2677 xfs_dir2_block_tail_t
*btp
;
2680 dir_hash_tab_t
*hashtab
;
2684 xfs_fileoff_t next_da_bno
;
2689 freetab
= malloc(FREETAB_SIZE(ip
->i_d
.di_size
/ mp
->m_dirblksize
));
2692 _("malloc failed in longform_dir2_entry_check (%u bytes)\n"),
2693 FREETAB_SIZE(ip
->i_d
.di_size
/ mp
->m_dirblksize
));
2696 freetab
->naents
= ip
->i_d
.di_size
/ mp
->m_dirblksize
;
2698 for (i
= 0; i
< freetab
->naents
; i
++) {
2699 freetab
->ents
[i
].v
= NULLDATAOFF
;
2700 freetab
->ents
[i
].s
= 0;
2702 /* is this a block, leaf, or node directory? */
2703 libxfs_dir2_isblock(NULL
, ip
, &isblock
);
2704 libxfs_dir2_isleaf(NULL
, ip
, &isleaf
);
2706 if (do_prefetch
&& !isblock
)
2707 prefetch_p6_dir2(mp
, ip
);
2709 /* check directory data */
2710 hashtab
= dir_hash_init(ip
->i_d
.di_size
);
2711 for (da_bno
= 0, next_da_bno
= 0;
2712 next_da_bno
!= NULLFILEOFF
&& da_bno
< mp
->m_dirleafblk
;
2713 da_bno
= (xfs_dablk_t
)next_da_bno
) {
2714 next_da_bno
= da_bno
+ mp
->m_dirblkfsbs
- 1;
2715 if (libxfs_bmap_next_offset(NULL
, ip
, &next_da_bno
, XFS_DATA_FORK
))
2717 if (libxfs_da_read_bufr(NULL
, ip
, da_bno
,
2718 da_bno
== 0 ? -2 : -1, &bp
, XFS_DATA_FORK
)) {
2719 do_error(_("can't read block %u for directory inode "
2724 /* is there a hole at the start? */
2725 if (da_bno
== 0 && bp
== NULL
)
2727 longform_dir2_entry_check_data(mp
, ip
, num_illegal
, need_dot
,
2728 stack
, irec
, ino_offset
, &bp
, hashtab
, &freetab
, da_bno
,
2730 /* it releases the buffer unless isblock is set */
2732 fixit
= (*num_illegal
!= 0) || dir2_is_badino(ino
);
2734 /* check btree and freespace */
2738 btp
= XFS_DIR2_BLOCK_TAIL_P(mp
, block
);
2739 blp
= XFS_DIR2_BLOCK_LEAF_P(btp
);
2740 seeval
= dir_hash_see_all(hashtab
, blp
, INT_GET(btp
->count
, ARCH_CONVERT
), INT_GET(btp
->stale
, ARCH_CONVERT
));
2741 if (dir_hash_check(hashtab
, ip
, seeval
))
2743 libxfs_da_brelse(NULL
, bp
);
2744 } else if (isleaf
) {
2745 fixit
|= longform_dir2_check_leaf(mp
, ip
, hashtab
, freetab
);
2747 fixit
|= longform_dir2_check_node(mp
, ip
, hashtab
, freetab
);
2749 dir_hash_done(hashtab
);
2750 if (!no_modify
&& fixit
)
2751 longform_dir2_rebuild(mp
, ino
, ip
, num_illegal
, freetab
,
2757 * shortform directory processing routines -- entry verification and
2758 * bad entry deletion (pruning).
2761 shortform_dir_entry_check(xfs_mount_t
*mp
,
2766 ino_tree_node_t
*current_irec
,
2767 int current_ino_offset
)
2771 xfs_dir_shortform_t
*sf
;
2772 xfs_dir_sf_entry_t
*sf_entry
, *next_sfe
, *tmp_sfe
;
2774 ino_tree_node_t
*irec
;
2784 char fname
[MAXNAMELEN
+ 1];
2787 sf
= (xfs_dir_shortform_t
*) ifp
->if_u1
.if_data
;
2791 max_size
= ifp
->if_bytes
;
2792 ASSERT(ip
->i_d
.di_size
<= ifp
->if_bytes
);
2795 * no '.' entry in shortform dirs, just bump up ref count by 1
2796 * '..' was already (or will be) accounted for and checked when
2797 * the directory is reached or will be taken care of when the
2798 * directory is moved to orphanage.
2800 add_inode_ref(current_irec
, current_ino_offset
);
2803 * now run through entries, stop at first bad entry, don't need
2804 * to skip over '..' since that's encoded in its own field and
2805 * no need to worry about '.' since it doesn't exist.
2807 sf_entry
= next_sfe
= &sf
->list
[0];
2810 do_warn(_("shortform dir inode %llu has null data entries \n"),
2815 for (i
= 0; i
< INT_GET(sf
->hdr
.count
, ARCH_CONVERT
) && max_size
>
2816 (__psint_t
)next_sfe
- (__psint_t
)sf
;
2817 sf_entry
= next_sfe
, i
++) {
2822 XFS_DIR_SF_GET_DIRINO(&sf_entry
->inumber
, &lino
);
2824 namelen
= sf_entry
->namelen
;
2826 ASSERT(no_modify
|| namelen
> 0);
2828 if (no_modify
&& namelen
== 0) {
2830 * if we're really lucky, this is
2831 * the last entry in which case we
2832 * can use the dir size to set the
2833 * namelen value. otherwise, forget
2834 * it because we're not going to be
2835 * able to find the next entry.
2839 if (i
== INT_GET(sf
->hdr
.count
, ARCH_CONVERT
) - 1) {
2840 namelen
= ip
->i_d
.di_size
-
2841 ((__psint_t
) &sf_entry
->name
[0] -
2845 * don't process the rest of the directory,
2846 * break out of processing looop
2850 } else if (no_modify
&& (__psint_t
) sf_entry
- (__psint_t
) sf
+
2851 + XFS_DIR_SF_ENTSIZE_BYENTRY(sf_entry
)
2852 > ip
->i_d
.di_size
) {
2855 if (i
== INT_GET(sf
->hdr
.count
, ARCH_CONVERT
) - 1) {
2856 namelen
= ip
->i_d
.di_size
-
2857 ((__psint_t
) &sf_entry
->name
[0] -
2861 * don't process the rest of the directory,
2862 * break out of processing looop
2868 bcopy(sf_entry
->name
, fname
, sf_entry
->namelen
);
2869 fname
[sf_entry
->namelen
] = '\0';
2871 ASSERT(no_modify
|| lino
!= NULLFSINO
);
2872 ASSERT(no_modify
|| !verify_inum(mp
, lino
));
2875 * special case the "lost+found" entry if it's pointing
2876 * to where we think lost+found should be. if that's
2877 * the case, that's the one we created in phase 6.
2878 * just skip it. no need to process it and its ..
2879 * link is already accounted for. Also skip entries
2880 * with bogus inode numbers if we're in no modify mode.
2883 if ((lino
== orphanage_ino
&& strcmp(fname
, ORPHANAGE
) == 0)
2884 || (no_modify
&& verify_inum(mp
, lino
))) {
2885 next_sfe
= (xfs_dir_sf_entry_t
*)
2886 ((__psint_t
) sf_entry
+
2887 XFS_DIR_SF_ENTSIZE_BYENTRY(sf_entry
));
2891 irec
= find_inode_rec(XFS_INO_TO_AGNO(mp
, lino
),
2892 XFS_INO_TO_AGINO(mp
, lino
));
2894 if (irec
== NULL
&& no_modify
) {
2896 _("entry \"%s\" in shortform dir %llu references non-existent ino %llu\n"),
2898 do_warn(_("would junk entry\n"));
2902 ASSERT(irec
!= NULL
);
2904 ino_offset
= XFS_INO_TO_AGINO(mp
, lino
) - irec
->ino_startnum
;
2907 * if it's a free inode, blow out the entry.
2908 * by now, any inode that we think is free
2911 if (is_inode_free(irec
, ino_offset
)) {
2913 * don't complain if this entry points to the old
2914 * and now-free lost+found inode
2916 if (verbose
|| no_modify
|| lino
!= old_orphanage_ino
)
2918 _("entry \"%s\" in shortform dir inode %llu points to free inode %llu\n"),
2924 do_warn(_("would junk entry \"%s\"\n"),
2927 } else if (!inode_isadir(irec
, ino_offset
)) {
2929 * check easy case first, regular inode, just bump
2930 * the link count and continue
2932 add_inode_reached(irec
, ino_offset
);
2934 next_sfe
= (xfs_dir_sf_entry_t
*)
2935 ((__psint_t
) sf_entry
+
2936 XFS_DIR_SF_ENTSIZE_BYENTRY(sf_entry
));
2939 parent
= get_inode_parent(irec
, ino_offset
);
2942 * bump up the link counts in parent and child.
2943 * directory but if the link doesn't agree with
2944 * the .. in the child, blow out the entry
2946 if (is_inode_reached(irec
, ino_offset
)) {
2949 _("entry \"%s\" in dir %llu references already connected dir ino %llu,\n"),
2951 } else if (parent
== ino
) {
2952 add_inode_reached(irec
, ino_offset
);
2953 add_inode_ref(current_irec
, current_ino_offset
);
2955 if (!is_inode_refchecked(lino
, irec
,
2957 push_dir(stack
, lino
);
2961 _("entry \"%s\" in dir %llu not consistent with .. value (%llu) in dir ino %llu,\n"),
2962 fname
, ino
, parent
, lino
);
2968 tmp_elen
= XFS_DIR_SF_ENTSIZE_BYENTRY(sf_entry
);
2969 tmp_sfe
= (xfs_dir_sf_entry_t
*)
2970 ((__psint_t
) sf_entry
+ tmp_elen
);
2971 tmp_len
= max_size
- ((__psint_t
) tmp_sfe
2973 max_size
-= tmp_elen
;
2974 bytes_deleted
+= tmp_elen
;
2976 memmove(sf_entry
, tmp_sfe
, tmp_len
);
2978 INT_MOD(sf
->hdr
.count
, ARCH_CONVERT
, -1);
2979 bzero((void *) ((__psint_t
) sf_entry
+ tmp_len
),
2983 * set the tmp value to the current
2984 * pointer so we'll process the entry
2990 * WARNING: drop the index i by one
2991 * so it matches the decremented count for
2992 * accurate comparisons in the loop test
2998 if (verbose
|| lino
!= old_orphanage_ino
)
3000 _("junking entry \"%s\" in directory inode %llu\n"),
3003 do_warn(_("would junk entry \"%s\"\n"), fname
);
3008 * go onto next entry unless we've just junked an
3009 * entry in which the current entry pointer points
3010 * to an unprocessed entry. have to take into entries
3011 * with bad namelen into account in no modify mode since we
3012 * calculate size based on next_sfe.
3014 ASSERT(no_modify
|| bad_sfnamelen
== 0);
3016 next_sfe
= (tmp_sfe
== NULL
)
3017 ? (xfs_dir_sf_entry_t
*) ((__psint_t
) sf_entry
3019 ? XFS_DIR_SF_ENTSIZE_BYENTRY(sf_entry
)
3020 : sizeof(xfs_dir_sf_entry_t
) - 1
3027 * sync up sizes if required
3030 ASSERT(bytes_deleted
> 0);
3032 libxfs_idata_realloc(ip
, -bytes_deleted
, XFS_DATA_FORK
);
3033 ip
->i_d
.di_size
-= bytes_deleted
;
3036 if (ip
->i_d
.di_size
!= ip
->i_df
.if_bytes
) {
3037 ASSERT(ip
->i_df
.if_bytes
== (xfs_fsize_t
)
3038 ((__psint_t
) next_sfe
- (__psint_t
) sf
));
3039 ip
->i_d
.di_size
= (xfs_fsize_t
)
3040 ((__psint_t
) next_sfe
- (__psint_t
) sf
);
3042 _("setting size to %lld bytes to reflect junked entries\n"),
3050 prune_sf_dir_entry(xfs_mount_t
*mp
, xfs_ino_t ino
, xfs_inode_t
*ip
)
3054 xfs_dir_shortform_t
*sf
;
3055 xfs_dir_sf_entry_t
*sf_entry
, *next_sfe
, *tmp_sfe
;
3062 char fname
[MAXNAMELEN
+ 1];
3065 sf
= (xfs_dir_shortform_t
*) ifp
->if_u1
.if_data
;
3068 max_size
= ifp
->if_bytes
;
3069 ASSERT(ip
->i_d
.di_size
<= ifp
->if_bytes
);
3072 * now run through entries and delete every bad entry
3074 sf_entry
= next_sfe
= &sf
->list
[0];
3076 for (i
= 0; i
< INT_GET(sf
->hdr
.count
, ARCH_CONVERT
) && max_size
>
3077 (__psint_t
)next_sfe
- (__psint_t
)sf
;
3078 sf_entry
= next_sfe
, i
++) {
3081 XFS_DIR_SF_GET_DIRINO(&sf_entry
->inumber
, &lino
);
3083 bcopy(sf_entry
->name
, fname
, sf_entry
->namelen
);
3084 fname
[sf_entry
->namelen
] = '\0';
3086 if (sf_entry
->name
[0] == '/') {
3088 tmp_elen
= XFS_DIR_SF_ENTSIZE_BYENTRY(sf_entry
);
3089 tmp_sfe
= (xfs_dir_sf_entry_t
*)
3090 ((__psint_t
) sf_entry
+ tmp_elen
);
3091 tmp_len
= max_size
- ((__psint_t
) tmp_sfe
3093 max_size
-= tmp_elen
;
3094 bytes_deleted
+= tmp_elen
;
3096 memmove(sf_entry
, tmp_sfe
, tmp_len
);
3098 INT_MOD(sf
->hdr
.count
, ARCH_CONVERT
, -1);
3099 bzero((void *) ((__psint_t
) sf_entry
+ tmp_len
),
3103 * set the tmp value to the current
3104 * pointer so we'll process the entry
3110 * WARNING: drop the index i by one
3111 * so it matches the decremented count for
3112 * accurate comparisons in the loop test
3117 next_sfe
= (tmp_sfe
== NULL
)
3118 ? (xfs_dir_sf_entry_t
*) ((__psint_t
) sf_entry
+
3119 XFS_DIR_SF_ENTSIZE_BYENTRY(sf_entry
))
3124 * sync up sizes if required
3126 if (bytes_deleted
> 0) {
3127 libxfs_idata_realloc(ip
, -bytes_deleted
, XFS_DATA_FORK
);
3128 ip
->i_d
.di_size
-= bytes_deleted
;
3131 if (ip
->i_d
.di_size
!= ip
->i_df
.if_bytes
) {
3132 ASSERT(ip
->i_df
.if_bytes
== (xfs_fsize_t
)
3133 ((__psint_t
) next_sfe
- (__psint_t
) sf
));
3134 ip
->i_d
.di_size
= (xfs_fsize_t
)
3135 ((__psint_t
) next_sfe
- (__psint_t
) sf
);
3137 _("setting size to %lld bytes to reflect junked entries\n"),
3143 * shortform directory v2 processing routines -- entry verification and
3144 * bad entry deletion (pruning).
3147 shortform_dir2_entry_check(xfs_mount_t
*mp
,
3152 ino_tree_node_t
*current_irec
,
3153 int current_ino_offset
)
3158 xfs_dir2_sf_entry_t
*sfep
, *next_sfep
, *tmp_sfep
;
3160 ino_tree_node_t
*irec
;
3170 char fname
[MAXNAMELEN
+ 1];
3174 sfp
= (xfs_dir2_sf_t
*) ifp
->if_u1
.if_data
;
3178 max_size
= ifp
->if_bytes
;
3179 ASSERT(ip
->i_d
.di_size
<= ifp
->if_bytes
);
3182 * no '.' entry in shortform dirs, just bump up ref count by 1
3183 * '..' was already (or will be) accounted for and checked when
3184 * the directory is reached or will be taken care of when the
3185 * directory is moved to orphanage.
3187 add_inode_ref(current_irec
, current_ino_offset
);
3190 * Initialise i8 counter -- the parent inode number counts as well.
3192 i8
= (XFS_DIR2_SF_GET_INUMBER(sfp
, &sfp
->hdr
.parent
) > XFS_DIR2_MAX_SHORT_INUM
);
3195 * now run through entries, stop at first bad entry, don't need
3196 * to skip over '..' since that's encoded in its own field and
3197 * no need to worry about '.' since it doesn't exist.
3199 sfep
= next_sfep
= XFS_DIR2_SF_FIRSTENTRY(sfp
);
3201 for (i
= 0; i
< INT_GET(sfp
->hdr
.count
, ARCH_CONVERT
) && max_size
>
3202 (__psint_t
)next_sfep
- (__psint_t
)sfp
;
3203 sfep
= next_sfep
, i
++) {
3208 lino
= XFS_DIR2_SF_GET_INUMBER(sfp
, XFS_DIR2_SF_INUMBERP(sfep
));
3210 namelen
= sfep
->namelen
;
3212 ASSERT(no_modify
|| namelen
> 0);
3214 if (no_modify
&& namelen
== 0) {
3216 * if we're really lucky, this is
3217 * the last entry in which case we
3218 * can use the dir size to set the
3219 * namelen value. otherwise, forget
3220 * it because we're not going to be
3221 * able to find the next entry.
3225 if (i
== INT_GET(sfp
->hdr
.count
, ARCH_CONVERT
) - 1) {
3226 namelen
= ip
->i_d
.di_size
-
3227 ((__psint_t
) &sfep
->name
[0] -
3231 * don't process the rest of the directory,
3232 * break out of processing loop
3236 } else if (no_modify
&& (__psint_t
) sfep
- (__psint_t
) sfp
+
3237 + XFS_DIR2_SF_ENTSIZE_BYENTRY(sfp
, sfep
)
3238 > ip
->i_d
.di_size
) {
3241 if (i
== INT_GET(sfp
->hdr
.count
, ARCH_CONVERT
) - 1) {
3242 namelen
= ip
->i_d
.di_size
-
3243 ((__psint_t
) &sfep
->name
[0] -
3247 * don't process the rest of the directory,
3248 * break out of processing loop
3254 bcopy(sfep
->name
, fname
, sfep
->namelen
);
3255 fname
[sfep
->namelen
] = '\0';
3257 ASSERT(no_modify
|| (lino
!= NULLFSINO
&& lino
!= 0));
3258 ASSERT(no_modify
|| !verify_inum(mp
, lino
));
3261 * special case the "lost+found" entry if it's pointing
3262 * to where we think lost+found should be. if that's
3263 * the case, that's the one we created in phase 6.
3264 * just skip it. no need to process it and its ..
3265 * link is already accounted for.
3268 if (lino
== orphanage_ino
&& strcmp(fname
, ORPHANAGE
) == 0) {
3269 if (lino
> XFS_DIR2_MAX_SHORT_INUM
)
3271 next_sfep
= (xfs_dir2_sf_entry_t
*)
3273 XFS_DIR2_SF_ENTSIZE_BYENTRY(sfp
, sfep
));
3278 * Also skip entries with bogus inode numbers if we're
3279 * in no modify mode.
3282 if (no_modify
&& verify_inum(mp
, lino
)) {
3283 next_sfep
= (xfs_dir2_sf_entry_t
*)
3285 XFS_DIR2_SF_ENTSIZE_BYENTRY(sfp
, sfep
));
3289 irec
= find_inode_rec(XFS_INO_TO_AGNO(mp
, lino
),
3290 XFS_INO_TO_AGINO(mp
, lino
));
3292 if (irec
== NULL
&& no_modify
) {
3293 do_warn(_("entry \"%s\" in shortform directory %llu "
3294 "references non-existent inode %llu\n"),
3296 do_warn(_("would junk entry\n"));
3300 ASSERT(irec
!= NULL
);
3302 ino_offset
= XFS_INO_TO_AGINO(mp
, lino
) - irec
->ino_startnum
;
3305 * if it's a free inode, blow out the entry.
3306 * by now, any inode that we think is free
3309 if (is_inode_free(irec
, ino_offset
)) {
3311 * don't complain if this entry points to the old
3312 * and now-free lost+found inode
3314 if (verbose
|| no_modify
|| lino
!= old_orphanage_ino
)
3315 do_warn(_("entry \"%s\" in shortform directory "
3316 "inode %llu points to free inode "
3323 do_warn(_("would junk entry \"%s\"\n"),
3326 } else if (!inode_isadir(irec
, ino_offset
)) {
3328 * check easy case first, regular inode, just bump
3331 add_inode_reached(irec
, ino_offset
);
3333 parent
= get_inode_parent(irec
, ino_offset
);
3336 * bump up the link counts in parent and child.
3337 * directory but if the link doesn't agree with
3338 * the .. in the child, blow out the entry
3340 if (is_inode_reached(irec
, ino_offset
)) {
3342 do_warn(_("entry \"%s\" in directory inode %llu"
3343 " references already connected inode "
3346 } else if (parent
== ino
) {
3347 add_inode_reached(irec
, ino_offset
);
3348 add_inode_ref(current_irec
, current_ino_offset
);
3350 if (!is_inode_refchecked(lino
, irec
,
3352 push_dir(stack
, lino
);
3355 do_warn(_("entry \"%s\" in directory inode %llu"
3356 " not consistent with .. value (%llu)"
3357 " in inode %llu,\n"),
3358 fname
, ino
, parent
, lino
);
3364 tmp_elen
= XFS_DIR2_SF_ENTSIZE_BYENTRY(sfp
, sfep
);
3365 tmp_sfep
= (xfs_dir2_sf_entry_t
*)
3366 ((__psint_t
) sfep
+ tmp_elen
);
3367 tmp_len
= max_size
- ((__psint_t
) tmp_sfep
3369 max_size
-= tmp_elen
;
3370 bytes_deleted
+= tmp_elen
;
3372 memmove(sfep
, tmp_sfep
, tmp_len
);
3374 INT_MOD(sfp
->hdr
.count
, ARCH_CONVERT
, -1);
3375 bzero((void *) ((__psint_t
) sfep
+ tmp_len
),
3379 * set the tmp value to the current
3380 * pointer so we'll process the entry
3386 * WARNING: drop the index i by one
3387 * so it matches the decremented count for
3388 * accurate comparisons in the loop test
3394 if (verbose
|| lino
!= old_orphanage_ino
)
3395 do_warn(_("junking entry \"%s\" in "
3396 "directory inode %llu\n"),
3399 do_warn(_("would junk entry \"%s\"\n"), fname
);
3401 } else if (lino
> XFS_DIR2_MAX_SHORT_INUM
)
3405 * go onto next entry unless we've just junked an
3406 * entry in which the current entry pointer points
3407 * to an unprocessed entry. have to take into entries
3408 * with bad namelen into account in no modify mode since we
3409 * calculate size based on next_sfep.
3411 ASSERT(no_modify
|| bad_sfnamelen
== 0);
3413 next_sfep
= (tmp_sfep
== NULL
)
3414 ? (xfs_dir2_sf_entry_t
*) ((__psint_t
) sfep
3416 ? XFS_DIR2_SF_ENTSIZE_BYENTRY(sfp
, sfep
)
3417 : XFS_DIR2_SF_ENTSIZE_BYNAME(sfp
, namelen
)))
3421 if (sfp
->hdr
.i8count
!= i8
) {
3423 do_warn(_("would fix i8count in inode %llu\n"), ino
);
3426 tmp_sfep
= next_sfep
;
3427 process_sf_dir2_fixi8(sfp
, &tmp_sfep
);
3429 (__psint_t
)next_sfep
-
3430 (__psint_t
)tmp_sfep
;
3431 next_sfep
= tmp_sfep
;
3433 sfp
->hdr
.i8count
= i8
;
3435 do_warn(_("fixing i8count in inode %llu\n"), ino
);
3440 * sync up sizes if required
3443 ASSERT(bytes_deleted
> 0);
3445 libxfs_idata_realloc(ip
, -bytes_deleted
, XFS_DATA_FORK
);
3446 ip
->i_d
.di_size
-= bytes_deleted
;
3449 if (ip
->i_d
.di_size
!= ip
->i_df
.if_bytes
) {
3450 ASSERT(ip
->i_df
.if_bytes
== (xfs_fsize_t
)
3451 ((__psint_t
) next_sfep
- (__psint_t
) sfp
));
3452 ip
->i_d
.di_size
= (xfs_fsize_t
)
3453 ((__psint_t
) next_sfep
- (__psint_t
) sfp
);
3454 do_warn(_("setting size to %lld bytes to reflect junked "
3462 * processes all directories reachable via the inodes on the stack
3463 * returns 0 if things are good, 1 if there's a problem
3466 process_dirstack(xfs_mount_t
*mp
, dir_stack_t
*stack
)
3468 xfs_bmap_free_t flist
;
3469 xfs_fsblock_t first
;
3473 xfs_dahash_t hashval
;
3474 ino_tree_node_t
*irec
;
3475 int ino_offset
, need_dot
, committed
;
3476 int dirty
, num_illegal
, error
, nres
;
3479 * pull directory inode # off directory stack
3481 * open up directory inode, check all entries,
3482 * then call prune_dir_entries to remove all
3483 * remaining illegal directory entries.
3486 while ((ino
= pop_dir(stack
)) != NULLFSINO
) {
3487 irec
= find_inode_rec(XFS_INO_TO_AGNO(mp
, ino
),
3488 XFS_INO_TO_AGINO(mp
, ino
));
3489 ASSERT(irec
!= NULL
);
3491 ino_offset
= XFS_INO_TO_AGINO(mp
, ino
) - irec
->ino_startnum
;
3493 ASSERT(!is_inode_refchecked(ino
, irec
, ino_offset
));
3495 if ((error
= libxfs_iget(mp
, NULL
, ino
, 0, &ip
, 0))) {
3498 _("couldn't map inode %llu, err = %d\n"),
3502 _("couldn't map inode %llu, err = %d\n"),
3505 * see below for what we're doing if this
3506 * is root. Why do we need to do this here?
3507 * to ensure that the root doesn't show up
3508 * as being disconnected in the no_modify case.
3510 if (mp
->m_sb
.sb_rootino
== ino
) {
3511 add_inode_reached(irec
, 0);
3512 add_inode_ref(irec
, 0);
3516 add_inode_refchecked(ino
, irec
, 0);
3520 need_dot
= dirty
= num_illegal
= 0;
3522 if (mp
->m_sb
.sb_rootino
== ino
) {
3524 * mark root inode reached and bump up
3525 * link count for root inode to account
3526 * for '..' entry since the root inode is
3527 * never reached by a parent. we know
3528 * that root's '..' is always good --
3529 * guaranteed by phase 3 and/or below.
3531 add_inode_reached(irec
, ino_offset
);
3533 * account for link for the orphanage
3534 * "lost+found". if we're running in
3535 * modify mode and it already existed,
3536 * we deleted it so it's '..' reference
3537 * never got counted. so add it here if
3538 * we're going to create lost+found.
3540 * if we're running in no_modify mode,
3541 * we never deleted lost+found and we're
3542 * not going to create it so do nothing.
3544 * either way, the counts will match when
3545 * we look at the root inode's nlinks
3546 * field and compare that to our incore
3550 add_inode_ref(irec
, ino_offset
);
3553 add_inode_refchecked(ino
, irec
, ino_offset
);
3556 * look for bogus entries
3558 switch (ip
->i_d
.di_format
) {
3559 case XFS_DINODE_FMT_EXTENTS
:
3560 case XFS_DINODE_FMT_BTREE
:
3562 * also check for missing '.' in longform dirs.
3563 * missing .. entries are added if required when
3564 * the directory is connected to lost+found. but
3565 * we need to create '.' entries here.
3567 if (XFS_SB_VERSION_HASDIRV2(&mp
->m_sb
))
3568 longform_dir2_entry_check(mp
, ino
, ip
,
3569 &num_illegal
, &need_dot
,
3573 longform_dir_entry_check(mp
, ino
, ip
,
3574 &num_illegal
, &need_dot
,
3578 case XFS_DINODE_FMT_LOCAL
:
3579 tp
= libxfs_trans_alloc(mp
, 0);
3581 * using the remove reservation is overkill
3582 * since at most we'll only need to log the
3583 * inode but it's easier than wedging a
3584 * new define in ourselves.
3586 nres
= no_modify
? 0 : XFS_REMOVE_SPACE_RES(mp
);
3587 error
= libxfs_trans_reserve(tp
, nres
,
3588 XFS_REMOVE_LOG_RES(mp
), 0,
3589 XFS_TRANS_PERM_LOG_RES
,
3590 XFS_REMOVE_LOG_COUNT
);
3594 libxfs_trans_ijoin(tp
, ip
, 0);
3595 libxfs_trans_ihold(tp
, ip
);
3597 if (XFS_SB_VERSION_HASDIRV2(&mp
->m_sb
))
3598 shortform_dir2_entry_check(mp
, ino
, ip
, &dirty
,
3602 shortform_dir_entry_check(mp
, ino
, ip
, &dirty
,
3606 ASSERT(dirty
== 0 || (dirty
&& !no_modify
));
3608 libxfs_trans_log_inode(tp
, ip
,
3609 XFS_ILOG_CORE
| XFS_ILOG_DDATA
);
3610 libxfs_trans_commit(tp
, XFS_TRANS_RELEASE_LOG_RES
3611 |XFS_TRANS_SYNC
, 0);
3613 libxfs_trans_cancel(tp
, XFS_TRANS_RELEASE_LOG_RES
);
3622 if (!no_modify
&& !orphanage_entered
&&
3623 ino
== mp
->m_sb
.sb_rootino
) {
3624 do_warn(_("re-entering %s into root directory\n"),
3626 tp
= libxfs_trans_alloc(mp
, 0);
3627 nres
= XFS_MKDIR_SPACE_RES(mp
, strlen(ORPHANAGE
));
3628 error
= libxfs_trans_reserve(tp
, nres
,
3629 XFS_MKDIR_LOG_RES(mp
), 0,
3630 XFS_TRANS_PERM_LOG_RES
,
3631 XFS_MKDIR_LOG_COUNT
);
3634 libxfs_trans_ijoin(tp
, ip
, 0);
3635 libxfs_trans_ihold(tp
, ip
);
3636 XFS_BMAP_INIT(&flist
, &first
);
3637 if ((error
= dir_createname(mp
, tp
, ip
, ORPHANAGE
,
3639 orphanage_ino
, &first
, &flist
,
3641 do_error(_("can't make %s entry in root inode "
3642 "%llu, createname error %d\n"),
3643 ORPHANAGE
, ino
, error
);
3644 libxfs_trans_log_inode(tp
, ip
, XFS_ILOG_CORE
);
3645 error
= libxfs_bmap_finish(&tp
, &flist
, first
, &committed
);
3647 libxfs_trans_commit(tp
,
3648 XFS_TRANS_RELEASE_LOG_RES
| XFS_TRANS_SYNC
, 0);
3649 orphanage_entered
= 1;
3653 * if we have to create a .. for /, do it now *before*
3654 * we delete the bogus entries, otherwise the directory
3655 * could transform into a shortform dir which would
3656 * probably cause the simulation to choke. Even
3657 * if the illegal entries get shifted around, it's ok
3658 * because the entries are structurally intact and in
3659 * in hash-value order so the simulation won't get confused
3660 * if it has to move them around.
3662 if (!no_modify
&& need_root_dotdot
&&
3663 ino
== mp
->m_sb
.sb_rootino
) {
3664 ASSERT(ip
->i_d
.di_format
!= XFS_DINODE_FMT_LOCAL
);
3666 do_warn(_("recreating root directory .. entry\n"));
3668 tp
= libxfs_trans_alloc(mp
, 0);
3671 nres
= XFS_MKDIR_SPACE_RES(mp
, 2);
3672 error
= libxfs_trans_reserve(tp
, nres
,
3673 XFS_MKDIR_LOG_RES(mp
),
3675 XFS_TRANS_PERM_LOG_RES
,
3676 XFS_MKDIR_LOG_COUNT
);
3681 libxfs_trans_ijoin(tp
, ip
, 0);
3682 libxfs_trans_ihold(tp
, ip
);
3684 XFS_BMAP_INIT(&flist
, &first
);
3686 if ((error
= dir_createname(mp
, tp
, ip
, "..", 2,
3687 ip
->i_ino
, &first
, &flist
, nres
)))
3689 _("can't make \"..\" entry in root inode %llu, createname error %d\n"),
3692 libxfs_trans_log_inode(tp
, ip
, XFS_ILOG_CORE
);
3694 error
= libxfs_bmap_finish(&tp
, &flist
, first
,
3697 libxfs_trans_commit(tp
, XFS_TRANS_RELEASE_LOG_RES
3698 |XFS_TRANS_SYNC
, 0);
3700 need_root_dotdot
= 0;
3701 } else if (need_root_dotdot
&& ino
== mp
->m_sb
.sb_rootino
) {
3702 do_warn(_("would recreate root directory .. entry\n"));
3706 * delete any illegal entries -- which should only exist
3707 * if the directory is a longform directory. bogus
3708 * shortform directory entries were deleted in phase 4.
3710 if (!no_modify
&& num_illegal
> 0) {
3711 ASSERT(ip
->i_d
.di_format
!= XFS_DINODE_FMT_LOCAL
);
3712 ASSERT(!XFS_SB_VERSION_HASDIRV2(&mp
->m_sb
));
3714 while (num_illegal
> 0 && ip
->i_d
.di_format
!=
3715 XFS_DINODE_FMT_LOCAL
) {
3716 prune_lf_dir_entry(mp
, ino
, ip
, &hashval
);
3721 * handle case where we've deleted so many
3722 * entries that the directory has changed from
3723 * a longform to a shortform directory. have
3724 * to allocate a transaction since we're working
3725 * with the incore data fork.
3727 if (num_illegal
> 0) {
3728 ASSERT(ip
->i_d
.di_format
==
3729 XFS_DINODE_FMT_LOCAL
);
3730 tp
= libxfs_trans_alloc(mp
, 0);
3732 * using the remove reservation is overkill
3733 * since at most we'll only need to log the
3734 * inode but it's easier than wedging a
3735 * new define in ourselves. 10 block fs
3736 * space reservation is also overkill but
3739 nres
= XFS_REMOVE_SPACE_RES(mp
);
3740 error
= libxfs_trans_reserve(tp
, nres
,
3741 XFS_REMOVE_LOG_RES(mp
), 0,
3742 XFS_TRANS_PERM_LOG_RES
,
3743 XFS_REMOVE_LOG_COUNT
);
3747 libxfs_trans_ijoin(tp
, ip
, 0);
3748 libxfs_trans_ihold(tp
, ip
);
3750 prune_sf_dir_entry(mp
, ino
, ip
);
3752 libxfs_trans_log_inode(tp
, ip
,
3753 XFS_ILOG_CORE
| XFS_ILOG_DDATA
);
3755 libxfs_trans_commit(tp
, XFS_TRANS_RELEASE_LOG_RES
3756 |XFS_TRANS_SYNC
, 0);
3761 * if we need to create the '.' entry, do so only if
3762 * the directory is a longform dir. it it's been
3763 * turned into a shortform dir, then the inode is ok
3764 * since shortform dirs have no '.' entry and the inode
3765 * has already been committed by prune_lf_dir_entry().
3769 * bump up our link count but don't
3770 * bump up the inode link count. chances
3771 * are good that even though we lost '.'
3772 * the inode link counts reflect '.' so
3773 * leave the inode link count alone and if
3774 * it turns out to be wrong, we'll catch
3777 add_inode_ref(irec
, ino_offset
);
3781 _("would create missing \".\" entry in dir ino %llu\n"),
3783 } else if (ip
->i_d
.di_format
!= XFS_DINODE_FMT_LOCAL
) {
3785 * need to create . entry in longform dir.
3788 _("creating missing \".\" entry in dir ino %llu\n"),
3791 tp
= libxfs_trans_alloc(mp
, 0);
3794 nres
= XFS_MKDIR_SPACE_RES(mp
, 1);
3795 error
= libxfs_trans_reserve(tp
, nres
,
3796 XFS_MKDIR_LOG_RES(mp
),
3798 XFS_TRANS_PERM_LOG_RES
,
3799 XFS_MKDIR_LOG_COUNT
);
3804 libxfs_trans_ijoin(tp
, ip
, 0);
3805 libxfs_trans_ihold(tp
, ip
);
3807 XFS_BMAP_INIT(&flist
, &first
);
3809 if ((error
= dir_createname(mp
, tp
, ip
, ".",
3810 1, ip
->i_ino
, &first
, &flist
,
3813 _("can't make \".\" entry in dir ino %llu, createname error %d\n"),
3816 libxfs_trans_log_inode(tp
, ip
, XFS_ILOG_CORE
);
3818 error
= libxfs_bmap_finish(&tp
, &flist
, first
,
3821 libxfs_trans_commit(tp
, XFS_TRANS_RELEASE_LOG_RES
3822 |XFS_TRANS_SYNC
, 0);
3831 * mark realtime bitmap and summary inodes as reached.
3832 * quota inode will be marked here as well
3835 mark_standalone_inodes(xfs_mount_t
*mp
)
3837 ino_tree_node_t
*irec
;
3840 irec
= find_inode_rec(XFS_INO_TO_AGNO(mp
, mp
->m_sb
.sb_rbmino
),
3841 XFS_INO_TO_AGINO(mp
, mp
->m_sb
.sb_rbmino
));
3843 ASSERT(irec
!= NULL
);
3845 offset
= XFS_INO_TO_AGINO(mp
, mp
->m_sb
.sb_rbmino
) -
3848 add_inode_reached(irec
, offset
);
3850 irec
= find_inode_rec(XFS_INO_TO_AGNO(mp
, mp
->m_sb
.sb_rsumino
),
3851 XFS_INO_TO_AGINO(mp
, mp
->m_sb
.sb_rsumino
));
3853 offset
= XFS_INO_TO_AGINO(mp
, mp
->m_sb
.sb_rsumino
) -
3856 ASSERT(irec
!= NULL
);
3858 add_inode_reached(irec
, offset
);
3861 if (mp
->m_sb
.sb_uquotino
3862 && mp
->m_sb
.sb_uquotino
!= NULLFSINO
) {
3863 irec
= find_inode_rec(XFS_INO_TO_AGNO(mp
,
3864 mp
->m_sb
.sb_uquotino
),
3865 XFS_INO_TO_AGINO(mp
, mp
->m_sb
.sb_uquotino
));
3866 offset
= XFS_INO_TO_AGINO(mp
, mp
->m_sb
.sb_uquotino
)
3867 - irec
->ino_startnum
;
3868 add_inode_reached(irec
, offset
);
3870 if (mp
->m_sb
.sb_gquotino
3871 && mp
->m_sb
.sb_gquotino
!= NULLFSINO
) {
3872 irec
= find_inode_rec(XFS_INO_TO_AGNO(mp
,
3873 mp
->m_sb
.sb_gquotino
),
3874 XFS_INO_TO_AGINO(mp
, mp
->m_sb
.sb_gquotino
));
3875 offset
= XFS_INO_TO_AGINO(mp
, mp
->m_sb
.sb_gquotino
)
3876 - irec
->ino_startnum
;
3877 add_inode_reached(irec
, offset
);
3883 phase6(xfs_mount_t
*mp
)
3886 ino_tree_node_t
*irec
;
3891 bzero(&zerocr
, sizeof(struct cred
));
3892 bzero(&zerofsx
, sizeof(struct fsxattr
));
3894 do_log(_("Phase 6 - check inode connectivity...\n"));
3897 teardown_bmap_finish(mp
);
3901 incore_ext_teardown(mp
);
3903 add_ino_backptrs(mp
);
3906 * verify existence of root directory - if we have to
3907 * make one, it's ok for the incore data structs not to
3908 * know about it since everything about it (and the other
3909 * inodes in its chunk if a new chunk was created) are ok
3911 if (need_root_inode
) {
3913 do_warn(_("reinitializing root directory\n"));
3915 need_root_inode
= 0;
3916 need_root_dotdot
= 0;
3918 do_warn(_("would reinitialize root directory\n"));
3924 do_warn(_("reinitializing realtime bitmap inode\n"));
3928 do_warn(_("would reinitialize realtime bitmap inode\n"));
3934 do_warn(_("reinitializing realtime summary inode\n"));
3938 do_warn(_("would reinitialize realtime summary inode\n"));
3944 _(" - resetting contents of realtime bitmap and summary inodes\n"));
3945 if (fill_rbmino(mp
)) {
3947 _("Warning: realtime bitmap may be inconsistent\n"));
3950 if (fill_rsumino(mp
)) {
3952 _("Warning: realtime bitmap may be inconsistent\n"));
3957 * make orphanage (it's guaranteed to not exist now)
3960 do_log(_(" - ensuring existence of %s directory\n"),
3962 orphanage_ino
= mk_orphanage(mp
);
3965 dir_stack_init(&stack
);
3967 mark_standalone_inodes(mp
);
3970 * push root dir on stack, then go
3972 if (!need_root_inode
) {
3973 do_log(_(" - traversing filesystem starting at / ... \n"));
3975 push_dir(&stack
, mp
->m_sb
.sb_rootino
);
3976 process_dirstack(mp
, &stack
);
3978 do_log(_(" - traversal finished ... \n"));
3980 ASSERT(no_modify
!= 0);
3983 _(" - root inode lost, cannot make new one in no modify mode ... \n"));
3985 _(" - skipping filesystem traversal from / ... \n"));
3988 do_log(_(" - traversing all unattached subtrees ... \n"));
3990 irec
= find_inode_rec(XFS_INO_TO_AGNO(mp
, mp
->m_sb
.sb_rootino
),
3991 XFS_INO_TO_AGINO(mp
, mp
->m_sb
.sb_rootino
));
3994 * we always have a root inode, even if it's free...
3995 * if the root is free, forget it, lost+found is already gone
3997 if (is_inode_free(irec
, 0) || !inode_isadir(irec
, 0)) {
3998 need_root_inode
= 1;
4002 * then process all unreached inodes
4003 * by walking incore inode tree
4005 * get next unreached directory inode # from
4007 * push inode on dir stack
4008 * call process_dirstack
4010 for (i
= 0; i
< glob_agcount
; i
++) {
4011 irec
= findfirst_inode_rec(i
);
4016 while (irec
!= NULL
) {
4017 for (j
= 0; j
< XFS_INODES_PER_CHUNK
; j
++) {
4018 if (!is_inode_confirmed(irec
, j
))
4021 * skip directories that have already been
4022 * processed, even if they haven't been
4023 * reached. If they are reachable, we'll
4024 * pick them up when we process their parent.
4026 ino
= XFS_AGINO_TO_INO(mp
, i
,
4027 j
+ irec
->ino_startnum
);
4028 if (inode_isadir(irec
, j
) &&
4029 !is_inode_refchecked(ino
,
4031 push_dir(&stack
, ino
);
4032 process_dirstack(mp
, &stack
);
4035 irec
= next_ino_rec(irec
);
4039 do_log(_(" - traversals finished ... \n"));
4040 do_log(_(" - moving disconnected inodes to lost+found ... \n"));
4043 * move all disconnected inodes to the orphanage
4045 for (i
= 0; i
< glob_agcount
; i
++) {
4046 irec
= findfirst_inode_rec(i
);
4051 while (irec
!= NULL
) {
4052 for (j
= 0; j
< XFS_INODES_PER_CHUNK
; j
++) {
4053 ASSERT(is_inode_confirmed(irec
, j
));
4054 if (is_inode_free(irec
, j
))
4056 if (!is_inode_reached(irec
, j
)) {
4057 ASSERT(inode_isadir(irec
, j
) ||
4058 num_inode_references(irec
, j
)
4060 ino
= XFS_AGINO_TO_INO(mp
, i
,
4061 j
+ irec
->ino_startnum
);
4062 if (inode_isadir(irec
, j
))
4064 _("disconnected dir inode %llu, "),
4068 _("disconnected inode %llu, "),
4071 do_warn(_("moving to %s\n"),
4073 mv_orphanage(mp
, orphanage_ino
,
4075 inode_isadir(irec
, j
));
4077 do_warn(_("would move to %s\n"),
4081 * for read-only case, even though
4082 * the inode isn't really reachable,
4083 * set the flag (and bump our link
4084 * count) anyway to fool phase 7
4086 add_inode_reached(irec
, j
);
4089 irec
= next_ino_rec(irec
);