Commit 920d213c authored by Peter Maydell's avatar Peter Maydell
Browse files

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 "kwolf@redhat.com"
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>" [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: default avatarPeter Maydell <peter.maydell@linaro.org>
parents b7bda69c a8c5cf27
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -2987,7 +2987,7 @@ F: block/vpc.c
vvfat
M: Kevin Wolf <kwolf@redhat.com>
L: qemu-block@nongnu.org
S: Supported
S: Odd Fixes
F: block/vvfat.c

Image format fuzzer
+16 −0
Original line number Diff line number Diff line
@@ -2025,6 +2025,22 @@ static int bdrv_check_perm(BlockDriverState *bs, BlockReopenQueue *q,
        return -EPERM;
    }

    /*
     * Unaligned requests will automatically be aligned to bl.request_alignment
     * and without RESIZE we can't extend requests to write to space beyond the
     * end of the image, so it's required that the image size is aligned.
     */
    if ((cumulative_perms & (BLK_PERM_WRITE | BLK_PERM_WRITE_UNCHANGED)) &&
        !(cumulative_perms & BLK_PERM_RESIZE))
    {
        if ((bs->total_sectors * BDRV_SECTOR_SIZE) % bs->bl.request_alignment) {
            error_setg(errp, "Cannot get 'write' permission without 'resize': "
                             "Image size is not a multiple of request "
                             "alignment");
            return -EPERM;
        }
    }

    /* Check this node */
    if (!drv) {
        return 0;
+0 −2
Original line number Diff line number Diff line
@@ -31,7 +31,6 @@ block-obj-$(CONFIG_LIBNFS) += nfs.o
block-obj-$(CONFIG_CURL) += curl.o
block-obj-$(CONFIG_RBD) += rbd.o
block-obj-$(CONFIG_GLUSTERFS) += gluster.o
block-obj-$(CONFIG_VXHS) += vxhs.o
block-obj-$(CONFIG_LIBSSH) += ssh.o
block-obj-y += accounting.o dirty-bitmap.o
block-obj-y += write-threshold.o
@@ -61,7 +60,6 @@ rbd.o-cflags := $(RBD_CFLAGS)
rbd.o-libs         := $(RBD_LIBS)
gluster.o-cflags   := $(GLUSTERFS_CFLAGS)
gluster.o-libs     := $(GLUSTERFS_LIBS)
vxhs.o-libs        := $(VXHS_LIBS)
ssh.o-cflags       := $(LIBSSH_CFLAGS)
ssh.o-libs         := $(LIBSSH_LIBS)
block-obj-dmg-bz2-$(CONFIG_BZIP2) += dmg-bz2.o
+79 −43
Original line number Diff line number Diff line
@@ -62,10 +62,12 @@
#include <sys/ioctl.h>
#include <sys/param.h>
#include <sys/syscall.h>
#include <sys/vfs.h>
#include <linux/cdrom.h>
#include <linux/fd.h>
#include <linux/fs.h>
#include <linux/hdreg.h>
#include <linux/magic.h>
#include <scsi/sg.h>
#ifdef __s390__
#include <asm/dasd.h>
@@ -300,6 +302,28 @@ static int probe_physical_blocksize(int fd, unsigned int *blk_size)
#endif
}

/*
 * Returns true if no alignment restrictions are necessary even for files
 * opened with O_DIRECT.
 *
 * raw_probe_alignment() probes the required alignment and assume that 1 means
 * the probing failed, so it falls back to a safe default of 4k. This can be
 * avoided if we know that byte alignment is okay for the file.
 */
static bool dio_byte_aligned(int fd)
{
#ifdef __linux__
    struct statfs buf;
    int ret;

    ret = fstatfs(fd, &buf);
    if (ret == 0 && buf.f_type == NFS_SUPER_MAGIC) {
        return true;
    }
#endif
    return false;
}

/* Check if read is allowed with given memory buffer and length.
 *
 * 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)
    }
}

static int check_hdev_writable(int fd)
{
#if defined(BLKROGET)
    /* Linux block devices can be configured "read-only" using blockdev(8).
     * This is independent of device node permissions and therefore open(2)
     * with O_RDWR succeeds.  Actual writes fail with EPERM.
     *
     * bdrv_open() is supposed to fail if the disk is read-only.  Explicitly
     * check for read-only block devices so that Linux block devices behave
     * properly.
     */
    struct stat st;
    int readonly = 0;

    if (fstat(fd, &st)) {
        return -errno;
    }

    if (!S_ISBLK(st.st_mode)) {
        return 0;
    }

    if (ioctl(fd, BLKROGET, &readonly) < 0) {
        return -errno;
    }

    if (readonly) {
        return -EACCES;
    }
#endif /* defined(BLKROGET) */
    return 0;
}

