Skip to content

Commit 920d213

Browse files
committed
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
Block layer patches: - file-posix: Fix read-only Linux block devices with auto-read-only - Require aligned image size with O_DIRECT to avoid assertion failure - Allow byte-aligned direct I/O on NFS instead of guessing 4k alignment - Fix nbd_export_close_all() crash - Fix race in iotests case 030 - qemu-img resize: Require --shrink for shrinking all image formats - crypto: use a stronger private key for tests - Remove VXHS block device - MAINTAINERS: vvfat: set status to odd fixes # gpg: Signature made Fri 17 Jul 2020 13:31:18 BST # gpg: using RSA key DC3DEB159A9AF95D3D7456FE7F09B272C88F2FD6 # gpg: issuer "[email protected]" # gpg: Good signature from "Kevin Wolf <[email protected]>" [full] # Primary key fingerprint: DC3D EB15 9A9A F95D 3D74 56FE 7F09 B272 C88F 2FD6 * remotes/kevin/tags/for-upstream: file-posix: Fix leaked fd in raw_open_common() error path file-posix: Fix check_hdev_writable() with auto-read-only file-posix: Move check_hdev_writable() up file-posix: Allow byte-aligned O_DIRECT with NFS block: Require aligned image size to avoid assertion failure iotests: test shutdown when bitmap is exported through NBD nbd: make nbd_export_close_all() synchronous iotests/030: Reduce job speed to make race less likely crypto: use a stronger private key for tests qemu-img resize: Require --shrink for shrinking all image formats Remove VXHS block device vvfat: set status to odd fixes Signed-off-by: Peter Maydell <[email protected]>
2 parents b7bda69 + a8c5cf2 commit 920d213

29 files changed

+273
-811
lines changed

MAINTAINERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2987,7 +2987,7 @@ F: block/vpc.c
29872987
vvfat
29882988
M: Kevin Wolf <[email protected]>
29892989
2990-
S: Supported
2990+
S: Odd Fixes
29912991
F: block/vvfat.c
29922992

29932993
Image format fuzzer

block.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2025,6 +2025,22 @@ static int bdrv_check_perm(BlockDriverState *bs, BlockReopenQueue *q,
20252025
return -EPERM;
20262026
}
20272027

2028+
/*
2029+
* Unaligned requests will automatically be aligned to bl.request_alignment
2030+
* and without RESIZE we can't extend requests to write to space beyond the
2031+
* end of the image, so it's required that the image size is aligned.
2032+
*/
2033+
if ((cumulative_perms & (BLK_PERM_WRITE | BLK_PERM_WRITE_UNCHANGED)) &&
2034+
!(cumulative_perms & BLK_PERM_RESIZE))
2035+
{
2036+
if ((bs->total_sectors * BDRV_SECTOR_SIZE) % bs->bl.request_alignment) {
2037+
error_setg(errp, "Cannot get 'write' permission without 'resize': "
2038+
"Image size is not a multiple of request "
2039+
"alignment");
2040+
return -EPERM;
2041+
}
2042+
}
2043+
20282044
/* Check this node */
20292045
if (!drv) {
20302046
return 0;

block/Makefile.objs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ block-obj-$(CONFIG_LIBNFS) += nfs.o
3131
block-obj-$(CONFIG_CURL) += curl.o
3232
block-obj-$(CONFIG_RBD) += rbd.o
3333
block-obj-$(CONFIG_GLUSTERFS) += gluster.o
34-
block-obj-$(CONFIG_VXHS) += vxhs.o
3534
block-obj-$(CONFIG_LIBSSH) += ssh.o
3635
block-obj-y += accounting.o dirty-bitmap.o
3736
block-obj-y += write-threshold.o
@@ -61,7 +60,6 @@ rbd.o-cflags := $(RBD_CFLAGS)
6160
rbd.o-libs := $(RBD_LIBS)
6261
gluster.o-cflags := $(GLUSTERFS_CFLAGS)
6362
gluster.o-libs := $(GLUSTERFS_LIBS)
64-
vxhs.o-libs := $(VXHS_LIBS)
6563
ssh.o-cflags := $(LIBSSH_CFLAGS)
6664
ssh.o-libs := $(LIBSSH_LIBS)
6765
block-obj-dmg-bz2-$(CONFIG_BZIP2) += dmg-bz2.o

block/file-posix.c

Lines changed: 79 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,12 @@
6262
#include <sys/ioctl.h>
6363
#include <sys/param.h>
6464
#include <sys/syscall.h>
65+
#include <sys/vfs.h>
6566
#include <linux/cdrom.h>
6667
#include <linux/fd.h>
6768
#include <linux/fs.h>
6869
#include <linux/hdreg.h>
70+
#include <linux/magic.h>
6971
#include <scsi/sg.h>
7072
#ifdef __s390__
7173
#include <asm/dasd.h>
@@ -300,6 +302,28 @@ static int probe_physical_blocksize(int fd, unsigned int *blk_size)
300302
#endif
301303
}
302304

