2 * Copyright (c) 2012-2013 Paulo Alcantara <pcacjr@zytor.com>
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms 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,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write the Free Software Foundation,
15 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 #include "xfs_types.h"
27 #include "xfs_dinode.h"
31 #define XFS_DIR2_DIRBLKS_CACHE_SIZE 128
33 struct xfs_dir2_dirblks_cache
{
34 block_t dc_startblock
;
35 xfs_filblks_t dc_blkscount
;
39 static struct xfs_dir2_dirblks_cache dirblks_cache
[XFS_DIR2_DIRBLKS_CACHE_SIZE
];
40 static unsigned char dirblks_cached_count
= 0;
42 uint32_t xfs_dir2_da_hashname(const uint8_t *name
, int namelen
)
47 * Do four characters at a time as long as we can.
49 for (hash
= 0; namelen
>= 4; namelen
-=4, name
+= 4)
50 hash
= (name
[0] << 21) ^ (name
[1] << 14) ^ (name
[2] << 7) ^
51 (name
[3] << 0) ^ rol32(hash
, 7 * 4);
54 * Now do the rest of the characters.
58 return (name
[0] << 14) ^ (name
[1] << 7) ^ (name
[2] << 0) ^
61 return (name
[0] << 7) ^ (name
[1] << 0) ^ rol32(hash
, 7 * 2);
63 return (name
[0] << 0) ^ rol32(hash
, 7 * 1);
64 default: /* case 0: */
69 static void *get_dirblks(struct fs_info
*fs
, block_t startblock
,
72 int count
= c
<< XFS_INFO(fs
)->dirblklog
;
77 buf
= malloc(c
* XFS_INFO(fs
)->dirblksize
);
79 malloc_error("buffer memory");
81 memset(buf
, 0, XFS_INFO(fs
)->dirblksize
);
84 p
= (uint8_t *)get_cache(fs
->fs_dev
, startblock
++);
85 memcpy(buf
+ offset
, p
, BLOCK_SIZE(fs
));
86 offset
+= BLOCK_SIZE(fs
);
92 const void *xfs_dir2_dirblks_get_cached(struct fs_info
*fs
, block_t startblock
,
98 xfs_debug("fs %p startblock %llu (0x%llx) blkscount %lu", fs
, startblock
,
101 if (!dirblks_cached_count
) {
102 buf
= get_dirblks(fs
, startblock
, c
);
104 dirblks_cache
[dirblks_cached_count
].dc_startblock
= startblock
;
105 dirblks_cache
[dirblks_cached_count
].dc_blkscount
= c
;
106 dirblks_cache
[dirblks_cached_count
].dc_area
= buf
;
108 return dirblks_cache
[dirblks_cached_count
++].dc_area
;
109 } else if (dirblks_cached_count
== XFS_DIR2_DIRBLKS_CACHE_SIZE
) {
110 for (i
= 0; i
< XFS_DIR2_DIRBLKS_CACHE_SIZE
/ 2; i
++) {
111 unsigned char k
= XFS_DIR2_DIRBLKS_CACHE_SIZE
- (i
+ 1);
113 free(dirblks_cache
[i
].dc_area
);
114 dirblks_cache
[i
] = dirblks_cache
[k
];
115 memset(&dirblks_cache
[k
], 0, sizeof(dirblks_cache
[k
]));
118 buf
= get_dirblks(fs
, startblock
, c
);
120 dirblks_cache
[XFS_DIR2_DIRBLKS_CACHE_SIZE
/ 2].dc_startblock
=
122 dirblks_cache
[XFS_DIR2_DIRBLKS_CACHE_SIZE
/ 2].dc_blkscount
= c
;
123 dirblks_cache
[XFS_DIR2_DIRBLKS_CACHE_SIZE
/ 2].dc_area
= buf
;
125 dirblks_cached_count
= XFS_DIR2_DIRBLKS_CACHE_SIZE
/ 2;
127 return dirblks_cache
[dirblks_cached_count
++].dc_area
;
132 block
= dirblks_cache
[dirblks_cached_count
- 1].dc_startblock
;
133 count
= dirblks_cache
[dirblks_cached_count
- 1].dc_blkscount
;
135 if (block
== startblock
&& count
== c
) {
136 return dirblks_cache
[dirblks_cached_count
- 1].dc_area
;
138 for (i
= 0; i
< dirblks_cached_count
; i
++) {
139 block
= dirblks_cache
[i
].dc_startblock
;
140 count
= dirblks_cache
[i
].dc_blkscount
;
142 if (block
== startblock
&& count
== c
)
143 return dirblks_cache
[i
].dc_area
;
146 buf
= get_dirblks(fs
, startblock
, c
);
148 dirblks_cache
[dirblks_cached_count
].dc_startblock
= startblock
;
149 dirblks_cache
[dirblks_cached_count
].dc_blkscount
= c
;
150 dirblks_cache
[dirblks_cached_count
].dc_area
= buf
;
152 return dirblks_cache
[dirblks_cached_count
++].dc_area
;
159 void xfs_dir2_dirblks_flush_cache(void)
163 for (i
= 0; i
< dirblks_cached_count
; i
++) {
164 free(dirblks_cache
[i
].dc_area
);
165 memset(&dirblks_cache
[i
], 0, sizeof(dirblks_cache
[i
]));
168 dirblks_cached_count
= 0;
171 struct inode
*xfs_dir2_local_find_entry(const char *dname
, struct inode
*parent
,
174 xfs_dir2_sf_t
*sf
= (xfs_dir2_sf_t
*)&core
->di_literal_area
[0];
175 xfs_dir2_sf_entry_t
*sf_entry
;
176 uint8_t count
= sf
->hdr
.i8count
? sf
->hdr
.i8count
: sf
->hdr
.count
;
177 struct fs_info
*fs
= parent
->fs
;
180 xfs_dinode_t
*ncore
= NULL
;
182 xfs_debug("dname %s parent %p core %p", dname
, parent
, core
);
183 xfs_debug("count %hhu i8count %hhu", sf
->hdr
.count
, sf
->hdr
.i8count
);
185 sf_entry
= (xfs_dir2_sf_entry_t
*)((uint8_t *)&sf
->list
[0] -
186 (!sf
->hdr
.i8count
? 4 : 0));
188 uint8_t *start_name
= &sf_entry
->name
[0];
189 uint8_t *end_name
= start_name
+ sf_entry
->namelen
;
191 if (!xfs_dir2_entry_name_cmp(start_name
, end_name
, dname
)) {
192 xfs_debug("Found entry %s", dname
);
196 sf_entry
= (xfs_dir2_sf_entry_t
*)((uint8_t *)sf_entry
+
197 offsetof(struct xfs_dir2_sf_entry
,
200 (sf
->hdr
.i8count
? 8 : 4));
206 inode
= xfs_new_inode(fs
);
208 ino
= xfs_dir2_sf_get_inumber(sf
, (xfs_dir2_inou_t
*)(
209 (uint8_t *)sf_entry
+
210 offsetof(struct xfs_dir2_sf_entry
,
214 xfs_debug("entry inode's number %lu", ino
);
216 ncore
= xfs_dinode_get_core(fs
, ino
);
218 xfs_error("Failed to get dinode!");
222 fill_xfs_inode_pvt(fs
, inode
, ino
);
225 inode
->size
= be64_to_cpu(ncore
->di_size
);
227 if ((be16_to_cpu(ncore
->di_mode
) & S_IFMT
) == S_IFDIR
) {
228 inode
->mode
= DT_DIR
;
229 xfs_debug("Found a directory inode!");
230 } else if ((be16_to_cpu(ncore
->di_mode
) & S_IFMT
) == S_IFREG
) {
231 inode
->mode
= DT_REG
;
232 xfs_debug("Found a file inode!");
233 xfs_debug("inode size %llu", inode
->size
);
234 } else if ((be16_to_cpu(ncore
->di_mode
) & S_IFMT
) == S_IFLNK
) {
235 inode
->mode
= DT_LNK
;
236 xfs_debug("Found a symbolic link inode!");
247 struct inode
*xfs_dir2_block_find_entry(const char *dname
, struct inode
*parent
,
252 struct fs_info
*fs
= parent
->fs
;
253 const uint8_t *dirblk_buf
;
255 xfs_dir2_data_hdr_t
*hdr
;
256 struct inode
*inode
= NULL
;
257 xfs_dir2_block_tail_t
*btp
;
258 xfs_dir2_data_unused_t
*dup
;
259 xfs_dir2_data_entry_t
*dep
;
263 xfs_debug("dname %s parent %p core %p", dname
, parent
, core
);
265 bmbt_irec_get(&r
, (xfs_bmbt_rec_t
*)&core
->di_literal_area
[0]);
266 dir_blk
= fsblock_to_bytes(fs
, r
.br_startblock
) >> BLOCK_SHIFT(fs
);
268 dirblk_buf
= xfs_dir2_dirblks_get_cached(fs
, dir_blk
, r
.br_blockcount
);
269 hdr
= (xfs_dir2_data_hdr_t
*)dirblk_buf
;
270 if (be32_to_cpu(hdr
->magic
) != XFS_DIR2_BLOCK_MAGIC
) {
271 xfs_error("Block directory header's magic number does not match!");
272 xfs_debug("hdr->magic: 0x%lx", be32_to_cpu(hdr
->magic
));
276 p
= (uint8_t *)(hdr
+ 1);
278 btp
= xfs_dir2_block_tail_p(XFS_INFO(fs
), hdr
);
279 endp
= (uint8_t *)((xfs_dir2_leaf_entry_t
*)btp
- be32_to_cpu(btp
->count
));
285 dup
= (xfs_dir2_data_unused_t
*)p
;
286 if (be16_to_cpu(dup
->freetag
) == XFS_DIR2_DATA_FREE_TAG
) {
287 p
+= be16_to_cpu(dup
->length
);
291 dep
= (xfs_dir2_data_entry_t
*)p
;
293 start_name
= &dep
->name
[0];
294 end_name
= start_name
+ dep
->namelen
;
296 if (!xfs_dir2_entry_name_cmp(start_name
, end_name
, dname
)) {
297 xfs_debug("Found entry %s", dname
);
301 p
+= xfs_dir2_data_entsize(dep
->namelen
);
308 inode
= xfs_new_inode(fs
);
310 ino
= be64_to_cpu(dep
->inumber
);
312 xfs_debug("entry inode's number %lu", ino
);
314 ncore
= xfs_dinode_get_core(fs
, ino
);
316 xfs_error("Failed to get dinode!");
320 fill_xfs_inode_pvt(fs
, inode
, ino
);
323 XFS_PVT(inode
)->i_ino_blk
= ino_to_bytes(fs
, ino
) >> BLOCK_SHIFT(fs
);
324 inode
->size
= be64_to_cpu(ncore
->di_size
);
326 if ((be16_to_cpu(ncore
->di_mode
) & S_IFMT
) == S_IFDIR
) {
327 inode
->mode
= DT_DIR
;
328 xfs_debug("Found a directory inode!");
329 } else if ((be16_to_cpu(ncore
->di_mode
) & S_IFMT
) == S_IFREG
) {
330 inode
->mode
= DT_REG
;
331 xfs_debug("Found a file inode!");
332 xfs_debug("inode size %llu", inode
->size
);
333 } else if ((be16_to_cpu(ncore
->di_mode
) & S_IFMT
) == S_IFLNK
) {
334 inode
->mode
= DT_LNK
;
335 xfs_debug("Found a symbolic link inode!");
338 xfs_debug("entry inode's number %lu", ino
);
348 struct inode
*xfs_dir2_leaf_find_entry(const char *dname
, struct inode
*parent
,
351 xfs_dir2_leaf_t
*leaf
;
352 xfs_bmbt_irec_t irec
;
353 block_t leaf_blk
, dir_blk
;
354 xfs_dir2_leaf_entry_t
*lep
;
360 uint32_t newdb
, curdb
= -1;
361 xfs_dir2_data_entry_t
*dep
;
363 xfs_dir2_data_hdr_t
*data_hdr
;
368 const uint8_t *buf
= NULL
;
370 xfs_debug("dname %s parent %p core %p", dname
, parent
, core
);
372 bmbt_irec_get(&irec
, ((xfs_bmbt_rec_t
*)&core
->di_literal_area
[0]) +
373 be32_to_cpu(core
->di_nextents
) - 1);
374 leaf_blk
= fsblock_to_bytes(parent
->fs
, irec
.br_startblock
) >>
375 BLOCK_SHIFT(parent
->fs
);
377 leaf
= (xfs_dir2_leaf_t
*)xfs_dir2_dirblks_get_cached(parent
->fs
, leaf_blk
,
379 if (be16_to_cpu(leaf
->hdr
.info
.magic
) != XFS_DIR2_LEAF1_MAGIC
) {
380 xfs_error("Single leaf block header's magic number does not match!");
384 if (!leaf
->hdr
.count
)
387 hashwant
= xfs_dir2_da_hashname((uint8_t *)dname
, strlen(dname
));
390 for (lep
= leaf
->ents
, low
= 0, high
= be16_to_cpu(leaf
->hdr
.count
) - 1;
392 mid
= (low
+ high
) >> 1;
393 if ((hash
= be32_to_cpu(lep
[mid
].hashval
)) == hashwant
)
401 /* If hash is not the one we want, then the directory does not contain the
402 * entry we're looking for and there is nothing to do anymore.
404 if (hash
!= hashwant
)
407 while (mid
> 0 && be32_to_cpu(lep
[mid
- 1].hashval
) == hashwant
)
410 for (lep
= &leaf
->ents
[mid
];
411 mid
< be16_to_cpu(leaf
->hdr
.count
) &&
412 be32_to_cpu(lep
->hashval
) == hashwant
;
414 /* Skip over stale leaf entries. */
415 if (be32_to_cpu(lep
->address
) == XFS_DIR2_NULL_DATAPTR
)
418 newdb
= xfs_dir2_dataptr_to_db(parent
->fs
, be32_to_cpu(lep
->address
));
419 if (newdb
!= curdb
) {
421 ((xfs_bmbt_rec_t
*)&core
->di_literal_area
[0]) + newdb
);
422 dir_blk
= fsblock_to_bytes(parent
->fs
, irec
.br_startblock
) >>
424 BLOCK_SHIFT(parent
->fs
);
425 buf
= xfs_dir2_dirblks_get_cached(parent
->fs
, dir_blk
, irec
.br_blockcount
);
426 data_hdr
= (xfs_dir2_data_hdr_t
*)buf
;
427 if (be32_to_cpu(data_hdr
->magic
) != XFS_DIR2_DATA_MAGIC
) {
428 xfs_error("Leaf directory's data magic No. does not match!");
435 dep
= (xfs_dir2_data_entry_t
*)((char *)buf
+
436 xfs_dir2_dataptr_to_off(parent
->fs
, be32_to_cpu(lep
->address
)));
438 start_name
= &dep
->name
[0];
439 end_name
= start_name
+ dep
->namelen
;
441 if (!xfs_dir2_entry_name_cmp(start_name
, end_name
, dname
)) {
442 xfs_debug("Found entry %s", dname
);
451 ip
= xfs_new_inode(parent
->fs
);
453 ino
= be64_to_cpu(dep
->inumber
);
455 xfs_debug("entry inode's number %lu", ino
);
457 ncore
= xfs_dinode_get_core(parent
->fs
, ino
);
459 xfs_error("Failed to get dinode!");
463 fill_xfs_inode_pvt(parent
->fs
, ip
, ino
);
466 XFS_PVT(ip
)->i_ino_blk
= ino_to_bytes(parent
->fs
, ino
) >>
467 BLOCK_SHIFT(parent
->fs
);
468 ip
->size
= be64_to_cpu(ncore
->di_size
);
470 if ((be16_to_cpu(ncore
->di_mode
) & S_IFMT
) == S_IFDIR
) {
472 xfs_debug("Found a directory inode!");
473 } else if ((be16_to_cpu(ncore
->di_mode
) & S_IFMT
) == S_IFREG
) {
475 xfs_debug("Found a file inode!");
476 xfs_debug("inode size %llu", ip
->size
);
477 } else if ((be16_to_cpu(ncore
->di_mode
) & S_IFMT
) == S_IFLNK
) {
479 xfs_debug("Found a symbolic link inode!");
482 xfs_debug("entry inode's number %lu", ino
);
493 select_child(xfs_dfiloff_t off
,
500 for (i
= 0; i
< nrecs
; i
++) {
501 if (be64_to_cpu(kp
[i
].br_startoff
) == off
)
502 return be64_to_cpu(pp
[i
]);
503 if (be64_to_cpu(kp
[i
].br_startoff
) > off
) {
505 return be64_to_cpu(pp
[i
]);
507 return be64_to_cpu(pp
[i
-1]);
511 return be64_to_cpu(pp
[nrecs
- 1]);
514 block_t
xfs_dir2_get_right_blk(struct fs_info
*fs
, xfs_dinode_t
*core
,
515 block_t fsblkno
, int *error
)
518 xfs_bmbt_irec_t irec
;
521 xfs_bmdr_block_t
*rblock
;
526 xfs_btree_block_t
*blk
;
530 if (core
->di_format
== XFS_DINODE_FMT_EXTENTS
) {
531 xfs_debug("XFS_DINODE_FMT_EXTENTS");
532 for (idx
= 0; idx
< be32_to_cpu(core
->di_nextents
); idx
++) {
534 ((xfs_bmbt_rec_t
*)&core
->di_literal_area
[0]) + idx
);
535 if (fsblkno
>= irec
.br_startoff
&&
536 fsblkno
< irec
.br_startoff
+ irec
.br_blockcount
)
539 } else if (core
->di_format
== XFS_DINODE_FMT_BTREE
) {
540 xfs_debug("XFS_DINODE_FMT_BTREE");
542 rblock
= (xfs_bmdr_block_t
*)&core
->di_literal_area
[0];
543 fsize
= XFS_DFORK_SIZE(core
, fs
, XFS_DATA_FORK
);
544 pp
= XFS_BMDR_PTR_ADDR(rblock
, 1, xfs_bmdr_maxrecs(fsize
, 0));
545 kp
= XFS_BMDR_KEY_ADDR(rblock
, 1);
546 bno
= fsblock_to_bytes(fs
,
547 select_child(fsblkno
, kp
, pp
,
548 be16_to_cpu(rblock
->bb_numrecs
))) >> BLOCK_SHIFT(fs
);
552 blk
= (xfs_btree_block_t
*)get_cache(fs
->fs_dev
, bno
);
553 if (be16_to_cpu(blk
->bb_level
) == 0)
555 pp
= XFS_BMBT_PTR_ADDR(fs
, blk
, 1,
556 xfs_bmdr_maxrecs(XFS_INFO(fs
)->blocksize
, 0));
557 kp
= XFS_BMBT_KEY_ADDR(fs
, blk
, 1);
558 bno
= fsblock_to_bytes(fs
,
559 select_child(fsblkno
, kp
, pp
,
560 be16_to_cpu(blk
->bb_numrecs
))) >> BLOCK_SHIFT(fs
);
563 /* Find the records among leaves */
565 nextbno
= be64_to_cpu(blk
->bb_u
.l
.bb_rightsib
);
566 nextents
= be16_to_cpu(blk
->bb_numrecs
);
567 xp
= (xfs_bmbt_rec_t
*)XFS_BMBT_REC_ADDR(fs
, blk
, 1);
568 for (idx
= 0; idx
< nextents
; idx
++) {
569 bmbt_irec_get(&irec
, xp
+ idx
);
570 if (fsblkno
>= irec
.br_startoff
&&
571 fsblkno
< irec
.br_startoff
+ irec
.br_blockcount
) {
572 nextbno
= NULLFSBLOCK
;
576 if (nextbno
== NULLFSBLOCK
)
578 bno
= fsblock_to_bytes(fs
, nextbno
) >> BLOCK_SHIFT(fs
);
579 blk
= (xfs_btree_block_t
*)get_cache(fs
->fs_dev
, bno
);
583 if (fsblkno
< irec
.br_startoff
||
584 fsblkno
>= irec
.br_startoff
+ irec
.br_blockcount
)
587 return fsblock_to_bytes(fs
,
588 fsblkno
- irec
.br_startoff
+ irec
.br_startblock
) >>
592 struct inode
*xfs_dir2_node_find_entry(const char *dname
, struct inode
*parent
,
596 xfs_da_intnode_t
*node
= NULL
;
599 xfs_da_node_entry_t
*btree
;
604 xfs_dir2_data_hdr_t
*data_hdr
;
605 xfs_dir2_leaf_t
*leaf
;
606 xfs_dir2_leaf_entry_t
*lep
;
607 xfs_dir2_data_entry_t
*dep
;
614 uint32_t newdb
, curdb
= -1;
617 const uint8_t *buf
= NULL
;
619 xfs_debug("dname %s parent %p core %p", dname
, parent
, core
);
621 hashwant
= xfs_dir2_da_hashname((uint8_t *)dname
, strlen(dname
));
623 fsblkno
= xfs_dir2_get_right_blk(parent
->fs
, core
,
624 xfs_dir2_byte_to_db(parent
->fs
, XFS_DIR2_LEAF_OFFSET
),
627 xfs_error("Cannot find right rec!");
631 node
= (xfs_da_intnode_t
*)xfs_dir2_dirblks_get_cached(parent
->fs
, fsblkno
,
633 if (be16_to_cpu(node
->hdr
.info
.magic
) != XFS_DA_NODE_MAGIC
) {
634 xfs_error("Node's magic number does not match!");
639 if (!node
->hdr
.count
)
642 /* Given a hash to lookup, you read the node's btree array and first
643 * "hashval" in the array that exceeds the given hash and it can then
644 * be found in the block pointed by the "before" value.
646 max
= be16_to_cpu(node
->hdr
.count
);
648 probe
= span
= max
/2;
649 for (btree
= &node
->btree
[probe
];
650 span
> 4; btree
= &node
->btree
[probe
]) {
652 hash
= be32_to_cpu(btree
->hashval
);
656 else if (hash
> hashwant
)
662 while ((probe
> 0) && (be32_to_cpu(btree
->hashval
) >= hashwant
)) {
667 while ((probe
< max
) && (be32_to_cpu(btree
->hashval
) < hashwant
)) {
673 fsblkno
= be32_to_cpu(node
->btree
[max
-1].before
);
675 fsblkno
= be32_to_cpu(node
->btree
[probe
].before
);
677 fsblkno
= xfs_dir2_get_right_blk(parent
->fs
, core
, fsblkno
, &error
);
679 xfs_error("Cannot find right rec!");
683 node
= (xfs_da_intnode_t
*)xfs_dir2_dirblks_get_cached(parent
->fs
,
685 } while(be16_to_cpu(node
->hdr
.info
.magic
) == XFS_DA_NODE_MAGIC
);
687 leaf
= (xfs_dir2_leaf_t
*)node
;
688 if (be16_to_cpu(leaf
->hdr
.info
.magic
) != XFS_DIR2_LEAFN_MAGIC
) {
689 xfs_error("Leaf's magic number does not match!");
693 if (!leaf
->hdr
.count
)
696 for (lep
= leaf
->ents
, low
= 0, high
= be16_to_cpu(leaf
->hdr
.count
) - 1;
698 mid
= (low
+ high
) >> 1;
700 if ((hash
= be32_to_cpu(lep
[mid
].hashval
)) == hashwant
)
708 /* If hash is not the one we want, then the directory does not contain the
709 * entry we're looking for and there is nothing to do anymore.
711 if (hash
!= hashwant
)
714 while (mid
> 0 && be32_to_cpu(lep
[mid
- 1].hashval
) == hashwant
)
717 for (lep
= &leaf
->ents
[mid
];
718 mid
< be16_to_cpu(leaf
->hdr
.count
) &&
719 be32_to_cpu(lep
->hashval
) == hashwant
;
721 /* Skip over stale leaf entries. */
722 if (be32_to_cpu(lep
->address
) == XFS_DIR2_NULL_DATAPTR
)
725 newdb
= xfs_dir2_dataptr_to_db(parent
->fs
, be32_to_cpu(lep
->address
));
726 if (newdb
!= curdb
) {
727 fsblkno
= xfs_dir2_get_right_blk(parent
->fs
, core
, newdb
, &error
);
729 xfs_error("Cannot find data block!");
733 buf
= xfs_dir2_dirblks_get_cached(parent
->fs
, fsblkno
, 1);
734 data_hdr
= (xfs_dir2_data_hdr_t
*)buf
;
735 if (be32_to_cpu(data_hdr
->magic
) != XFS_DIR2_DATA_MAGIC
) {
736 xfs_error("Leaf directory's data magic No. does not match!");
743 dep
= (xfs_dir2_data_entry_t
*)((char *)buf
+
744 xfs_dir2_dataptr_to_off(parent
->fs
, be32_to_cpu(lep
->address
)));
746 start_name
= &dep
->name
[0];
747 end_name
= start_name
+ dep
->namelen
;
749 if (!xfs_dir2_entry_name_cmp(start_name
, end_name
, dname
)) {
750 xfs_debug("Found entry %s", dname
);
759 ip
= xfs_new_inode(parent
->fs
);
760 ino
= be64_to_cpu(dep
->inumber
);
761 ncore
= xfs_dinode_get_core(parent
->fs
, ino
);
763 xfs_error("Failed to get dinode!");
767 fill_xfs_inode_pvt(parent
->fs
, ip
, ino
);
769 XFS_PVT(ip
)->i_ino_blk
= ino_to_bytes(parent
->fs
, ino
) >>
770 BLOCK_SHIFT(parent
->fs
);
771 ip
->size
= be64_to_cpu(ncore
->di_size
);
773 if ((be16_to_cpu(ncore
->di_mode
) & S_IFMT
) == S_IFDIR
) {
775 xfs_debug("Found a directory inode!");
776 } else if ((be16_to_cpu(ncore
->di_mode
) & S_IFMT
) == S_IFREG
) {
778 xfs_debug("Found a file inode!");
779 xfs_debug("inode size %llu", ip
->size
);
780 } else if ((be16_to_cpu(ncore
->di_mode
) & S_IFMT
) == S_IFLNK
) {
782 xfs_debug("Found a symbolic link inode!");
785 xfs_debug("entry inode's number %lu", ino
);