Acknowledged On Thu, Nov 6, 2025 at 10:26 AM Kui Liu <[email protected]> wrote: > > This is a resend of previous patch however including the removal patch. > Please take this version > ________________________________ > From: Liu Kui <[email protected]> > Sent: 06 November 2025 10:14 > To: [email protected] <[email protected]> > Cc: Alexey Kuznetsov <[email protected]>; Andrey Zaitsev > <[email protected]>; Konstantin Khorenko <[email protected]>; Kui > Liu <[email protected]> > Subject: [PATCH VZ9 v2 1/2] fs/fuse/kio: fix unwarranted warning due to flush > request race > > The warning in pcs_map_queue_resolve() was triggered not by an expected > bug, but due to a race in processing flush requests originating from the > timer. > > Straighten out the map resolve process flow to fix the race by avoiding > repeated lock/unlock of the map lock across several functions. > > Additionally, promote the warning condition in pcs_map_queue_resolve() to > an assertion in map_submit() to trigger a coredump if the condition truly > occurs. > > Related to: #VSTOR-116825 > https://virtuozzo.atlassian.net/browse/VSTOR-116825 > > Signed-off-by: Liu Kui <[email protected]> > --- > fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 11 ---- > fs/fuse/kio/pcs/pcs_map.c | 91 +++++++++++++++--------------- > 2 files changed, 44 insertions(+), 58 deletions(-) > > diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c > b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c > index 5444fb8aeb05..1031c43bbec7 100644 > --- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c > +++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c > @@ -601,22 +601,11 @@ int fuse_map_resolve(struct pcs_map_entry *m, int > direction) > size_t map_sz; > int err; > > - spin_lock(&m->lock); > - > - if (m->state & PCS_MAP_DEAD) { > - spin_unlock(&m->lock); > - pcs_map_put(m); > - return 0; > - } > di = pcs_dentry_from_mapping(m->mapping); > fm = get_fuse_mount(&di->inode->inode); > > DTRACE("enter m: " MAP_FMT ", dir:%d \n", MAP_ARGS(m), direction); > > - BUG_ON(!(m->state & PCS_MAP_RESOLVING)); > - > - spin_unlock(&m->lock); > - > map_sz = sizeof(*map_ioc) + PCS_MAX_CS_CNT * sizeof(struct > pcs_cs_info); > map_ioc = kzalloc(map_sz, GFP_NOIO); > if (!map_ioc) > diff --git a/fs/fuse/kio/pcs/pcs_map.c b/fs/fuse/kio/pcs/pcs_map.c > index 62b083b4947f..8baff296aaa7 100644 > --- a/fs/fuse/kio/pcs/pcs_map.c > +++ b/fs/fuse/kio/pcs/pcs_map.c > @@ -1266,23 +1266,14 @@ void pcs_map_complete(struct pcs_map_entry *m, struct > pcs_ioc_getmap *omap) > > /* Atomically schedule map resolve and push ireq to wait completion */ > static void pcs_map_queue_resolve(struct pcs_map_entry * m, struct > pcs_int_request *ireq, int direction) > +__releases(m->lock) > { > LIST_HEAD(l); > int ret; > > - DTRACE("enter m:%p, state:%x, ireq:%p dir:%d \n", m, m->state, ireq, > direction); > - > - spin_lock(&m->lock); > - /* This should not happen unless aio_dio/fsync vs truncate race */ > - if (m->state & PCS_MAP_DEAD) { > - spin_unlock(&m->lock); > + assert_spin_locked(&m->lock); > > - /* If this happens, it's assumed this is a bug that needs to > be fixed */ > - WARN_ON_ONCE(1); > - list_add(&ireq->list, &l); > - pcs_ireq_queue_fail(&l, PCS_ERR_NET_ABORT); > - return; > - } > + DTRACE("enter m:%p, state:%x, ireq:%p dir:%d \n", m, m->state, ireq, > direction); > DTRACE("dentry: "DENTRY_FMT, DENTRY_ARGS(pcs_dentry_from_map(m))); > DTRACE("%p {%p %p}\n",ireq, ireq->list.next, ireq->list.prev); > BUG_ON(!list_empty(&ireq->list)); > @@ -1293,8 +1284,7 @@ static void pcs_map_queue_resolve(struct pcs_map_entry > * m, struct pcs_int_reque > return; > } > /* If converting a hole, adjust res_offset */ > - if (direction && !m->cs_list && !(m->state & PCS_MAP_RESOLVING) > - && ireq->type == PCS_IREQ_IOCHUNK) > + if (direction && !m->cs_list && (ireq->type == PCS_IREQ_IOCHUNK)) > m->res_offset = ireq->iochunk.chunk + ireq->iochunk.offset; > > m->state |= PCS_MAP_RESOLVING; > @@ -1307,8 +1297,10 @@ static void pcs_map_queue_resolve(struct pcs_map_entry > * m, struct pcs_int_reque > if (ret) { > TRACE("map error: %d for " MAP_FMT "\n", ret, MAP_ARGS(m)); > spin_lock(&m->lock); > - pcs_map_truncate(m, &l); > - map_del_lru(m); > + if (!(m->state & PCS_MAP_DEAD)) { > + pcs_map_truncate(m, &l); > + map_del_lru(m); > + } > spin_unlock(&m->lock); > pcs_ireq_queue_fail(&l, PCS_ERR_NOMEM); > pcs_map_put(m); > @@ -1582,37 +1574,34 @@ static void pcs_cs_wakeup(struct pcs_cs * cs) > > sreq->flags |= IREQ_F_REQUEUED; > > - if (sreq->type != PCS_IREQ_FLUSH) { > - FUSE_KDTRACE(sreq->cc->fc, > - "wakeup {%p} cpu%u %d %u/%u " DENTRY_FMT > " %llu+%llu", > - sreq, smp_processor_id(), > cs->cong_queue_len, > - cs->in_flight, cs->eff_cwnd, > DENTRY_ARGS(sreq->dentry), > - sreq->iochunk.chunk + > sreq->iochunk.offset, > - sreq->iochunk.size); > - map = pcs_find_get_map(sreq->dentry, > sreq->iochunk.chunk + > - ((sreq->flags & > IREQ_F_MAPPED) ? 0 : sreq->iochunk.offset)); > - if (map) { > - if (sreq->iochunk.map) > - pcs_map_put(sreq->iochunk.map); > - sreq->iochunk.map = map; > - if (sreq->iochunk.flow) { > - struct pcs_int_request * preq = > sreq->completion_data.parent; > - > - pcs_flow_confirm(sreq->iochunk.flow, > &map->mapping->ftab, preq->apireq.req->type == PCS_REQ_T_WRITE, > - > preq->apireq.req->pos, preq->apireq.req->size, > - > &sreq->cc->maps.ftab); > - } > - map_submit(map, sreq); > - } else { > - map_queue_on_limit(sreq); > + if (sreq->type == PCS_IREQ_FLUSH) { > + map = sreq->flushreq.map; > + map_submit(map, sreq); > + continue; > + } > + > + FUSE_KDTRACE(sreq->cc->fc, > + "wakeup {%p} cpu%u %d %u/%u " DENTRY_FMT " > %llu+%llu", > + sreq, smp_processor_id(), cs->cong_queue_len, > + cs->in_flight, cs->eff_cwnd, > DENTRY_ARGS(sreq->dentry), > + sreq->iochunk.chunk + sreq->iochunk.offset, > + sreq->iochunk.size); > + map = pcs_find_get_map(sreq->dentry, sreq->iochunk.chunk + > + ((sreq->flags & IREQ_F_MAPPED) ? 0 > : sreq->iochunk.offset)); > + if (map) { > + if (sreq->iochunk.map) > + pcs_map_put(sreq->iochunk.map); > + sreq->iochunk.map = map; > + if (sreq->iochunk.flow) { > + struct pcs_int_request * preq = > sreq->completion_data.parent; > + > + pcs_flow_confirm(sreq->iochunk.flow, > &map->mapping->ftab, preq->apireq.req->type == PCS_REQ_T_WRITE, > + preq->apireq.req->pos, > preq->apireq.req->size, > + &sreq->cc->maps.ftab); > } > + map_submit(map, sreq); > } else { > - map = sreq->flushreq.map; > - if (map->state & PCS_MAP_DEAD) { > - pcs_clear_error(&sreq->error); > - ireq_complete(sreq); > - } else > - map_submit(map, sreq); > + map_queue_on_limit(sreq); > } > } > } > @@ -2474,12 +2463,20 @@ void map_submit(struct pcs_map_entry * m, struct > pcs_int_request *ireq) > if (ireq->type == PCS_IREQ_IOCHUNK && !(ireq->flags & > IREQ_F_MAPPED)) > ireq->iochunk.hbuf.map_version = m->version; > > - if (!(m->state & (1 << direction)) || (m->state & > PCS_MAP_DEAD) || > - map_chk_stale(m)) { > + if (m->state & PCS_MAP_DEAD) { > + /* This should not happen unless aio_dio/fsync vs > truncate race */ > + BUG_ON(ireq->type != PCS_IREQ_FLUSH); > spin_unlock(&m->lock); > + pcs_clear_error(&ireq->error); > + ireq_complete(ireq); > + return; > + } > + > + if (!(m->state & (1 << direction)) || map_chk_stale(m)) { > pcs_map_queue_resolve(m, ireq, direction); > return; > } > + > DTRACE("enter m: " MAP_FMT ", ireq:%p \n", MAP_ARGS(m), > ireq); > > csl = m->cs_list; > -- > 2.39.5 (Apple Git-154) >
_______________________________________________ Devel mailing list [email protected] https://lists.openvz.org/mailman/listinfo/devel
