summaryrefslogtreecommitdiffstats
path: root/fs/ext4/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext4/inode.c')
-rw-r--r--fs/ext4/inode.c66
1 files changed, 17 insertions, 49 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 3e9415e2e74d..46def73d3472 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -239,7 +239,11 @@ void ext4_evict_inode(struct inode *inode)
239 */ 239 */
240 sb_start_intwrite(inode->i_sb); 240 sb_start_intwrite(inode->i_sb);
241 241
242 handle = ext4_journal_start(inode, EXT4_HT_TRUNCATE, extra_credits); 242 if (!IS_NOQUOTA(inode))
243 extra_credits += EXT4_MAXQUOTAS_DEL_BLOCKS(inode->i_sb);
244
245 handle = ext4_journal_start(inode, EXT4_HT_TRUNCATE,
246 ext4_blocks_for_truncate(inode)+extra_credits);
243 if (IS_ERR(handle)) { 247 if (IS_ERR(handle)) {
244 ext4_std_error(inode->i_sb, PTR_ERR(handle)); 248 ext4_std_error(inode->i_sb, PTR_ERR(handle));
245 /* 249 /*
@@ -251,36 +255,9 @@ void ext4_evict_inode(struct inode *inode)
251 sb_end_intwrite(inode->i_sb); 255 sb_end_intwrite(inode->i_sb);
252 goto no_delete; 256 goto no_delete;
253 } 257 }
258
254 if (IS_SYNC(inode)) 259 if (IS_SYNC(inode))
255 ext4_handle_sync(handle); 260 ext4_handle_sync(handle);
256
257 /*
258 * Delete xattr inode before deleting the main inode.
259 */
260 err = ext4_xattr_delete_inode(handle, inode, &ea_inode_array);
261 if (err) {
262 ext4_warning(inode->i_sb,
263 "couldn't delete inode's xattr (err %d)", err);
264 goto stop_handle;
265 }
266
267 if (!IS_NOQUOTA(inode))
268 extra_credits += 2 * EXT4_QUOTA_DEL_BLOCKS(inode->i_sb);
269
270 if (!ext4_handle_has_enough_credits(handle,
271 ext4_blocks_for_truncate(inode) + extra_credits)) {
272 err = ext4_journal_extend(handle,
273 ext4_blocks_for_truncate(inode) + extra_credits);
274 if (err > 0)
275 err = ext4_journal_restart(handle,
276 ext4_blocks_for_truncate(inode) + extra_credits);
277 if (err != 0) {
278 ext4_warning(inode->i_sb,
279 "couldn't extend journal (err %d)", err);
280 goto stop_handle;
281 }
282 }
283
284 inode->i_size = 0; 261 inode->i_size = 0;
285 err = ext4_mark_inode_dirty(handle, inode); 262 err = ext4_mark_inode_dirty(handle, inode);
286 if (err) { 263 if (err) {
@@ -298,25 +275,17 @@ void ext4_evict_inode(struct inode *inode)
298 } 275 }
299 } 276 }
300 277
301 /* 278 /* Remove xattr references. */
302 * ext4_ext_truncate() doesn't reserve any slop when it 279 err = ext4_xattr_delete_inode(handle, inode, &ea_inode_array,
303 * restarts journal transactions; therefore there may not be 280 extra_credits);
304 * enough credits left in the handle to remove the inode from 281 if (err) {
305 * the orphan list and set the dtime field. 282 ext4_warning(inode->i_sb, "xattr delete (err %d)", err);
306 */ 283stop_handle:
307 if (!ext4_handle_has_enough_credits(handle, extra_credits)) { 284 ext4_journal_stop(handle);
308 err = ext4_journal_extend(handle, extra_credits); 285 ext4_orphan_del(NULL, inode);
309 if (err > 0) 286 sb_end_intwrite(inode->i_sb);
310 err = ext4_journal_restart(handle, extra_credits); 287 ext4_xattr_inode_array_free(ea_inode_array);
311 if (err != 0) { 288 goto no_delete;
312 ext4_warning(inode->i_sb,
313 "couldn't extend journal (err %d)", err);
314 stop_handle:
315 ext4_journal_stop(handle);
316 ext4_orphan_del(NULL, inode);
317 sb_end_intwrite(inode->i_sb);
318 goto no_delete;
319 }
320 } 289 }
321 290
322 /* 291 /*
@@ -342,7 +311,6 @@ void ext4_evict_inode(struct inode *inode)
342 ext4_clear_inode(inode); 311 ext4_clear_inode(inode);
343 else 312 else
344 ext4_free_inode(handle, inode); 313 ext4_free_inode(handle, inode);
345
346 ext4_journal_stop(handle); 314 ext4_journal_stop(handle);
347 sb_end_intwrite(inode->i_sb); 315 sb_end_intwrite(inode->i_sb);
348 ext4_xattr_inode_array_free(ea_inode_array); 316 ext4_xattr_inode_array_free(ea_inode_array);