Skip to content

Commit 30a7eb9

Browse files
Tahsin Erdogantytso
authored andcommitted
ext4: cleanup transaction restarts during inode deletion
During inode deletion, the number of journal credits that will be needed is hard to determine. For that reason we have journal extend/restart calls in several places. Whenever a transaction is restarted, filesystem must be in a consistent state because there is no atomicity guarantee beyond a restart call. Add ext4_xattr_ensure_credits() helper function which takes care of journal extend/restart logic. It also handles getting jbd2 write access and dirty metadata calls. This function is called at every iteration of handling an ea_inode reference. Signed-off-by: Tahsin Erdogan <[email protected]> Signed-off-by: Theodore Ts'o <[email protected]>
1 parent 02749a4 commit 30a7eb9

File tree

3 files changed

+184
-143
lines changed

3 files changed

+184
-143
lines changed

fs/ext4/inode.c

Lines changed: 17 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,11 @@ void ext4_evict_inode(struct inode *inode)
239239
*/
240240
sb_start_intwrite(inode->i_sb);
241241

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);
243247
if (IS_ERR(handle)) {
244248
ext4_std_error(inode->i_sb, PTR_ERR(handle));
245249
/*
@@ -251,36 +255,9 @@ void ext4_evict_inode(struct inode *inode)
251255
sb_end_intwrite(inode->i_sb);
252256
goto no_delete;
253257
}
258+
254259
if (IS_SYNC(inode))
255260
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-
284261
inode->i_size = 0;
285262
err = ext4_mark_inode_dirty(handle, inode);
286263
if (err) {
@@ -298,25 +275,17 @@ void ext4_evict_inode(struct inode *inode)
298275
}
299276
}
300277

301-
/*
302-
* ext4_ext_truncate() doesn't reserve any slop when it
303-
* restarts journal transactions; therefore there may not be
304-
* enough credits left in the handle to remove the inode from
305-
* the orphan list and set the dtime field.
306-
*/
307-
if (!ext4_handle_has_enough_credits(handle, extra_credits)) {
308-
err = ext4_journal_extend(handle, extra_credits);
309-
if (err > 0)
310-
err = ext4_journal_restart(handle, extra_credits);
311-
if (err != 0) {
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-
}
278+
/* Remove xattr references. */
279+
err = ext4_xattr_delete_inode(handle, inode, &ea_inode_array,
280+
extra_credits);
281+
if (err) {
282+
ext4_warning(inode->i_sb, "xattr delete (err %d)", err);
283+
stop_handle:
284+
ext4_journal_stop(handle);
285+
ext4_orphan_del(NULL, inode);
286+
sb_end_intwrite(inode->i_sb);
287+
ext4_xattr_inode_array_free(ea_inode_array);
288+
goto no_delete;
320289
}
321290

322291
/*
@@ -342,7 +311,6 @@ void ext4_evict_inode(struct inode *inode)
342311
ext4_clear_inode(inode);
343312
else
344313
ext4_free_inode(handle, inode);
345-
346314
ext4_journal_stop(handle);
347315
sb_end_intwrite(inode->i_sb);
348316
ext4_xattr_inode_array_free(ea_inode_array);

0 commit comments

Comments
 (0)