On 20.12.24 14:51, Andrey Zhadchenko wrote:


On 12/13/24 15:15, Alexander Atanasov wrote:
On 13.12.24 15:22, Andrey Zhadchenko wrote:


On 12/13/24 14:12, Alexander Atanasov wrote:
On 13.12.24 14:58, Andrey Zhadchenko wrote:
No, REQ_FUA does not oblige us to make sync. REQ_FUA is translated into IOCB_DSYNC. It is IOCB layer job to datasync this exact request. Also REQ_FUA usually is coupled with REQ_PREFLUSH and we already handle that.


We do this only for metadata in previous patches - pure data pios do not handle it. And you are right about REQ_PREFLUSH but i think the vfs layer will handle it along the sync - which is translated to PREFLUSH+FUA


I think in "[RFC PATCH vz9 v6 17/62] dm-ploop: set IOCB_DSYNC on all FUA requests" we just save rq->cmd_flags and set IOCB_DSYNC if initial request contained REQ_FUA. Does this not cover pure data pios?

I suppose you are talking about an extra code to mark piwb if one of data pios with REQ_FUA triggered metadata change.

I checked now and i think that patch would stay but i need to fix the
patch that copies to cmd_flags to bi_op.
I see REQ_FUA is not cleared anywhere but it should be. why?
split_and_chain_pio will clone it to all resulting split pios,
in turn ploop_call_rw_iter will set IOCB_DSYNC on all pios from that split, which results in a vfs_fsync (in an aio worker, so one by one). But we want to do only one vfs_sync for the whole split, right before we call endio_cb.

Are you sure that aio worker does the sync on every FUA request? I think it is up to the driver in the end.


iirc I tracked it down to which was called on every iocb that was sync, which was set via DSYNC.

static void aio_fsync_work(struct work_struct *work)

        iocb->ki_res.res = vfs_fsync(iocb->fsync.file, iocb->fsync.datasync);



However this is more important :


fs/iomap/direct-io.c:


                /* for data sync or sync, we need sync completion processing */
                if (iocb->ki_flags & IOCB_DSYNC)
                        dio->flags |= IOMAP_DIO_NEED_SYNC;



ssize_t iomap_dio_complete(struct iomap_dio *dio)

{

       ....

        if (ret > 0) {
                iocb->ki_pos += ret;

                /*
                 * If this is a DSYNC write, make sure we push it to stable
                 * storage now that we've written data.
                 */
                if (dio->flags & IOMAP_DIO_NEED_SYNC)
                        ret = generic_write_sync(iocb, ret);
                if (ret > 0)
                        ret += dio->done_before;
        }

}


Which is resorting to sync_write and we want to do only dio all the way to avoid having dirty pages from buffered io. (we get ENOTBLKDEV due to dirty page we get otherwise)


But if if does, we probably need to add sync() for split requests and do not add anything for single-pio (just leave REQ_FUA).


What i did is to maskout REQ_FUA on the bi_op that is used to init a split pio.

We need to sync before we call endio on the initial PIO which is done after the whole split is ready, i.e. the original pio is first.


--
Regards,
Alexander Atanasov

_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to