@@ -4491,7 +4491,8 @@ static void qrq_endio(struct qcow2_target *tgt, struct 
qio *qio,
         * callers receive -ENOSPC synchronous without intermediaries.
         */
        if (unlikely(bi_status == BLK_STS_NOSPC)) {
-               WARN_ON_ONCE(!op_is_write(qio->bi_op));
+               WARN_ON_ONCE(!op_is_write(qio->bi_op) &&
+                            qio->bi_op != REQ_OP_FLUSH);
                if (qcow2_try_delay_enospc(tgt, qrq, qio))
                        return;
        }
[Severity: Medium]
The commit message says "Delaying and resubmitting the flush is already
correct". Is that accurate?

The flush ENOSPC originates in do_qcow2_fsync_work():

     if (fsync_ret == -EAGAIN)
         fsync_ret = vfs_fsync(qcow2->file, 0);

     end_qios(&flush_qios, errno_to_blk_status(fsync_ret));

On -ENOSPC, qrq_endio() calls qcow2_try_delay_enospc(), which requeues the
qio on tgt->enospc_qios. After the timer fires, qcow2_submit_embedded_qio()
sends it back to the fsync worker:

     WARN_ON_ONCE(qio->bi_op != REQ_OP_FLUSH);
     queue_list_id = QLIST_FLUSH;
     worker = &qcow2->fsync_worker;

The worker then calls vfs_fsync() again on the same struct file.

Writeback errors are reported through errseq. As documented in
file_check_and_advance_wb_err(), fsync reports errors that occurred since
the last fsync, and the call advances file->f_wb_err:

     err = errseq_check_and_advance(&mapping->wb_err,
                                    &file->f_wb_err);

Can the retried vfs_fsync() on the same qcow2->file therefore return 0 on
ext4 or xfs, which the commit message names for "a failed delayed write"?

If so, the flush that originally failed with -ENOSPC would complete with
BLK_STS_OK. The upper layer could then treat earlier writes as durable
when they were not.

A retried write resends its data, but a retried flush resends nothing. Is
there something in dm-qcow2 that retains the earlier failure, or that
otherwise makes the retry safe?

Could the commit message explain why resubmitting the flush is correct,
given the errseq behaviour?
dm-qcow2 refuses an image file without O_DIRECT (qcow2_attach_file()),
so it leaves no dirty page cache. Allocation failures of direct writes are
returned to the write itself, not through errseq, so there is no one-shot
error for the retried fsync to miss. An fsync ENOSPC can only come from
the backing fs's own fsync handler (e.g. a FUSE daemon), which reports
it again on the next call. Besides, this patch only silences the WARN: the
flush was delayed and resubmitted before it too.
_______________________________________________
Devel mailing list
[email protected]
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to