aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ext4/ext4.h7
-rw-r--r--fs/ext4/namei.c72
2 files changed, 53 insertions, 26 deletions
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index a971b65bf5ca..6cfe546282dc 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -2129,6 +2129,13 @@ extern int search_dir(struct buffer_head *bh,
2129 const struct qstr *d_name, 2129 const struct qstr *d_name,
2130 unsigned int offset, 2130 unsigned int offset,
2131 struct ext4_dir_entry_2 **res_dir); 2131 struct ext4_dir_entry_2 **res_dir);
2132extern int ext4_generic_delete_entry(handle_t *handle,
2133 struct inode *dir,
2134 struct ext4_dir_entry_2 *de_del,
2135 struct buffer_head *bh,
2136 void *entry_buf,
2137 int buf_size,
2138 int csum_size);
2132 2139
2133/* resize.c */ 2140/* resize.c */
2134extern int ext4_group_add(struct super_block *sb, 2141extern int ext4_group_add(struct super_block *sb,
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index b498cafed12b..c10fc2631ff5 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -2109,37 +2109,29 @@ cleanup:
2109} 2109}
2110 2110
2111/* 2111/*
2112 * ext4_delete_entry deletes a directory entry by merging it with the 2112 * ext4_generic_delete_entry deletes a directory entry by merging it
2113 * previous entry 2113 * with the previous entry
2114 */ 2114 */
2115static int ext4_delete_entry(handle_t *handle, 2115int ext4_generic_delete_entry(handle_t *handle,
2116 struct inode *dir, 2116 struct inode *dir,
2117 struct ext4_dir_entry_2 *de_del, 2117 struct ext4_dir_entry_2 *de_del,
2118 struct buffer_head *bh) 2118 struct buffer_head *bh,
2119 void *entry_buf,
2120 int buf_size,
2121 int csum_size)
2119{ 2122{
2120 struct ext4_dir_entry_2 *de, *pde; 2123 struct ext4_dir_entry_2 *de, *pde;
2121 unsigned int blocksize = dir->i_sb->s_blocksize; 2124 unsigned int blocksize = dir->i_sb->s_blocksize;
2122 int csum_size = 0; 2125 int i;
2123 int i, err;
2124
2125 if (EXT4_HAS_RO_COMPAT_FEATURE(dir->i_sb,
2126 EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
2127 csum_size = sizeof(struct ext4_dir_entry_tail);
2128 2126
2129 i = 0; 2127 i = 0;
2130 pde = NULL; 2128 pde = NULL;
2131 de = (struct ext4_dir_entry_2 *) bh->b_data; 2129 de = (struct ext4_dir_entry_2 *)entry_buf;
2132 while (i < bh->b_size - csum_size) { 2130 while (i < buf_size - csum_size) {
2133 if (ext4_check_dir_entry(dir, NULL, de, bh, 2131 if (ext4_check_dir_entry(dir, NULL, de, bh,
2134 bh->b_data, bh->b_size, i)) 2132 bh->b_data, bh->b_size, i))
2135 return -EIO; 2133 return -EIO;
2136 if (de == de_del) { 2134 if (de == de_del) {
2137 BUFFER_TRACE(bh, "get_write_access");
2138 err = ext4_journal_get_write_access(handle, bh);
2139 if (unlikely(err)) {
2140 ext4_std_error(dir->i_sb, err);
2141 return err;
2142 }
2143 if (pde) 2135 if (pde)
2144 pde->rec_len = ext4_rec_len_to_disk( 2136 pde->rec_len = ext4_rec_len_to_disk(
2145 ext4_rec_len_from_disk(pde->rec_len, 2137 ext4_rec_len_from_disk(pde->rec_len,
@@ -2150,12 +2142,6 @@ static int ext4_delete_entry(handle_t *handle,
2150 else 2142 else
2151 de->inode = 0; 2143 de->inode = 0;
2152 dir->i_version++; 2144 dir->i_version++;
2153 BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata");
2154 err = ext4_handle_dirty_dirent_node(handle, dir, bh);
2155 if (unlikely(err)) {
2156 ext4_std_error(dir->i_sb, err);
2157 return err;
2158 }
2159 return 0; 2145 return 0;
2160 } 2146 }
2161 i += ext4_rec_len_from_disk(de->rec_len, blocksize); 2147 i += ext4_rec_len_from_disk(de->rec_len, blocksize);
@@ -2165,6 +2151,40 @@ static int ext4_delete_entry(handle_t *handle,
2165 return -ENOENT; 2151 return -ENOENT;
2166} 2152}
2167 2153
2154static int ext4_delete_entry(handle_t *handle,
2155 struct inode *dir,
2156 struct ext4_dir_entry_2 *de_del,
2157 struct buffer_head *bh)
2158{
2159 int err, csum_size = 0;
2160
2161 if (EXT4_HAS_RO_COMPAT_FEATURE(dir->i_sb,
2162 EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
2163 csum_size = sizeof(struct ext4_dir_entry_tail);
2164
2165 BUFFER_TRACE(bh, "get_write_access");
2166 err = ext4_journal_get_write_access(handle, bh);
2167 if (unlikely(err))
2168 goto out;
2169
2170 err = ext4_generic_delete_entry(handle, dir, de_del,
2171 bh, bh->b_data,
2172 dir->i_sb->s_blocksize, csum_size);
2173 if (err)
2174 goto out;
2175
2176 BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata");
2177 err = ext4_handle_dirty_dirent_node(handle, dir, bh);
2178 if (unlikely(err))
2179 goto out;
2180
2181 return 0;
2182out:
2183 if (err != -ENOENT)
2184 ext4_std_error(dir->i_sb, err);
2185 return err;
2186}
2187
2168/* 2188/*
2169 * DIR_NLINK feature is set if 1) nlinks > EXT4_LINK_MAX or 2) nlinks == 2, 2189 * DIR_NLINK feature is set if 1) nlinks > EXT4_LINK_MAX or 2) nlinks == 2,
2170 * since this indicates that nlinks count was previously 1. 2190 * since this indicates that nlinks count was previously 1.