2 * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as
6 * published by the Free Software Foundation.
8 * This program is distributed in the hope that it would be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 * Further, this software is distributed without any warranty that it is
13 * free of the rightful claim of any third person regarding infringement
14 * or the like. Any license provided herein, whether implied or
15 * otherwise, applies only to this software file. Patent licenses, if
16 * any, provided herein do not apply to combinations of this program with
17 * other software, or any other product whatsoever.
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write the Free Software Foundation, Inc., 59
21 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
28 * For further information regarding this notice, see:
30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
40 #include "dir_stack.h"
42 #include "err_protos.h"
47 static int orphanage_entered
;
50 * Data structures and routines to keep track of directory entries
51 * and whether their leaf entry has been seen
53 typedef struct dir_hash_ent
{
54 struct dir_hash_ent
*next
; /* pointer to next entry */
55 xfs_dir2_leaf_entry_t ent
; /* address and hash value */
56 short junkit
; /* name starts with / */
57 short seen
; /* have seen leaf entry */
60 typedef struct dir_hash_tab
{
61 int size
; /* size of hash table */
62 dir_hash_ent_t
*tab
[1];/* actual hash table, variable size */
64 #define DIR_HASH_TAB_SIZE(n) \
65 (offsetof(dir_hash_tab_t, tab) + (sizeof(dir_hash_ent_t *) * (n)))
66 #define DIR_HASH_FUNC(t,a) ((a) % (t)->size)
69 * Track the contents of the freespace table in a directory.
71 typedef struct freetab
{
72 int naents
; /* expected number of data blocks */
73 int nents
; /* number of data blocks processed */
75 xfs_dir2_data_off_t v
;
79 #define FREETAB_SIZE(n) \
80 (offsetof(freetab_t, ents) + (sizeof(struct freetab_ent) * (n)))
82 #define DIR_HASH_CK_OK 0
83 #define DIR_HASH_CK_DUPLEAF 1
84 #define DIR_HASH_CK_BADHASH 2
85 #define DIR_HASH_CK_NODATA 3
86 #define DIR_HASH_CK_NOLEAF 4
87 #define DIR_HASH_CK_BADSTALE 5
88 #define DIR_HASH_CK_TOTAL 6
92 dir_hash_tab_t
*hashtab
,
94 xfs_dir2_dataptr_t addr
,
100 i
= DIR_HASH_FUNC(hashtab
, addr
);
101 if ((p
= malloc(sizeof(*p
))) == NULL
)
102 do_error(_("malloc failed in dir_hash_add (%u bytes)\n"),
104 p
->next
= hashtab
->tab
[i
];
106 if (!(p
->junkit
= junk
))
107 p
->ent
.hashval
= hash
;
108 p
->ent
.address
= addr
;
114 dir_hash_tab_t
*hashtab
)
119 for (i
= 0; i
< hashtab
->size
; i
++) {
120 for (p
= hashtab
->tab
[i
]; p
; p
= p
->next
) {
130 dir_hash_tab_t
*hashtab
,
134 static char *seevalstr
[DIR_HASH_CK_TOTAL
];
138 seevalstr
[DIR_HASH_CK_OK
] = _("ok");
139 seevalstr
[DIR_HASH_CK_DUPLEAF
] = _("duplicate leaf");
140 seevalstr
[DIR_HASH_CK_BADHASH
] = _("hash value mismatch");
141 seevalstr
[DIR_HASH_CK_NODATA
] = _("no data entry");
142 seevalstr
[DIR_HASH_CK_NOLEAF
] = _("no leaf entry");
143 seevalstr
[DIR_HASH_CK_BADSTALE
] = _("bad stale count");
147 if (seeval
== DIR_HASH_CK_OK
&& dir_hash_unseen(hashtab
))
148 seeval
= DIR_HASH_CK_NOLEAF
;
149 if (seeval
== DIR_HASH_CK_OK
)
151 do_warn(_("bad hash table for directory inode %llu (%s): "),
152 ip
->i_ino
, seevalstr
[seeval
]);
154 do_warn(_("rebuilding\n"));
156 do_warn(_("would rebuild\n"));
162 dir_hash_tab_t
*hashtab
)
168 for (i
= 0; i
< hashtab
->size
; i
++) {
169 for (p
= hashtab
->tab
[i
]; p
; p
= n
) {
177 static dir_hash_tab_t
*
181 dir_hash_tab_t
*hashtab
;
184 hsize
= size
/ (16 * 4);
189 if ((hashtab
= calloc(DIR_HASH_TAB_SIZE(hsize
), 1)) == NULL
)
190 do_error(_("calloc failed in dir_hash_init\n"));
191 hashtab
->size
= hsize
;
197 dir_hash_tab_t
*hashtab
,
199 xfs_dir2_dataptr_t addr
)
204 i
= DIR_HASH_FUNC(hashtab
, addr
);
205 for (p
= hashtab
->tab
[i
]; p
; p
= p
->next
) {
206 if (p
->ent
.address
!= addr
)
209 return DIR_HASH_CK_DUPLEAF
;
210 if (p
->junkit
== 0 && p
->ent
.hashval
!= hash
)
211 return DIR_HASH_CK_BADHASH
;
213 return DIR_HASH_CK_OK
;
215 return DIR_HASH_CK_NODATA
;
220 dir_hash_tab_t
*hashtab
,
221 xfs_dir2_leaf_entry_t
*ents
,
229 for (i
= j
= 0; i
< count
; i
++) {
230 if (INT_GET(ents
[i
].address
, ARCH_CONVERT
) == XFS_DIR2_NULL_DATAPTR
) {
234 rval
= dir_hash_see(hashtab
, INT_GET(ents
[i
].hashval
, ARCH_CONVERT
), INT_GET(ents
[i
].address
, ARCH_CONVERT
));
235 if (rval
!= DIR_HASH_CK_OK
)
238 return j
== stale
? DIR_HASH_CK_OK
: DIR_HASH_CK_BADSTALE
;
243 * Version 1 or 2 directory routine wrappers
246 dir_init(xfs_mount_t
*mp
, xfs_trans_t
*tp
, xfs_inode_t
*dp
, xfs_inode_t
*pdp
)
248 if (XFS_SB_VERSION_HASDIRV2(&mp
->m_sb
))
249 libxfs_dir2_init(tp
, dp
, pdp
);
251 libxfs_dir_init(tp
, dp
, pdp
);
255 dir_createname(xfs_mount_t
*mp
, xfs_trans_t
*tp
, xfs_inode_t
*pip
,
256 char *name
, int namelen
, xfs_ino_t inum
, xfs_fsblock_t
*first
,
257 xfs_bmap_free_t
*flist
, xfs_extlen_t total
)
259 if (XFS_SB_VERSION_HASDIRV2(&mp
->m_sb
))
260 return libxfs_dir2_createname(tp
, pip
, name
, namelen
,
261 inum
, first
, flist
, total
);
263 return libxfs_dir_createname(tp
, pip
, name
, namelen
,
264 inum
, first
, flist
, total
);
268 dir_lookup(xfs_mount_t
*mp
, xfs_trans_t
*tp
, xfs_inode_t
*dp
, char *name
,
269 int namelen
, xfs_ino_t
*inum
)
271 if (XFS_SB_VERSION_HASDIRV2(&mp
->m_sb
))
272 return libxfs_dir2_lookup(tp
, dp
, name
, namelen
, inum
);
274 return libxfs_dir_lookup(tp
, dp
, name
, namelen
, inum
);
278 dir_replace(xfs_mount_t
*mp
, xfs_trans_t
*tp
, xfs_inode_t
*dp
, char *name
,
279 int namelen
, xfs_ino_t inum
, xfs_fsblock_t
*firstblock
,
280 xfs_bmap_free_t
*flist
, xfs_extlen_t total
)
282 if (XFS_SB_VERSION_HASDIRV2(&mp
->m_sb
))
283 return libxfs_dir2_replace(tp
, dp
, name
, namelen
, inum
,
284 firstblock
, flist
, total
);
286 return libxfs_dir_replace(tp
, dp
, name
, namelen
, inum
,
287 firstblock
, flist
, total
);
291 dir_removename(xfs_mount_t
*mp
, xfs_trans_t
*tp
, xfs_inode_t
*dp
, char *name
,
292 int namelen
, xfs_ino_t inum
, xfs_fsblock_t
*firstblock
,
293 xfs_bmap_free_t
*flist
, xfs_extlen_t total
)
295 if (XFS_SB_VERSION_HASDIRV2(&mp
->m_sb
))
296 return libxfs_dir2_removename(tp
, dp
, name
, namelen
, inum
,
297 firstblock
, flist
, total
);
299 return libxfs_dir_removename(tp
, dp
, name
, namelen
, inum
,
300 firstblock
, flist
, total
);
304 dir_bogus_removename(xfs_mount_t
*mp
, xfs_trans_t
*tp
, xfs_inode_t
*dp
,
305 char *name
, xfs_fsblock_t
*firstblock
, xfs_bmap_free_t
*flist
,
306 xfs_extlen_t total
, xfs_dahash_t hashval
, int namelen
)
308 if (XFS_SB_VERSION_HASDIRV2(&mp
->m_sb
))
309 return libxfs_dir2_bogus_removename(tp
, dp
, name
, firstblock
,
310 flist
, total
, hashval
, namelen
);
312 return libxfs_dir_bogus_removename(tp
, dp
, name
, firstblock
,
313 flist
, total
, hashval
, namelen
);
322 do_error(_("ran out of disk space!\n"));
324 do_error(_("xfs_trans_reserve returned %d\n"), err
);
328 mk_rbmino(xfs_mount_t
*mp
)
338 xfs_bmap_free_t flist
;
340 xfs_bmbt_irec_t map
[XFS_BMAP_MAX_NMAP
];
345 tp
= libxfs_trans_alloc(mp
, 0);
347 if ((i
= libxfs_trans_reserve(tp
, 10, 0, 0, 0, 0)))
350 error
= libxfs_trans_iget(mp
, tp
, mp
->m_sb
.sb_rbmino
, 0, &ip
);
353 _("couldn't iget realtime bitmap inode -- error - %d\n"),
357 bzero(&ip
->i_d
, sizeof(xfs_dinode_core_t
));
359 ip
->i_d
.di_magic
= XFS_DINODE_MAGIC
;
360 ip
->i_d
.di_mode
= IFREG
;
361 ip
->i_d
.di_version
= XFS_DINODE_VERSION_1
;
362 ip
->i_d
.di_format
= XFS_DINODE_FMT_EXTENTS
;
363 ip
->i_d
.di_aformat
= XFS_DINODE_FMT_EXTENTS
;
365 ip
->i_d
.di_nlink
= 1; /* account for sb ptr */
370 ip
->i_df
.if_flags
= XFS_IFEXTENTS
;
371 ip
->i_df
.if_bytes
= ip
->i_df
.if_real_bytes
= 0;
372 ip
->i_df
.if_u1
.if_extents
= NULL
;
374 ip
->i_d
.di_size
= mp
->m_sb
.sb_rbmblocks
* mp
->m_sb
.sb_blocksize
;
379 libxfs_trans_log_inode(tp
, ip
, XFS_ILOG_CORE
);
380 libxfs_trans_ihold(tp
, ip
);
381 libxfs_trans_commit(tp
, XFS_TRANS_RELEASE_LOG_RES
|XFS_TRANS_SYNC
, NULL
);
384 * then allocate blocks for file and fill with zeroes (stolen
387 tp
= libxfs_trans_alloc(mp
, 0);
388 if ((error
= libxfs_trans_reserve(tp
, mp
->m_sb
.sb_rbmblocks
+
389 (XFS_BM_MAXLEVELS(mp
, XFS_DATA_FORK
) - 1), 0, 0, 0, 0)))
392 libxfs_trans_ijoin(tp
, ip
, 0);
394 XFS_BMAP_INIT(&flist
, &first
);
395 while (bno
< mp
->m_sb
.sb_rbmblocks
) {
396 nmap
= XFS_BMAP_MAX_NMAP
;
397 error
= libxfs_bmapi(tp
, ip
, bno
,
398 (xfs_extlen_t
)(mp
->m_sb
.sb_rbmblocks
- bno
),
399 XFS_BMAPI_WRITE
, &first
, mp
->m_sb
.sb_rbmblocks
,
403 _("couldn't allocate realtime bitmap, error = %d\n"),
406 for (i
= 0, ep
= map
; i
< nmap
; i
++, ep
++) {
407 libxfs_device_zero(mp
->m_dev
,
408 XFS_FSB_TO_DADDR(mp
, ep
->br_startblock
),
409 XFS_FSB_TO_BB(mp
, ep
->br_blockcount
));
410 bno
+= ep
->br_blockcount
;
413 error
= libxfs_bmap_finish(&tp
, &flist
, first
, &committed
);
416 _("allocation of the realtime bitmap failed, error = %d\n"),
419 libxfs_trans_commit(tp
, XFS_TRANS_RELEASE_LOG_RES
|XFS_TRANS_SYNC
, 0);
423 fill_rbmino(xfs_mount_t
*mp
)
438 tp
= libxfs_trans_alloc(mp
, 0);
440 if ((error
= libxfs_trans_reserve(tp
, 10, 0, 0, 0, 0)))
443 error
= libxfs_trans_iget(mp
, tp
, mp
->m_sb
.sb_rbmino
, 0, &ip
);
446 _("couldn't iget realtime bitmap inode -- error - %d\n"),
450 while (bno
< mp
->m_sb
.sb_rbmblocks
) {
452 * fill the file one block at a time
455 error
= libxfs_bmapi(tp
, ip
, bno
, 1, XFS_BMAPI_WRITE
,
456 &first
, 1, &map
, &nmap
, NULL
);
457 if (error
|| nmap
!= 1) {
459 _("couldn't map realtime bitmap block %llu, error = %d\n"),
463 ASSERT(map
.br_startblock
!= HOLESTARTBLOCK
);
465 error
= libxfs_trans_read_buf(
467 XFS_FSB_TO_DADDR(mp
, map
.br_startblock
),
468 XFS_FSB_TO_BB(mp
, 1), 1, &bp
);
472 _("can't access block %llu (fsbno %llu) of realtime bitmap inode %llu\n"),
473 bno
, map
.br_startblock
, mp
->m_sb
.sb_rbmino
);
477 bcopy(bmp
, XFS_BUF_PTR(bp
), mp
->m_sb
.sb_blocksize
);
479 libxfs_trans_log_buf(tp
, bp
, 0, mp
->m_sb
.sb_blocksize
- 1);
481 bmp
= (xfs_rtword_t
*)((__psint_t
) bmp
+ mp
->m_sb
.sb_blocksize
);
485 libxfs_trans_commit(tp
, XFS_TRANS_RELEASE_LOG_RES
|XFS_TRANS_SYNC
, 0);
491 fill_rsumino(xfs_mount_t
*mp
)
501 xfs_dfiloff_t end_bno
;
506 end_bno
= mp
->m_rsumsize
>> mp
->m_sb
.sb_blocklog
;
508 tp
= libxfs_trans_alloc(mp
, 0);
510 if ((error
= libxfs_trans_reserve(tp
, 10, 0, 0, 0, 0)))
513 error
= libxfs_trans_iget(mp
, tp
, mp
->m_sb
.sb_rsumino
, 0, &ip
);
516 _("couldn't iget realtime summary inode -- error - %d\n"),
520 while (bno
< end_bno
) {
522 * fill the file one block at a time
525 error
= libxfs_bmapi(tp
, ip
, bno
, 1, XFS_BMAPI_WRITE
,
526 &first
, 1, &map
, &nmap
, NULL
);
527 if (error
|| nmap
!= 1) {
529 _("couldn't map realtime summary inode block %llu, error = %d\n"),
533 ASSERT(map
.br_startblock
!= HOLESTARTBLOCK
);
535 error
= libxfs_trans_read_buf(
537 XFS_FSB_TO_DADDR(mp
, map
.br_startblock
),
538 XFS_FSB_TO_BB(mp
, 1), 1, &bp
);
542 _("can't access block %llu (fsbno %llu) of realtime summary inode %llu\n"),
543 bno
, map
.br_startblock
, mp
->m_sb
.sb_rsumino
);
547 bcopy(smp
, XFS_BUF_PTR(bp
), mp
->m_sb
.sb_blocksize
);
549 libxfs_trans_log_buf(tp
, bp
, 0, mp
->m_sb
.sb_blocksize
- 1);
551 smp
= (xfs_suminfo_t
*)((__psint_t
)smp
+ mp
->m_sb
.sb_blocksize
);
555 libxfs_trans_commit(tp
, XFS_TRANS_RELEASE_LOG_RES
|XFS_TRANS_SYNC
, 0);
561 mk_rsumino(xfs_mount_t
*mp
)
572 xfs_bmap_free_t flist
;
574 xfs_bmbt_irec_t map
[XFS_BMAP_MAX_NMAP
];
579 tp
= libxfs_trans_alloc(mp
, 0);
581 if ((i
= libxfs_trans_reserve(tp
, 10, XFS_ICHANGE_LOG_RES(mp
), 0,
582 XFS_TRANS_PERM_LOG_RES
, XFS_MKDIR_LOG_COUNT
)))
585 error
= libxfs_trans_iget(mp
, tp
, mp
->m_sb
.sb_rsumino
, 0, &ip
);
588 _("couldn't iget realtime summary inode -- error - %d\n"),
592 bzero(&ip
->i_d
, sizeof(xfs_dinode_core_t
));
594 ip
->i_d
.di_magic
= XFS_DINODE_MAGIC
;
595 ip
->i_d
.di_mode
= IFREG
;
596 ip
->i_d
.di_version
= XFS_DINODE_VERSION_1
;
597 ip
->i_d
.di_format
= XFS_DINODE_FMT_EXTENTS
;
598 ip
->i_d
.di_aformat
= XFS_DINODE_FMT_EXTENTS
;
600 ip
->i_d
.di_nlink
= 1; /* account for sb ptr */
605 ip
->i_df
.if_flags
= XFS_IFEXTENTS
;
606 ip
->i_df
.if_bytes
= ip
->i_df
.if_real_bytes
= 0;
607 ip
->i_df
.if_u1
.if_extents
= NULL
;
609 ip
->i_d
.di_size
= mp
->m_rsumsize
;
614 libxfs_trans_log_inode(tp
, ip
, XFS_ILOG_CORE
);
615 libxfs_trans_ihold(tp
, ip
);
616 libxfs_trans_commit(tp
, XFS_TRANS_RELEASE_LOG_RES
|XFS_TRANS_SYNC
, 0);
619 * then allocate blocks for file and fill with zeroes (stolen
622 tp
= libxfs_trans_alloc(mp
, 0);
623 XFS_BMAP_INIT(&flist
, &first
);
625 nsumblocks
= mp
->m_rsumsize
>> mp
->m_sb
.sb_blocklog
;
626 if ((error
= libxfs_trans_reserve(tp
,
627 mp
->m_sb
.sb_rbmblocks
+
628 (XFS_BM_MAXLEVELS(mp
, XFS_DATA_FORK
) - 1),
629 BBTOB(128), 0, XFS_TRANS_PERM_LOG_RES
,
630 XFS_DEFAULT_PERM_LOG_COUNT
)))
633 libxfs_trans_ijoin(tp
, ip
, 0);
635 XFS_BMAP_INIT(&flist
, &first
);
636 while (bno
< nsumblocks
) {
637 nmap
= XFS_BMAP_MAX_NMAP
;
638 error
= libxfs_bmapi(tp
, ip
, bno
,
639 (xfs_extlen_t
)(nsumblocks
- bno
),
640 XFS_BMAPI_WRITE
, &first
, nsumblocks
,
644 _("couldn't allocate realtime summary inode, error = %d\n"),
647 for (i
= 0, ep
= map
; i
< nmap
; i
++, ep
++) {
648 libxfs_device_zero(mp
->m_dev
,
649 XFS_FSB_TO_DADDR(mp
, ep
->br_startblock
),
650 XFS_FSB_TO_BB(mp
, ep
->br_blockcount
));
651 bno
+= ep
->br_blockcount
;
654 error
= libxfs_bmap_finish(&tp
, &flist
, first
, &committed
);
657 _("allocation of the realtime summary ino failed, error = %d\n"),
660 libxfs_trans_commit(tp
, XFS_TRANS_RELEASE_LOG_RES
|XFS_TRANS_SYNC
, 0);
664 * makes a new root directory.
667 mk_root_dir(xfs_mount_t
*mp
)
673 const mode_t mode
= 0755;
675 tp
= libxfs_trans_alloc(mp
, 0);
678 if ((i
= libxfs_trans_reserve(tp
, 10, XFS_ICHANGE_LOG_RES(mp
), 0,
679 XFS_TRANS_PERM_LOG_RES
, XFS_MKDIR_LOG_COUNT
)))
682 error
= libxfs_trans_iget(mp
, tp
, mp
->m_sb
.sb_rootino
, 0, &ip
);
684 do_error(_("could not iget root inode -- error - %d\n"), error
);
688 * take care of the core -- initialization from xfs_ialloc()
690 bzero(&ip
->i_d
, sizeof(xfs_dinode_core_t
));
692 ip
->i_d
.di_magic
= XFS_DINODE_MAGIC
;
693 ip
->i_d
.di_mode
= (__uint16_t
) mode
|IFDIR
;
694 ip
->i_d
.di_version
= XFS_DINODE_VERSION_1
;
695 ip
->i_d
.di_format
= XFS_DINODE_FMT_EXTENTS
;
696 ip
->i_d
.di_aformat
= XFS_DINODE_FMT_EXTENTS
;
698 ip
->i_d
.di_nlink
= 1; /* account for . */
700 libxfs_trans_log_inode(tp
, ip
, XFS_ILOG_CORE
);
705 ip
->i_df
.if_flags
= XFS_IFEXTENTS
;
706 ip
->i_df
.if_bytes
= ip
->i_df
.if_real_bytes
= 0;
707 ip
->i_df
.if_u1
.if_extents
= NULL
;
712 * initialize the directory
714 dir_init(mp
, tp
, ip
, ip
);
716 libxfs_trans_commit(tp
, XFS_TRANS_RELEASE_LOG_RES
|XFS_TRANS_SYNC
, 0);
720 * orphanage name == lost+found
723 mk_orphanage(xfs_mount_t
*mp
)
733 xfs_bmap_free_t flist
;
734 const int mode
= 0755;
739 tp
= libxfs_trans_alloc(mp
, 0);
740 XFS_BMAP_INIT(&flist
, &first
);
742 nres
= XFS_MKDIR_SPACE_RES(mp
, strlen(ORPHANAGE
));
743 if ((i
= libxfs_trans_reserve(tp
, nres
, XFS_MKDIR_LOG_RES(mp
), 0,
744 XFS_TRANS_PERM_LOG_RES
, XFS_MKDIR_LOG_COUNT
)))
748 * use iget/ijoin instead of trans_iget because the ialloc
749 * wrapper can commit the transaction and start a new one
751 if ((i
= libxfs_iget(mp
, NULL
, mp
->m_sb
.sb_rootino
, 0, &pip
, 0)))
752 do_error(_("%d - couldn't iget root inode to make %s\n"),
755 error
= libxfs_inode_alloc(&tp
, pip
, mode
|IFDIR
,
756 1, mp
->m_dev
, &zerocr
, &ip
);
759 do_error(_("%s inode allocation failed %d\n"),
763 ip
->i_d
.di_uid
= uid
;
764 ip
->i_d
.di_gid
= gid
;
765 ip
->i_d
.di_nlink
++; /* account for . */
768 * now that we know the transaction will stay around,
769 * add the root inode to it
771 libxfs_trans_ijoin(tp
, pip
, 0);
774 * create the actual entry
776 if ((error
= dir_createname(mp
, tp
, pip
, ORPHANAGE
,
777 strlen(ORPHANAGE
), ip
->i_ino
, &first
, &flist
, nres
))) {
779 _("can't make %s, createname error %d, will try later\n"),
781 orphanage_entered
= 0;
783 orphanage_entered
= 1;
786 * bump up the link count in the root directory to account
787 * for .. in the new directory
791 libxfs_trans_log_inode(tp
, pip
, XFS_ILOG_CORE
);
792 dir_init(mp
, tp
, ip
, pip
);
793 libxfs_trans_log_inode(tp
, ip
, XFS_ILOG_CORE
);
795 error
= libxfs_bmap_finish(&tp
, &flist
, first
, &committed
);
797 do_error(_("%s directory creation failed -- bmapf error %d\n"),
803 libxfs_trans_commit(tp
, XFS_TRANS_RELEASE_LOG_RES
|XFS_TRANS_SYNC
, 0);
805 /* need libxfs_iput here? - nathans TODO - possible memory leak? */
811 * move a file to the orphange. the orphanage is guaranteed
812 * at this point to only have file in it whose name == file inode #
815 mv_orphanage(xfs_mount_t
*mp
,
816 xfs_ino_t dir_ino
, /* orphange inode # */
817 xfs_ino_t ino
, /* inode # to be moved */
818 int isa_dir
) /* 1 if inode is a directory */
820 xfs_ino_t entry_ino_num
;
821 xfs_inode_t
*dir_ino_p
;
825 xfs_bmap_free_t flist
;
828 char fname
[MAXPATHLEN
+ 1];
831 snprintf(fname
, sizeof(fname
), "%llu", (unsigned long long)ino
);
833 if ((err
= libxfs_iget(mp
, NULL
, dir_ino
, 0, &dir_ino_p
, 0)))
834 do_error(_("%d - couldn't iget orphanage inode\n"), err
);
836 tp
= libxfs_trans_alloc(mp
, 0);
838 if ((err
= libxfs_iget(mp
, NULL
, ino
, 0, &ino_p
, 0)))
839 do_error(_("%d - couldn't iget disconnected inode\n"), err
);
842 nres
= XFS_DIRENTER_SPACE_RES(mp
, strlen(fname
)) +
843 XFS_DIRENTER_SPACE_RES(mp
, 2);
844 if ((err
= dir_lookup(mp
, tp
, ino_p
, "..", 2,
846 ASSERT(err
== ENOENT
);
848 if ((err
= libxfs_trans_reserve(tp
, nres
,
849 XFS_RENAME_LOG_RES(mp
), 0,
850 XFS_TRANS_PERM_LOG_RES
,
851 XFS_RENAME_LOG_COUNT
)))
853 _("space reservation failed (%d), filesystem may be out of space\n"),
856 libxfs_trans_ijoin(tp
, dir_ino_p
, 0);
857 libxfs_trans_ijoin(tp
, ino_p
, 0);
859 XFS_BMAP_INIT(&flist
, &first
);
860 if ((err
= dir_createname(mp
, tp
, dir_ino_p
, fname
,
861 strlen(fname
), ino
, &first
,
864 _("name create failed in %s (%d), filesystem may be out of space\n"),
867 dir_ino_p
->i_d
.di_nlink
++;
868 libxfs_trans_log_inode(tp
, dir_ino_p
, XFS_ILOG_CORE
);
870 if ((err
= dir_createname(mp
, tp
, ino_p
, "..", 2,
871 dir_ino
, &first
, &flist
, nres
)))
873 _("creation of .. entry failed (%d), filesystem may be out of space\n"),
876 ino_p
->i_d
.di_nlink
++;
877 libxfs_trans_log_inode(tp
, ino_p
, XFS_ILOG_CORE
);
879 if ((err
= libxfs_bmap_finish(&tp
, &flist
, first
, &committed
)))
881 _("bmap finish failed (err - %d), filesystem may be out of space\n"),
884 libxfs_trans_commit(tp
,
885 XFS_TRANS_RELEASE_LOG_RES
|XFS_TRANS_SYNC
, 0);
887 if ((err
= libxfs_trans_reserve(tp
, nres
,
888 XFS_RENAME_LOG_RES(mp
), 0,
889 XFS_TRANS_PERM_LOG_RES
,
890 XFS_RENAME_LOG_COUNT
)))
892 _("space reservation failed (%d), filesystem may be out of space\n"),
895 libxfs_trans_ijoin(tp
, dir_ino_p
, 0);
896 libxfs_trans_ijoin(tp
, ino_p
, 0);
898 XFS_BMAP_INIT(&flist
, &first
);
900 if ((err
= dir_createname(mp
, tp
, dir_ino_p
, fname
,
901 strlen(fname
), ino
, &first
,
904 _("name create failed in %s (%d), filesystem may be out of space\n"),
907 dir_ino_p
->i_d
.di_nlink
++;
908 libxfs_trans_log_inode(tp
, dir_ino_p
, XFS_ILOG_CORE
);
911 * don't replace .. value if it already points
912 * to us. that'll pop a libxfs/kernel ASSERT.
914 if (entry_ino_num
!= dir_ino
) {
915 if ((err
= dir_replace(mp
, tp
, ino_p
, "..",
919 _("name replace op failed (%d), filesystem may be out of space\n"),
923 if ((err
= libxfs_bmap_finish(&tp
, &flist
, first
,
926 _("bmap finish failed (%d), filesystem may be out of space\n"),
929 libxfs_trans_commit(tp
,
930 XFS_TRANS_RELEASE_LOG_RES
|XFS_TRANS_SYNC
, 0);
934 * use the remove log reservation as that's
935 * more accurate. we're only creating the
936 * links, we're not doing the inode allocation
937 * also accounted for in the create
939 nres
= XFS_DIRENTER_SPACE_RES(mp
, strlen(fname
));
940 if ((err
= libxfs_trans_reserve(tp
, nres
, XFS_REMOVE_LOG_RES(mp
), 0,
941 XFS_TRANS_PERM_LOG_RES
, XFS_REMOVE_LOG_COUNT
)))
943 _("space reservation failed (%d), filesystem may be out of space\n"),
946 libxfs_trans_ijoin(tp
, dir_ino_p
, 0);
947 libxfs_trans_ijoin(tp
, ino_p
, 0);
949 XFS_BMAP_INIT(&flist
, &first
);
950 if ((err
= dir_createname(mp
, tp
, dir_ino_p
, fname
,
951 strlen(fname
), ino
, &first
, &flist
, nres
)))
953 _("name create failed in %s (%d), filesystem may be out of space\n"),
957 ino_p
->i_d
.di_nlink
= 1;
958 libxfs_trans_log_inode(tp
, ino_p
, XFS_ILOG_CORE
);
960 if ((err
= libxfs_bmap_finish(&tp
, &flist
, first
, &committed
)))
962 _("bmap finish failed (%d), filesystem may be out of space\n"),
965 libxfs_trans_commit(tp
, XFS_TRANS_RELEASE_LOG_RES
|XFS_TRANS_SYNC
, 0);
970 * like get_first_dblock_fsbno only it uses the simulation code instead
973 * Returns the fsbno of the first (leftmost) block in the directory leaf.
974 * sets *bno to the directory block # corresponding to the returned fsbno.
977 map_first_dblock_fsbno(xfs_mount_t
*mp
,
982 xfs_fsblock_t fblock
;
983 xfs_da_intnode_t
*node
;
994 * traverse down left-side of tree until we hit the
995 * left-most leaf block setting up the btree cursor along
1002 fblock
= NULLFSBLOCK
;
1006 error
= libxfs_bmapi(NULL
, ip
, (xfs_fileoff_t
) da_bno
, 1,
1007 XFS_BMAPI_METADATA
, &fblock
, 0,
1009 if (error
|| nmap
!= 1) {
1012 _("can't map block %d in %s inode %llu, xfs_bmapi returns %d, nmap = %d\n"),
1013 da_bno
, ftype
, ino
, error
, nmap
);
1016 _("can't map block %d in %s inode %llu, xfs_bmapi returns %d, nmap = %d\n"),
1017 da_bno
, ftype
, ino
, error
, nmap
);
1022 if ((fsbno
= map
.br_startblock
) == HOLESTARTBLOCK
) {
1024 do_error(_("block %d in %s ino %llu doesn't exist\n"),
1025 da_bno
, ftype
, ino
);
1027 do_warn(_("block %d in %s ino %llu doesn't exist\n"),
1028 da_bno
, ftype
, ino
);
1033 if (ip
->i_d
.di_size
<= XFS_LBSIZE(mp
))
1036 if (XFS_SB_VERSION_HASDIRV2(&mp
->m_sb
))
1041 * walk down left side of btree, release buffers as you
1042 * go. if the root block is a leaf (single-level btree),
1047 bp
= libxfs_readbuf(mp
->m_dev
, XFS_FSB_TO_DADDR(mp
, fsbno
),
1048 XFS_FSB_TO_BB(mp
, 1), 0);
1052 _("can't read block %u (fsbno %llu) for directory inode %llu\n"),
1053 da_bno
, fsbno
, ino
);
1057 node
= (xfs_da_intnode_t
*)XFS_BUF_PTR(bp
);
1059 if (INT_GET(node
->hdr
.info
.magic
, ARCH_CONVERT
) != XFS_DA_NODE_MAGIC
) {
1062 _("bad dir/attr magic number in inode %llu, file bno = %u, fsbno = %llu\n"),
1063 ino
, da_bno
, fsbno
);
1068 i
= INT_GET(node
->hdr
.level
, ARCH_CONVERT
);
1070 da_bno
= INT_GET(node
->btree
[0].before
, ARCH_CONVERT
);
1076 error
= libxfs_bmapi(NULL
, ip
, (xfs_fileoff_t
) da_bno
, 1,
1077 XFS_BMAPI_METADATA
, &fblock
, 0,
1079 if (error
|| nmap
!= 1) {
1082 _("can't map block %d in %s ino %llu, xfs_bmapi returns %d, nmap = %d\n"),
1083 da_bno
, ftype
, ino
, error
, nmap
);
1086 _("can't map block %d in %s ino %llu, xfs_bmapi returns %d, nmap = %d\n"),
1087 da_bno
, ftype
, ino
, error
, nmap
);
1091 if ((fsbno
= map
.br_startblock
) == HOLESTARTBLOCK
) {
1094 _("block %d in %s inode %llu doesn't exist\n"),
1095 da_bno
, ftype
, ino
);
1098 _("block %d in %s inode %llu doesn't exist\n"),
1099 da_bno
, ftype
, ino
);
1112 * scan longform directory and prune first bad entry. returns 1 if
1113 * it had to remove something, 0 if it made it all the way through
1114 * the directory. prune_lf_dir_entry does all the necessary bmap calls.
1116 * hashval is an in/out -- starting hashvalue in, hashvalue of the
1117 * deleted entry (if there was one) out
1119 * this routine can NOT be called if running in no modify mode
1122 prune_lf_dir_entry(xfs_mount_t
*mp
, xfs_ino_t ino
, xfs_inode_t
*ip
,
1123 xfs_dahash_t
*hashval
)
1130 xfs_bmap_free_t free_list
;
1131 xfs_fsblock_t first_block
;
1133 xfs_dir_leaf_name_t
*namest
;
1134 xfs_dir_leafblock_t
*leaf
;
1135 xfs_dir_leaf_entry_t
*entry
;
1138 xfs_fsblock_t fblock
;
1141 xfs_bmbt_irec_t map
;
1142 char fname
[MAXNAMELEN
+ 1];
1147 * ok, this is kind of a schizoid routine. we use our
1148 * internal bmapi routines to walk the directory. when
1149 * we find a bogus entry, we release the buffer so
1150 * the simulation code doesn't deadlock and use the
1151 * sim code to remove the entry. That will cause an
1152 * extra bmap traversal to map the block but I think
1153 * that's preferable to hacking the bogus removename
1154 * function to be really different and then trying to
1155 * maintain both versions as time goes on.
1157 * first, grab the dinode and find the right leaf block.
1164 fblock
= NULLFSBLOCK
;
1166 fsbno
= map_first_dblock_fsbno(mp
, ino
, ip
, &da_bno
);
1169 * now go foward along the leaves of the btree looking
1170 * for an entry beginning with '/'
1173 bp
= libxfs_readbuf(mp
->m_dev
, XFS_FSB_TO_DADDR(mp
, fsbno
),
1174 XFS_FSB_TO_BB(mp
, 1), 0);
1178 _("can't read directory inode %llu (leaf) block %u (fsbno %llu)\n"),
1179 ino
, da_bno
, fsbno
);
1183 leaf
= (xfs_dir_leafblock_t
*)XFS_BUF_PTR(bp
);
1184 ASSERT(INT_GET(leaf
->hdr
.info
.magic
, ARCH_CONVERT
) == XFS_DIR_LEAF_MAGIC
);
1185 entry
= &leaf
->entries
[0];
1187 for (index
= -1, i
= 0;
1188 i
< INT_GET(leaf
->hdr
.count
, ARCH_CONVERT
) && index
== -1;
1190 namest
= XFS_DIR_LEAF_NAMESTRUCT(leaf
, INT_GET(entry
->nameidx
, ARCH_CONVERT
));
1191 if (namest
->name
[0] != '/')
1198 * if we got a bogus entry, exit loop with a pointer to
1199 * the leaf block buffer. otherwise, keep trying blocks
1201 da_bno
= INT_GET(leaf
->hdr
.info
.forw
, ARCH_CONVERT
);
1210 * map next leaf block unless we've run out
1214 error
= libxfs_bmapi(NULL
, ip
,
1215 (xfs_fileoff_t
) da_bno
, 1,
1216 XFS_BMAPI_METADATA
, &fblock
, 0,
1218 if (error
|| nmap
!= 1)
1220 _("can't map block %d in directory %llu, xfs_bmapi returns %d, nmap = %d\n"),
1221 da_bno
, ino
, error
, nmap
);
1222 if ((fsbno
= map
.br_startblock
)
1223 == HOLESTARTBLOCK
) {
1225 _("%s ino %llu block %d doesn't exist\n"),
1226 ftype
, ino
, da_bno
);
1230 } while (da_bno
!= 0 && index
== -1);
1233 * if we hit the edge of the tree with no bad entries, we're done
1234 * and the buffer was released.
1236 if (da_bno
== 0 && index
== -1)
1240 ASSERT(entry
== &leaf
->entries
[index
]);
1241 ASSERT(namest
== XFS_DIR_LEAF_NAMESTRUCT(leaf
,
1242 INT_GET(entry
->nameidx
, ARCH_CONVERT
)));
1245 * snag the info we need out of the directory then release all buffers
1247 bcopy(namest
->name
, fname
, entry
->namelen
);
1248 fname
[entry
->namelen
] = '\0';
1249 *hashval
= INT_GET(entry
->hashval
, ARCH_CONVERT
);
1250 namelen
= entry
->namelen
;
1255 * ok, now the hard part, blow away the index'th entry in this block
1257 * allocate a remove transaction for it. that's not quite true since
1258 * we're only messing with one inode, not two but...
1261 tp
= libxfs_trans_alloc(mp
, XFS_TRANS_REMOVE
);
1263 nres
= XFS_REMOVE_SPACE_RES(mp
);
1264 error
= libxfs_trans_reserve(tp
, nres
, XFS_REMOVE_LOG_RES(mp
),
1265 0, XFS_TRANS_PERM_LOG_RES
,
1266 XFS_REMOVE_LOG_COUNT
);
1270 libxfs_trans_ijoin(tp
, ip
, 0);
1271 libxfs_trans_ihold(tp
, ip
);
1273 XFS_BMAP_INIT(&free_list
, &first_block
);
1275 error
= dir_bogus_removename(mp
, tp
, ip
, fname
,
1276 &first_block
, &free_list
, nres
, *hashval
, namelen
);
1280 _("couldn't remove bogus entry \"%s\" in\n\tdirectory inode %llu, errno = %d\n"),
1285 error
= libxfs_bmap_finish(&tp
, &free_list
, first_block
, &committed
);
1289 libxfs_trans_commit(tp
, XFS_TRANS_RELEASE_LOG_RES
|XFS_TRANS_SYNC
, 0);
1295 * process a leaf block, also checks for .. entry
1296 * and corrects it to match what we think .. should be
1299 lf_block_dir_entry_check(xfs_mount_t
*mp
,
1301 xfs_dir_leafblock_t
*leaf
,
1306 ino_tree_node_t
*current_irec
,
1307 int current_ino_offset
)
1309 xfs_dir_leaf_entry_t
*entry
;
1310 ino_tree_node_t
*irec
;
1313 xfs_dir_leaf_name_t
*namest
;
1318 char fname
[MAXNAMELEN
+ 1];
1320 entry
= &leaf
->entries
[0];
1325 * look at each entry. reference inode pointed to by each
1326 * entry in the incore inode tree.
1327 * if not a directory, set reached flag, increment link count
1328 * if a directory and reached, mark entry as to be deleted.
1329 * if a directory, check to see if recorded parent
1330 * matches current inode #,
1331 * if so, then set reached flag, increment link count
1332 * of current and child dir inodes, push the child
1333 * directory inode onto the directory stack.
1334 * if current inode != parent, then mark entry to be deleted.
1338 for (i
= 0; i
< INT_GET(leaf
->hdr
.count
, ARCH_CONVERT
); entry
++, i
++) {
1340 * snag inode #, update link counts, and make sure
1341 * this isn't a loop if the child is a directory
1343 namest
= XFS_DIR_LEAF_NAMESTRUCT(leaf
, INT_GET(entry
->nameidx
, ARCH_CONVERT
));
1346 * skip bogus entries (leading '/'). they'll be deleted
1349 if (namest
->name
[0] == '/') {
1356 XFS_DIR_SF_GET_DIRINO_ARCH(&namest
->inumber
, &lino
, ARCH_CONVERT
);
1357 bcopy(namest
->name
, fname
, entry
->namelen
);
1358 fname
[entry
->namelen
] = '\0';
1360 ASSERT(lino
!= NULLFSINO
);
1363 * skip the '..' entry since it's checked when the
1364 * directory is reached by something else. if it never
1365 * gets reached, it'll be moved to the orphanage and we'll
1366 * take care of it then.
1368 if (entry
->namelen
== 2 && namest
->name
[0] == '.' &&
1369 namest
->name
[1] == '.') {
1372 ASSERT(no_modify
|| !verify_inum(mp
, lino
));
1375 * special case the . entry. we know there's only one
1376 * '.' and only '.' points to itself because bogus entries
1377 * got trashed in phase 3 if there were > 1.
1378 * bump up link count for '.' but don't set reached
1379 * until we're actually reached by another directory
1380 * '..' is already accounted for or will be taken care
1381 * of when directory is moved to orphanage.
1384 ASSERT(namest
->name
[0] == '.' && entry
->namelen
== 1);
1385 add_inode_ref(current_irec
, current_ino_offset
);
1391 * special case the "lost+found" entry if pointing
1392 * to where we think lost+found should be. if that's
1393 * the case, that's the one we created in phase 6.
1394 * just skip it. no need to process it and it's ..
1395 * link is already accounted for.
1398 if (lino
== orphanage_ino
&& strcmp(fname
, ORPHANAGE
) == 0)
1402 * skip entries with bogus inumbers if we're in no modify mode
1404 if (no_modify
&& verify_inum(mp
, lino
))
1408 * ok, now handle the rest of the cases besides '.' and '..'
1410 irec
= find_inode_rec(XFS_INO_TO_AGNO(mp
, lino
),
1411 XFS_INO_TO_AGINO(mp
, lino
));
1416 _("entry \"%s\" in dir inode %llu points to non-existent inode, "),
1420 namest
->name
[0] = '/';
1422 do_warn(_("marking entry to be junked\n"));
1424 do_warn(_("would junk entry\n"));
1430 ino_offset
= XFS_INO_TO_AGINO(mp
, lino
) - irec
->ino_startnum
;
1433 * if it's a free inode, blow out the entry.
1434 * by now, any inode that we think is free
1437 if (is_inode_free(irec
, ino_offset
)) {
1439 * don't complain if this entry points to the old
1440 * and now-free lost+found inode
1442 if (verbose
|| no_modify
|| lino
!= old_orphanage_ino
)
1444 _("entry \"%s\" in dir inode %llu points to free inode %llu"),
1449 if (verbose
|| lino
!= old_orphanage_ino
)
1451 _(", marking entry to be junked\n"));
1455 namest
->name
[0] = '/';
1458 do_warn(_(", would junk entry\n"));
1465 * check easy case first, regular inode, just bump
1466 * the link count and continue
1468 if (!inode_isadir(irec
, ino_offset
)) {
1469 add_inode_reached(irec
, ino_offset
);
1473 parent
= get_inode_parent(irec
, ino_offset
);
1474 ASSERT(parent
!= 0);
1477 * bump up the link counts in parent and child
1478 * directory but if the link doesn't agree with
1479 * the .. in the child, blow out the entry.
1480 * if the directory has already been reached,
1481 * blow away the entry also.
1483 if (is_inode_reached(irec
, ino_offset
)) {
1486 _("entry \"%s\" in dir %llu points to an already connected dir inode %llu,\n"),
1488 } else if (parent
== ino
) {
1489 add_inode_reached(irec
, ino_offset
);
1490 add_inode_ref(current_irec
, current_ino_offset
);
1492 if (!is_inode_refchecked(lino
, irec
, ino_offset
))
1493 push_dir(stack
, lino
);
1497 _("entry \"%s\" in dir ino %llu not consistent with .. value (%llu) in ino %llu,\n"),
1498 fname
, ino
, parent
, lino
);
1506 namest
->name
[0] = '/';
1508 if (verbose
|| lino
!= old_orphanage_ino
)
1510 _("\twill clear entry \"%s\"\n"),
1513 do_warn(_("\twould clear entry \"%s\"\n"),
1519 *num_illegal
+= nbad
;
1523 * succeeds or dies, inode never gets dirtied since all changes
1524 * happen in file blocks. the inode size and other core info
1525 * is already correct, it's just the leaf entries that get altered.
1528 longform_dir_entry_check(xfs_mount_t
*mp
,
1534 ino_tree_node_t
*irec
,
1537 xfs_dir_leafblock_t
*leaf
;
1540 xfs_fsblock_t fblock
;
1546 xfs_bmbt_irec_t map
;
1550 fblock
= NULLFSBLOCK
;
1554 fsbno
= map_first_dblock_fsbno(mp
, ino
, ip
, &da_bno
);
1556 if (fsbno
== NULLDFSBNO
&& no_modify
) {
1557 do_warn(_("cannot map block 0 of directory inode %llu\n"), ino
);
1562 ASSERT(fsbno
!= NULLDFSBNO
);
1565 bp
= libxfs_readbuf(mp
->m_dev
, XFS_FSB_TO_DADDR(mp
, fsbno
),
1566 XFS_FSB_TO_BB(mp
, 1), 0);
1570 _("can't read block %u (fsbno %llu) for directory inode %llu\n"),
1571 da_bno
, fsbno
, ino
);
1575 leaf
= (xfs_dir_leafblock_t
*)XFS_BUF_PTR(bp
);
1577 da_bno
= INT_GET(leaf
->hdr
.info
.forw
, ARCH_CONVERT
);
1579 if (INT_GET(leaf
->hdr
.info
.magic
, ARCH_CONVERT
) !=
1580 XFS_DIR_LEAF_MAGIC
) {
1583 _("bad magic # (0x%x) for dir ino %llu leaf block (bno %u fsbno %llu)\n"),
1584 INT_GET(leaf
->hdr
.info
.magic
,
1586 ino
, da_bno
, fsbno
);
1590 * this block's bad but maybe the
1591 * forward pointer is good...
1599 lf_block_dir_entry_check(mp
, ino
, leaf
, &dirty
,
1600 num_illegal
, need_dot
, stack
,
1603 ASSERT(dirty
== 0 || (dirty
&& !no_modify
));
1605 if (dirty
&& !no_modify
)
1606 libxfs_writebuf(bp
, 0);
1613 error
= libxfs_bmapi(NULL
, ip
, (xfs_fileoff_t
)da_bno
, 1,
1614 XFS_BMAPI_METADATA
, &fblock
, 0,
1616 if (error
|| nmap
!= 1) {
1619 _("can't map leaf block %d in dir %llu, xfs_bmapi returns %d, nmap = %d\n"),
1620 da_bno
, ino
, error
, nmap
);
1623 _("can't map leaf block %d in dir %llu, xfs_bmapi returns %d, nmap = %d\n"),
1624 da_bno
, ino
, error
, nmap
);
1628 if ((fsbno
= map
.br_startblock
) == HOLESTARTBLOCK
) {
1631 _("block %d in %s ino %llu doesn't exist\n"),
1632 da_bno
, ftype
, ino
);
1635 _("block %d in %s ino %llu doesn't exist\n"),
1636 da_bno
, ftype
, ino
);
1641 } while (da_bno
!= 0);
1645 * Kill a block in a version 2 inode.
1646 * Makes its own transaction.
1658 xfs_fsblock_t firstblock
;
1659 xfs_bmap_free_t flist
;
1663 tp
= libxfs_trans_alloc(mp
, 0);
1664 nres
= XFS_REMOVE_SPACE_RES(mp
);
1665 error
= libxfs_trans_reserve(tp
, nres
, XFS_REMOVE_LOG_RES(mp
), 0,
1666 XFS_TRANS_PERM_LOG_RES
, XFS_REMOVE_LOG_COUNT
);
1669 libxfs_trans_ijoin(tp
, ip
, 0);
1670 libxfs_trans_ihold(tp
, ip
);
1671 libxfs_da_bjoin(tp
, bp
);
1672 bzero(&args
, sizeof(args
));
1673 XFS_BMAP_INIT(&flist
, &firstblock
);
1676 args
.firstblock
= &firstblock
;
1677 args
.flist
= &flist
;
1678 args
.whichfork
= XFS_DATA_FORK
;
1679 if (da_bno
>= mp
->m_dirleafblk
&& da_bno
< mp
->m_dirfreeblk
)
1680 error
= libxfs_da_shrink_inode(&args
, da_bno
, bp
);
1682 error
= libxfs_dir2_shrink_inode(&args
,
1683 XFS_DIR2_DA_TO_DB(mp
, da_bno
), bp
);
1685 do_error(_("shrink_inode failed inode %llu block %u\n"),
1687 libxfs_bmap_finish(&tp
, &flist
, firstblock
, &committed
);
1688 libxfs_trans_commit(tp
, 0, 0);
1692 * process a data block, also checks for .. entry
1693 * and corrects it to match what we think .. should be
1696 longform_dir2_entry_check_data(
1702 ino_tree_node_t
*current_irec
,
1703 int current_ino_offset
,
1705 dir_hash_tab_t
*hashtab
,
1706 freetab_t
**freetabp
,
1710 xfs_dir2_dataptr_t addr
;
1711 xfs_dir2_leaf_entry_t
*blp
;
1713 xfs_dir2_block_tail_t
*btp
;
1717 xfs_dir2_data_entry_t
*dep
;
1718 xfs_dir2_data_unused_t
*dup
;
1721 xfs_fsblock_t firstblock
;
1722 xfs_bmap_free_t flist
;
1723 char fname
[MAXNAMELEN
+ 1];
1727 ino_tree_node_t
*irec
;
1743 needscan
= needlog
= 0;
1745 freetab
= *freetabp
;
1747 btp
= XFS_DIR2_BLOCK_TAIL_P(mp
, d
);
1748 blp
= XFS_DIR2_BLOCK_LEAF_P_ARCH(btp
, ARCH_CONVERT
);
1749 endptr
= (char *)blp
;
1750 if (endptr
> (char *)btp
)
1751 endptr
= (char *)btp
;
1752 wantmagic
= XFS_DIR2_BLOCK_MAGIC
;
1754 endptr
= (char *)d
+ mp
->m_dirblksize
;
1755 wantmagic
= XFS_DIR2_DATA_MAGIC
;
1757 db
= XFS_DIR2_DA_TO_DB(mp
, da_bno
);
1759 /* check for data block beyond expected end */
1760 if (freetab
->naents
<= db
) {
1761 struct freetab_ent e
;
1763 *freetabp
= freetab
= realloc(freetab
, FREETAB_SIZE(db
+ 1));
1766 _("realloc failed in longform_dir2_entry_check_data (%u bytes)\n"),
1767 FREETAB_SIZE(db
+ 1));
1771 for (i
= freetab
->naents
; i
< db
; i
++)
1772 freetab
->ents
[i
] = e
;
1773 freetab
->naents
= db
+ 1;
1776 /* check the data block */
1777 while (ptr
< endptr
) {
1779 /* check for freespace */
1780 dup
= (xfs_dir2_data_unused_t
*)ptr
;
1781 if (XFS_DIR2_DATA_FREE_TAG
==
1782 INT_GET(dup
->freetag
, ARCH_CONVERT
)) {
1784 /* check for invalid freespace length */
1785 if (ptr
+ INT_GET(dup
->length
, ARCH_CONVERT
) > endptr
||
1786 INT_GET(dup
->length
, ARCH_CONVERT
) == 0 ||
1787 (INT_GET(dup
->length
, ARCH_CONVERT
) &
1788 (XFS_DIR2_DATA_ALIGN
- 1)))
1791 /* check for invalid tag */
1792 if (INT_GET(*XFS_DIR2_DATA_UNUSED_TAG_P_ARCH(
1793 dup
, ARCH_CONVERT
), ARCH_CONVERT
) !=
1794 (char *)dup
- (char *)d
)
1797 /* check for block with no data entries */
1798 if ((ptr
== (char *)d
->u
) &&
1799 (ptr
+ INT_GET(dup
->length
, ARCH_CONVERT
) >=
1806 /* continue at the end of the freespace */
1807 ptr
+= INT_GET(dup
->length
, ARCH_CONVERT
);
1812 /* validate data entry size */
1813 dep
= (xfs_dir2_data_entry_t
*)ptr
;
1814 if (ptr
+ XFS_DIR2_DATA_ENTSIZE(dep
->namelen
) > endptr
)
1816 if (INT_GET(*XFS_DIR2_DATA_ENTRY_TAG_P(dep
), ARCH_CONVERT
) !=
1817 (char *)dep
- (char *)d
)
1819 ptr
+= XFS_DIR2_DATA_ENTSIZE(dep
->namelen
);
1822 /* did we find an empty or corrupt block? */
1823 if (ptr
!= endptr
) {
1826 _("empty data block %u in directory inode %llu: "),
1829 do_warn(_("corrupt block %u in directory inode %llu: "),
1833 do_warn(_("junking block\n"));
1834 dir2_kill_block(mp
, ip
, da_bno
, bp
);
1836 do_warn(_("would junk block\n"));
1837 libxfs_da_brelse(NULL
, bp
);
1839 freetab
->ents
[db
].v
= NULLDATAOFF
;
1844 /* update number of data blocks processed */
1845 if (freetab
->nents
< db
+ 1)
1846 freetab
->nents
= db
+ 1;
1848 tp
= libxfs_trans_alloc(mp
, 0);
1849 error
= libxfs_trans_reserve(tp
, 0, XFS_REMOVE_LOG_RES(mp
), 0,
1850 XFS_TRANS_PERM_LOG_RES
, XFS_REMOVE_LOG_COUNT
);
1853 libxfs_trans_ijoin(tp
, ip
, 0);
1854 libxfs_trans_ihold(tp
, ip
);
1855 libxfs_da_bjoin(tp
, bp
);
1857 libxfs_da_bhold(tp
, bp
);
1858 XFS_BMAP_INIT(&flist
, &firstblock
);
1859 if (INT_GET(d
->hdr
.magic
, ARCH_CONVERT
) != wantmagic
) {
1860 do_warn(_("bad directory block magic # %#x for directory inode "
1862 INT_GET(d
->hdr
.magic
, ARCH_CONVERT
), ip
->i_ino
, da_bno
);
1864 do_warn(_("fixing magic # to %#x\n"), wantmagic
);
1865 INT_SET(d
->hdr
.magic
, ARCH_CONVERT
, wantmagic
);
1868 do_warn(_("would fix magic # to %#x\n"), wantmagic
);
1873 * look at each entry. reference inode pointed to by each
1874 * entry in the incore inode tree.
1875 * if not a directory, set reached flag, increment link count
1876 * if a directory and reached, mark entry as to be deleted.
1877 * if a directory, check to see if recorded parent
1878 * matches current inode #,
1879 * if so, then set reached flag, increment link count
1880 * of current and child dir inodes, push the child
1881 * directory inode onto the directory stack.
1882 * if current inode != parent, then mark entry to be deleted.
1884 while (ptr
< endptr
) {
1885 dup
= (xfs_dir2_data_unused_t
*)ptr
;
1886 if (INT_GET(dup
->freetag
, ARCH_CONVERT
) ==
1887 XFS_DIR2_DATA_FREE_TAG
) {
1889 do_warn(_("directory inode %llu block %u has "
1890 "consecutive free entries: "),
1893 do_warn(_("joining together\n"));
1894 len
= INT_GET(dup
->length
, ARCH_CONVERT
);
1895 libxfs_dir2_data_use_free(tp
, bp
, dup
,
1896 ptr
- (char *)d
, len
, &needlog
,
1898 libxfs_dir2_data_make_free(tp
, bp
,
1899 ptr
- (char *)d
, len
, &needlog
,
1902 do_warn(_("would join together\n"));
1904 ptr
+= INT_GET(dup
->length
, ARCH_CONVERT
);
1908 addr
= XFS_DIR2_DB_OFF_TO_DATAPTR(mp
, db
, ptr
- (char *)d
);
1909 dep
= (xfs_dir2_data_entry_t
*)ptr
;
1910 ptr
+= XFS_DIR2_DATA_ENTSIZE(dep
->namelen
);
1912 dir_hash_add(hashtab
,
1913 libxfs_da_hashname((char *)dep
->name
, dep
->namelen
),
1914 addr
, dep
->name
[0] == '/');
1916 * skip bogus entries (leading '/'). they'll be deleted
1919 if (dep
->name
[0] == '/') {
1924 bcopy(dep
->name
, fname
, dep
->namelen
);
1925 fname
[dep
->namelen
] = '\0';
1926 ASSERT(INT_GET(dep
->inumber
, ARCH_CONVERT
) != NULLFSINO
);
1928 * skip the '..' entry since it's checked when the
1929 * directory is reached by something else. if it never
1930 * gets reached, it'll be moved to the orphanage and we'll
1931 * take care of it then.
1933 if (dep
->namelen
== 2 && dep
->name
[0] == '.' &&
1934 dep
->name
[1] == '.')
1936 ASSERT(no_modify
|| !verify_inum(mp
, INT_GET(dep
->inumber
, ARCH_CONVERT
)));
1938 * special case the . entry. we know there's only one
1939 * '.' and only '.' points to itself because bogus entries
1940 * got trashed in phase 3 if there were > 1.
1941 * bump up link count for '.' but don't set reached
1942 * until we're actually reached by another directory
1943 * '..' is already accounted for or will be taken care
1944 * of when directory is moved to orphanage.
1946 if (ip
->i_ino
== INT_GET(dep
->inumber
, ARCH_CONVERT
)) {
1947 ASSERT(dep
->name
[0] == '.' && dep
->namelen
== 1);
1948 add_inode_ref(current_irec
, current_ino_offset
);
1953 * special case the "lost+found" entry if pointing
1954 * to where we think lost+found should be. if that's
1955 * the case, that's the one we created in phase 6.
1956 * just skip it. no need to process it and it's ..
1957 * link is already accounted for.
1959 if (INT_GET(dep
->inumber
, ARCH_CONVERT
) == orphanage_ino
&&
1960 strcmp(fname
, ORPHANAGE
) == 0)
1963 * skip entries with bogus inumbers if we're in no modify mode
1966 verify_inum(mp
, INT_GET(dep
->inumber
, ARCH_CONVERT
)))
1969 * ok, now handle the rest of the cases besides '.' and '..'
1971 irec
= find_inode_rec(
1973 INT_GET(dep
->inumber
, ARCH_CONVERT
)),
1974 XFS_INO_TO_AGINO(mp
,
1975 INT_GET(dep
->inumber
, ARCH_CONVERT
)));
1978 do_warn(_("entry \"%s\" in directory inode %llu points "
1979 "to non-existent inode, "),
1983 libxfs_dir2_data_log_entry(tp
, bp
, dep
);
1984 do_warn(_("marking entry to be junked\n"));
1986 do_warn(_("would junk entry\n"));
1990 ino_offset
= XFS_INO_TO_AGINO(mp
,
1991 INT_GET(dep
->inumber
, ARCH_CONVERT
)) -
1994 * if it's a free inode, blow out the entry.
1995 * by now, any inode that we think is free
1998 if (is_inode_free(irec
, ino_offset
)) {
2000 * don't complain if this entry points to the old
2001 * and now-free lost+found inode
2003 if (verbose
|| no_modify
||
2004 INT_GET(dep
->inumber
, ARCH_CONVERT
) !=
2007 _("entry \"%s\" in directory inode %llu points to free inode %llu"),
2009 INT_GET(dep
->inumber
, ARCH_CONVERT
));
2013 INT_GET(dep
->inumber
, ARCH_CONVERT
) !=
2016 _(", marking entry to be junked\n"));
2020 libxfs_dir2_data_log_entry(tp
, bp
, dep
);
2022 do_warn(_(", would junk entry\n"));
2027 * check easy case first, regular inode, just bump
2028 * the link count and continue
2030 if (!inode_isadir(irec
, ino_offset
)) {
2031 add_inode_reached(irec
, ino_offset
);
2034 parent
= get_inode_parent(irec
, ino_offset
);
2035 ASSERT(parent
!= 0);
2037 * bump up the link counts in parent and child
2038 * directory but if the link doesn't agree with
2039 * the .. in the child, blow out the entry.
2040 * if the directory has already been reached,
2041 * blow away the entry also.
2043 if (is_inode_reached(irec
, ino_offset
)) {
2046 _("entry \"%s\" in dir %llu points to an already connected directory inode %llu,\n"),
2048 INT_GET(dep
->inumber
, ARCH_CONVERT
));
2049 } else if (parent
== ip
->i_ino
) {
2050 add_inode_reached(irec
, ino_offset
);
2051 add_inode_ref(current_irec
, current_ino_offset
);
2052 if (!is_inode_refchecked(
2053 INT_GET(dep
->inumber
, ARCH_CONVERT
), irec
,
2056 INT_GET(dep
->inumber
, ARCH_CONVERT
));
2060 _("entry \"%s\" in dir inode %llu inconsistent with .. value (%llu) in ino %llu,\n"),
2061 fname
, ip
->i_ino
, parent
,
2062 INT_GET(dep
->inumber
, ARCH_CONVERT
));
2069 libxfs_dir2_data_log_entry(tp
, bp
, dep
);
2071 INT_GET(dep
->inumber
, ARCH_CONVERT
) !=
2074 _("\twill clear entry \"%s\"\n"),
2077 do_warn(_("\twould clear entry \"%s\"\n"),
2082 *num_illegal
+= nbad
;
2084 libxfs_dir2_data_freescan(mp
, d
, &needlog
, NULL
);
2086 libxfs_dir2_data_log_header(tp
, bp
);
2087 libxfs_bmap_finish(&tp
, &flist
, firstblock
, &committed
);
2088 libxfs_trans_commit(tp
, 0, 0);
2089 freetab
->ents
[db
].v
= INT_GET(d
->hdr
.bestfree
[0].length
, ARCH_CONVERT
);
2090 freetab
->ents
[db
].s
= 0;
2094 * Check contents of leaf-form block.
2097 longform_dir2_check_leaf(
2100 dir_hash_tab_t
*hashtab
,
2104 xfs_dir2_data_off_t
*bestsp
;
2108 xfs_dir2_leaf_t
*leaf
;
2109 xfs_dir2_leaf_tail_t
*ltp
;
2112 da_bno
= mp
->m_dirleafblk
;
2113 if (libxfs_da_read_bufr(NULL
, ip
, da_bno
, -1, &bp
, XFS_DATA_FORK
)) {
2114 do_error(_("can't read block %u for directory inode %llu\n"),
2119 ltp
= XFS_DIR2_LEAF_TAIL_P(mp
, leaf
);
2120 bestsp
= XFS_DIR2_LEAF_BESTS_P_ARCH(ltp
, ARCH_CONVERT
);
2121 if (INT_GET(leaf
->hdr
.info
.magic
, ARCH_CONVERT
) !=
2122 XFS_DIR2_LEAF1_MAGIC
||
2123 INT_GET(leaf
->hdr
.info
.forw
, ARCH_CONVERT
) ||
2124 INT_GET(leaf
->hdr
.info
.back
, ARCH_CONVERT
) ||
2125 INT_GET(leaf
->hdr
.count
, ARCH_CONVERT
) <
2126 INT_GET(leaf
->hdr
.stale
, ARCH_CONVERT
) ||
2127 INT_GET(leaf
->hdr
.count
, ARCH_CONVERT
) >
2128 XFS_DIR2_MAX_LEAF_ENTS(mp
) ||
2129 (char *)&leaf
->ents
[INT_GET(leaf
->hdr
.count
, ARCH_CONVERT
)] >
2132 _("leaf block %u for directory inode %llu bad header\n"),
2134 libxfs_da_brelse(NULL
, bp
);
2137 seeval
= dir_hash_see_all(hashtab
, leaf
->ents
,
2138 INT_GET(leaf
->hdr
.count
, ARCH_CONVERT
),
2139 INT_GET(leaf
->hdr
.stale
, ARCH_CONVERT
));
2140 if (dir_hash_check(hashtab
, ip
, seeval
)) {
2141 libxfs_da_brelse(NULL
, bp
);
2144 badtail
= freetab
->nents
!= INT_GET(ltp
->bestcount
, ARCH_CONVERT
);
2145 for (i
= 0; !badtail
&& i
< INT_GET(ltp
->bestcount
, ARCH_CONVERT
); i
++) {
2146 freetab
->ents
[i
].s
= 1;
2147 badtail
= freetab
->ents
[i
].v
!= INT_GET(bestsp
[i
], ARCH_CONVERT
);
2150 do_warn(_("leaf block %u for directory inode %llu bad tail\n"),
2152 libxfs_da_brelse(NULL
, bp
);
2155 libxfs_da_brelse(NULL
, bp
);
2160 * Check contents of the node blocks (leaves)
2161 * Looks for matching hash values for the data entries.
2164 longform_dir2_check_node(
2167 dir_hash_tab_t
*hashtab
,
2173 xfs_dir2_free_t
*free
;
2175 xfs_dir2_leaf_t
*leaf
;
2176 xfs_fileoff_t next_da_bno
;
2180 for (da_bno
= mp
->m_dirleafblk
, next_da_bno
= 0;
2181 next_da_bno
!= NULLFILEOFF
&& da_bno
< mp
->m_dirfreeblk
;
2182 da_bno
= (xfs_dablk_t
)next_da_bno
) {
2183 next_da_bno
= da_bno
+ mp
->m_dirblkfsbs
- 1;
2184 if (libxfs_bmap_next_offset(NULL
, ip
, &next_da_bno
, XFS_DATA_FORK
))
2186 if (libxfs_da_read_bufr(NULL
, ip
, da_bno
, -1, &bp
,
2189 _("can't read block %u for directory inode %llu\n"),
2194 if (INT_GET(leaf
->hdr
.info
.magic
, ARCH_CONVERT
) !=
2195 XFS_DIR2_LEAFN_MAGIC
) {
2196 if (INT_GET(leaf
->hdr
.info
.magic
, ARCH_CONVERT
) ==
2197 XFS_DA_NODE_MAGIC
) {
2198 libxfs_da_brelse(NULL
, bp
);
2201 do_warn(_("unknown magic number %#x for block %u in "
2202 "directory inode %llu\n"),
2203 INT_GET(leaf
->hdr
.info
.magic
, ARCH_CONVERT
),
2205 libxfs_da_brelse(NULL
, bp
);
2208 if (INT_GET(leaf
->hdr
.count
, ARCH_CONVERT
) <
2209 INT_GET(leaf
->hdr
.stale
, ARCH_CONVERT
) ||
2210 INT_GET(leaf
->hdr
.count
, ARCH_CONVERT
) >
2211 XFS_DIR2_MAX_LEAF_ENTS(mp
)) {
2212 do_warn(_("leaf block %u for directory inode %llu bad "
2215 libxfs_da_brelse(NULL
, bp
);
2218 seeval
= dir_hash_see_all(hashtab
, leaf
->ents
, INT_GET(leaf
->hdr
.count
, ARCH_CONVERT
),
2219 INT_GET(leaf
->hdr
.stale
, ARCH_CONVERT
));
2220 libxfs_da_brelse(NULL
, bp
);
2221 if (seeval
!= DIR_HASH_CK_OK
)
2224 if (dir_hash_check(hashtab
, ip
, seeval
))
2226 for (da_bno
= mp
->m_dirfreeblk
, next_da_bno
= 0;
2227 next_da_bno
!= NULLFILEOFF
;
2228 da_bno
= (xfs_dablk_t
)next_da_bno
) {
2229 next_da_bno
= da_bno
+ mp
->m_dirblkfsbs
- 1;
2230 if (libxfs_bmap_next_offset(NULL
, ip
, &next_da_bno
, XFS_DATA_FORK
))
2232 if (libxfs_da_read_bufr(NULL
, ip
, da_bno
, -1, &bp
,
2234 do_error(_("can't read block %u for directory inode "
2240 fdb
= XFS_DIR2_DA_TO_DB(mp
, da_bno
);
2241 if (INT_GET(free
->hdr
.magic
, ARCH_CONVERT
) !=
2242 XFS_DIR2_FREE_MAGIC
||
2243 INT_GET(free
->hdr
.firstdb
, ARCH_CONVERT
) !=
2244 (fdb
- XFS_DIR2_FREE_FIRSTDB(mp
)) *
2245 XFS_DIR2_MAX_FREE_BESTS(mp
) ||
2246 INT_GET(free
->hdr
.nvalid
, ARCH_CONVERT
) <
2247 INT_GET(free
->hdr
.nused
, ARCH_CONVERT
)) {
2248 do_warn(_("free block %u for directory inode %llu bad "
2251 libxfs_da_brelse(NULL
, bp
);
2254 for (i
= used
= 0; i
< INT_GET(free
->hdr
.nvalid
, ARCH_CONVERT
); i
++) {
2255 if (i
+ INT_GET(free
->hdr
.firstdb
, ARCH_CONVERT
) >=
2257 freetab
->ents
[i
+ INT_GET(free
->hdr
.firstdb
,
2259 INT_GET(free
->bests
[i
], ARCH_CONVERT
)) {
2261 _("free block %u entry %i for directory ino %llu bad\n"),
2262 da_bno
, i
, ip
->i_ino
);
2263 libxfs_da_brelse(NULL
, bp
);
2266 used
+= INT_GET(free
->bests
[i
], ARCH_CONVERT
) != NULLDATAOFF
;
2267 freetab
->ents
[i
+ INT_GET(free
->hdr
.firstdb
, ARCH_CONVERT
)].s
= 1;
2269 if (used
!= INT_GET(free
->hdr
.nused
, ARCH_CONVERT
)) {
2270 do_warn(_("free block %u for directory inode %llu bad "
2273 libxfs_da_brelse(NULL
, bp
);
2276 libxfs_da_brelse(NULL
, bp
);
2278 for (i
= 0; i
< freetab
->nents
; i
++) {
2279 if (freetab
->ents
[i
].s
== 0) {
2280 do_warn(_("missing freetab entry %u for "
2281 "directory inode %llu\n"),
2290 * Rebuild a directory: set up.
2291 * Turn it into a node-format directory with no contents in the
2292 * upper area. Also has correct freespace blocks.
2295 longform_dir2_rebuild_setup(
2303 xfs_dir2_data_t
*data
= NULL
;
2308 xfs_fsblock_t firstblock
;
2309 xfs_bmap_free_t flist
;
2310 xfs_dir2_free_t
*free
;
2315 xfs_dir2_leaf_t
*leaf
;
2319 /* read first directory block */
2320 tp
= libxfs_trans_alloc(mp
, 0);
2321 nres
= XFS_DAENTER_SPACE_RES(mp
, XFS_DATA_FORK
);
2322 error
= libxfs_trans_reserve(tp
,
2323 nres
, XFS_CREATE_LOG_RES(mp
), 0, XFS_TRANS_PERM_LOG_RES
,
2324 XFS_CREATE_LOG_COUNT
);
2327 libxfs_trans_ijoin(tp
, ip
, 0);
2328 libxfs_trans_ihold(tp
, ip
);
2329 XFS_BMAP_INIT(&flist
, &firstblock
);
2330 if (libxfs_da_read_buf(tp
, ip
, mp
->m_dirdatablk
, -2, &dbp
,
2332 do_error(_("can't read block %u for directory inode %llu\n"),
2333 mp
->m_dirdatablk
, ino
);
2340 /* check for block format directory */
2342 INT_GET((data
)->hdr
.magic
, ARCH_CONVERT
) == XFS_DIR2_BLOCK_MAGIC
) {
2343 xfs_dir2_block_t
*block
;
2344 xfs_dir2_leaf_entry_t
*blp
;
2345 xfs_dir2_block_tail_t
*btp
;
2349 /* convert directory block from block format to data format */
2350 INT_SET(data
->hdr
.magic
, ARCH_CONVERT
, XFS_DIR2_DATA_MAGIC
);
2352 /* construct freelist */
2353 block
= (xfs_dir2_block_t
*)data
;
2354 btp
= XFS_DIR2_BLOCK_TAIL_P(mp
, block
);
2355 blp
= XFS_DIR2_BLOCK_LEAF_P_ARCH(btp
, ARCH_CONVERT
);
2356 needlog
= needscan
= 0;
2357 libxfs_dir2_data_make_free(tp
, dbp
, (char *)blp
- (char *)block
,
2358 (char *)block
+ mp
->m_dirblksize
- (char *)blp
,
2359 &needlog
, &needscan
);
2361 libxfs_dir2_data_freescan(mp
, data
, &needlog
, NULL
);
2362 libxfs_da_log_buf(tp
, dbp
, 0, mp
->m_dirblksize
- 1);
2365 /* allocate blocks for btree */
2366 bzero(&args
, sizeof(args
));
2369 args
.whichfork
= XFS_DATA_FORK
;
2370 args
.firstblock
= &firstblock
;
2371 args
.flist
= &flist
;
2373 if ((error
= libxfs_da_grow_inode(&args
, &lblkno
)) ||
2374 (error
= libxfs_da_get_buf(tp
, ip
, lblkno
, -1, &lbp
, XFS_DATA_FORK
))) {
2375 do_error(_("can't add btree block to directory inode %llu\n"),
2380 bzero(leaf
, mp
->m_dirblksize
);
2381 INT_SET(leaf
->hdr
.info
.magic
, ARCH_CONVERT
, XFS_DIR2_LEAFN_MAGIC
);
2382 libxfs_da_log_buf(tp
, lbp
, 0, mp
->m_dirblksize
- 1);
2383 libxfs_bmap_finish(&tp
, &flist
, firstblock
, &committed
);
2384 libxfs_trans_commit(tp
, 0, 0);
2386 for (i
= 0; i
< freetab
->nents
; i
+= XFS_DIR2_MAX_FREE_BESTS(mp
)) {
2387 tp
= libxfs_trans_alloc(mp
, 0);
2388 nres
= XFS_DAENTER_SPACE_RES(mp
, XFS_DATA_FORK
);
2389 error
= libxfs_trans_reserve(tp
,
2390 nres
, XFS_CREATE_LOG_RES(mp
), 0, XFS_TRANS_PERM_LOG_RES
,
2391 XFS_CREATE_LOG_COUNT
);
2394 libxfs_trans_ijoin(tp
, ip
, 0);
2395 libxfs_trans_ihold(tp
, ip
);
2396 XFS_BMAP_INIT(&flist
, &firstblock
);
2397 bzero(&args
, sizeof(args
));
2400 args
.whichfork
= XFS_DATA_FORK
;
2401 args
.firstblock
= &firstblock
;
2402 args
.flist
= &flist
;
2404 if ((error
= libxfs_dir2_grow_inode(&args
, XFS_DIR2_FREE_SPACE
,
2406 (error
= libxfs_da_get_buf(tp
, ip
, XFS_DIR2_DB_TO_DA(mp
, fbno
),
2407 -1, &fbp
, XFS_DATA_FORK
))) {
2408 do_error(_("can't add free block to directory inode "
2414 bzero(free
, mp
->m_dirblksize
);
2415 INT_SET(free
->hdr
.magic
, ARCH_CONVERT
, XFS_DIR2_FREE_MAGIC
);
2416 INT_SET(free
->hdr
.firstdb
, ARCH_CONVERT
, i
);
2417 INT_SET(free
->hdr
.nvalid
, ARCH_CONVERT
, XFS_DIR2_MAX_FREE_BESTS(mp
));
2418 if (i
+ INT_GET(free
->hdr
.nvalid
, ARCH_CONVERT
) > freetab
->nents
)
2419 INT_SET(free
->hdr
.nvalid
, ARCH_CONVERT
, freetab
->nents
- i
);
2420 for (j
= 0; j
< INT_GET(free
->hdr
.nvalid
, ARCH_CONVERT
); j
++) {
2421 INT_SET(free
->bests
[j
], ARCH_CONVERT
, freetab
->ents
[i
+ j
].v
);
2422 if (INT_GET(free
->bests
[j
], ARCH_CONVERT
) != NULLDATAOFF
)
2423 INT_MOD(free
->hdr
.nused
, ARCH_CONVERT
, +1);
2425 libxfs_da_log_buf(tp
, fbp
, 0, mp
->m_dirblksize
- 1);
2426 libxfs_bmap_finish(&tp
, &flist
, firstblock
, &committed
);
2427 libxfs_trans_commit(tp
, 0, 0);
2432 * Rebuild the entries from a single data block.
2435 longform_dir2_rebuild_data(
2442 xfs_dir2_block_tail_t
*btp
;
2444 xfs_dir2_data_t
*data
;
2446 xfs_dir2_data_entry_t
*dep
;
2447 xfs_dir2_data_unused_t
*dup
;
2450 xfs_dir2_free_t
*fblock
;
2454 xfs_fsblock_t firstblock
;
2455 xfs_bmap_free_t flist
;
2462 if (libxfs_da_read_buf(NULL
, ip
, da_bno
, da_bno
== 0 ? -2 : -1, &bp
,
2464 do_error(_("can't read block %u for directory inode %llu\n"),
2468 if (da_bno
== 0 && bp
== NULL
)
2470 * The block was punched out.
2474 dbno
= XFS_DIR2_DA_TO_DB(mp
, da_bno
);
2475 fdb
= XFS_DIR2_DB_TO_FDB(mp
, dbno
);
2476 if (libxfs_da_read_buf(NULL
, ip
, XFS_DIR2_DB_TO_DA(mp
, fdb
), -1, &fbp
,
2478 do_error(_("can't read block %u for directory inode %llu\n"),
2479 XFS_DIR2_DB_TO_DA(mp
, fdb
), ino
);
2482 data
= malloc(mp
->m_dirblksize
);
2485 _("malloc failed in longform_dir2_rebuild_data (%u bytes)\n"),
2489 bcopy(bp
->data
, data
, mp
->m_dirblksize
);
2490 ptr
= (char *)data
->u
;
2491 if (INT_GET(data
->hdr
.magic
, ARCH_CONVERT
) == XFS_DIR2_BLOCK_MAGIC
) {
2492 btp
= XFS_DIR2_BLOCK_TAIL_P(mp
, (xfs_dir2_block_t
*)data
);
2493 endptr
= (char *)XFS_DIR2_BLOCK_LEAF_P_ARCH(btp
, ARCH_CONVERT
);
2495 endptr
= (char *)data
+ mp
->m_dirblksize
;
2497 fi
= XFS_DIR2_DB_TO_FDINDEX(mp
, dbno
);
2498 tp
= libxfs_trans_alloc(mp
, 0);
2499 error
= libxfs_trans_reserve(tp
, 0, XFS_CREATE_LOG_RES(mp
), 0,
2500 XFS_TRANS_PERM_LOG_RES
, XFS_CREATE_LOG_COUNT
);
2503 libxfs_trans_ijoin(tp
, ip
, 0);
2504 libxfs_trans_ihold(tp
, ip
);
2505 libxfs_da_bjoin(tp
, bp
);
2506 libxfs_da_bhold(tp
, bp
);
2507 libxfs_da_bjoin(tp
, fbp
);
2508 libxfs_da_bhold(tp
, fbp
);
2509 XFS_BMAP_INIT(&flist
, &firstblock
);
2510 needlog
= needscan
= 0;
2511 bzero(((xfs_dir2_data_t
*)(bp
->data
))->hdr
.bestfree
,
2512 sizeof(data
->hdr
.bestfree
));
2513 libxfs_dir2_data_make_free(tp
, bp
, (xfs_dir2_data_aoff_t
)sizeof(data
->hdr
),
2514 mp
->m_dirblksize
- sizeof(data
->hdr
), &needlog
, &needscan
);
2515 ASSERT(needscan
== 0);
2516 libxfs_dir2_data_log_header(tp
, bp
);
2517 INT_SET(fblock
->bests
[fi
], ARCH_CONVERT
,
2518 INT_GET(((xfs_dir2_data_t
*)(bp
->data
))->hdr
.bestfree
[0].length
, ARCH_CONVERT
));
2519 libxfs_dir2_free_log_bests(tp
, fbp
, fi
, fi
);
2520 libxfs_bmap_finish(&tp
, &flist
, firstblock
, &committed
);
2521 libxfs_trans_commit(tp
, 0, 0);
2523 while (ptr
< endptr
) {
2524 dup
= (xfs_dir2_data_unused_t
*)ptr
;
2525 if (INT_GET(dup
->freetag
, ARCH_CONVERT
) == XFS_DIR2_DATA_FREE_TAG
) {
2526 ptr
+= INT_GET(dup
->length
, ARCH_CONVERT
);
2529 dep
= (xfs_dir2_data_entry_t
*)ptr
;
2530 ptr
+= XFS_DIR2_DATA_ENTSIZE(dep
->namelen
);
2531 if (dep
->name
[0] == '/')
2533 tp
= libxfs_trans_alloc(mp
, 0);
2534 nres
= XFS_CREATE_SPACE_RES(mp
, dep
->namelen
);
2535 error
= libxfs_trans_reserve(tp
, nres
, XFS_CREATE_LOG_RES(mp
), 0,
2536 XFS_TRANS_PERM_LOG_RES
, XFS_CREATE_LOG_COUNT
);
2539 libxfs_trans_ijoin(tp
, ip
, 0);
2540 libxfs_trans_ihold(tp
, ip
);
2541 libxfs_da_bjoin(tp
, bp
);
2542 libxfs_da_bhold(tp
, bp
);
2543 libxfs_da_bjoin(tp
, fbp
);
2544 libxfs_da_bhold(tp
, fbp
);
2545 XFS_BMAP_INIT(&flist
, &firstblock
);
2546 error
= dir_createname(mp
, tp
, ip
, (char *)dep
->name
,
2547 dep
->namelen
, INT_GET(dep
->inumber
, ARCH_CONVERT
),
2548 &firstblock
, &flist
, nres
);
2550 libxfs_bmap_finish(&tp
, &flist
, firstblock
, &committed
);
2551 libxfs_trans_commit(tp
, 0, 0);
2553 libxfs_da_brelse(NULL
, bp
);
2554 libxfs_da_brelse(NULL
, fbp
);
2559 * Finish the rebuild of a directory.
2560 * Stuff / in and then remove it, this forces the directory to end
2561 * up in the right format.
2564 longform_dir2_rebuild_finish(
2571 xfs_fsblock_t firstblock
;
2572 xfs_bmap_free_t flist
;
2576 tp
= libxfs_trans_alloc(mp
, 0);
2577 nres
= XFS_CREATE_SPACE_RES(mp
, 1);
2578 error
= libxfs_trans_reserve(tp
, nres
, XFS_CREATE_LOG_RES(mp
), 0,
2579 XFS_TRANS_PERM_LOG_RES
, XFS_CREATE_LOG_COUNT
);
2582 libxfs_trans_ijoin(tp
, ip
, 0);
2583 libxfs_trans_ihold(tp
, ip
);
2584 XFS_BMAP_INIT(&flist
, &firstblock
);
2585 error
= dir_createname(mp
, tp
, ip
, "/", 1, ino
,
2586 &firstblock
, &flist
, nres
);
2588 libxfs_bmap_finish(&tp
, &flist
, firstblock
, &committed
);
2589 libxfs_trans_commit(tp
, 0, 0);
2591 /* could kill trailing empty data blocks here */
2593 tp
= libxfs_trans_alloc(mp
, 0);
2594 nres
= XFS_REMOVE_SPACE_RES(mp
);
2595 error
= libxfs_trans_reserve(tp
, nres
, XFS_REMOVE_LOG_RES(mp
), 0,
2596 XFS_TRANS_PERM_LOG_RES
, XFS_REMOVE_LOG_COUNT
);
2599 libxfs_trans_ijoin(tp
, ip
, 0);
2600 libxfs_trans_ihold(tp
, ip
);
2601 XFS_BMAP_INIT(&flist
, &firstblock
);
2602 error
= dir_removename(mp
, tp
, ip
, "/", 1, ino
,
2603 &firstblock
, &flist
, nres
);
2605 libxfs_bmap_finish(&tp
, &flist
, firstblock
, &committed
);
2606 libxfs_trans_commit(tp
, 0, 0);
2610 * Rebuild a directory.
2611 * Remove all the non-data blocks.
2612 * Re-initialize to (empty) node form.
2613 * Loop over the data blocks reinserting each entry.
2614 * Force the directory into the right format.
2617 longform_dir2_rebuild(
2627 xfs_fileoff_t next_da_bno
;
2629 do_warn(_("rebuilding directory inode %llu\n"), ino
);
2631 /* kill leaf blocks */
2632 for (da_bno
= mp
->m_dirleafblk
, next_da_bno
= isblock
? NULLFILEOFF
: 0;
2633 next_da_bno
!= NULLFILEOFF
;
2634 da_bno
= (xfs_dablk_t
)next_da_bno
) {
2635 next_da_bno
= da_bno
+ mp
->m_dirblkfsbs
- 1;
2636 if (libxfs_bmap_next_offset(NULL
, ip
, &next_da_bno
, XFS_DATA_FORK
))
2638 if (libxfs_da_get_buf(NULL
, ip
, da_bno
, -1, &bp
, XFS_DATA_FORK
)) {
2639 do_error(_("can't get block %u for directory inode "
2644 dir2_kill_block(mp
, ip
, da_bno
, bp
);
2647 /* rebuild empty btree and freelist */
2648 longform_dir2_rebuild_setup(mp
, ino
, ip
, freetab
);
2650 /* rebuild directory */
2651 for (da_bno
= mp
->m_dirdatablk
, next_da_bno
= 0;
2652 da_bno
< mp
->m_dirleafblk
&& next_da_bno
!= NULLFILEOFF
;
2653 da_bno
= (xfs_dablk_t
)next_da_bno
) {
2654 next_da_bno
= da_bno
+ mp
->m_dirblkfsbs
- 1;
2655 if (libxfs_bmap_next_offset(NULL
, ip
, &next_da_bno
, XFS_DATA_FORK
))
2657 longform_dir2_rebuild_data(mp
, ino
, ip
, da_bno
);
2660 /* put the directory in the appropriate on-disk format */
2661 longform_dir2_rebuild_finish(mp
, ino
, ip
);
2666 * succeeds or dies, inode never gets dirtied since all changes
2667 * happen in file blocks. the inode size and other core info
2668 * is already correct, it's just the leaf entries that get altered.
2669 * XXX above comment is wrong for v2 - need to see why it matters
2672 longform_dir2_entry_check(xfs_mount_t
*mp
,
2678 ino_tree_node_t
*irec
,
2681 xfs_dir2_block_t
*block
;
2682 xfs_dir2_leaf_entry_t
*blp
;
2684 xfs_dir2_block_tail_t
*btp
;
2687 dir_hash_tab_t
*hashtab
;
2691 xfs_fileoff_t next_da_bno
;
2696 freetab
= malloc(FREETAB_SIZE(ip
->i_d
.di_size
/ mp
->m_dirblksize
));
2699 _("malloc failed in longform_dir2_entry_check (%u bytes)\n"),
2700 FREETAB_SIZE(ip
->i_d
.di_size
/ mp
->m_dirblksize
));
2703 freetab
->naents
= ip
->i_d
.di_size
/ mp
->m_dirblksize
;
2705 for (i
= 0; i
< freetab
->naents
; i
++) {
2706 freetab
->ents
[i
].v
= NULLDATAOFF
;
2707 freetab
->ents
[i
].s
= 0;
2709 /* is this a block, leaf, or node directory? */
2710 libxfs_dir2_isblock(NULL
, ip
, &isblock
);
2711 libxfs_dir2_isleaf(NULL
, ip
, &isleaf
);
2713 /* check directory data */
2714 hashtab
= dir_hash_init(ip
->i_d
.di_size
);
2715 for (da_bno
= 0, next_da_bno
= 0;
2716 next_da_bno
!= NULLFILEOFF
&& da_bno
< mp
->m_dirleafblk
;
2717 da_bno
= (xfs_dablk_t
)next_da_bno
) {
2718 next_da_bno
= da_bno
+ mp
->m_dirblkfsbs
- 1;
2719 if (libxfs_bmap_next_offset(NULL
, ip
, &next_da_bno
, XFS_DATA_FORK
))
2721 if (libxfs_da_read_bufr(NULL
, ip
, da_bno
, -1, &bp
,
2723 do_error(_("can't read block %u for directory inode "
2728 longform_dir2_entry_check_data(mp
, ip
, num_illegal
, need_dot
,
2729 stack
, irec
, ino_offset
, &bp
, hashtab
, &freetab
, da_bno
,
2731 /* it releases the buffer unless isblock is set */
2733 fixit
= (*num_illegal
!= 0) || dir2_is_badino(ino
);
2735 /* check btree and freespace */
2739 btp
= XFS_DIR2_BLOCK_TAIL_P(mp
, block
);
2740 blp
= XFS_DIR2_BLOCK_LEAF_P_ARCH(btp
, ARCH_CONVERT
);
2741 seeval
= dir_hash_see_all(hashtab
, blp
, INT_GET(btp
->count
, ARCH_CONVERT
), INT_GET(btp
->stale
, ARCH_CONVERT
));
2742 if (dir_hash_check(hashtab
, ip
, seeval
))
2744 libxfs_da_brelse(NULL
, bp
);
2745 } else if (isleaf
) {
2746 fixit
|= longform_dir2_check_leaf(mp
, ip
, hashtab
, freetab
);
2748 fixit
|= longform_dir2_check_node(mp
, ip
, hashtab
, freetab
);
2750 dir_hash_done(hashtab
);
2751 if (!no_modify
&& fixit
)
2752 longform_dir2_rebuild(mp
, ino
, ip
, num_illegal
, freetab
,
2758 * shortform directory processing routines -- entry verification and
2759 * bad entry deletion (pruning).
2762 shortform_dir_entry_check(xfs_mount_t
*mp
,
2767 ino_tree_node_t
*current_irec
,
2768 int current_ino_offset
)
2772 xfs_dir_shortform_t
*sf
;
2773 xfs_dir_sf_entry_t
*sf_entry
, *next_sfe
, *tmp_sfe
;
2775 ino_tree_node_t
*irec
;
2785 char fname
[MAXNAMELEN
+ 1];
2788 sf
= (xfs_dir_shortform_t
*) ifp
->if_u1
.if_data
;
2792 max_size
= ifp
->if_bytes
;
2793 ASSERT(ip
->i_d
.di_size
<= ifp
->if_bytes
);
2796 * no '.' entry in shortform dirs, just bump up ref count by 1
2797 * '..' was already (or will be) accounted for and checked when
2798 * the directory is reached or will be taken care of when the
2799 * directory is moved to orphanage.
2801 add_inode_ref(current_irec
, current_ino_offset
);
2804 * now run through entries, stop at first bad entry, don't need
2805 * to skip over '..' since that's encoded in its own field and
2806 * no need to worry about '.' since it doesn't exist.
2808 sf_entry
= next_sfe
= &sf
->list
[0];
2811 do_warn(_("shortform dir inode %llu has null data entries \n"),
2816 for (i
= 0; i
< INT_GET(sf
->hdr
.count
, ARCH_CONVERT
) && max_size
>
2817 (__psint_t
)next_sfe
- (__psint_t
)sf
;
2818 sf_entry
= next_sfe
, i
++) {
2823 XFS_DIR_SF_GET_DIRINO_ARCH(&sf_entry
->inumber
, &lino
, ARCH_CONVERT
);
2825 namelen
= sf_entry
->namelen
;
2827 ASSERT(no_modify
|| namelen
> 0);
2829 if (no_modify
&& namelen
== 0) {
2831 * if we're really lucky, this is
2832 * the last entry in which case we
2833 * can use the dir size to set the
2834 * namelen value. otherwise, forget
2835 * it because we're not going to be
2836 * able to find the next entry.
2840 if (i
== INT_GET(sf
->hdr
.count
, ARCH_CONVERT
) - 1) {
2841 namelen
= ip
->i_d
.di_size
-
2842 ((__psint_t
) &sf_entry
->name
[0] -
2846 * don't process the rest of the directory,
2847 * break out of processing looop
2851 } else if (no_modify
&& (__psint_t
) sf_entry
- (__psint_t
) sf
+
2852 + XFS_DIR_SF_ENTSIZE_BYENTRY(sf_entry
)
2853 > ip
->i_d
.di_size
) {
2856 if (i
== INT_GET(sf
->hdr
.count
, ARCH_CONVERT
) - 1) {
2857 namelen
= ip
->i_d
.di_size
-
2858 ((__psint_t
) &sf_entry
->name
[0] -
2862 * don't process the rest of the directory,
2863 * break out of processing looop
2869 bcopy(sf_entry
->name
, fname
, sf_entry
->namelen
);
2870 fname
[sf_entry
->namelen
] = '\0';
2872 ASSERT(no_modify
|| lino
!= NULLFSINO
);
2873 ASSERT(no_modify
|| !verify_inum(mp
, lino
));
2876 * special case the "lost+found" entry if it's pointing
2877 * to where we think lost+found should be. if that's
2878 * the case, that's the one we created in phase 6.
2879 * just skip it. no need to process it and its ..
2880 * link is already accounted for. Also skip entries
2881 * with bogus inode numbers if we're in no modify mode.
2884 if ((lino
== orphanage_ino
&& strcmp(fname
, ORPHANAGE
) == 0)
2885 || (no_modify
&& verify_inum(mp
, lino
))) {
2886 next_sfe
= (xfs_dir_sf_entry_t
*)
2887 ((__psint_t
) sf_entry
+
2888 XFS_DIR_SF_ENTSIZE_BYENTRY(sf_entry
));
2892 irec
= find_inode_rec(XFS_INO_TO_AGNO(mp
, lino
),
2893 XFS_INO_TO_AGINO(mp
, lino
));
2895 if (irec
== NULL
&& no_modify
) {
2897 _("entry \"%s\" in shortform dir %llu references non-existent ino %llu\n"),
2899 do_warn(_("would junk entry\n"));
2903 ASSERT(irec
!= NULL
);
2905 ino_offset
= XFS_INO_TO_AGINO(mp
, lino
) - irec
->ino_startnum
;
2908 * if it's a free inode, blow out the entry.
2909 * by now, any inode that we think is free
2912 if (is_inode_free(irec
, ino_offset
)) {
2914 * don't complain if this entry points to the old
2915 * and now-free lost+found inode
2917 if (verbose
|| no_modify
|| lino
!= old_orphanage_ino
)
2919 _("entry \"%s\" in shortform dir inode %llu points to free inode %llu\n"),
2925 do_warn(_("would junk entry \"%s\"\n"),
2928 } else if (!inode_isadir(irec
, ino_offset
)) {
2930 * check easy case first, regular inode, just bump
2931 * the link count and continue
2933 add_inode_reached(irec
, ino_offset
);
2935 next_sfe
= (xfs_dir_sf_entry_t
*)
2936 ((__psint_t
) sf_entry
+
2937 XFS_DIR_SF_ENTSIZE_BYENTRY(sf_entry
));
2940 parent
= get_inode_parent(irec
, ino_offset
);
2943 * bump up the link counts in parent and child.
2944 * directory but if the link doesn't agree with
2945 * the .. in the child, blow out the entry
2947 if (is_inode_reached(irec
, ino_offset
)) {
2950 _("entry \"%s\" in dir %llu references already connected dir ino %llu,\n"),
2952 } else if (parent
== ino
) {
2953 add_inode_reached(irec
, ino_offset
);
2954 add_inode_ref(current_irec
, current_ino_offset
);
2956 if (!is_inode_refchecked(lino
, irec
,
2958 push_dir(stack
, lino
);
2962 _("entry \"%s\" in dir %llu not consistent with .. value (%llu) in dir ino %llu,\n"),
2963 fname
, ino
, parent
, lino
);
2969 tmp_elen
= XFS_DIR_SF_ENTSIZE_BYENTRY(sf_entry
);
2970 tmp_sfe
= (xfs_dir_sf_entry_t
*)
2971 ((__psint_t
) sf_entry
+ tmp_elen
);
2972 tmp_len
= max_size
- ((__psint_t
) tmp_sfe
2974 max_size
-= tmp_elen
;
2975 bytes_deleted
+= tmp_elen
;
2977 memmove(sf_entry
, tmp_sfe
, tmp_len
);
2979 INT_MOD(sf
->hdr
.count
, ARCH_CONVERT
, -1);
2980 bzero((void *) ((__psint_t
) sf_entry
+ tmp_len
),
2984 * set the tmp value to the current
2985 * pointer so we'll process the entry
2991 * WARNING: drop the index i by one
2992 * so it matches the decremented count for
2993 * accurate comparisons in the loop test
2999 if (verbose
|| lino
!= old_orphanage_ino
)
3001 _("junking entry \"%s\" in directory inode %llu\n"),
3004 do_warn(_("would junk entry \"%s\"\n"), fname
);
3009 * go onto next entry unless we've just junked an
3010 * entry in which the current entry pointer points
3011 * to an unprocessed entry. have to take into entries
3012 * with bad namelen into account in no modify mode since we
3013 * calculate size based on next_sfe.
3015 ASSERT(no_modify
|| bad_sfnamelen
== 0);
3017 next_sfe
= (tmp_sfe
== NULL
)
3018 ? (xfs_dir_sf_entry_t
*) ((__psint_t
) sf_entry
3020 ? XFS_DIR_SF_ENTSIZE_BYENTRY(sf_entry
)
3021 : sizeof(xfs_dir_sf_entry_t
) - 1
3028 * sync up sizes if required
3031 ASSERT(bytes_deleted
> 0);
3033 libxfs_idata_realloc(ip
, -bytes_deleted
, XFS_DATA_FORK
);
3034 ip
->i_d
.di_size
-= bytes_deleted
;
3037 if (ip
->i_d
.di_size
!= ip
->i_df
.if_bytes
) {
3038 ASSERT(ip
->i_df
.if_bytes
== (xfs_fsize_t
)
3039 ((__psint_t
) next_sfe
- (__psint_t
) sf
));
3040 ip
->i_d
.di_size
= (xfs_fsize_t
)
3041 ((__psint_t
) next_sfe
- (__psint_t
) sf
);
3043 _("setting size to %lld bytes to reflect junked entries\n"),
3051 prune_sf_dir_entry(xfs_mount_t
*mp
, xfs_ino_t ino
, xfs_inode_t
*ip
)
3055 xfs_dir_shortform_t
*sf
;
3056 xfs_dir_sf_entry_t
*sf_entry
, *next_sfe
, *tmp_sfe
;
3063 char fname
[MAXNAMELEN
+ 1];
3066 sf
= (xfs_dir_shortform_t
*) ifp
->if_u1
.if_data
;
3069 max_size
= ifp
->if_bytes
;
3070 ASSERT(ip
->i_d
.di_size
<= ifp
->if_bytes
);
3073 * now run through entries and delete every bad entry
3075 sf_entry
= next_sfe
= &sf
->list
[0];
3077 for (i
= 0; i
< INT_GET(sf
->hdr
.count
, ARCH_CONVERT
) && max_size
>
3078 (__psint_t
)next_sfe
- (__psint_t
)sf
;
3079 sf_entry
= next_sfe
, i
++) {
3082 XFS_DIR_SF_GET_DIRINO_ARCH(&sf_entry
->inumber
, &lino
, ARCH_CONVERT
);
3084 bcopy(sf_entry
->name
, fname
, sf_entry
->namelen
);
3085 fname
[sf_entry
->namelen
] = '\0';
3087 if (sf_entry
->name
[0] == '/') {
3089 tmp_elen
= XFS_DIR_SF_ENTSIZE_BYENTRY(sf_entry
);
3090 tmp_sfe
= (xfs_dir_sf_entry_t
*)
3091 ((__psint_t
) sf_entry
+ tmp_elen
);
3092 tmp_len
= max_size
- ((__psint_t
) tmp_sfe
3094 max_size
-= tmp_elen
;
3095 bytes_deleted
+= tmp_elen
;
3097 memmove(sf_entry
, tmp_sfe
, tmp_len
);
3099 INT_MOD(sf
->hdr
.count
, ARCH_CONVERT
, -1);
3100 bzero((void *) ((__psint_t
) sf_entry
+ tmp_len
),
3104 * set the tmp value to the current
3105 * pointer so we'll process the entry
3111 * WARNING: drop the index i by one
3112 * so it matches the decremented count for
3113 * accurate comparisons in the loop test
3118 next_sfe
= (tmp_sfe
== NULL
)
3119 ? (xfs_dir_sf_entry_t
*) ((__psint_t
) sf_entry
+
3120 XFS_DIR_SF_ENTSIZE_BYENTRY(sf_entry
))
3125 * sync up sizes if required
3127 if (bytes_deleted
> 0) {
3128 libxfs_idata_realloc(ip
, -bytes_deleted
, XFS_DATA_FORK
);
3129 ip
->i_d
.di_size
-= bytes_deleted
;
3132 if (ip
->i_d
.di_size
!= ip
->i_df
.if_bytes
) {
3133 ASSERT(ip
->i_df
.if_bytes
== (xfs_fsize_t
)
3134 ((__psint_t
) next_sfe
- (__psint_t
) sf
));
3135 ip
->i_d
.di_size
= (xfs_fsize_t
)
3136 ((__psint_t
) next_sfe
- (__psint_t
) sf
);
3138 _("setting size to %lld bytes to reflect junked entries\n"),
3144 * shortform directory v2 processing routines -- entry verification and
3145 * bad entry deletion (pruning).
3148 shortform_dir2_entry_check(xfs_mount_t
*mp
,
3153 ino_tree_node_t
*current_irec
,
3154 int current_ino_offset
)
3159 xfs_dir2_sf_entry_t
*sfep
, *next_sfep
, *tmp_sfep
;
3161 ino_tree_node_t
*irec
;
3171 char fname
[MAXNAMELEN
+ 1];
3175 sfp
= (xfs_dir2_sf_t
*) ifp
->if_u1
.if_data
;
3179 max_size
= ifp
->if_bytes
;
3180 ASSERT(ip
->i_d
.di_size
<= ifp
->if_bytes
);
3183 * no '.' entry in shortform dirs, just bump up ref count by 1
3184 * '..' was already (or will be) accounted for and checked when
3185 * the directory is reached or will be taken care of when the
3186 * directory is moved to orphanage.
3188 add_inode_ref(current_irec
, current_ino_offset
);
3191 * Initialise i8 counter -- the parent inode number counts as well.
3193 i8
= (XFS_DIR2_SF_GET_INUMBER_ARCH(sfp
, &sfp
->hdr
.parent
, ARCH_CONVERT
) > XFS_DIR2_MAX_SHORT_INUM
);
3196 * now run through entries, stop at first bad entry, don't need
3197 * to skip over '..' since that's encoded in its own field and
3198 * no need to worry about '.' since it doesn't exist.
3200 sfep
= next_sfep
= XFS_DIR2_SF_FIRSTENTRY(sfp
);
3202 for (i
= 0; i
< INT_GET(sfp
->hdr
.count
, ARCH_CONVERT
) && max_size
>
3203 (__psint_t
)next_sfep
- (__psint_t
)sfp
;
3204 sfep
= next_sfep
, i
++) {
3209 lino
= XFS_DIR2_SF_GET_INUMBER_ARCH(sfp
, XFS_DIR2_SF_INUMBERP(sfep
), ARCH_CONVERT
);
3211 namelen
= sfep
->namelen
;
3213 ASSERT(no_modify
|| namelen
> 0);
3215 if (no_modify
&& namelen
== 0) {
3217 * if we're really lucky, this is
3218 * the last entry in which case we
3219 * can use the dir size to set the
3220 * namelen value. otherwise, forget
3221 * it because we're not going to be
3222 * able to find the next entry.
3226 if (i
== INT_GET(sfp
->hdr
.count
, ARCH_CONVERT
) - 1) {
3227 namelen
= ip
->i_d
.di_size
-
3228 ((__psint_t
) &sfep
->name
[0] -
3232 * don't process the rest of the directory,
3233 * break out of processing loop
3237 } else if (no_modify
&& (__psint_t
) sfep
- (__psint_t
) sfp
+
3238 + XFS_DIR2_SF_ENTSIZE_BYENTRY(sfp
, sfep
)
3239 > ip
->i_d
.di_size
) {
3242 if (i
== INT_GET(sfp
->hdr
.count
, ARCH_CONVERT
) - 1) {
3243 namelen
= ip
->i_d
.di_size
-
3244 ((__psint_t
) &sfep
->name
[0] -
3248 * don't process the rest of the directory,
3249 * break out of processing loop
3255 bcopy(sfep
->name
, fname
, sfep
->namelen
);
3256 fname
[sfep
->namelen
] = '\0';
3258 ASSERT(no_modify
|| (lino
!= NULLFSINO
&& lino
!= 0));
3259 ASSERT(no_modify
|| !verify_inum(mp
, lino
));
3262 * special case the "lost+found" entry if it's pointing
3263 * to where we think lost+found should be. if that's
3264 * the case, that's the one we created in phase 6.
3265 * just skip it. no need to process it and its ..
3266 * link is already accounted for.
3269 if (lino
== orphanage_ino
&& strcmp(fname
, ORPHANAGE
) == 0) {
3270 if (lino
> XFS_DIR2_MAX_SHORT_INUM
)
3272 next_sfep
= (xfs_dir2_sf_entry_t
*)
3274 XFS_DIR2_SF_ENTSIZE_BYENTRY(sfp
, sfep
));
3279 * Also skip entries with bogus inode numbers if we're
3280 * in no modify mode.
3283 if (no_modify
&& verify_inum(mp
, lino
)) {
3284 next_sfep
= (xfs_dir2_sf_entry_t
*)
3286 XFS_DIR2_SF_ENTSIZE_BYENTRY(sfp
, sfep
));
3290 irec
= find_inode_rec(XFS_INO_TO_AGNO(mp
, lino
),
3291 XFS_INO_TO_AGINO(mp
, lino
));
3293 if (irec
== NULL
&& no_modify
) {
3294 do_warn(_("entry \"%s\" in shortform directory %llu "
3295 "references non-existent inode %llu\n"),
3297 do_warn(_("would junk entry\n"));
3301 ASSERT(irec
!= NULL
);
3303 ino_offset
= XFS_INO_TO_AGINO(mp
, lino
) - irec
->ino_startnum
;
3306 * if it's a free inode, blow out the entry.
3307 * by now, any inode that we think is free
3310 if (is_inode_free(irec
, ino_offset
)) {
3312 * don't complain if this entry points to the old
3313 * and now-free lost+found inode
3315 if (verbose
|| no_modify
|| lino
!= old_orphanage_ino
)
3316 do_warn(_("entry \"%s\" in shortform directory "
3317 "inode %llu points to free inode "
3324 do_warn(_("would junk entry \"%s\"\n"),
3327 } else if (!inode_isadir(irec
, ino_offset
)) {
3329 * check easy case first, regular inode, just bump
3332 add_inode_reached(irec
, ino_offset
);
3334 parent
= get_inode_parent(irec
, ino_offset
);
3337 * bump up the link counts in parent and child.
3338 * directory but if the link doesn't agree with
3339 * the .. in the child, blow out the entry
3341 if (is_inode_reached(irec
, ino_offset
)) {
3343 do_warn(_("entry \"%s\" in directory inode %llu"
3344 " references already connected inode "
3347 } else if (parent
== ino
) {
3348 add_inode_reached(irec
, ino_offset
);
3349 add_inode_ref(current_irec
, current_ino_offset
);
3351 if (!is_inode_refchecked(lino
, irec
,
3353 push_dir(stack
, lino
);
3356 do_warn(_("entry \"%s\" in directory inode %llu"
3357 " not consistent with .. value (%llu)"
3358 " in inode %llu,\n"),
3359 fname
, ino
, parent
, lino
);
3365 tmp_elen
= XFS_DIR2_SF_ENTSIZE_BYENTRY(sfp
, sfep
);
3366 tmp_sfep
= (xfs_dir2_sf_entry_t
*)
3367 ((__psint_t
) sfep
+ tmp_elen
);
3368 tmp_len
= max_size
- ((__psint_t
) tmp_sfep
3370 max_size
-= tmp_elen
;
3371 bytes_deleted
+= tmp_elen
;
3373 memmove(sfep
, tmp_sfep
, tmp_len
);
3375 INT_MOD(sfp
->hdr
.count
, ARCH_CONVERT
, -1);
3376 bzero((void *) ((__psint_t
) sfep
+ tmp_len
),
3380 * set the tmp value to the current
3381 * pointer so we'll process the entry
3387 * WARNING: drop the index i by one
3388 * so it matches the decremented count for
3389 * accurate comparisons in the loop test
3395 if (verbose
|| lino
!= old_orphanage_ino
)
3396 do_warn(_("junking entry \"%s\" in "
3397 "directory inode %llu\n"),
3400 do_warn(_("would junk entry \"%s\"\n"), fname
);
3402 } else if (lino
> XFS_DIR2_MAX_SHORT_INUM
)
3406 * go onto next entry unless we've just junked an
3407 * entry in which the current entry pointer points
3408 * to an unprocessed entry. have to take into entries
3409 * with bad namelen into account in no modify mode since we
3410 * calculate size based on next_sfep.
3412 ASSERT(no_modify
|| bad_sfnamelen
== 0);
3414 next_sfep
= (tmp_sfep
== NULL
)
3415 ? (xfs_dir2_sf_entry_t
*) ((__psint_t
) sfep
3417 ? XFS_DIR2_SF_ENTSIZE_BYENTRY(sfp
, sfep
)
3418 : XFS_DIR2_SF_ENTSIZE_BYNAME(sfp
, namelen
)))
3422 if (sfp
->hdr
.i8count
!= i8
) {
3424 do_warn(_("would fix i8count in inode %llu\n"), ino
);
3427 tmp_sfep
= next_sfep
;
3428 process_sf_dir2_fixi8(sfp
, &tmp_sfep
);
3430 (__psint_t
)next_sfep
-
3431 (__psint_t
)tmp_sfep
;
3432 next_sfep
= tmp_sfep
;
3434 sfp
->hdr
.i8count
= i8
;
3436 do_warn(_("fixing i8count in inode %llu\n"), ino
);
3441 * sync up sizes if required
3444 ASSERT(bytes_deleted
> 0);
3446 libxfs_idata_realloc(ip
, -bytes_deleted
, XFS_DATA_FORK
);
3447 ip
->i_d
.di_size
-= bytes_deleted
;
3450 if (ip
->i_d
.di_size
!= ip
->i_df
.if_bytes
) {
3451 ASSERT(ip
->i_df
.if_bytes
== (xfs_fsize_t
)
3452 ((__psint_t
) next_sfep
- (__psint_t
) sfp
));
3453 ip
->i_d
.di_size
= (xfs_fsize_t
)
3454 ((__psint_t
) next_sfep
- (__psint_t
) sfp
);
3455 do_warn(_("setting size to %lld bytes to reflect junked "
3463 * processes all directories reachable via the inodes on the stack
3464 * returns 0 if things are good, 1 if there's a problem
3467 process_dirstack(xfs_mount_t
*mp
, dir_stack_t
*stack
)
3469 xfs_bmap_free_t flist
;
3470 xfs_fsblock_t first
;
3474 xfs_dahash_t hashval
;
3475 ino_tree_node_t
*irec
;
3476 int ino_offset
, need_dot
, committed
;
3477 int dirty
, num_illegal
, error
, nres
;
3480 * pull directory inode # off directory stack
3482 * open up directory inode, check all entries,
3483 * then call prune_dir_entries to remove all
3484 * remaining illegal directory entries.
3487 while ((ino
= pop_dir(stack
)) != NULLFSINO
) {
3488 irec
= find_inode_rec(XFS_INO_TO_AGNO(mp
, ino
),
3489 XFS_INO_TO_AGINO(mp
, ino
));
3490 ASSERT(irec
!= NULL
);
3492 ino_offset
= XFS_INO_TO_AGINO(mp
, ino
) - irec
->ino_startnum
;
3494 ASSERT(!is_inode_refchecked(ino
, irec
, ino_offset
));
3496 if ((error
= libxfs_iget(mp
, NULL
, ino
, 0, &ip
, 0))) {
3499 _("couldn't map inode %llu, err = %d\n"),
3503 _("couldn't map inode %llu, err = %d\n"),
3506 * see below for what we're doing if this
3507 * is root. Why do we need to do this here?
3508 * to ensure that the root doesn't show up
3509 * as being disconnected in the no_modify case.
3511 if (mp
->m_sb
.sb_rootino
== ino
) {
3512 add_inode_reached(irec
, 0);
3513 add_inode_ref(irec
, 0);
3517 add_inode_refchecked(ino
, irec
, 0);
3521 need_dot
= dirty
= num_illegal
= 0;
3523 if (mp
->m_sb
.sb_rootino
== ino
) {
3525 * mark root inode reached and bump up
3526 * link count for root inode to account
3527 * for '..' entry since the root inode is
3528 * never reached by a parent. we know
3529 * that root's '..' is always good --
3530 * guaranteed by phase 3 and/or below.
3532 add_inode_reached(irec
, ino_offset
);
3534 * account for link for the orphanage
3535 * "lost+found". if we're running in
3536 * modify mode and it already existed,
3537 * we deleted it so it's '..' reference
3538 * never got counted. so add it here if
3539 * we're going to create lost+found.
3541 * if we're running in no_modify mode,
3542 * we never deleted lost+found and we're
3543 * not going to create it so do nothing.
3545 * either way, the counts will match when
3546 * we look at the root inode's nlinks
3547 * field and compare that to our incore
3551 add_inode_ref(irec
, ino_offset
);
3554 add_inode_refchecked(ino
, irec
, ino_offset
);
3557 * look for bogus entries
3559 switch (ip
->i_d
.di_format
) {
3560 case XFS_DINODE_FMT_EXTENTS
:
3561 case XFS_DINODE_FMT_BTREE
:
3563 * also check for missing '.' in longform dirs.
3564 * missing .. entries are added if required when
3565 * the directory is connected to lost+found. but
3566 * we need to create '.' entries here.
3568 if (XFS_SB_VERSION_HASDIRV2(&mp
->m_sb
))
3569 longform_dir2_entry_check(mp
, ino
, ip
,
3570 &num_illegal
, &need_dot
,
3574 longform_dir_entry_check(mp
, ino
, ip
,
3575 &num_illegal
, &need_dot
,
3579 case XFS_DINODE_FMT_LOCAL
:
3580 tp
= libxfs_trans_alloc(mp
, 0);
3582 * using the remove reservation is overkill
3583 * since at most we'll only need to log the
3584 * inode but it's easier than wedging a
3585 * new define in ourselves.
3587 nres
= no_modify
? 0 : XFS_REMOVE_SPACE_RES(mp
);
3588 error
= libxfs_trans_reserve(tp
, nres
,
3589 XFS_REMOVE_LOG_RES(mp
), 0,
3590 XFS_TRANS_PERM_LOG_RES
,
3591 XFS_REMOVE_LOG_COUNT
);
3595 libxfs_trans_ijoin(tp
, ip
, 0);
3596 libxfs_trans_ihold(tp
, ip
);
3598 if (XFS_SB_VERSION_HASDIRV2(&mp
->m_sb
))
3599 shortform_dir2_entry_check(mp
, ino
, ip
, &dirty
,
3603 shortform_dir_entry_check(mp
, ino
, ip
, &dirty
,
3607 ASSERT(dirty
== 0 || (dirty
&& !no_modify
));
3609 libxfs_trans_log_inode(tp
, ip
,
3610 XFS_ILOG_CORE
| XFS_ILOG_DDATA
);
3611 libxfs_trans_commit(tp
, XFS_TRANS_RELEASE_LOG_RES
3612 |XFS_TRANS_SYNC
, 0);
3614 libxfs_trans_cancel(tp
, XFS_TRANS_RELEASE_LOG_RES
);
3623 if (!no_modify
&& !orphanage_entered
&&
3624 ino
== mp
->m_sb
.sb_rootino
) {
3625 do_warn(_("re-entering %s into root directory\n"),
3627 tp
= libxfs_trans_alloc(mp
, 0);
3628 nres
= XFS_MKDIR_SPACE_RES(mp
, strlen(ORPHANAGE
));
3629 error
= libxfs_trans_reserve(tp
, nres
,
3630 XFS_MKDIR_LOG_RES(mp
), 0,
3631 XFS_TRANS_PERM_LOG_RES
,
3632 XFS_MKDIR_LOG_COUNT
);
3635 libxfs_trans_ijoin(tp
, ip
, 0);
3636 libxfs_trans_ihold(tp
, ip
);
3637 XFS_BMAP_INIT(&flist
, &first
);
3638 if ((error
= dir_createname(mp
, tp
, ip
, ORPHANAGE
,
3640 orphanage_ino
, &first
, &flist
,
3642 do_error(_("can't make %s entry in root inode "
3643 "%llu, createname error %d\n"),
3644 ORPHANAGE
, ino
, error
);
3645 libxfs_trans_log_inode(tp
, ip
, XFS_ILOG_CORE
);
3646 error
= libxfs_bmap_finish(&tp
, &flist
, first
, &committed
);
3648 libxfs_trans_commit(tp
,
3649 XFS_TRANS_RELEASE_LOG_RES
| XFS_TRANS_SYNC
, 0);
3650 orphanage_entered
= 1;
3654 * if we have to create a .. for /, do it now *before*
3655 * we delete the bogus entries, otherwise the directory
3656 * could transform into a shortform dir which would
3657 * probably cause the simulation to choke. Even
3658 * if the illegal entries get shifted around, it's ok
3659 * because the entries are structurally intact and in
3660 * in hash-value order so the simulation won't get confused
3661 * if it has to move them around.
3663 if (!no_modify
&& need_root_dotdot
&&
3664 ino
== mp
->m_sb
.sb_rootino
) {
3665 ASSERT(ip
->i_d
.di_format
!= XFS_DINODE_FMT_LOCAL
);
3667 do_warn(_("recreating root directory .. entry\n"));
3669 tp
= libxfs_trans_alloc(mp
, 0);
3672 nres
= XFS_MKDIR_SPACE_RES(mp
, 2);
3673 error
= libxfs_trans_reserve(tp
, nres
,
3674 XFS_MKDIR_LOG_RES(mp
),
3676 XFS_TRANS_PERM_LOG_RES
,
3677 XFS_MKDIR_LOG_COUNT
);
3682 libxfs_trans_ijoin(tp
, ip
, 0);
3683 libxfs_trans_ihold(tp
, ip
);
3685 XFS_BMAP_INIT(&flist
, &first
);
3687 if ((error
= dir_createname(mp
, tp
, ip
, "..", 2,
3688 ip
->i_ino
, &first
, &flist
, nres
)))
3690 _("can't make \"..\" entry in root inode %llu, createname error %d\n"),
3693 libxfs_trans_log_inode(tp
, ip
, XFS_ILOG_CORE
);
3695 error
= libxfs_bmap_finish(&tp
, &flist
, first
,
3698 libxfs_trans_commit(tp
, XFS_TRANS_RELEASE_LOG_RES
3699 |XFS_TRANS_SYNC
, 0);
3701 need_root_dotdot
= 0;
3702 } else if (need_root_dotdot
&& ino
== mp
->m_sb
.sb_rootino
) {
3703 do_warn(_("would recreate root directory .. entry\n"));
3707 * delete any illegal entries -- which should only exist
3708 * if the directory is a longform directory. bogus
3709 * shortform directory entries were deleted in phase 4.
3711 if (!no_modify
&& num_illegal
> 0) {
3712 ASSERT(ip
->i_d
.di_format
!= XFS_DINODE_FMT_LOCAL
);
3713 ASSERT(!XFS_SB_VERSION_HASDIRV2(&mp
->m_sb
));
3715 while (num_illegal
> 0 && ip
->i_d
.di_format
!=
3716 XFS_DINODE_FMT_LOCAL
) {
3717 prune_lf_dir_entry(mp
, ino
, ip
, &hashval
);
3722 * handle case where we've deleted so many
3723 * entries that the directory has changed from
3724 * a longform to a shortform directory. have
3725 * to allocate a transaction since we're working
3726 * with the incore data fork.
3728 if (num_illegal
> 0) {
3729 ASSERT(ip
->i_d
.di_format
==
3730 XFS_DINODE_FMT_LOCAL
);
3731 tp
= libxfs_trans_alloc(mp
, 0);
3733 * using the remove reservation is overkill
3734 * since at most we'll only need to log the
3735 * inode but it's easier than wedging a
3736 * new define in ourselves. 10 block fs
3737 * space reservation is also overkill but
3740 nres
= XFS_REMOVE_SPACE_RES(mp
);
3741 error
= libxfs_trans_reserve(tp
, nres
,
3742 XFS_REMOVE_LOG_RES(mp
), 0,
3743 XFS_TRANS_PERM_LOG_RES
,
3744 XFS_REMOVE_LOG_COUNT
);
3748 libxfs_trans_ijoin(tp
, ip
, 0);
3749 libxfs_trans_ihold(tp
, ip
);
3751 prune_sf_dir_entry(mp
, ino
, ip
);
3753 libxfs_trans_log_inode(tp
, ip
,
3754 XFS_ILOG_CORE
| XFS_ILOG_DDATA
);
3756 libxfs_trans_commit(tp
, XFS_TRANS_RELEASE_LOG_RES
3757 |XFS_TRANS_SYNC
, 0);
3762 * if we need to create the '.' entry, do so only if
3763 * the directory is a longform dir. it it's been
3764 * turned into a shortform dir, then the inode is ok
3765 * since shortform dirs have no '.' entry and the inode
3766 * has already been committed by prune_lf_dir_entry().
3770 * bump up our link count but don't
3771 * bump up the inode link count. chances
3772 * are good that even though we lost '.'
3773 * the inode link counts reflect '.' so
3774 * leave the inode link count alone and if
3775 * it turns out to be wrong, we'll catch
3778 add_inode_ref(irec
, ino_offset
);
3782 _("would create missing \".\" entry in dir ino %llu\n"),
3784 } else if (ip
->i_d
.di_format
!= XFS_DINODE_FMT_LOCAL
) {
3786 * need to create . entry in longform dir.
3789 _("creating missing \".\" entry in dir ino %llu\n"),
3792 tp
= libxfs_trans_alloc(mp
, 0);
3795 nres
= XFS_MKDIR_SPACE_RES(mp
, 1);
3796 error
= libxfs_trans_reserve(tp
, nres
,
3797 XFS_MKDIR_LOG_RES(mp
),
3799 XFS_TRANS_PERM_LOG_RES
,
3800 XFS_MKDIR_LOG_COUNT
);
3805 libxfs_trans_ijoin(tp
, ip
, 0);
3806 libxfs_trans_ihold(tp
, ip
);
3808 XFS_BMAP_INIT(&flist
, &first
);
3810 if ((error
= dir_createname(mp
, tp
, ip
, ".",
3811 1, ip
->i_ino
, &first
, &flist
,
3814 _("can't make \".\" entry in dir ino %llu, createname error %d\n"),
3817 libxfs_trans_log_inode(tp
, ip
, XFS_ILOG_CORE
);
3819 error
= libxfs_bmap_finish(&tp
, &flist
, first
,
3822 libxfs_trans_commit(tp
, XFS_TRANS_RELEASE_LOG_RES
3823 |XFS_TRANS_SYNC
, 0);
3832 * mark realtime bitmap and summary inodes as reached.
3833 * quota inode will be marked here as well
3836 mark_standalone_inodes(xfs_mount_t
*mp
)
3838 ino_tree_node_t
*irec
;
3841 irec
= find_inode_rec(XFS_INO_TO_AGNO(mp
, mp
->m_sb
.sb_rbmino
),
3842 XFS_INO_TO_AGINO(mp
, mp
->m_sb
.sb_rbmino
));
3844 ASSERT(irec
!= NULL
);
3846 offset
= XFS_INO_TO_AGINO(mp
, mp
->m_sb
.sb_rbmino
) -
3849 add_inode_reached(irec
, offset
);
3851 irec
= find_inode_rec(XFS_INO_TO_AGNO(mp
, mp
->m_sb
.sb_rsumino
),
3852 XFS_INO_TO_AGINO(mp
, mp
->m_sb
.sb_rsumino
));
3854 offset
= XFS_INO_TO_AGINO(mp
, mp
->m_sb
.sb_rsumino
) -
3857 ASSERT(irec
!= NULL
);
3859 add_inode_reached(irec
, offset
);
3862 if (mp
->m_sb
.sb_uquotino
3863 && mp
->m_sb
.sb_uquotino
!= NULLFSINO
) {
3864 irec
= find_inode_rec(XFS_INO_TO_AGNO(mp
,
3865 mp
->m_sb
.sb_uquotino
),
3866 XFS_INO_TO_AGINO(mp
, mp
->m_sb
.sb_uquotino
));
3867 offset
= XFS_INO_TO_AGINO(mp
, mp
->m_sb
.sb_uquotino
)
3868 - irec
->ino_startnum
;
3869 add_inode_reached(irec
, offset
);
3871 if (mp
->m_sb
.sb_gquotino
3872 && mp
->m_sb
.sb_gquotino
!= NULLFSINO
) {
3873 irec
= find_inode_rec(XFS_INO_TO_AGNO(mp
,
3874 mp
->m_sb
.sb_gquotino
),
3875 XFS_INO_TO_AGINO(mp
, mp
->m_sb
.sb_gquotino
));
3876 offset
= XFS_INO_TO_AGINO(mp
, mp
->m_sb
.sb_gquotino
)
3877 - irec
->ino_startnum
;
3878 add_inode_reached(irec
, offset
);
3884 phase6(xfs_mount_t
*mp
)
3887 ino_tree_node_t
*irec
;
3892 bzero(&zerocr
, sizeof(cred_t
));
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
);