xfs: improve lock annotations in the log code

Improve the __acquires and __releases annotations so that the new
clang code that is a bit more picky than sparse is happy.  This involves
passing an explicit struct xlog argument in a few places because
alias analysis can't figure out it is the same lock when dereferencing
changing iclogs.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
This commit is contained in:
Christoph Hellwig 2026-07-20 11:45:41 +02:00 committed by Carlos Maiolino
parent b2ae7f2435
commit 64e1f211d9
3 changed files with 22 additions and 15 deletions

View File

@ -470,6 +470,8 @@ xlog_state_release_iclog(
struct xlog *log,
struct xlog_in_core *iclog,
struct xlog_ticket *ticket)
__releases(&log->l_icloglock)
__acquires(&log->l_icloglock)
{
bool last_ref;
@ -744,13 +746,16 @@ xfs_log_mount_cancel(
*/
static inline int
xlog_force_iclog(
struct xlog *log,
struct xlog_in_core *iclog)
__releases(&log->l_icloglock)
__acquires(&log->l_icloglock)
{
atomic_inc(&iclog->ic_refcnt);
iclog->ic_flags |= XLOG_ICL_NEED_FLUSH | XLOG_ICL_NEED_FUA;
if (iclog->ic_state == XLOG_STATE_ACTIVE)
xlog_state_switch_iclogs(iclog->ic_log, iclog, 0);
return xlog_state_release_iclog(iclog->ic_log, iclog, NULL);
xlog_state_switch_iclogs(log, iclog, 0);
return xlog_state_release_iclog(log, iclog, NULL);
}
/*
@ -778,11 +783,10 @@ xlog_wait_iclog_completion(struct xlog *log)
*/
int
xlog_wait_on_iclog(
struct xlog *log,
struct xlog_in_core *iclog)
__releases(iclog->ic_log->l_icloglock)
__releases(log->l_icloglock)
{
struct xlog *log = iclog->ic_log;
trace_xlog_iclog_wait_on(iclog, _RET_IP_);
if (!xlog_is_shutdown(log) &&
iclog->ic_state != XLOG_STATE_ACTIVE &&
@ -879,8 +883,8 @@ xlog_unmount_write(
spin_lock(&log->l_icloglock);
iclog = log->l_iclog;
error = xlog_force_iclog(iclog);
xlog_wait_on_iclog(iclog);
error = xlog_force_iclog(log, iclog);
xlog_wait_on_iclog(log, iclog);
if (tic) {
trace_xfs_log_umount_write(log, tic);
@ -2741,14 +2745,17 @@ xlog_state_switch_iclogs(
*/
static int
xlog_force_and_check_iclog(
struct xlog *log,
struct xlog_in_core *iclog,
bool *completed)
__releases(&log->l_icloglock)
__acquires(&log->l_icloglock)
{
xfs_lsn_t lsn = be64_to_cpu(iclog->ic_header->h_lsn);
int error;
*completed = false;
error = xlog_force_iclog(iclog);
error = xlog_force_iclog(log, iclog);
if (error)
return error;
@ -2825,7 +2832,7 @@ xfs_log_force(
/* We have exclusive access to this iclog. */
bool completed;
if (xlog_force_and_check_iclog(iclog, &completed))
if (xlog_force_and_check_iclog(log, iclog, &completed))
goto out_error;
if (completed)
@ -2850,7 +2857,7 @@ xfs_log_force(
iclog->ic_flags |= XLOG_ICL_NEED_FLUSH | XLOG_ICL_NEED_FUA;
if (flags & XFS_LOG_SYNC)
return xlog_wait_on_iclog(iclog);
return xlog_wait_on_iclog(log, iclog);
out_unlock:
spin_unlock(&log->l_icloglock);
return 0;
@ -2920,7 +2927,7 @@ xlog_force_lsn(
&log->l_icloglock);
return -EAGAIN;
}
if (xlog_force_and_check_iclog(iclog, &completed))
if (xlog_force_and_check_iclog(log, iclog, &completed))
goto out_error;
if (log_flushed)
*log_flushed = 1;
@ -2948,7 +2955,7 @@ xlog_force_lsn(
}
if (flags & XFS_LOG_SYNC)
return xlog_wait_on_iclog(iclog);
return xlog_wait_on_iclog(log, iclog);
out_unlock:
spin_unlock(&log->l_icloglock);
return 0;

View File

@ -1556,7 +1556,7 @@ xlog_cil_push_work(
* iclogs older than ic_prev. Hence we only need to wait
* on the most recent older iclog here.
*/
xlog_wait_on_iclog(ctx->commit_iclog->ic_prev);
xlog_wait_on_iclog(log, ctx->commit_iclog->ic_prev);
spin_lock(&log->l_icloglock);
}

View File

@ -605,8 +605,8 @@ xlog_wait(
remove_wait_queue(wq, &wait);
}
int xlog_wait_on_iclog(struct xlog_in_core *iclog)
__releases(iclog->ic_log->l_icloglock);
int xlog_wait_on_iclog(struct xlog *log, struct xlog_in_core *iclog)
__releases(log->l_icloglock);
/* Calculate the distance between two LSNs in bytes */
static inline uint64_t