dx_get_limit((frame - 1)->entries)) {
@@ -2277,16 +2622,43 @@ again:
restart = 1;
- goto cleanup;
+ goto journal_error;
}
+ } else if (!ext4_htree_dx_locked(lck)) {
+ struct ext4_dir_lock_data *ld = ext4_htree_lock_data(lck);
goto cleanup;
journal_error:
- ext4_std_error(dir->i_sb, err);
+ ext4_std_error(dir->i_sb, err); /* this is a no-op if err == 0 */
cleanup:
+ ext4_htree_dx_unlock(lck);
+ ext4_htree_de_unlock(lck);
extern int search_dir(struct buffer_head *bh,
char *search_buf,
int buf_size,
-@@ -2865,6 +2916,28 @@ extern struct mutex ext4__aio_mutex[EXT4
+@@ -2865,6 +2916,36 @@ extern struct mutex ext4__aio_mutex[EXT4
extern int ext4_resize_begin(struct super_block *sb);
extern void ext4_resize_end(struct super_block *sb);
+ char *len = de->name + de->name_len + 1 /* NUL terminator */;
+ int dlen = 0;
+ __u8 extra_data_flags = (de->file_type & ~EXT4_FT_MASK) >> 4;
++ struct ext4_dir_entry_tail *t = (struct ext4_dir_entry_tail *)de;
++
++ if (!t->det_reserved_zero1 &&
++ le16_to_cpu(t->det_rec_len) ==
++ sizeof(struct ext4_dir_entry_tail) &&
++ !t->det_reserved_zero2 &&
++ t->det_reserved_ft == EXT4_FT_DIR_CSUM)
++ return 0;
+
+ while (extra_data_flags) {
+ if (extra_data_flags & 1) {
static unsigned dx_node_limit(struct inode *dir);
static struct dx_frame *dx_probe(const struct qstr *d_name,
struct inode *dir,
+@@ -379,22 +380,23 @@ static struct dx_countlimit *get_dx_coun
+ {
+ struct ext4_dir_entry *dp;
+ struct dx_root_info *root;
+- int count_offset;
++ int count_offset, dot_rec_len, dotdot_rec_len;
+
+ if (le16_to_cpu(dirent->rec_len) == EXT4_BLOCK_SIZE(inode->i_sb))
+ count_offset = 8;
+- else if (le16_to_cpu(dirent->rec_len) == 12) {
+- dp = (struct ext4_dir_entry *)(((void *)dirent) + 12);
++ else {
++ dot_rec_len = le16_to_cpu(dirent->rec_len);
++ dp = (struct ext4_dir_entry *)(((void *)dirent) + dot_rec_len);
+ if (le16_to_cpu(dp->rec_len) !=
+- EXT4_BLOCK_SIZE(inode->i_sb) - 12)
++ EXT4_BLOCK_SIZE(inode->i_sb) - dot_rec_len)
+ return NULL;
+- root = (struct dx_root_info *)(((void *)dp + 12));
++ dotdot_rec_len = EXT4_DIR_REC_LEN((struct ext4_dir_entry_2 *)dp);
++ root = (struct dx_root_info *)(((void *)dp + dotdot_rec_len));
+ if (root->reserved_zero ||
+ root->info_length != sizeof(struct dx_root_info))
+ return NULL;
+- count_offset = 32;
+- } else
+- return NULL;
++ count_offset = 8 + dot_rec_len + dotdot_rec_len;
++ }
+
+ if (offset)
+ *offset = count_offset;
@@ -500,11 +501,12 @@ ext4_next_entry(struct ext4_dir_entry_2
*/
struct dx_root_info *dx_get_dx_info(struct ext4_dir_entry_2 *de)
if (err)
goto journal_error;
-@@ -2203,19 +2240,25 @@ static int ext4_dx_add_entry(handle_t *h
+@@ -2203,19 +2240,27 @@ static int ext4_dx_add_entry(handle_t *h
frame->entries = entries = entries2;
swap(frame->bh, bh2);
}
if (err)
goto journal_error;
brelse (bh2);
-+ ext4_handle_dirty_dirent_node(handle, dir,
-+ (frame - 1)->bh);
++ err = ext4_handle_dirty_dx_node(handle, dir,
++ (frame - 1)->bh);
++ if (err)
++ goto journal_error;
+ if (restart) {
-+ ext4_handle_dirty_dirent_node(handle, dir,
-+ frame->bh);
-+ goto cleanup;
++ err = ext4_handle_dirty_dx_node(handle, dir,
++ frame->bh);
++ goto journal_error;
+ }
} else {
struct dx_root_info *info;
icount * sizeof(struct dx_entry));
dx_set_limit(entries2, dx_node_limit(dir));
-@@ -2224,21 +2267,14 @@ static int ext4_dx_add_entry(handle_t *h
+@@ -2224,22 +2267,17 @@ static int ext4_dx_add_entry(handle_t *h
dx_set_block(entries + 0, newblock);
info = dx_get_dx_info((struct ext4_dir_entry_2*)
frames[0].bh->b_data);
- frame->bh = bh2;
- err = ext4_journal_get_write_access(handle,
- frame->bh);
-- if (err)
-- goto journal_error;
-- }
-- err = ext4_handle_dirty_dx_node(handle, dir, frames[0].bh);
-- if (err) {
-- ext4_std_error(inode->i_sb, err);
+ info->indirect_levels += 1;
+ dxtrace(printk(KERN_DEBUG
+ "Creating %d level index...\n",
+ info->indirect_levels));
-+ ext4_handle_dirty_dirent_node(handle, dir, frame->bh);
-+ ext4_handle_dirty_dirent_node(handle, dir, bh2);
++ err = ext4_handle_dirty_dx_node(handle, dir, frame->bh);
+ if (err)
+ goto journal_error;
+- }
+- err = ext4_handle_dirty_dx_node(handle, dir, frames[0].bh);
+- if (err) {
+- ext4_std_error(inode->i_sb, err);
+- goto cleanup;
++ err = ext4_handle_dirty_dx_node(handle, dir, bh2);
+ brelse(bh2);
+ restart = 1;
- goto cleanup;
++ goto journal_error;
}
}
-@@ -2253,6 +2289,10 @@ journal_error:
+ de = do_split(handle, dir, &bh, frame, &hinfo, &err);
+@@ -2249,10 +2285,14 @@ static int ext4_dx_add_entry(handle_t *h
+ goto cleanup;
+
+ journal_error:
+- ext4_std_error(dir->i_sb, err);
++ ext4_std_error(dir->i_sb, err); /* this is a no-op if err == 0 */
cleanup:
brelse(bh);
dx_release(frames);
dx_get_limit((frame - 1)->entries)) {
@@ -2277,16 +2622,43 @@ again:
restart = 1;
- goto cleanup;
+ goto journal_error;
}
+ } else if (!ext4_htree_dx_locked(lck)) {
+ struct ext4_dir_lock_data *ld = ext4_htree_lock_data(lck);
goto cleanup;
journal_error:
- ext4_std_error(dir->i_sb, err);
+ ext4_std_error(dir->i_sb, err); /* this is a no-op if err == 0 */
cleanup:
+ ext4_htree_dx_unlock(lck);
+ ext4_htree_de_unlock(lck);
extern int search_dir(struct buffer_head *bh,
char *search_buf,
int buf_size,
-@@ -2761,6 +2810,28 @@ extern struct mutex ext4__aio_mutex[EXT4
+@@ -2761,6 +2810,36 @@ extern struct mutex ext4__aio_mutex[EXT4
extern int ext4_resize_begin(struct super_block *sb);
extern void ext4_resize_end(struct super_block *sb);
+ char *len = de->name + de->name_len + 1 /* NUL terminator */;
+ int dlen = 0;
+ __u8 extra_data_flags = (de->file_type & ~EXT4_FT_MASK) >> 4;
++ struct ext4_dir_entry_tail *t = (struct ext4_dir_entry_tail *)de;
++
++ if (!t->det_reserved_zero1 &&
++ le16_to_cpu(t->det_rec_len) ==
++ sizeof(struct ext4_dir_entry_tail) &&
++ !t->det_reserved_zero2 &&
++ t->det_reserved_ft == EXT4_FT_DIR_CSUM)
++ return 0;
+
+ while (extra_data_flags) {
+ if (extra_data_flags & 1) {
static unsigned dx_node_limit(struct inode *dir);
static struct dx_frame *dx_probe(const struct qstr *d_name,
struct inode *dir,
+@@ -379,22 +380,23 @@ static struct dx_countlimit *get_dx_coun
+ {
+ struct ext4_dir_entry *dp;
+ struct dx_root_info *root;
+- int count_offset;
++ int count_offset, dot_rec_len, dotdot_rec_len;
+
+ if (le16_to_cpu(dirent->rec_len) == EXT4_BLOCK_SIZE(inode->i_sb))
+ count_offset = 8;
+- else if (le16_to_cpu(dirent->rec_len) == 12) {
+- dp = (struct ext4_dir_entry *)(((void *)dirent) + 12);
++ else {
++ dot_rec_len = le16_to_cpu(dirent->rec_len);
++ dp = (struct ext4_dir_entry *)(((void *)dirent) + dot_rec_len);
+ if (le16_to_cpu(dp->rec_len) !=
+- EXT4_BLOCK_SIZE(inode->i_sb) - 12)
++ EXT4_BLOCK_SIZE(inode->i_sb) - dot_rec_len)
+ return NULL;
+- root = (struct dx_root_info *)(((void *)dp + 12));
++ dotdot_rec_len = EXT4_DIR_REC_LEN((struct ext4_dir_entry_2 *)dp);
++ root = (struct dx_root_info *)(((void *)dp + dotdot_rec_len));
+ if (root->reserved_zero ||
+ root->info_length != sizeof(struct dx_root_info))
+ return NULL;
+- count_offset = 32;
+- } else
+- return NULL;
++ count_offset = 8 + dot_rec_len + dotdot_rec_len;
++ }
+
+ if (offset)
+ *offset = count_offset;
@@ -504,11 +505,12 @@ ext4_next_entry(struct ext4_dir_entry_2
*/
struct dx_root_info *dx_get_dx_info(struct ext4_dir_entry_2 *de)
if (err)
goto journal_error;
-@@ -2203,19 +2240,25 @@ static int ext4_dx_add_entry(handle_t *h
+@@ -2203,19 +2240,27 @@ static int ext4_dx_add_entry(handle_t *h
frame->entries = entries = entries2;
swap(frame->bh, bh2);
}
if (err)
goto journal_error;
brelse (bh2);
-+ ext4_handle_dirty_dirent_node(handle, dir,
-+ (frame - 1)->bh);
++ err = ext4_handle_dirty_dx_node(handle, dir,
++ (frame - 1)->bh);
++ if (err)
++ goto journal_error;
+ if (restart) {
-+ ext4_handle_dirty_dirent_node(handle, dir,
-+ frame->bh);
-+ goto cleanup;
++ err = ext4_handle_dirty_dx_node(handle, dir,
++ frame->bh);
++ goto journal_error;
+ }
} else {
struct dx_root_info *info;
icount * sizeof(struct dx_entry));
dx_set_limit(entries2, dx_node_limit(dir));
-@@ -2224,21 +2267,14 @@ static int ext4_dx_add_entry(handle_t *h
+@@ -2224,22 +2267,17 @@ static int ext4_dx_add_entry(handle_t *h
dx_set_block(entries + 0, newblock);
info = dx_get_dx_info((struct ext4_dir_entry_2*)
frames[0].bh->b_data);
- frame->bh = bh2;
- err = ext4_journal_get_write_access(handle,
- frame->bh);
-- if (err)
-- goto journal_error;
-- }
-- err = ext4_handle_dirty_dx_node(handle, dir, frames[0].bh);
-- if (err) {
-- ext4_std_error(inode->i_sb, err);
+ info->indirect_levels += 1;
+ dxtrace(printk(KERN_DEBUG
+ "Creating %d level index...\n",
+ info->indirect_levels));
-+ ext4_handle_dirty_dirent_node(handle, dir, frame->bh);
-+ ext4_handle_dirty_dirent_node(handle, dir, bh2);
++ err = ext4_handle_dirty_dx_node(handle, dir, frame->bh);
+ if (err)
+ goto journal_error;
+- }
+- err = ext4_handle_dirty_dx_node(handle, dir, frames[0].bh);
+- if (err) {
+- ext4_std_error(inode->i_sb, err);
+- goto cleanup;
++ err = ext4_handle_dirty_dx_node(handle, dir, bh2);
+ brelse(bh2);
+ restart = 1;
- goto cleanup;
++ goto journal_error;
}
}
-@@ -2253,6 +2289,10 @@ journal_error:
+ de = do_split(handle, dir, &bh, frame, &hinfo, &err);
+@@ -2249,10 +2285,14 @@ static int ext4_dx_add_entry(handle_t *h
+ goto cleanup;
+
+ journal_error:
+- ext4_std_error(dir->i_sb, err);
++ ext4_std_error(dir->i_sb, err); /* this is a no-op if err == 0 */
cleanup:
brelse(bh);
dx_release(frames);
dx_get_limit((frame - 1)->entries)) {
@@ -2277,16 +2622,43 @@ again:
restart = 1;
- goto cleanup;
+ goto journal_error;
}
+ } else if (!ext4_htree_dx_locked(lck)) {
+ struct ext4_dir_lock_data *ld = ext4_htree_lock_data(lck);
goto cleanup;
journal_error:
- ext4_std_error(dir->i_sb, err);
+ ext4_std_error(dir->i_sb, err); /* this is a no-op if err == 0 */
cleanup:
+ ext4_htree_dx_unlock(lck);
+ ext4_htree_de_unlock(lck);
extern int search_dir(struct buffer_head *bh,
char *search_buf,
int buf_size,
-@@ -2834,6 +2885,28 @@ extern struct mutex ext4__aio_mutex[EXT4
+@@ -2834,6 +2885,36 @@ extern struct mutex ext4__aio_mutex[EXT4
extern int ext4_resize_begin(struct super_block *sb);
extern void ext4_resize_end(struct super_block *sb);
+ char *len = de->name + de->name_len + 1 /* NUL terminator */;
+ int dlen = 0;
+ __u8 extra_data_flags = (de->file_type & ~EXT4_FT_MASK) >> 4;
++ struct ext4_dir_entry_tail *t = (struct ext4_dir_entry_tail *)de;
++
++ if (!t->det_reserved_zero1 &&
++ le16_to_cpu(t->det_rec_len) ==
++ sizeof(struct ext4_dir_entry_tail) &&
++ !t->det_reserved_zero2 &&
++ t->det_reserved_ft == EXT4_FT_DIR_CSUM)
++ return 0;
+
+ while (extra_data_flags) {
+ if (extra_data_flags & 1) {
static unsigned dx_node_limit(struct inode *dir);
static struct dx_frame *dx_probe(const struct qstr *d_name,
struct inode *dir,
+@@ -379,22 +380,23 @@ static struct dx_countlimit *get_dx_coun
+ {
+ struct ext4_dir_entry *dp;
+ struct dx_root_info *root;
+- int count_offset;
++ int count_offset, dot_rec_len, dotdot_rec_len;
+
+ if (le16_to_cpu(dirent->rec_len) == EXT4_BLOCK_SIZE(inode->i_sb))
+ count_offset = 8;
+- else if (le16_to_cpu(dirent->rec_len) == 12) {
+- dp = (struct ext4_dir_entry *)(((void *)dirent) + 12);
++ else {
++ dot_rec_len = le16_to_cpu(dirent->rec_len);
++ dp = (struct ext4_dir_entry *)(((void *)dirent) + dot_rec_len);
+ if (le16_to_cpu(dp->rec_len) !=
+- EXT4_BLOCK_SIZE(inode->i_sb) - 12)
++ EXT4_BLOCK_SIZE(inode->i_sb) - dot_rec_len)
+ return NULL;
+- root = (struct dx_root_info *)(((void *)dp + 12));
++ dotdot_rec_len = EXT4_DIR_REC_LEN((struct ext4_dir_entry_2 *)dp);
++ root = (struct dx_root_info *)(((void *)dp + dotdot_rec_len));
+ if (root->reserved_zero ||
+ root->info_length != sizeof(struct dx_root_info))
+ return NULL;
+- count_offset = 32;
+- } else
+- return NULL;
++ count_offset = 8 + dot_rec_len + dotdot_rec_len;
++ }
+
+ if (offset)
+ *offset = count_offset;
@@ -500,11 +501,12 @@ ext4_next_entry(struct ext4_dir_entry_2
*/
struct dx_root_info *dx_get_dx_info(struct ext4_dir_entry_2 *de)
dx_get_limit((frame - 1)->entries)) {
@@ -2277,16 +2622,43 @@ again:
restart = 1;
- goto cleanup;
+ goto journal_error;
}
+ } else if (!ext4_htree_dx_locked(lck)) {
+ struct ext4_dir_lock_data *ld = ext4_htree_lock_data(lck);
goto cleanup;
journal_error:
- ext4_std_error(dir->i_sb, err);
+ ext4_std_error(dir->i_sb, err); /* this is a no-op if err == 0 */
cleanup:
+ ext4_htree_dx_unlock(lck);
+ ext4_htree_de_unlock(lck);
if (err)
goto journal_error;
-@@ -2203,19 +2240,25 @@ static int ext4_dx_add_entry(handle_t *h
+@@ -2203,19 +2240,27 @@ static int ext4_dx_add_entry(handle_t *h
frame->entries = entries = entries2;
swap(frame->bh, bh2);
}
if (err)
goto journal_error;
brelse (bh2);
-+ ext4_handle_dirty_dirent_node(handle, dir,
-+ (frame - 1)->bh);
++ err = ext4_handle_dirty_dx_node(handle, dir,
++ (frame - 1)->bh);
++ if (err)
++ goto journal_error;
+ if (restart) {
-+ ext4_handle_dirty_dirent_node(handle, dir,
-+ frame->bh);
-+ goto cleanup;
++ err = ext4_handle_dirty_dx_node(handle, dir,
++ frame->bh);
++ goto journal_error;
+ }
} else {
struct dx_root_info *info;
icount * sizeof(struct dx_entry));
dx_set_limit(entries2, dx_node_limit(dir));
-@@ -2224,21 +2267,14 @@ static int ext4_dx_add_entry(handle_t *h
+@@ -2224,22 +2267,17 @@ static int ext4_dx_add_entry(handle_t *h
dx_set_block(entries + 0, newblock);
info = dx_get_dx_info((struct ext4_dir_entry_2*)
frames[0].bh->b_data);
- frame->bh = bh2;
- err = ext4_journal_get_write_access(handle,
- frame->bh);
-- if (err)
-- goto journal_error;
-- }
-- err = ext4_handle_dirty_dx_node(handle, dir, frames[0].bh);
-- if (err) {
-- ext4_std_error(inode->i_sb, err);
+ info->indirect_levels += 1;
+ dxtrace(printk(KERN_DEBUG
+ "Creating %d level index...\n",
+ info->indirect_levels));
-+ ext4_handle_dirty_dirent_node(handle, dir, frame->bh);
-+ ext4_handle_dirty_dirent_node(handle, dir, bh2);
++ err = ext4_handle_dirty_dx_node(handle, dir, frame->bh);
+ if (err)
+ goto journal_error;
+- }
+- err = ext4_handle_dirty_dx_node(handle, dir, frames[0].bh);
+- if (err) {
+- ext4_std_error(inode->i_sb, err);
+- goto cleanup;
++ err = ext4_handle_dirty_dx_node(handle, dir, bh2);
+ brelse(bh2);
+ restart = 1;
- goto cleanup;
++ goto journal_error;
}
}
-@@ -2253,6 +2289,10 @@ journal_error:
+ de = do_split(handle, dir, &bh, frame, &hinfo, &err);
+@@ -2249,10 +2285,14 @@ static int ext4_dx_add_entry(handle_t *h
+ goto cleanup;
+
+ journal_error:
+- ext4_std_error(dir->i_sb, err);
++ ext4_std_error(dir->i_sb, err); /* this is a no-op if err == 0 */
cleanup:
brelse(bh);
dx_release(frames);
extern int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash,
__u32 start_minor_hash, __u32 *next_hash);
extern int ext4_search_dir(struct buffer_head *bh,
-@@ -2761,6 +2810,28 @@ extern struct mutex ext4__aio_mutex[EXT4
+@@ -2761,6 +2810,36 @@ extern struct mutex ext4__aio_mutex[EXT4
extern int ext4_resize_begin(struct super_block *sb);
extern void ext4_resize_end(struct super_block *sb);
+ char *len = de->name + de->name_len + 1 /* NUL terminator */;
+ int dlen = 0;
+ __u8 extra_data_flags = (de->file_type & ~EXT4_FT_MASK) >> 4;
++ struct ext4_dir_entry_tail *t = (struct ext4_dir_entry_tail *)de;
++
++ if (!t->det_reserved_zero1 &&
++ le16_to_cpu(t->det_rec_len) ==
++ sizeof(struct ext4_dir_entry_tail) &&
++ !t->det_reserved_zero2 &&
++ t->det_reserved_ft == EXT4_FT_DIR_CSUM)
++ return 0;
+
+ while (extra_data_flags) {
+ if (extra_data_flags & 1) {
static unsigned dx_node_limit(struct inode *dir);
static struct dx_frame *dx_probe(const struct qstr *d_name,
struct inode *dir,
+@@ -379,22 +380,23 @@ static struct dx_countlimit *get_dx_coun
+ {
+ struct ext4_dir_entry *dp;
+ struct dx_root_info *root;
+- int count_offset;
++ int count_offset, dot_rec_len, dotdot_rec_len;
+
+ if (le16_to_cpu(dirent->rec_len) == EXT4_BLOCK_SIZE(inode->i_sb))
+ count_offset = 8;
+- else if (le16_to_cpu(dirent->rec_len) == 12) {
+- dp = (struct ext4_dir_entry *)(((void *)dirent) + 12);
++ else {
++ dot_rec_len = le16_to_cpu(dirent->rec_len);
++ dp = (struct ext4_dir_entry *)(((void *)dirent) + dot_rec_len);
+ if (le16_to_cpu(dp->rec_len) !=
+- EXT4_BLOCK_SIZE(inode->i_sb) - 12)
++ EXT4_BLOCK_SIZE(inode->i_sb) - dot_rec_len)
+ return NULL;
+- root = (struct dx_root_info *)(((void *)dp + 12));
++ dotdot_rec_len = EXT4_DIR_REC_LEN((struct ext4_dir_entry_2 *)dp);
++ root = (struct dx_root_info *)(((void *)dp + dotdot_rec_len));
+ if (root->reserved_zero ||
+ root->info_length != sizeof(struct dx_root_info))
+ return NULL;
+- count_offset = 32;
+- } else
+- return NULL;
++ count_offset = 8 + dot_rec_len + dotdot_rec_len;
++ }
+
+ if (offset)
+ *offset = count_offset;
@@ -504,11 +505,12 @@ ext4_next_entry(struct ext4_dir_entry_2
*/
struct dx_root_info *dx_get_dx_info(struct ext4_dir_entry_2 *de)
if (err)
goto journal_error;
-@@ -2203,19 +2240,25 @@ static int ext4_dx_add_entry(handle_t *h
+@@ -2203,19 +2240,27 @@ static int ext4_dx_add_entry(handle_t *h
frame->entries = entries = entries2;
swap(frame->bh, bh2);
}
if (err)
goto journal_error;
brelse (bh2);
-+ ext4_handle_dirty_dirent_node(handle, dir,
-+ (frame - 1)->bh);
++ err = ext4_handle_dirty_dx_node(handle, dir,
++ (frame - 1)->bh);
++ if (err)
++ goto journal_error;
+ if (restart) {
-+ ext4_handle_dirty_dirent_node(handle, dir,
-+ frame->bh);
-+ goto cleanup;
++ err = ext4_handle_dirty_dx_node(handle, dir,
++ frame->bh);
++ goto journal_error;
+ }
} else {
struct dx_root_info *info;
icount * sizeof(struct dx_entry));
dx_set_limit(entries2, dx_node_limit(dir));
-@@ -2224,21 +2267,14 @@ static int ext4_dx_add_entry(handle_t *h
+@@ -2224,22 +2267,17 @@ static int ext4_dx_add_entry(handle_t *h
dx_set_block(entries + 0, newblock);
info = dx_get_dx_info((struct ext4_dir_entry_2*)
frames[0].bh->b_data);
- frame->bh = bh2;
- err = ext4_journal_get_write_access(handle,
- frame->bh);
-- if (err)
-- goto journal_error;
-- }
-- err = ext4_handle_dirty_dx_node(handle, dir, frames[0].bh);
-- if (err) {
-- ext4_std_error(inode->i_sb, err);
+ info->indirect_levels += 1;
+ dxtrace(printk(KERN_DEBUG
+ "Creating %d level index...\n",
+ info->indirect_levels));
-+ ext4_handle_dirty_dirent_node(handle, dir, frame->bh);
-+ ext4_handle_dirty_dirent_node(handle, dir, bh2);
++ err = ext4_handle_dirty_dx_node(handle, dir, frame->bh);
+ if (err)
+ goto journal_error;
+- }
+- err = ext4_handle_dirty_dx_node(handle, dir, frames[0].bh);
+- if (err) {
+- ext4_std_error(inode->i_sb, err);
+- goto cleanup;
++ err = ext4_handle_dirty_dx_node(handle, dir, bh2);
+ brelse(bh2);
+ restart = 1;
- goto cleanup;
++ goto journal_error;
}
}
-@@ -2253,6 +2289,10 @@ journal_error:
+ de = do_split(handle, dir, &bh, frame, &fname->hinfo);
+@@ -2249,10 +2285,14 @@ static int ext4_dx_add_entry(handle_t *h
+ goto cleanup;
+
+ journal_error:
+- ext4_std_error(dir->i_sb, err);
++ ext4_std_error(dir->i_sb, err); /* this is a no-op if err == 0 */
cleanup:
brelse(bh);
dx_release(frames);
dx_get_limit((frame - 1)->entries)) {
@@ -2277,8 +2622,32 @@ again:
restart = 1;
- goto cleanup;
+ goto journal_error;
}
+ } else if (!ext4_htree_dx_locked(lck)) {
+ struct ext4_dir_lock_data *ld = ext4_htree_lock_data(lck);
goto cleanup;
@@ -2277,6 +2622,8 @@ again:
journal_error:
- ext4_std_error(dir->i_sb, err);
+ ext4_std_error(dir->i_sb, err); /* this is a no-op if err == 0 */
cleanup:
+ ext4_htree_dx_unlock(lck);
+ ext4_htree_de_unlock(lck);
extern int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash,
__u32 start_minor_hash, __u32 *next_hash);
extern int ext4_search_dir(struct buffer_head *bh,
-@@ -2761,6 +2810,28 @@ extern struct mutex ext4__aio_mutex[EXT4
+@@ -2761,6 +2810,36 @@ extern struct mutex ext4__aio_mutex[EXT4
extern int ext4_resize_begin(struct super_block *sb);
extern void ext4_resize_end(struct super_block *sb);
+ char *len = de->name + de->name_len + 1 /* NUL terminator */;
+ int dlen = 0;
+ __u8 extra_data_flags = (de->file_type & ~EXT4_FT_MASK) >> 4;
++ struct ext4_dir_entry_tail *t = (struct ext4_dir_entry_tail *)de;
++
++ if (!t->det_reserved_zero1 &&
++ le16_to_cpu(t->det_rec_len) ==
++ sizeof(struct ext4_dir_entry_tail) &&
++ !t->det_reserved_zero2 &&
++ t->det_reserved_ft == EXT4_FT_DIR_CSUM)
++ return 0;
+
+ while (extra_data_flags) {
+ if (extra_data_flags & 1) {
static unsigned dx_node_limit(struct inode *dir);
static struct dx_frame *dx_probe(struct ext4_filename *fname,
struct inode *dir,
+@@ -383,22 +384,23 @@ static struct dx_countlimit *get_dx_coun
+ {
+ struct ext4_dir_entry *dp;
+ struct dx_root_info *root;
+- int count_offset;
++ int count_offset, dot_rec_len, dotdot_rec_len;
+
+ if (le16_to_cpu(dirent->rec_len) == EXT4_BLOCK_SIZE(inode->i_sb))
+ count_offset = 8;
+- else if (le16_to_cpu(dirent->rec_len) == 12) {
+- dp = (struct ext4_dir_entry *)(((void *)dirent) + 12);
++ else {
++ dot_rec_len = le16_to_cpu(dirent->rec_len);
++ dp = (struct ext4_dir_entry *)(((void *)dirent) + dot_rec_len);
+ if (le16_to_cpu(dp->rec_len) !=
+- EXT4_BLOCK_SIZE(inode->i_sb) - 12)
++ EXT4_BLOCK_SIZE(inode->i_sb) - dot_rec_len)
+ return NULL;
+- root = (struct dx_root_info *)(((void *)dp + 12));
++ dotdot_rec_len = EXT4_DIR_REC_LEN((struct ext4_dir_entry_2 *)dp);
++ root = (struct dx_root_info *)(((void *)dp + dotdot_rec_len));
+ if (root->reserved_zero ||
+ root->info_length != sizeof(struct dx_root_info))
+ return NULL;
+- count_offset = 32;
+- } else
+- return NULL;
++ count_offset = 8 + dot_rec_len + dotdot_rec_len;
++ }
+
+ if (offset)
+ *offset = count_offset;
@@ -504,11 +505,12 @@ ext4_next_entry(struct ext4_dir_entry_2
*/
struct dx_root_info *dx_get_dx_info(struct ext4_dir_entry_2 *de)
if (err)
goto journal_error;
-@@ -2203,19 +2240,25 @@ static int ext4_dx_add_entry(handle_t *h
+@@ -2203,19 +2240,27 @@ static int ext4_dx_add_entry(handle_t *h
frame->entries = entries = entries2;
swap(frame->bh, bh2);
}
if (err)
goto journal_error;
brelse (bh2);
-+ ext4_handle_dirty_dirent_node(handle, dir,
-+ (frame - 1)->bh);
++ err = ext4_handle_dirty_dx_node(handle, dir,
++ (frame - 1)->bh);
++ if (err)
++ goto journal_error;
+ if (restart) {
-+ ext4_handle_dirty_dirent_node(handle, dir,
-+ frame->bh);
-+ goto cleanup;
++ err = ext4_handle_dirty_dx_node(handle, dir,
++ frame->bh);
++ goto journal_error;
+ }
} else {
struct dx_root_info *info;
icount * sizeof(struct dx_entry));
dx_set_limit(entries2, dx_node_limit(dir));
-@@ -2224,21 +2267,14 @@ static int ext4_dx_add_entry(handle_t *h
+@@ -2224,22 +2267,17 @@ static int ext4_dx_add_entry(handle_t *h
dx_set_block(entries + 0, newblock);
info = dx_get_dx_info((struct ext4_dir_entry_2*)
frames[0].bh->b_data);
- frame->bh = bh2;
- err = ext4_journal_get_write_access(handle,
- frame->bh);
-- if (err)
-- goto journal_error;
-- }
-- err = ext4_handle_dirty_dx_node(handle, dir, frames[0].bh);
-- if (err) {
-- ext4_std_error(inode->i_sb, err);
+ info->indirect_levels += 1;
+ dxtrace(printk(KERN_DEBUG
+ "Creating %d level index...\n",
+ info->indirect_levels));
-+ ext4_handle_dirty_dirent_node(handle, dir, frame->bh);
-+ ext4_handle_dirty_dirent_node(handle, dir, bh2);
++ err = ext4_handle_dirty_dx_node(handle, dir, frame->bh);
+ if (err)
+ goto journal_error;
+- }
+- err = ext4_handle_dirty_dx_node(handle, dir, frames[0].bh);
+- if (err) {
+- ext4_std_error(inode->i_sb, err);
+- goto cleanup;
++ err = ext4_handle_dirty_dx_node(handle, dir, bh2);
+ brelse(bh2);
+ restart = 1;
- goto cleanup;
++ goto journal_error;
}
}
-@@ -2253,6 +2289,10 @@ journal_error:
+ de = do_split(handle, dir, &bh, frame, &fname->hinfo);
+@@ -2249,10 +2285,14 @@ static int ext4_dx_add_entry(handle_t *h
+ goto cleanup;
+
+ journal_error:
+- ext4_std_error(dir->i_sb, err);
++ ext4_std_error(dir->i_sb, err); /* this is a no-op if err == 0 */
cleanup:
brelse(bh);
dx_release(frames);
dx_get_limit((frame - 1)->entries)) {
@@ -2496,8 +2842,32 @@ again:
restart = 1;
- goto cleanup;
+ goto journal_error;
}
+ } else if (!ext4_htree_dx_locked(lck)) {
+ struct ext4_dir_lock_data *ld = ext4_htree_lock_data(lck);
goto cleanup;
@@ -2508,6 +2878,8 @@ again:
journal_error:
- ext4_std_error(dir->i_sb, err);
+ ext4_std_error(dir->i_sb, err); /* this is a no-op if err == 0 */
cleanup:
+ ext4_htree_dx_unlock(lck);
+ ext4_htree_de_unlock(lck);
extern int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash,
__u32 start_minor_hash, __u32 *next_hash);
extern int ext4_search_dir(struct buffer_head *bh,
-@@ -3292,6 +3343,28 @@ extern struct mutex ext4__aio_mutex[EXT4_WQ_HASH_SZ];
+@@ -3292,6 +3343,36 @@ extern struct mutex ext4__aio_mutex[EXT4_WQ_HASH_SZ];
extern int ext4_resize_begin(struct super_block *sb);
extern void ext4_resize_end(struct super_block *sb);
+ char *len = de->name + de->name_len + 1 /* NUL terminator */;
+ int dlen = 0;
+ __u8 extra_data_flags = (de->file_type & ~EXT4_FT_MASK) >> 4;
++ struct ext4_dir_entry_tail *t = (struct ext4_dir_entry_tail *)de;
++
++ if (!t->det_reserved_zero1 &&
++ le16_to_cpu(t->det_rec_len) ==
++ sizeof(struct ext4_dir_entry_tail) &&
++ !t->det_reserved_zero2 &&
++ t->det_reserved_ft == EXT4_FT_DIR_CSUM)
++ return 0;
+
+ while (extra_data_flags) {
+ if (extra_data_flags & 1) {
static unsigned dx_node_limit(struct inode *dir);
static struct dx_frame *dx_probe(struct ext4_filename *fname,
struct inode *dir,
+@@ -384,22 +385,23 @@ static struct dx_countlimit *get_dx_coun
+ {
+ struct ext4_dir_entry *dp;
+ struct dx_root_info *root;
+- int count_offset;
++ int count_offset, dot_rec_len, dotdot_rec_len;
+
+ if (le16_to_cpu(dirent->rec_len) == EXT4_BLOCK_SIZE(inode->i_sb))
+ count_offset = 8;
+- else if (le16_to_cpu(dirent->rec_len) == 12) {
+- dp = (struct ext4_dir_entry *)(((void *)dirent) + 12);
++ else {
++ dot_rec_len = le16_to_cpu(dirent->rec_len);
++ dp = (struct ext4_dir_entry *)(((void *)dirent) + dot_rec_len);
+ if (le16_to_cpu(dp->rec_len) !=
+- EXT4_BLOCK_SIZE(inode->i_sb) - 12)
++ EXT4_BLOCK_SIZE(inode->i_sb) - dot_rec_len)
+ return NULL;
+- root = (struct dx_root_info *)(((void *)dp + 12));
++ dotdot_rec_len = EXT4_DIR_REC_LEN((struct ext4_dir_entry_2 *)dp);
++ root = (struct dx_root_info *)(((void *)dp + dotdot_rec_len));
+ if (root->reserved_zero ||
+ root->info_length != sizeof(struct dx_root_info))
+ return NULL;
+- count_offset = 32;
+- } else
+- return NULL;
++ count_offset = 8 + dot_rec_len + dotdot_rec_len;
++ }
+
+ if (offset)
+ *offset = count_offset;
@@ -504,11 +505,12 @@ ext4_next_entry(struct ext4_dir_entry_2 *p, unsigned long blocksize)
*/
struct dx_root_info *dx_get_dx_info(struct ext4_dir_entry_2 *de)
extern int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash,
__u32 start_minor_hash, __u32 *next_hash);
extern int ext4_search_dir(struct buffer_head *bh,
-@@ -3292,6 +3343,28 @@ extern struct mutex ext4__aio_mutex[EXT4_WQ_HASH_SZ];
+@@ -3292,6 +3343,36 @@ extern struct mutex ext4__aio_mutex[EXT4_WQ_HASH_SZ];
extern int ext4_resize_begin(struct super_block *sb);
extern void ext4_resize_end(struct super_block *sb);
+ char *len = de->name + de->name_len + 1 /* NUL terminator */;
+ int dlen = 0;
+ __u8 extra_data_flags = (de->file_type & ~EXT4_FT_MASK) >> 4;
++ struct ext4_dir_entry_tail *t = (struct ext4_dir_entry_tail *)de;
++
++ if (!t->det_reserved_zero1 &&
++ le16_to_cpu(t->det_rec_len) ==
++ sizeof(struct ext4_dir_entry_tail) &&
++ !t->det_reserved_zero2 &&
++ t->det_reserved_ft == EXT4_FT_DIR_CSUM)
++ return 0;
+
+ while (extra_data_flags) {
+ if (extra_data_flags & 1) {
static unsigned dx_node_limit(struct inode *dir);
static struct dx_frame *dx_probe(struct ext4_filename *fname,
struct inode *dir,
+@@ -384,22 +385,23 @@ static struct dx_countlimit *get_dx_coun
+ {
+ struct ext4_dir_entry *dp;
+ struct dx_root_info *root;
+- int count_offset;
++ int count_offset, dot_rec_len, dotdot_rec_len;
+
+ if (le16_to_cpu(dirent->rec_len) == EXT4_BLOCK_SIZE(inode->i_sb))
+ count_offset = 8;
+- else if (le16_to_cpu(dirent->rec_len) == 12) {
+- dp = (struct ext4_dir_entry *)(((void *)dirent) + 12);
++ else {
++ dot_rec_len = le16_to_cpu(dirent->rec_len);
++ dp = (struct ext4_dir_entry *)(((void *)dirent) + dot_rec_len);
+ if (le16_to_cpu(dp->rec_len) !=
+- EXT4_BLOCK_SIZE(inode->i_sb) - 12)
++ EXT4_BLOCK_SIZE(inode->i_sb) - dot_rec_len)
+ return NULL;
+- root = (struct dx_root_info *)(((void *)dp + 12));
++ dotdot_rec_len = EXT4_DIR_REC_LEN((struct ext4_dir_entry_2 *)dp);
++ root = (struct dx_root_info *)(((void *)dp + dotdot_rec_len));
+ if (root->reserved_zero ||
+ root->info_length != sizeof(struct dx_root_info))
+ return NULL;
+- count_offset = 32;
+- } else
+- return NULL;
++ count_offset = 8 + dot_rec_len + dotdot_rec_len;
++ }
+
+ if (offset)
+ *offset = count_offset;
@@ -504,11 +505,12 @@ ext4_next_entry(struct ext4_dir_entry_2 *p, unsigned long blocksize)
*/
struct dx_root_info *dx_get_dx_info(struct ext4_dir_entry_2 *de)
if (err)
goto journal_error;
-@@ -2397,19 +2435,25 @@ static int ext4_dx_add_entry(handle_t *handle, struct ext4_filename *fname,
+@@ -2397,19 +2435,27 @@ static int ext4_dx_add_entry(handle_t *handle, struct ext4_filename *fname,
frame->entries = entries = entries2;
swap(frame->bh, bh2);
}
if (err)
goto journal_error;
brelse (bh2);
-+ ext4_handle_dirty_dirent_node(handle, dir,
-+ (frame - 1)->bh);
++ err = ext4_handle_dirty_dx_node(handle, dir,
++ (frame - 1)->bh);
++ if (err)
++ goto journal_error;
+ if (restart) {
-+ ext4_handle_dirty_dirent_node(handle, dir,
-+ frame->bh);
-+ goto cleanup;
++ err = ext4_handle_dirty_dx_node(handle, dir,
++ frame->bh);
++ goto journal_error;
+ }
} else {
struct dx_root_info *info;
icount * sizeof(struct dx_entry));
dx_set_limit(entries2, dx_node_limit(dir));
-@@ -2418,21 +2462,14 @@ static int ext4_dx_add_entry(handle_t *handle, struct ext4_filename *fname,
+@@ -2418,22 +2462,17 @@ static int ext4_dx_add_entry(handle_t *handle, struct ext4_filename *fname,
dx_set_block(entries + 0, newblock);
info = dx_get_dx_info((struct ext4_dir_entry_2 *)
frames[0].bh->b_data);
- frame->bh = bh2;
- err = ext4_journal_get_write_access(handle,
- frame->bh);
-- if (err)
-- goto journal_error;
-- }
-- err = ext4_handle_dirty_dx_node(handle, dir, frames[0].bh);
-- if (err) {
-- ext4_std_error(inode->i_sb, err);
+ info->indirect_levels += 1;
+ dxtrace(printk(KERN_DEBUG
+ "Creating %d level index...\n",
+ info->indirect_levels));
-+ ext4_handle_dirty_dirent_node(handle, dir, frame->bh);
-+ ext4_handle_dirty_dirent_node(handle, dir, bh2);
++ err = ext4_handle_dirty_dx_node(handle, dir, frame->bh);
+ if (err)
+ goto journal_error;
+- }
+- err = ext4_handle_dirty_dx_node(handle, dir, frames[0].bh);
+- if (err) {
+- ext4_std_error(inode->i_sb, err);
+- goto cleanup;
++ err = ext4_handle_dirty_dx_node(handle, dir, bh2);
+ brelse(bh2);
+ restart = 1;
- goto cleanup;
++ goto journal_error;
}
}
-@@ -2449,6 +2486,10 @@ journal_error:
+ de = do_split(handle, dir, &bh, frame, &fname->hinfo);
+@@ -2446,10 +2486,14 @@ static int ext4_dx_add_entry(handle_t *handle, struct ext4_filename *fname,
+ goto cleanup;
+
+ journal_error:
+- ext4_std_error(dir->i_sb, err);
++ ext4_std_error(dir->i_sb, err); /* this is a no-op if err == 0 */
cleanup:
brelse(bh);
dx_release(frames);
if (err)
goto journal_error;
-@@ -2399,19 +2437,25 @@ static int ext4_dx_add_entry(handle_t *handle, struct ext4_filename *fname,
+@@ -2399,19 +2437,27 @@ static int ext4_dx_add_entry(handle_t *handle, struct ext4_filename *fname,
frame->entries = entries = entries2;
swap(frame->bh, bh2);
}
if (err)
goto journal_error;
brelse (bh2);
-+ ext4_handle_dirty_dirent_node(handle, dir,
-+ (frame - 1)->bh);
++ err = ext4_handle_dirty_dx_node(handle, dir,
++ (frame - 1)->bh);
++ if (err)
++ goto journal_error;
+ if (restart) {
-+ ext4_handle_dirty_dirent_node(handle, dir,
-+ frame->bh);
-+ goto cleanup;
++ err = ext4_handle_dirty_dx_node(handle, dir,
++ frame->bh);
++ goto journal_error;
+ }
} else {
struct dx_root_info *info;
icount * sizeof(struct dx_entry));
dx_set_limit(entries2, dx_node_limit(dir));
-@@ -2420,21 +2464,14 @@ static int ext4_dx_add_entry(handle_t *handle, struct ext4_filename *fname,
+@@ -2420,22 +2464,17 @@ static int ext4_dx_add_entry(handle_t *handle, struct ext4_filename *fname,
dx_set_block(entries + 0, newblock);
info = dx_get_dx_info((struct ext4_dir_entry_2 *)
frames[0].bh->b_data);
- frame->bh = bh2;
- err = ext4_journal_get_write_access(handle,
- frame->bh);
-- if (err)
-- goto journal_error;
-- }
-- err = ext4_handle_dirty_dx_node(handle, dir, frames[0].bh);
-- if (err) {
-- ext4_std_error(inode->i_sb, err);
+ info->indirect_levels += 1;
+ dxtrace(printk(KERN_DEBUG
+ "Creating %d level index...\n",
+ info->indirect_levels));
-+ ext4_handle_dirty_dirent_node(handle, dir, frame->bh);
-+ ext4_handle_dirty_dirent_node(handle, dir, bh2);
++ err = ext4_handle_dirty_dx_node(handle, dir, frame->bh);
+ if (err)
+ goto journal_error;
+- }
+- err = ext4_handle_dirty_dx_node(handle, dir, frames[0].bh);
+- if (err) {
+- ext4_std_error(inode->i_sb, err);
+- goto cleanup;
++ err = ext4_handle_dirty_dx_node(handle, dir, bh2);
+ brelse(bh2);
+ restart = 1;
- goto cleanup;
++ goto journal_error;
}
}
-@@ -2451,6 +2488,10 @@ journal_error:
+ de = do_split(handle, dir, &bh, frame, &fname->hinfo);
+@@ -2447,10 +2488,14 @@ static int ext4_dx_add_entry(handle_t *handle, struct ext4_filename *fname,
+ goto cleanup;
+
+ journal_error:
+- ext4_std_error(dir->i_sb, err);
++ ext4_std_error(dir->i_sb, err); /* this is a no-op if err == 0 */
cleanup:
brelse(bh);
dx_release(frames);
dx_get_limit((frame - 1)->entries)) {
@@ -2472,8 +2818,32 @@ again:
restart = 1;
- goto cleanup;
+ goto journal_error;
}
+ } else if (!ext4_htree_dx_locked(lck)) {
+ struct ext4_dir_lock_data *ld = ext4_htree_lock_data(lck);
goto cleanup;
@@ -2484,6 +2854,8 @@ again:
journal_error:
- ext4_std_error(dir->i_sb, err);
+ ext4_std_error(dir->i_sb, err); /* this is a no-op if err == 0 */
cleanup:
+ ext4_htree_dx_unlock(lck);
+ ext4_htree_de_unlock(lck);
dx_get_limit((frame - 1)->entries)) {
@@ -2474,8 +2820,32 @@ again:
restart = 1;
- goto cleanup;
+ goto journal_error;
}
+ } else if (!ext4_htree_dx_locked(lck)) {
+ struct ext4_dir_lock_data *ld = ext4_htree_lock_data(lck);
goto cleanup;
@@ -2486,6 +2856,8 @@ again:
journal_error:
- ext4_std_error(dir->i_sb, err);
+ ext4_std_error(dir->i_sb, err); /* this is a no-op if err == 0 */
cleanup:
+ ext4_htree_dx_unlock(lck);
+ ext4_htree_de_unlock(lck);
extern int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash,
__u32 start_minor_hash, __u32 *next_hash);
extern int ext4_search_dir(struct buffer_head *bh,
-@@ -3265,6 +3317,28 @@ static inline void ext4_clear_io_unwritt
+@@ -3265,6 +3317,36 @@ static inline void ext4_clear_io_unwritt
extern const struct iomap_ops ext4_iomap_ops;
+ char *len = de->name + de->name_len + 1 /* NUL terminator */;
+ int dlen = 0;
+ __u8 extra_data_flags = (de->file_type & ~EXT4_FT_MASK) >> 4;
++ struct ext4_dir_entry_tail *t = (struct ext4_dir_entry_tail *)de;
++
++ if (!t->det_reserved_zero1 &&
++ le16_to_cpu(t->det_rec_len) ==
++ sizeof(struct ext4_dir_entry_tail) &&
++ !t->det_reserved_zero2 &&
++ t->det_reserved_ft == EXT4_FT_DIR_CSUM)
++ return 0;
+
+ while (extra_data_flags) {
+ if (extra_data_flags & 1) {
static unsigned dx_node_limit(struct inode *dir);
static struct dx_frame *dx_probe(struct ext4_filename *fname,
struct inode *dir,
+@@ -385,22 +386,23 @@ static struct dx_countlimit *get_dx_coun
+ {
+ struct ext4_dir_entry *dp;
+ struct dx_root_info *root;
+- int count_offset;
++ int count_offset, dot_rec_len, dotdot_rec_len;
+
+ if (le16_to_cpu(dirent->rec_len) == EXT4_BLOCK_SIZE(inode->i_sb))
+ count_offset = 8;
+- else if (le16_to_cpu(dirent->rec_len) == 12) {
+- dp = (struct ext4_dir_entry *)(((void *)dirent) + 12);
++ else {
++ dot_rec_len = le16_to_cpu(dirent->rec_len);
++ dp = (struct ext4_dir_entry *)(((void *)dirent) + dot_rec_len);
+ if (le16_to_cpu(dp->rec_len) !=
+- EXT4_BLOCK_SIZE(inode->i_sb) - 12)
++ EXT4_BLOCK_SIZE(inode->i_sb) - dot_rec_len)
+ return NULL;
+- root = (struct dx_root_info *)(((void *)dp + 12));
++ dotdot_rec_len = EXT4_DIR_REC_LEN((struct ext4_dir_entry_2 *)dp);
++ root = (struct dx_root_info *)(((void *)dp + dotdot_rec_len));
+ if (root->reserved_zero ||
+ root->info_length != sizeof(struct dx_root_info))
+ return NULL;
+- count_offset = 32;
+- } else
+- return NULL;
++ count_offset = 8 + dot_rec_len + dotdot_rec_len;
++ }
+
+ if (offset)
+ *offset = count_offset;
@@ -505,11 +506,12 @@ ext4_next_entry(struct ext4_dir_entry_2
*/
struct dx_root_info *dx_get_dx_info(struct ext4_dir_entry_2 *de)