offset += rec_len;
if ((rec_len < 8) ||
((rec_len % 4) != 0) ||
- ((((unsigned) dirent->name_len & 0xFF)+8) > rec_len))
+ ((ext2fs_dirent_name_len(dirent)+8) > rec_len))
return 0;
}
return (offset == final_offset);
unsigned int rec_len, size;
int entry;
struct ext2_dir_entry *dirent;
+ int csum_size = 0;
if (blockcnt < 0)
return 0;
entry = blockcnt ? DIRENT_OTHER_FILE : DIRENT_DOT_FILE;
- ctx->errcode = ext2fs_read_dir_block3(fs, *blocknr, ctx->buf, 0);
+ ctx->errcode = ext2fs_read_dir_block4(fs, *blocknr, ctx->buf, 0,
+ ctx->dir);
if (ctx->errcode)
return BLOCK_ABORT;
+ if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
+ EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
+ csum_size = sizeof(struct ext2_dir_entry_tail);
+
while (offset < fs->blocksize) {
dirent = (struct ext2_dir_entry *) (ctx->buf + offset);
if (ext2fs_get_rec_len(fs, dirent, &rec_len))
if (((offset + rec_len) > fs->blocksize) ||
(rec_len < 8) ||
((rec_len % 4) != 0) ||
- ((((unsigned) dirent->name_len & 0xFF)+8) > rec_len)) {
+ ((ext2fs_dirent_name_len(dirent)+8) > rec_len)) {
ctx->errcode = EXT2_ET_DIR_CORRUPTED;
return BLOCK_ABORT;
}
- if (!dirent->inode &&
- !(ctx->flags & DIRENT_FLAG_INCLUDE_EMPTY))
- goto next;
+ if (!dirent->inode) {
+ if ((offset == fs->blocksize - csum_size) &&
+ (dirent->rec_len == csum_size) &&
+ (dirent->name_len == EXT2_DIR_NAME_LEN_CSUM)) {
+ if (!(ctx->flags & DIRENT_FLAG_INCLUDE_CSUM))
+ goto next;
+ entry = DIRENT_CHECKSUM;
+ } else if (!(ctx->flags & DIRENT_FLAG_INCLUDE_EMPTY))
+ goto next;
+ }
ret = (ctx->func)(ctx->dir,
(next_real_entry > offset) ?
next_real_entry += rec_len;
if (ctx->flags & DIRENT_FLAG_INCLUDE_REMOVED) {
- size = ((dirent->name_len & 0xFF) + 11) & ~3;
+ size = (ext2fs_dirent_name_len(dirent) + 11) & ~3;
if (rec_len != size) {
unsigned int final_offset;
}
if (changed) {
- ctx->errcode = ext2fs_write_dir_block3(fs, *blocknr, ctx->buf,
- 0);
+ ctx->errcode = ext2fs_write_dir_block4(fs, *blocknr, ctx->buf,
+ 0, ctx->dir);
if (ctx->errcode)
return BLOCK_ABORT;
}