int compress;
ext2_ino_t parent;
ext2_ino_t dir;
+ struct ext2_dir_entry *dot_de;
+ struct ext2_dir_entry *dotdot_de;
};
struct hash_entry {
return BLOCK_ABORT;
}
if (!fd->compress && (name_len == 1) &&
- (dirent->name[0] == '.'))
+ (dirent->name[0] == '.')) {
+ fd->dot_de = dirent;
continue;
+ }
if (!fd->compress && (name_len == 2) &&
(dirent->name[0] == '.') && (dirent->name[1] == '.')) {
fd->parent = dirent->inode;
+ fd->dotdot_de = dirent;
continue;
}
if (fd->num_array >= fd->max_array) {
}
ent = fd->harray + fd->num_array++;
ent->dir = dirent;
- fd->dir_size += ext2fs_dir_rec_len(name_len, extended);
+ fd->dir_size += ext2fs_dirdata_rec_len(dirent, extended);
ent->ino = dirent->inode;
if (extended) {
ent->hash = EXT2_DIRENT_HASH(dirent);
ent = fd->harray + i;
if (ent->dir->inode == 0)
continue;
- rec_len = ext2fs_dir_rec_len(ext2fs_dirent_name_len(ent->dir),
- hash_in_entry);
+ rec_len = ext2fs_dirdata_rec_len(ent->dir, hash_in_entry);
if (rec_len > left) {
if (left) {
left += prev_rec_len;
if (retval)
return retval;
prev_rec_len = rec_len;
- memcpy(dirent->name, ent->dir->name,
- ext2fs_dirent_name_len(dirent));
+ memcpy(dirent->name, ent->dir->name, rec_len);
if (hash_in_entry) {
EXT2_DIRENT_HASHES(dirent)->hash = ext2fs_cpu_to_le32(ent->hash);
EXT2_DIRENT_HASHES(dirent)->minor_hash =
static struct ext2_dx_root_info *set_root_node(ext2_filsys fs, char *buf,
ext2_ino_t ino, ext2_ino_t parent,
+ struct ext2_dir_entry *dot_de,
+ struct ext2_dir_entry *dotdot_de,
struct ext2_inode *inode)
{
- struct ext2_dir_entry *dir;
- struct ext2_dx_root_info *root;
+ struct ext2_dir_entry *dirent;
+ struct ext2_dx_root_info *root;
struct ext2_dx_countlimit *limits;
- int filetype = 0;
int csum_size = 0;
-
- if (ext2fs_has_feature_filetype(fs->super))
- filetype = EXT2_FT_DIR;
+ int offset;
+ int rec_len;
memset(buf, 0, fs->blocksize);
- dir = (struct ext2_dir_entry *) buf;
- dir->inode = ino;
- dir->name[0] = '.';
- ext2fs_dirent_set_name_len(dir, 1);
- ext2fs_dirent_set_file_type(dir, filetype);
- dir->rec_len = 12;
- dir = (struct ext2_dir_entry *) (buf + 12);
- dir->inode = parent;
- dir->name[0] = '.';
- dir->name[1] = '.';
- ext2fs_dirent_set_name_len(dir, 2);
- ext2fs_dirent_set_file_type(dir, filetype);
- dir->rec_len = fs->blocksize - 12;
-
- root = (struct ext2_dx_root_info *) (buf+24);
+ dirent = (struct ext2_dir_entry *) buf;
+ dirent->inode = ino;
+
+ dirent->name_len = dot_de->name_len;
+ offset = rec_len = dirent->rec_len = dot_de->rec_len;
+ memcpy(dirent->name, dot_de->name, rec_len);
+
+ dirent = EXT2_NEXT_DIRENT(dirent);
+ /* set to jump over the index block */
+
+ dirent->inode = parent;
+
+ dirent->name_len = dotdot_de->name_len;
+ dirent->rec_len = fs->blocksize - rec_len;
+ rec_len = EXT2_DIR_REC_LEN(dotdot_de);
+ memcpy(dirent->name, dotdot_de->name, rec_len);
+ offset += rec_len;
+
+ root = (struct ext2_dx_root_info *)(buf + offset);
root->reserved_zero = 0;
if (ext4_hash_in_dirent(inode))
root->hash_version = EXT2_HASH_SIPHASH;
else
root->hash_version = fs->super->s_def_hash_version;
- root->info_length = 8;
+ root->info_length = sizeof(*root);
root->indirect_levels = 0;
root->unused_flags = 0;
+ offset += root->info_length;
if (ext2fs_has_feature_metadata_csum(fs->super))
csum_size = sizeof(struct ext2_dx_tail);
- limits = (struct ext2_dx_countlimit *) (buf+32);
- limits->limit = (fs->blocksize - (32 + csum_size)) /
+ limits = (struct ext2_dx_countlimit *) (buf + offset);
+ limits->limit = (fs->blocksize - (offset + csum_size)) /
sizeof(struct ext2_dx_entry);
limits->count = 0;
struct out_dir *outdir,
ext2_ino_t ino,
ext2_ino_t parent,
+ struct ext2_dir_entry *dot_de,
+ struct ext2_dir_entry *dotdot_de,
struct ext2_inode *inode)
{
struct ext2_dx_root_info *root_info;
int i, c1, c2, c3, nblks;
int limit_offset, int_offset, root_offset;
- root_info = set_root_node(fs, outdir->buf, ino, parent, inode);
+ root_info = set_root_node(fs, outdir->buf, ino, parent, dot_de,
+ dotdot_de, inode);
+
root_offset = limit_offset = ((char *) root_info - outdir->buf) +
root_info->info_length;
root_limit = (struct ext2_dx_countlimit *) (outdir->buf + limit_offset);
if (retval)
goto errout;
- free(dir_buf); dir_buf = 0;
-
if (!fd.compress) {
/* Calculate the interior nodes */
- retval = calculate_tree(fs, &outdir, ino, fd.parent, fd.inode);
+ retval = calculate_tree(fs, &outdir, ino, fd.parent,
+ fd.dot_de, fd.dotdot_de, fd.inode);
if (retval)
goto errout;
}