From bc256c25631960e1386f3359bb6c85cfe6481fb7 Mon Sep 17 00:00:00 2001 From: Li Dongyang Date: Mon, 19 Feb 2024 13:27:22 +1100 Subject: [PATCH] LU-16692 osp: osp_fid_diff vs rollover_new_seq race osp_fid_diff/osp_objs_precreated is accessing the last_created_fid and pre_used_fid without opd_pre_lock, and this could race with osp_precreate_rollover_new_seq() when updating them to new fids. Change-Id: I3a61c99570b5532776ddc43247c1513b8c89fb32 Signed-off-by: Li Dongyang Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/54087 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Alexander Boyko Reviewed-by: Oleg Drokin --- lustre/osp/osp_internal.h | 12 +++++++++++- lustre/osp/osp_precreate.c | 13 ++++++------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/lustre/osp/osp_internal.h b/lustre/osp/osp_internal.h index f98a7a4..1ba8c54 100644 --- a/lustre/osp/osp_internal.h +++ b/lustre/osp/osp_internal.h @@ -613,12 +613,22 @@ static inline bool osp_precreate_end_seq(struct osp_device *osp) return rc; } -static inline int osp_objs_precreated(struct osp_device *osp) +static inline int osp_objs_precreated_nolock(struct osp_device *osp) { return osp_fid_diff(&osp->opd_pre_last_created_fid, &osp->opd_pre_used_fid); } +static inline int osp_objs_precreated(struct osp_device *osp) +{ + int diff; + + spin_lock(&osp->opd_pre_lock); + diff = osp_objs_precreated_nolock(osp); + spin_unlock(&osp->opd_pre_lock); + return diff; +} + static inline int osp_is_fid_client(struct osp_device *osp) { struct obd_import *imp = osp->opd_obd->u.cli.cl_import; diff --git a/lustre/osp/osp_precreate.c b/lustre/osp/osp_precreate.c index c5e2ca9..64d5a80 100644 --- a/lustre/osp/osp_precreate.c +++ b/lustre/osp/osp_precreate.c @@ -317,7 +317,7 @@ void osp_statfs_need_now(struct osp_device *d) */ static inline int osp_precreate_is_low_nolock(struct osp_device *d) { - int available = osp_objs_precreated(d) - d->opd_pre_reserved; + int available = osp_objs_precreated_nolock(d) - d->opd_pre_reserved; int precreate_needed = d->opd_pre_create_count > 1024 ? d->opd_pre_create_count / 4 : d->opd_pre_create_count / 2; @@ -681,16 +681,18 @@ static int osp_precreate_send(const struct lu_env *env, struct osp_device *d) ostid_to_fid(fid, &body->oa.o_oi, d->opd_index); ready: + spin_lock(&d->opd_pre_lock); + if (osp_fid_diff(fid, &d->opd_pre_used_fid) <= 0) { CERROR("%s: precreate fid "DFID" <= local used fid "DFID ": rc = %d\n", d->opd_obd->obd_name, PFID(fid), PFID(&d->opd_pre_used_fid), -ESTALE); + spin_unlock(&d->opd_pre_lock); GOTO(out_req, rc = -ESTALE); } diff = osp_fid_diff(fid, &d->opd_pre_last_created_fid); - spin_lock(&d->opd_pre_lock); if (diff < grow) { /* the OST has not managed to create all the * objects we asked for */ @@ -1477,21 +1479,18 @@ int osp_precreate_reserve(const struct lu_env *env, struct osp_device *d, while ((rc = d->opd_pre_status) == 0 || rc == -ENOSPC || rc == -ENODEV || rc == -EAGAIN || rc == -ENOTCONN) { + spin_lock(&d->opd_pre_lock); + precreated = osp_objs_precreated_nolock(d); /* * increase number of precreations */ - precreated = osp_objs_precreated(d); if (d->opd_pre_create_count < d->opd_pre_max_create_count && d->opd_pre_create_slow == 0 && precreated <= (d->opd_pre_create_count / 4 + 1)) { - spin_lock(&d->opd_pre_lock); d->opd_pre_create_slow = 1; d->opd_pre_create_count *= 2; - spin_unlock(&d->opd_pre_lock); } - spin_lock(&d->opd_pre_lock); - precreated = osp_objs_precreated(d); if (!d->opd_pre_recovering && !d->opd_force_creation) { if (precreated > d->opd_pre_reserved) { d->opd_pre_reserved++; -- 1.8.3.1