}
/* fsync.c */
-@@ -2157,7 +2206,7 @@ extern struct buffer_head * ext4_find_en
- struct ext4_dir_entry_2 ** res_dir,
- int *inlined);
- extern int ext4_add_dot_dotdot(handle_t *handle, struct inode *dir,
-- struct inode *inode);
+@@ -2157,6 +2206,8 @@ extern struct buffer_head * ext4_find_en
+ extern int ext4_delete_entry(handle_t *handle, struct inode * dir,
+ struct ext4_dir_entry_2 *de_del,
+ struct buffer_head *bh);
++extern int ext4_add_dot_dotdot(handle_t *handle, struct inode *dir,
+ struct inode *inode, const void *, const void *);
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)
set_nlink(inode, 2);
if (csum_size) {
t = EXT4_DIRENT_TAIL(dir_block->b_data, blocksize);
-@@ -2508,7 +2597,8 @@ out:
- /* Initialize @inode as a subdirectory of @dir, and add the
- * "." and ".." entries into the first directory block. */
- int ext4_add_dot_dotdot(handle_t *handle, struct inode *dir,
-- struct inode *inode)
+@@ -2402,6 +2426,29 @@ out:
+ return err;
+ }
+
++/* Initialize @inode as a subdirectory of @dir, and add the
++ * "." and ".." entries into the first directory block. */
++int ext4_add_dot_dotdot(handle_t *handle, struct inode *dir,
+ struct inode *inode,
+ const void *data1, const void *data2)
++{
++ int rc;
++
++ if (IS_ERR(handle))
++ return PTR_ERR(handle);
++
++ if (IS_DIRSYNC(dir))
++ ext4_handle_sync(handle);
++
++ inode->i_op = &ext4_dir_inode_operations.ops;
++ inode->i_fop = &ext4_dir_operations;
++ rc = ext4_init_new_dir(handle, dir, inode, data1, data2);
++ if (!rc)
++ rc = ext4_mark_inode_dirty(handle, inode);
++ return rc;
++}
++EXPORT_SYMBOL(ext4_add_dot_dotdot);
++
+ static int ext4_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
{
- if (IS_ERR(handle))
- return PTR_ERR(handle);
-@@ -2518,7 +2608,7 @@ int ext4_add_dot_dotdot(handle_t *handle
-
- inode->i_op = &ext4_dir_inode_operations;
- inode->i_fop = &ext4_dir_operations;
-- return ext4_init_new_dir(handle, dir, inode);
-+ return ext4_init_new_dir(handle, dir, inode, data1, data2);
- }
- EXPORT_SYMBOL(ext4_add_dot_dotdot);
-
+ handle_t *handle;
@@ -2546,7 +2636,7 @@ retry:
inode->i_op = &ext4_dir_inode_operations;