305+
/*
306+
* Returns true if no alignment restrictions are necessary even for files
307+
* opened with O_DIRECT.
308+
*
309+
* raw_probe_alignment() probes the required alignment and assume that 1 means
310+
* the probing failed, so it falls back to a safe default of 4k. This can be
311+
* avoided if we know that byte alignment is okay for the file.
312+
*/
313+
static bool dio_byte_aligned(int fd)
314+
{
315+
#ifdef __linux__
316+
struct statfs buf;
317+
int ret;
318+
319+
ret = fstatfs(fd, &buf);
320+
if (ret == 0 && buf.f_type == NFS_SUPER_MAGIC) {
321+
return true;
322+
}
323+
#endif
324+
return false;
325+
}
326+
303327
/* Check if read is allowed with given memory buffer and length.
304328
*
305329
* This function is used to check O_DIRECT memory buffer and request alignment.
@@ -401,6 +425,39 @@ static void raw_probe_alignment(BlockDriverState *bs, int fd, Error **errp)
401425
}
402426
}
403427

428+
static int check_hdev_writable(int fd)
429+
{
430+
#if defined(BLKROGET)
431+
/* Linux block devices can be configured "read-only" using blockdev(8).
432+
* This is independent of device node permissions and therefore open(2)
433+
* with O_RDWR succeeds. Actual writes fail with EPERM.
434+
*
435+
* bdrv_open() is supposed to fail if the disk is read-only. Explicitly
436+
* check for read-only block devices so that Linux block devices behave
437+
* properly.
438+
*/
439+
struct stat st;
440+
int readonly = 0;
441+
442+
if (fstat(fd, &st)) {
443+
return -errno;
444+
}
445+
446+
if (!S_ISBLK(st.st_mode)) {
447+
return 0;
448+
}
449+
450+
if (ioctl(fd, BLKROGET, &readonly) < 0) {
451+
return -errno;
452+
}
453+
454+
if (readonly) {
455+
return -EACCES;
456+
}
457+
#endif /* defined(BLKROGET) */
458+
return 0;
459+
}
460+
404461
static void raw_parse_flags(int bdrv_flags, int *open_flags, bool has_writers)
405462
{
406463
bool read_write = false;
@@ -585,6 +642,15 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
585642
}
586643
s->fd = fd;
587644

645+
/* Check s->open_flags rather than bdrv_flags due to auto-read-only */
646+
if (s->open_flags & O_RDWR) {
647+
ret = check_hdev_writable(s->fd);
648+
if (ret < 0) {
649+
error_setg_errno(errp, -ret, "The device is not writable");
650+
goto fail;
651+
}
652+
}
653+
588654
s->perm = 0;
589655
s->shared_perm = BLK_PERM_ALL;
590656

@@ -629,7 +695,7 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
629695

630696
s->has_discard = true;
631697
s->has_write_zeroes = true;
632-
if ((bs->open_flags & BDRV_O_NOCACHE) != 0) {
698+
if ((bs->open_flags & BDRV_O_NOCACHE) != 0 && !dio_byte_aligned(s->fd)) {
633699
s->needs_alignment = true;
634700
}
635701

@@ -707,6 +773,9 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
707773
}
708774
ret = 0;
709775
fail:
776+
if (ret < 0 && s->fd != -1) {
777+
qemu_close(s->fd);
778+
}
710779
if (filename && (bdrv_flags & BDRV_O_TEMPORARY)) {
711780
unlink(filename);
712781
}
@@ -977,6 +1046,15 @@ static int raw_reconfigure_getfd(BlockDriverState *bs, int flags,
9771046
}
9781047
}
9791048

1049+
if (fd != -1 && (*open_flags & O_RDWR)) {
1050+
ret = check_hdev_writable(fd);
1051+
if (ret < 0) {
1052+
qemu_close(fd);
1053+
error_setg_errno(errp, -ret, "The device is not writable");
1054+
return -1;
1055+
}
1056+
}
1057+
9801058
return fd;
9811059
}
9821060

@@ -3299,39 +3377,6 @@ static int hdev_probe_device(const char *filename)
32993377
return 0;
33003378
}
33013379

