xemu/block
Nir Soffer a6b257a08e file-posix: Handle undetectable alignment
In some cases buf_align or request_alignment cannot be detected:

1. With Gluster, buf_align cannot be detected since the actual I/O is
   done on Gluster server, and qemu buffer alignment does not matter.
   Since we don't have alignment requirement, buf_align=1 is the best
   value.

2. With local XFS filesystem, buf_align cannot be detected if reading
   from unallocated area. In this we must align the buffer, but we don't
   know what is the correct size. Using the wrong alignment results in
   I/O error.

3. With Gluster backed by XFS, request_alignment cannot be detected if
   reading from unallocated area. In this case we need to use the
   correct alignment, and failing to do so results in I/O errors.

4. With NFS, the server does not use direct I/O, so both buf_align cannot
   be detected. In this case we don't need any alignment so we can use
   buf_align=1 and request_alignment=1.

These cases seems to work when storage sector size is 512 bytes, because
the current code starts checking align=512. If the check succeeds
because alignment cannot be detected we use 512. But this does not work
for storage with 4k sector size.

To determine if we can detect the alignment, we probe first with
align=1. If probing succeeds, maybe there are no alignment requirement
(cases 1, 4) or we are probing unallocated area (cases 2, 3). Since we
don't have any way to tell, we treat this as undetectable alignment. If
probing with align=1 fails with EINVAL, but probing with one of the
expected alignments succeeds, we know that we found a working alignment.

Practically the alignment requirements are the same for buffer
alignment, buffer length, and offset in file. So in case we cannot
detect buf_align, we can use request alignment. If we cannot detect
request alignment, we can fallback to a safe value. To use this logic,
we probe first request alignment instead of buf_align.

Here is a table showing the behaviour with current code (the value in
parenthesis is the optimal value).

Case    Sector    buf_align (opt)   request_alignment (opt)     result
======================================================================
1       512       512   (1)          512   (512)                 OK
1       4096      512   (1)          4096  (4096)                FAIL
----------------------------------------------------------------------
2       512       512   (512)        512   (512)                 OK
2       4096      512   (4096)       4096  (4096)                FAIL
----------------------------------------------------------------------
3       512       512   (1)          512   (512)                 OK
3       4096      512   (1)          512   (4096)                FAIL
----------------------------------------------------------------------
4       512       512   (1)          512   (1)                   OK
4       4096      512   (1)          512   (1)                   OK

Same cases with this change:

Case    Sector    buf_align (opt)   request_alignment (opt)     result
======================================================================
1       512       512   (1)          512   (512)                 OK
1       4096      4096  (1)          4096  (4096)                OK
----------------------------------------------------------------------
2       512       512   (512)        512   (512)                 OK
2       4096      4096  (4096)       4096  (4096)                OK
----------------------------------------------------------------------
3       512       4096  (1)          4096  (512)                 OK
3       4096      4096  (1)          4096  (4096)                OK
----------------------------------------------------------------------
4       512       4096  (1)          4096  (1)                   OK
4       4096      4096  (1)          4096  (1)                   OK

I tested that provisioning VMs and copying disks on local XFS and
Gluster with 4k bytes sector size work now, resolving bugs [1],[2].
I tested also on XFS, NFS, Gluster with 512 bytes sector size.

[1] https://bugzilla.redhat.com/1737256
[2] https://bugzilla.redhat.com/1738657

