X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=ldiskfs%2Fkernel_patches%2Fpatches%2Frhel8.7%2Fext4-hash-indexed-dir-dotdot-update.patch;fp=ldiskfs%2Fkernel_patches%2Fpatches%2Frhel8.7%2Fext4-hash-indexed-dir-dotdot-update.patch;h=68d4aa2900095163a66988d45f69e62ae0a1d895;hb=0536b2a26992f5d2ef9e3537a196afac81281f60;hp=0000000000000000000000000000000000000000;hpb=9d9b8cbaa4123df708a072acd1a4f30120075418;p=fs%2Flustre-release.git diff --git a/ldiskfs/kernel_patches/patches/rhel8.7/ext4-hash-indexed-dir-dotdot-update.patch b/ldiskfs/kernel_patches/patches/rhel8.7/ext4-hash-indexed-dir-dotdot-update.patch new file mode 100644 index 0000000..68d4aa2 --- /dev/null +++ b/ldiskfs/kernel_patches/patches/rhel8.7/ext4-hash-indexed-dir-dotdot-update.patch @@ -0,0 +1,83 @@ +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))