3302-
static int check_hdev_writable(BDRVRawState *s)
3303-
{
3304-
#if defined(BLKROGET)
3305-
/* Linux block devices can be configured "read-only" using blockdev(8).
3306-
* This is independent of device node permissions and therefore open(2)
3307-
* with O_RDWR succeeds. Actual writes fail with EPERM.
3308-
*
3309-
* bdrv_open() is supposed to fail if the disk is read-only. Explicitly
3310-
* check for read-only block devices so that Linux block devices behave
3311-
* properly.
3312-
*/
3313-
struct stat st;
3314-
int readonly = 0;
3315-
3316-
if (fstat(s->fd, &st)) {
3317-
return -errno;
3318-
}
3319-
3320-
if (!S_ISBLK(st.st_mode)) {
3321-
return 0;
3322-
}
3323-
3324-
if (ioctl(s->fd, BLKROGET, &readonly) < 0) {
3325-
return -errno;
3326-
}
3327-
3328-
if (readonly) {
3329-
return -EACCES;
3330-
}
3331-
#endif /* defined(BLKROGET) */
3332-
return 0;
3333-
}
3334-
33353380
static void hdev_parse_filename(const char *filename, QDict *options,
33363381
Error **errp)
33373382
{
@@ -3454,15 +3499,6 @@ static int hdev_open(BlockDriverState *bs, QDict *options, int flags,
34543499
/* Since this does ioctl the device must be already opened */
34553500
bs->sg = hdev_is_sg(bs);
34563501

3457-
if (flags & BDRV_O_RDWR) {
3458-
ret = check_hdev_writable(s);
3459-
if (ret < 0) {
3460-
raw_close(bs);
3461-
error_setg_errno(errp, -ret, "The device is not writable");
3462-
return ret;
3463-
}
3464-
}
3465-
34663502
return ret;
34673503
}
34683504

block/trace-events

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -136,23 +136,6 @@ qed_aio_write_prefill(void *s, void *acb, uint64_t start, size_t len, uint64_t o
136136
qed_aio_write_postfill(void *s, void *acb, uint64_t start, size_t len, uint64_t offset) "s %p acb %p start %"PRIu64" len %zu offset %"PRIu64
137137
qed_aio_write_main(void *s, void *acb, int ret, uint64_t offset, size_t len) "s %p acb %p ret %d offset %"PRIu64" len %zu"
138138

139-
# vxhs.c
140-
vxhs_iio_callback(int error) "ctx is NULL: error %d"
141-
vxhs_iio_callback_chnfail(int err, int error) "QNIO channel failed, no i/o %d, %d"
142-
vxhs_iio_callback_unknwn(int opcode, int err) "unexpected opcode %d, errno %d"
143-
vxhs_aio_rw_invalid(int req) "Invalid I/O request iodir %d"
144-
vxhs_aio_rw_ioerr(char *guid, int iodir, uint64_t size, uint64_t off, void *acb, int ret, int err) "IO ERROR (vDisk %s) FOR : Read/Write = %d size = %"PRIu64" offset = %"PRIu64" ACB = %p. Error = %d, errno = %d"
145-
vxhs_get_vdisk_stat_err(char *guid, int ret, int err) "vDisk (%s) stat ioctl failed, ret = %d, errno = %d"
146-
vxhs_get_vdisk_stat(char *vdisk_guid, uint64_t vdisk_size) "vDisk %s stat ioctl returned size %"PRIu64
147-
vxhs_complete_aio(void *acb, uint64_t ret) "aio failed acb %p ret %"PRIu64
148-
vxhs_parse_uri_filename(const char *filename) "URI passed via bdrv_parse_filename %s"
149-
vxhs_open_vdiskid(const char *vdisk_id) "Opening vdisk-id %s"
150-
vxhs_open_hostinfo(char *of_vsa_addr, int port) "Adding host %s:%d to BDRVVXHSState"
151-
vxhs_open_iio_open(const char *host) "Failed to connect to storage agent on host %s"
152-
vxhs_parse_uri_hostinfo(char *host, int port) "Host: IP %s, Port %d"
153-
vxhs_close(char *vdisk_guid) "Closing vdisk %s"
154-
vxhs_get_creds(const char *cacert, const char *client_key, const char *client_cert) "cacert %s, client_key %s, client_cert %s"
155-
156139
# nvme.c
157140
nvme_kick(void *s, int queue) "s %p queue %d"
158141
nvme_dma_flush_queue_wait(void *s) "s %p"

0 commit comments

Comments
 (0)