Signed-off-by: Nir Soffer <nsoffer@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2019-08-16 11:29:11 +02:00
..
Makefile.objs ssh: switch from libssh2 to libssh 2019-06-24 16:01:04 +02:00
accounting.c block/accounting: introduce latency histogram 2018-03-19 14:58:37 -05:00
backup.c block-backend: Queue requests while drained 2019-08-16 10:25:16 +02:00
blkdebug.c blkdebug: Inject errors on .bdrv_co_block_status() 2019-06-14 14:16:57 +02:00
blklogwrites.c Include qemu/module.h where needed, drop it from qemu-common.h 2019-06-12 13:18:33 +02:00
blkreplay.c Include qemu/module.h where needed, drop it from qemu-common.h 2019-06-12 13:18:33 +02:00
blkverify.c Include qemu/module.h where needed, drop it from qemu-common.h 2019-06-12 13:18:33 +02:00
block-backend.c block-backend: Queue requests while drained 2019-08-16 10:25:16 +02:00
bochs.c Include qemu-common.h exactly where needed 2019-06-12 13:20:20 +02:00
cloop.c Include qemu-common.h exactly where needed 2019-06-12 13:20:20 +02:00
commit.c block-backend: Queue requests while drained 2019-08-16 10:25:16 +02:00
copy-on-read.c block/copy-on-read: Fix permissions for inactive node 2019-07-30 12:25:43 +02:00
create.c jobs: utilize job_exit shim 2018-08-31 16:28:33 +02:00
crypto.c Include qemu/module.h where needed, drop it from qemu-common.h 2019-06-12 13:18:33 +02:00
crypto.h Clean up ill-advised or unusual header guards 2019-05-13 08:58:55 +02:00
curl.c Include qemu/module.h where needed, drop it from qemu-common.h 2019-06-12 13:18:33 +02:00
dirty-bitmap.c Include qemu-common.h exactly where needed 2019-06-12 13:20:20 +02:00
dmg-bz2.c Include qemu-common.h exactly where needed 2019-06-12 13:20:20 +02:00
dmg-lzfse.c block: adding lzfse decompressing support as a module. 2018-12-14 11:52:40 +01:00
dmg.c Include qemu-common.h exactly where needed 2019-06-12 13:20:20 +02:00
dmg.h Include qemu-common.h exactly where needed 2019-06-12 13:20:20 +02:00
file-posix.c file-posix: Handle undetectable alignment 2019-08-16 11:29:11 +02:00
file-win32.c avoid TABs in files that only contain a few 2019-01-11 15:46:56 +01:00
gluster.c gluster: fix .bdrv_reopen_prepare when backing file is a JSON object 2019-07-15 15:48:41 +02:00
io.c block: Dec. drained_end_counter before bdrv_wakeup 2019-07-22 18:41:35 +02:00
iscsi-opts.c Include qemu/module.h where needed, drop it from qemu-common.h 2019-06-12 13:18:33 +02:00
iscsi.c iscsi: base all handling of check condition on scsi_sense_to_errno 2019-07-15 11:20:42 +02:00
linux-aio.c Include qemu-common.h exactly where needed 2019-06-12 13:20:20 +02:00
mirror.c block-backend: Queue requests while drained 2019-08-16 10:25:16 +02:00
nbd.c nbd: Initialize reply on failure 2019-07-19 13:19:18 -05:00
nfs.c Include qemu/module.h where needed, drop it from qemu-common.h 2019-06-12 13:18:33 +02:00
null.c Include qemu/module.h where needed, drop it from qemu-common.h 2019-06-12 13:18:33 +02:00
nvme.c nvme: Limit blkshift to 12 (for 4 kB blocks) 2019-07-30 14:49:24 +02:00
parallels.c block: Add BlockBackend.ctx 2019-06-04 15:22:22 +02:00
parallels.h Clean up includes 2018-02-09 05:05:11 +01:00
qapi.c Include qemu-common.h exactly where needed 2019-06-12 13:20:20 +02:00
qcow.c block/qcow: Improve error when opening qcow2 files as qcow 2019-07-08 16:00:26 +02:00
qcow2-bitmap.c qcow2-bitmap: initialize bitmap directory alignment 2019-05-28 20:30:55 +02:00
qcow2-cache.c Include qemu-common.h exactly where needed 2019-06-12 13:20:20 +02:00
qcow2-cluster.c Include qemu-common.h exactly where needed 2019-06-12 13:20:20 +02:00
qcow2-refcount.c Include qemu-common.h exactly where needed 2019-06-12 13:20:20 +02:00
qcow2-snapshot.c qcow2.h: add missing include 2019-05-28 20:30:55 +02:00
qcow2-threads.c qcow2: do encryption in threads 2019-05-28 20:30:55 +02:00
qcow2.c qcow2: Allow -o compat=v3 during qemu-img amend 2019-07-08 16:00:31 +02:00
qcow2.h block: avoid recursive block_status call if possible 2019-06-04 15:20:41 +02:00
qed-check.c block/qed: add missed coroutine_fn markers 2019-04-30 15:29:00 +02:00
qed-cluster.c qed: protect table cache with CoMutex 2017-07-17 11:34:11 +08:00
qed-l2-cache.c qed: protect table cache with CoMutex 2017-07-17 11:34:11 +08:00
qed-table.c block/qed: add missed coroutine_fn markers 2019-04-30 15:29:00 +02:00
qed.c Include qemu/module.h where needed, drop it from qemu-common.h 2019-06-12 13:18:33 +02:00
qed.h block/qed: add missed coroutine_fn markers 2019-04-30 15:29:00 +02:00
quorum.c Include qemu/module.h where needed, drop it from qemu-common.h 2019-06-12 13:18:33 +02:00
raw-format.c Include qemu/module.h where needed, drop it from qemu-common.h 2019-06-12 13:18:33 +02:00
rbd.c block/rbd: increase dynamically the image size 2019-07-02 03:53:04 +02:00
replication.c block: include base when checking image chain for block allocation 2019-07-02 03:53:04 +02:00
sheepdog.c Include qemu-common.h exactly where needed 2019-06-12 13:20:20 +02:00
snapshot.c block/snapshot: remove bdrv_snapshot_delete_by_id_or_name 2019-02-25 15:03:18 +01:00
ssh.c ssh: switch from libssh2 to libssh 2019-06-24 16:01:04 +02:00
stream.c block/stream: Swap backing file change order 2019-07-15 15:48:40 +02:00
throttle-groups.c throttle-groups: fix restart coroutine iothread race 2019-01-24 10:02:28 +00:00
throttle.c Include qemu/module.h where needed, drop it from qemu-common.h 2019-06-12 13:18:33 +02:00
trace-events ssh: switch from libssh2 to libssh 2019-06-24 16:01:04 +02:00
vdi.c block: Add BlockBackend.ctx 2019-06-04 15:22:22 +02:00
vhdx-endian.c Include qemu-common.h exactly where needed 2019-06-12 13:20:20 +02:00
vhdx-log.c Include qemu/module.h where needed, drop it from qemu-common.h 2019-06-12 13:18:33 +02:00
vhdx.c block: Add BlockBackend.ctx 2019-06-04 15:22:22 +02:00
vhdx.h block/vhdx: Use IEC binary prefixes for size constants 2019-04-30 15:29:00 +02:00
vmdk.c vmdk: Add read-only support for seSparse snapshots 2019-06-24 15:53:02 +02:00
vpc.c block: Add BlockBackend.ctx 2019-06-04 15:22:22 +02:00
vvfat.c qemu-common: Move qemu_isalnum() etc. to qemu/ctype.h 2019-06-11 20:22:09 +02:00
vxhs.c Include qemu/module.h where needed, drop it from qemu-common.h 2019-06-12 13:18:33 +02:00
win32-aio.c Include qemu/module.h where needed, drop it from qemu-common.h 2019-06-12 13:18:33 +02:00
write-threshold.c qapi: Drop qapi_event_send_FOO()'s Error ** argument 2018-08-28 18:21:38 +02:00