--- /dev/null
+Index: linux-4.15.0/fs/ext4/namei.c
+===================================================================
+--- linux-4.15.0.orig/fs/ext4/namei.c
++++ linux-4.15.0/fs/ext4/namei.c
+@@ -2043,6 +2043,67 @@ out_frames:
+ return retval;
+ }
+
++/* update ".." entry */
++static int ext4_update_dotdot(handle_t *handle, struct dentry *dentry,
++ struct inode *inode)
++{
++ struct inode *dir = dentry->d_parent->d_inode;
++ struct buffer_head *bh;
++ struct ext4_dir_entry_2 *dot_de, *dotdot_de;
++ unsigned int offset;
++ int retval = 0;
++
++ if (IS_ERR(handle))
++ return PTR_ERR(handle);
++
++ if (IS_DIRSYNC(dir))
++ handle->h_sync = 1;
++
++ bh = ext4_read_dirblock(dir, 0, DIRENT_HTREE);
++ if (IS_ERR(bh))
++ return PTR_ERR(bh);
++
++ dot_de = (struct ext4_dir_entry_2 *) bh->b_data;
++ if (ext4_check_dir_entry(dir, NULL, dot_de, bh, bh->b_data,
++ bh->b_size, 0) ||
++ le32_to_cpu(dot_de->inode) != dir->i_ino ||
++ strcmp(".", dot_de->name)) {
++ EXT4_ERROR_INODE(dir, "directory missing '.'");
++ retval = -EFSCORRUPTED;
++ goto out;
++ }
++ offset = ext4_rec_len_from_disk(dot_de->rec_len,
++ dir->i_sb->s_blocksize);
++ dotdot_de = ext4_next_entry(dot_de, dir->i_sb->s_blocksize);
++ if (ext4_check_dir_entry(dir, NULL, dotdot_de, bh, bh->b_data,
++ bh->b_size, offset) ||
++ le32_to_cpu(dotdot_de->inode) == 0 ||
++ strcmp("..", dotdot_de->name)) {
++ EXT4_ERROR_INODE(dir, "directory missing '..'");
++ retval = -EFSCORRUPTED;
++ goto out;
++ }
++
++ BUFFER_TRACE(dir_block, "get_write_access");
++ retval = ext4_journal_get_write_access(handle, bh);
++ if (retval)
++ goto out;
++
++ dotdot_de->inode = cpu_to_le32(inode->i_ino);
++
++ ext4_mark_inode_dirty(handle, dir);
++ BUFFER_TRACE(dir_block, "call ext4_handle_dirty_metadata");
++ if (is_dx(dir)) {
++ retval = ext4_handle_dirty_dx_node(handle, dir, bh);
++ } else {
++ retval = ext4_handle_dirty_dirent_node(handle, dir, bh);
++ }
++
++out:
++ brelse(bh);
++ return retval;
++}
++
+ /*
+ * ext4_add_entry()
+ *
+@@ -2090,6 +2158,10 @@ static int ext4_add_entry(handle_t *hand
+ }
+ }
+
++ if (dentry->d_name.len == 2 &&
++ memcmp(dentry->d_name.name, "..", 2) == 0)
++ return ext4_update_dotdot(handle, dentry, inode);
++
+ if (is_dx(dir)) {
+ retval = ext4_dx_add_entry(handle, &fname, dir, inode);
+ if (!retval || (retval != ERR_BAD_DX_DIR))