diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-07-13 08:50:13 +0200 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-07-13 08:50:13 +0200 |
commit | 54ef76f37bcccf8c16fbaaed13c3c40825195958 (patch) | |
tree | 59afdb95e68f2fbac2550aa42135921086649c38 /fs/xfs/xfs_log.c | |
parent | 032f82786f9be4635acaa5f77feca175a4ac5fe1 (diff) | |
parent | 9df2fe986770bc4c76e8fe72c20b71268eec39a7 (diff) | |
download | linux-54ef76f37bcccf8c16fbaaed13c3c40825195958.tar.bz2 |
Merge branch 'linus' into sched/devel
Diffstat (limited to 'fs/xfs/xfs_log.c')
-rw-r--r-- | fs/xfs/xfs_log.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index afaee301b0ee..ad3d26ddfe31 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -2427,13 +2427,20 @@ restart: if (iclog->ic_size - iclog->ic_offset < 2*sizeof(xlog_op_header_t)) { xlog_state_switch_iclogs(log, iclog, iclog->ic_size); - /* If I'm the only one writing to this iclog, sync it to disk */ - if (atomic_read(&iclog->ic_refcnt) == 1) { + /* + * If I'm the only one writing to this iclog, sync it to disk. + * We need to do an atomic compare and decrement here to avoid + * racing with concurrent atomic_dec_and_lock() calls in + * xlog_state_release_iclog() when there is more than one + * reference to the iclog. + */ + if (!atomic_add_unless(&iclog->ic_refcnt, -1, 1)) { + /* we are the only one */ spin_unlock(&log->l_icloglock); - if ((error = xlog_state_release_iclog(log, iclog))) + error = xlog_state_release_iclog(log, iclog); + if (error) return error; } else { - atomic_dec(&iclog->ic_refcnt); spin_unlock(&log->l_icloglock); } goto restart; |