Skip to content

Commit 2b0ad00

Browse files
biger410torvalds
authored andcommitted
ocfs2: fix trans extend while flush truncate log
Every time, ocfs2_extend_trans() included a credit for truncate log inode, but as that inode had been managed by jbd2 running transaction first time, it will not consume that credit until jbd2_journal_restart(). Since total credits to extend always included the un-consumed ones, there will be more and more un-consumed credit, at last jbd2_journal_restart() will fail due to credit number over the half of max transction credit. The following error was caught when unlinking a large file with many extents: ------------[ cut here ]------------ WARNING: CPU: 0 PID: 13626 at fs/jbd2/transaction.c:269 start_this_handle+0x4c3/0x510 [jbd2]() Modules linked in: ocfs2 nfsd lockd grace nfs_acl auth_rpcgss sunrpc autofs4 ocfs2_dlmfs ocfs2_stack_o2cb ocfs2_dlm ocfs2_nodemanager ocfs2_stackglue configfs sd_mod sg ip6t_REJECT nf_reject_ipv6 nf_conntrack_ipv6 nf_defrag_ipv6 xt_state nf_conntrack ip6table_filter ip6_tables be2iscsi iscsi_boot_sysfs bnx2i cnic uio cxgb4i cxgb4 cxgb3i libcxgbi cxgb3 mdio ib_iser rdma_cm ib_cm iw_cm ib_sa ib_mad ib_core ib_addr ipv6 iscsi_tcp libiscsi_tcp libiscsi scsi_transport_iscsi ppdev xen_kbdfront xen_netfront fb_sys_fops sysimgblt sysfillrect syscopyarea parport_pc parport pcspkr i2c_piix4 i2c_core acpi_cpufreq ext4 jbd2 mbcache xen_blkfront floppy pata_acpi ata_generic ata_piix dm_mirror dm_region_hash dm_log dm_mod CPU: 0 PID: 13626 Comm: unlink Tainted: G W 4.1.12-37.6.3.el6uek.x86_64 #2 Hardware name: Xen HVM domU, BIOS 4.4.4OVM 02/11/2016 Call Trace: dump_stack+0x48/0x5c warn_slowpath_common+0x95/0xe0 warn_slowpath_null+0x1a/0x20 start_this_handle+0x4c3/0x510 [jbd2] jbd2__journal_restart+0x161/0x1b0 [jbd2] jbd2_journal_restart+0x13/0x20 [jbd2] ocfs2_extend_trans+0x74/0x220 [ocfs2] ocfs2_replay_truncate_records+0x93/0x360 [ocfs2] __ocfs2_flush_truncate_log+0x13e/0x3a0 [ocfs2] ocfs2_remove_btree_range+0x458/0x7f0 [ocfs2] ocfs2_commit_truncate+0x1b3/0x6f0 [ocfs2] ocfs2_truncate_for_delete+0xbd/0x380 [ocfs2] ocfs2_wipe_inode+0x136/0x6a0 [ocfs2] ocfs2_delete_inode+0x2a2/0x3e0 [ocfs2] ocfs2_evict_inode+0x28/0x60 [ocfs2] evict+0xab/0x1a0 iput_final+0xf6/0x190 iput+0xc8/0xe0 do_unlinkat+0x1b7/0x310 SyS_unlink+0x16/0x20 system_call_fastpath+0x12/0x71 ---[ end trace 28aa7410e69369cf ]--- JBD2: unlink wants too many credits (251 > 128) Link: http://lkml.kernel.org/r/1473674623-11810-1-git-send-email-junxiao.bi@oracle.com Signed-off-by: Junxiao Bi <junxiao.bi@oracle.com> Reviewed-by: Joseph Qi <joseph.qi@huawei.com> Cc: Mark Fasheh <mfasheh@suse.de> Cc: Joel Becker <jlbec@evilplan.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent 31b4beb commit 2b0ad00

1 file changed

Lines changed: 10 additions & 19 deletions

File tree

fs/ocfs2/alloc.c

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5922,7 +5922,6 @@ int ocfs2_truncate_log_append(struct ocfs2_super *osb,
59225922
}
59235923

59245924
static int ocfs2_replay_truncate_records(struct ocfs2_super *osb,
5925-
handle_t *handle,
59265925
struct inode *data_alloc_inode,
59275926
struct buffer_head *data_alloc_bh)
59285927
{
@@ -5935,11 +5934,19 @@ static int ocfs2_replay_truncate_records(struct ocfs2_super *osb,
59355934
struct ocfs2_truncate_log *tl;
59365935
struct inode *tl_inode = osb->osb_tl_inode;
59375936
struct buffer_head *tl_bh = osb->osb_tl_bh;
5937+
handle_t *handle;
59385938

59395939
di = (struct ocfs2_dinode *) tl_bh->b_data;
59405940
tl = &di->id2.i_dealloc;
59415941
i = le16_to_cpu(tl->tl_used) - 1;
59425942
while (i >= 0) {
5943+
handle = ocfs2_start_trans(osb, OCFS2_TRUNCATE_LOG_FLUSH_ONE_REC);
5944+
if (IS_ERR(handle)) {
5945+
status = PTR_ERR(handle);
5946+
mlog_errno(status);
5947+
goto bail;
5948+
}
5949+
59435950
/* Caller has given us at least enough credits to
59445951
* update the truncate log dinode */
59455952
status = ocfs2_journal_access_di(handle, INODE_CACHE(tl_inode), tl_bh,
@@ -5974,12 +5981,7 @@ static int ocfs2_replay_truncate_records(struct ocfs2_super *osb,
59745981
}
59755982
}
59765983

5977-
status = ocfs2_extend_trans(handle,
5978-
OCFS2_TRUNCATE_LOG_FLUSH_ONE_REC);
5979-
if (status < 0) {
5980-
mlog_errno(status);
5981-
goto bail;
5982-
}
5984+
ocfs2_commit_trans(osb, handle);
59835985
i--;
59845986
}
59855987

@@ -5994,7 +5996,6 @@ int __ocfs2_flush_truncate_log(struct ocfs2_super *osb)
59945996
{
59955997
int status;
59965998
unsigned int num_to_flush;
5997-
handle_t *handle;
59985999
struct inode *tl_inode = osb->osb_tl_inode;
59996000
struct inode *data_alloc_inode = NULL;
60006001
struct buffer_head *tl_bh = osb->osb_tl_bh;
@@ -6038,21 +6039,11 @@ int __ocfs2_flush_truncate_log(struct ocfs2_super *osb)
60386039
goto out_mutex;
60396040
}
60406041

6041-
handle = ocfs2_start_trans(osb, OCFS2_TRUNCATE_LOG_FLUSH_ONE_REC);
6042-
if (IS_ERR(handle)) {
6043-
status = PTR_ERR(handle);
6044-
mlog_errno(status);
6045-
goto out_unlock;
6046-
}
6047-
6048-
status = ocfs2_replay_truncate_records(osb, handle, data_alloc_inode,
6042+
status = ocfs2_replay_truncate_records(osb, data_alloc_inode,
60496043
data_alloc_bh);
60506044
if (status < 0)
60516045
mlog_errno(status);
60526046

6053-
ocfs2_commit_trans(osb, handle);
6054-
6055-
out_unlock:
60566047
brelse(data_alloc_bh);
60576048
ocfs2_inode_unlock(data_alloc_inode, 1);
60586049

0 commit comments

Comments
 (0)