static void raw_parse_flags(int bdrv_flags, int *open_flags, bool has_writers)
{
    bool read_write = false;
@@ -585,6 +642,15 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
    }
    s->fd = fd;

    /* Check s->open_flags rather than bdrv_flags due to auto-read-only */
    if (s->open_flags & O_RDWR) {
        ret = check_hdev_writable(s->fd);
        if (ret < 0) {
            error_setg_errno(errp, -ret, "The device is not writable");
            goto fail;
        }
    }

    s->perm = 0;
    s->shared_perm = BLK_PERM_ALL;

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

    s->has_discard = true;
    s->has_write_zeroes = true;
    if ((bs->open_flags & BDRV_O_NOCACHE) != 0) {
    if ((bs->open_flags & BDRV_O_NOCACHE) != 0 && !dio_byte_aligned(s->fd)) {
        s->needs_alignment = true;
    }

@@ -707,6 +773,9 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
    }
    ret = 0;
fail:
    if (ret < 0 && s->fd != -1) {
        qemu_close(s->fd);
    }
    if (filename && (bdrv_flags & BDRV_O_TEMPORARY)) {
        unlink(filename);
    }
@@ -977,6 +1046,15 @@ static int raw_reconfigure_getfd(BlockDriverState *bs, int flags,
        }
    }

    if (fd != -1 && (*open_flags & O_RDWR)) {
        ret = check_hdev_writable(fd);
        if (ret < 0) {
            qemu_close(fd);
            error_setg_errno(errp, -ret, "The device is not writable");
            return -1;
        }
    }

    return fd;
}

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

static int check_hdev_writable(BDRVRawState *s)
{
#if defined(BLKROGET)
    /* Linux block devices can be configured "read-only" using blockdev(8).
     * This is independent of device node permissions and therefore open(2)
     * with O_RDWR succeeds.  Actual writes fail with EPERM.
     *
     * bdrv_open() is supposed to fail if the disk is read-only.  Explicitly
     * check for read-only block devices so that Linux block devices behave
     * properly.
     */
    struct stat st;
    int readonly = 0;

    if (fstat(s->fd, &st)) {
        return -errno;
    }

    if (!S_ISBLK(st.st_mode)) {
        return 0;
    }

    if (ioctl(s->fd, BLKROGET, &readonly) < 0) {
        return -errno;
    }

    if (readonly) {
        return -EACCES;
    }
#endif /* defined(BLKROGET) */
    return 0;
}

static void hdev_parse_filename(const char *filename, QDict *options,
                                Error **errp)
{
@@ -3454,15 +3499,6 @@ hdev_open_Mac_error:
    /* Since this does ioctl the device must be already opened */
    bs->sg = hdev_is_sg(bs);

    if (flags & BDRV_O_RDWR) {
        ret = check_hdev_writable(s);
        if (ret < 0) {
            raw_close(bs);
            error_setg_errno(errp, -ret, "The device is not writable");
            return ret;
        }
    }

    return ret;
}

+0 −17
Original line number Diff line number Diff line
@@ -136,23 +136,6 @@ qed_aio_write_prefill(void *s, void *acb, uint64_t start, size_t len, uint64_t o
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
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"

# vxhs.c
vxhs_iio_callback(int error) "ctx is NULL: error %d"
vxhs_iio_callback_chnfail(int err, int error) "QNIO channel failed, no i/o %d, %d"
vxhs_iio_callback_unknwn(int opcode, int err) "unexpected opcode %d, errno %d"
vxhs_aio_rw_invalid(int req) "Invalid I/O request iodir %d"
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"
vxhs_get_vdisk_stat_err(char *guid, int ret, int err) "vDisk (%s) stat ioctl failed, ret = %d, errno = %d"
vxhs_get_vdisk_stat(char *vdisk_guid, uint64_t vdisk_size) "vDisk %s stat ioctl returned size %"PRIu64
vxhs_complete_aio(void *acb, uint64_t ret) "aio failed acb %p ret %"PRIu64
vxhs_parse_uri_filename(const char *filename) "URI passed via bdrv_parse_filename %s"
vxhs_open_vdiskid(const char *vdisk_id) "Opening vdisk-id %s"
vxhs_open_hostinfo(char *of_vsa_addr, int port) "Adding host %s:%d to BDRVVXHSState"
vxhs_open_iio_open(const char *host) "Failed to connect to storage agent on host %s"
vxhs_parse_uri_hostinfo(char *host, int port) "Host: IP %s, Port %d"
vxhs_close(char *vdisk_guid) "Closing vdisk %s"
vxhs_get_creds(const char *cacert, const char *client_key, const char *client_cert) "cacert %s, client_key %s, client_cert %s"

# nvme.c
nvme_kick(void *s, int queue) "s %p queue %d"
nvme_dma_flush_queue_wait(void *s) "s %p"
Loading