Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/cody/tags/block-pull-request' i…
Browse files Browse the repository at this point in the history
…nto staging

# gpg: Signature made Fri 25 Sep 2015 16:47:31 BST using RSA key ID C0DE3057
# gpg: Good signature from "Jeffrey Cody <jcody@redhat.com>"
# gpg:                 aka "Jeffrey Cody <jeff@codyprime.org>"
# gpg:                 aka "Jeffrey Cody <codyprime@gmail.com>"

* remotes/cody/tags/block-pull-request:
  sheepdog: refine discard support
  sheepdog: use per AIOCB dirty indexes for non overlapping requests
  Backup: don't do copy-on-read in before_write_notifier
  block: Introduce a new API bdrv_co_no_copy_on_readv()
  sheepdog: add reopen support
  block/nfs: cache allocated filesize for read-only files
  block/nfs: fix calculation of allocated file size

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
pm215 committed Sep 25, 2015
2 parents 690b286 + e6fd57e commit 54b3762
Show file tree
Hide file tree
Showing 6 changed files with 200 additions and 48 deletions.
20 changes: 14 additions & 6 deletions block/backup.c
Expand Up @@ -89,7 +89,8 @@ static void cow_request_end(CowRequest *req)

static int coroutine_fn backup_do_cow(BlockDriverState *bs,
int64_t sector_num, int nb_sectors,
bool *error_is_read)
bool *error_is_read,
bool is_write_notifier)
{
BackupBlockJob *job = (BackupBlockJob *)bs->job;
CowRequest cow_request;
Expand Down Expand Up @@ -129,8 +130,14 @@ static int coroutine_fn backup_do_cow(BlockDriverState *bs,
iov.iov_len = n * BDRV_SECTOR_SIZE;
qemu_iovec_init_external(&bounce_qiov, &iov, 1);

ret = bdrv_co_readv(bs, start * BACKUP_SECTORS_PER_CLUSTER, n,
&bounce_qiov);
if (is_write_notifier) {
ret = bdrv_co_no_copy_on_readv(bs,
start * BACKUP_SECTORS_PER_CLUSTER,
n, &bounce_qiov);
} else {
ret = bdrv_co_readv(bs, start * BACKUP_SECTORS_PER_CLUSTER, n,
&bounce_qiov);
}
if (ret < 0) {
trace_backup_do_cow_read_fail(job, start, ret);
if (error_is_read) {
Expand Down Expand Up @@ -190,7 +197,7 @@ static int coroutine_fn backup_before_write_notify(
assert((req->offset & (BDRV_SECTOR_SIZE - 1)) == 0);
assert((req->bytes & (BDRV_SECTOR_SIZE - 1)) == 0);

return backup_do_cow(req->bs, sector_num, nb_sectors, NULL);
return backup_do_cow(req->bs, sector_num, nb_sectors, NULL, true);
}

static void backup_set_speed(BlockJob *job, int64_t speed, Error **errp)
Expand Down Expand Up @@ -303,7 +310,8 @@ static int coroutine_fn backup_run_incremental(BackupBlockJob *job)
return ret;
}
ret = backup_do_cow(bs, cluster * BACKUP_SECTORS_PER_CLUSTER,
BACKUP_SECTORS_PER_CLUSTER, &error_is_read);
BACKUP_SECTORS_PER_CLUSTER, &error_is_read,
false);
if ((ret < 0) &&
backup_error_action(job, error_is_read, -ret) ==
BLOCK_ERROR_ACTION_REPORT) {
Expand Down Expand Up @@ -408,7 +416,7 @@ static void coroutine_fn backup_run(void *opaque)
}
/* FULL sync mode we copy the whole drive. */
ret = backup_do_cow(bs, start * BACKUP_SECTORS_PER_CLUSTER,
BACKUP_SECTORS_PER_CLUSTER, &error_is_read);
BACKUP_SECTORS_PER_CLUSTER, &error_is_read, false);
if (ret < 0) {
/* Depending on error action, fail now or retry cluster */
BlockErrorAction action =
Expand Down
12 changes: 11 additions & 1 deletion block/io.c
Expand Up @@ -932,7 +932,8 @@ static int coroutine_fn bdrv_co_do_preadv(BlockDriverState *bs,
return ret;
}

if (bs->copy_on_read) {
/* Don't do copy-on-read if we read data before write operation */
if (bs->copy_on_read && !(flags & BDRV_REQ_NO_COPY_ON_READ)) {
flags |= BDRV_REQ_COPY_ON_READ;
}

Expand Down Expand Up @@ -1001,6 +1002,15 @@ int coroutine_fn bdrv_co_readv(BlockDriverState *bs, int64_t sector_num,
return bdrv_co_do_readv(bs, sector_num, nb_sectors, qiov, 0);
}

int coroutine_fn bdrv_co_no_copy_on_readv(BlockDriverState *bs,
int64_t sector_num, int nb_sectors, QEMUIOVector *qiov)
{
trace_bdrv_co_no_copy_on_readv(bs, sector_num, nb_sectors);

return bdrv_co_do_readv(bs, sector_num, nb_sectors, qiov,
BDRV_REQ_NO_COPY_ON_READ);
}

int coroutine_fn bdrv_co_copy_on_readv(BlockDriverState *bs,
int64_t sector_num, int nb_sectors, QEMUIOVector *qiov)
{
Expand Down
38 changes: 37 additions & 1 deletion block/nfs.c
Expand Up @@ -43,6 +43,7 @@ typedef struct NFSClient {
int events;
bool has_zero_init;
AioContext *aio_context;
blkcnt_t st_blocks;
} NFSClient;

typedef struct NFSRPC {
Expand Down Expand Up @@ -374,6 +375,7 @@ static int64_t nfs_client_open(NFSClient *client, const char *filename,
}

ret = DIV_ROUND_UP(st.st_size, BDRV_SECTOR_SIZE);
client->st_blocks = st.st_blocks;
client->has_zero_init = S_ISREG(st.st_mode);
goto out;
fail:
Expand Down Expand Up @@ -464,6 +466,11 @@ static int64_t nfs_get_allocated_file_size(BlockDriverState *bs)
NFSRPC task = {0};
struct stat st;

if (bdrv_is_read_only(bs) &&
!(bs->open_flags & BDRV_O_NOCACHE)) {
return client->st_blocks * 512;
}

task.st = &st;
if (nfs_fstat_async(client->context, client->fh, nfs_co_generic_cb,
&task) != 0) {
Expand All @@ -475,7 +482,7 @@ static int64_t nfs_get_allocated_file_size(BlockDriverState *bs)
aio_poll(client->aio_context, true);
}

return (task.ret < 0 ? task.ret : st.st_blocks * st.st_blksize);
return (task.ret < 0 ? task.ret : st.st_blocks * 512);
}

static int nfs_file_truncate(BlockDriverState *bs, int64_t offset)
Expand All @@ -484,6 +491,34 @@ static int nfs_file_truncate(BlockDriverState *bs, int64_t offset)
return nfs_ftruncate(client->context, client->fh, offset);
}

/* Note that this will not re-establish a connection with the NFS server
* - it is effectively a NOP. */
static int nfs_reopen_prepare(BDRVReopenState *state,
BlockReopenQueue *queue, Error **errp)
{
NFSClient *client = state->bs->opaque;
struct stat st;
int ret = 0;

if (state->flags & BDRV_O_RDWR && bdrv_is_read_only(state->bs)) {
error_setg(errp, "Cannot open a read-only mount as read-write");
return -EACCES;
}

/* Update cache for read-only reopens */
if (!(state->flags & BDRV_O_RDWR)) {
ret = nfs_fstat(client->context, client->fh, &st);
if (ret < 0) {
error_setg(errp, "Failed to fstat file: %s",
nfs_get_error(client->context));
return ret;
}
client->st_blocks = st.st_blocks;
}

return 0;
}

static BlockDriver bdrv_nfs = {
.format_name = "nfs",
.protocol_name = "nfs",
Expand All @@ -499,6 +534,7 @@ static BlockDriver bdrv_nfs = {
.bdrv_file_open = nfs_file_open,
.bdrv_close = nfs_file_close,
.bdrv_create = nfs_file_create,
.bdrv_reopen_prepare = nfs_reopen_prepare,

.bdrv_co_readv = nfs_co_readv,
.bdrv_co_writev = nfs_co_writev,
Expand Down

0 comments on commit 54b3762

Please sign in to comment.