1 | The following changes since commit ab08440a4ee09032d1a9cb22fdcab23bc7e1c656: | 1 | The following changes since commit 9c125d17e9402c232c46610802e5931b3639d77b: |
---|---|---|---|
2 | 2 | ||
3 | Merge remote-tracking branch 'remotes/rth/tags/pull-tcg-20180702' into staging (2018-07-02 17:57:46 +0100) | 3 | Merge tag 'pull-tcg-20220420' of https://gitlab.com/rth7680/qemu into staging (2022-04-20 16:43:11 -0700) |
4 | 4 | ||
5 | are available in the Git repository at: | 5 | are available in the Git repository at: |
6 | 6 | ||
7 | git://github.com/codyprime/qemu-kvm-jtc.git tags/block-pull-request | 7 | https://gitlab.com/stefanha/qemu.git tags/block-pull-request |
8 | 8 | ||
9 | for you to fetch changes up to 9ded4a0114968e98b41494fc035ba14f84cdf700: | 9 | for you to fetch changes up to d45c83328feab2e4083991693160f0a417cfd9b0: |
10 | 10 | ||
11 | backup: Use copy offloading (2018-07-02 23:23:45 -0400) | 11 | virtiofsd: Add docs/helper for killpriv_v2/no_killpriv_v2 option (2022-04-21 12:05:15 +0200) |
12 | 12 | ||
13 | ---------------------------------------------------------------- | 13 | ---------------------------------------------------------------- |
14 | Block backup patches | 14 | Pull request |
15 | |||
16 | Small contrib/vhost-user-blk, contrib/vhost-user-scsi, and tools/virtiofsd | ||
17 | improvements. | ||
18 | |||
15 | ---------------------------------------------------------------- | 19 | ---------------------------------------------------------------- |
16 | 20 | ||
17 | Fam Zheng (3): | 21 | Liu Yiding (1): |
18 | block: Fix parameter checking in bdrv_co_copy_range_internal | 22 | virtiofsd: Add docs/helper for killpriv_v2/no_killpriv_v2 option |
19 | block: Honour BDRV_REQ_NO_SERIALISING in copy range | ||
20 | backup: Use copy offloading | ||
21 | 23 | ||
22 | block/backup.c | 150 ++++++++++++++++++++++++++++++------------ | 24 | Sakshi Kaushik (1): |
23 | block/io.c | 35 +++++----- | 25 | Implements Backend Program conventions for vhost-user-scsi |
24 | block/trace-events | 1 + | 26 | |
25 | include/block/block.h | 5 +- | 27 | Stefan Hajnoczi (1): |
26 | 4 files changed, 132 insertions(+), 59 deletions(-) | 28 | contrib/vhost-user-blk: add missing GOptionEntry NULL terminator |
29 | |||
30 | docs/tools/virtiofsd.rst | 5 ++ | ||
31 | contrib/vhost-user-blk/vhost-user-blk.c | 3 +- | ||
32 | contrib/vhost-user-scsi/vhost-user-scsi.c | 77 +++++++++++++++-------- | ||
33 | tools/virtiofsd/helper.c | 3 + | ||
34 | 4 files changed, 62 insertions(+), 26 deletions(-) | ||
27 | 35 | ||
28 | -- | 36 | -- |
29 | 2.17.1 | 37 | 2.35.1 |
30 | |||
31 | diff view generated by jsdifflib |
1 | From: Fam Zheng <famz@redhat.com> | 1 | From: Sakshi Kaushik <sakshikaushik717@gmail.com> |
---|---|---|---|
2 | 2 | ||
3 | The implementation is similar to the 'qemu-img convert'. In the | 3 | Signed-off-by: Sakshi Kaushik <sakshikaushik717@gmail.com> |
4 | beginning of the job, offloaded copy is attempted. If it fails, further | 4 | Message-id: 20220406162410.8536-1-sakshikaushik717@gmail.com |
5 | I/O will go through the existing bounce buffer code path. | ||
6 | 5 | ||
7 | Then, as Kevin pointed out, both this and qemu-img convert can benefit | 6 | [Name the iSCSI URL long option --iscsi-uri instead of --iscsi_uri for |
8 | from a local check if one request fails because of, for example, the | 7 | consistency, fix --fd which was rejected due to an outdated |
9 | offset is beyond EOF, but another may well be accepted by the protocol | 8 | --socket-path check, and add missing entries[] terminator. |
10 | layer. This will be implemented separately. | 9 | --Stefan] |
11 | 10 | ||
12 | Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> | 11 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> |
13 | Signed-off-by: Fam Zheng <famz@redhat.com> | ||
14 | Message-id: 20180703023758.14422-4-famz@redhat.com | ||
15 | Signed-off-by: Jeff Cody <jcody@redhat.com> | ||
16 | --- | 12 | --- |
17 | block/backup.c | 150 ++++++++++++++++++++++++++++++++------------- | 13 | contrib/vhost-user-scsi/vhost-user-scsi.c | 77 +++++++++++++++-------- |
18 | block/trace-events | 1 + | 14 | 1 file changed, 52 insertions(+), 25 deletions(-) |
19 | 2 files changed, 110 insertions(+), 41 deletions(-) | ||
20 | 15 | ||
21 | diff --git a/block/backup.c b/block/backup.c | 16 | diff --git a/contrib/vhost-user-scsi/vhost-user-scsi.c b/contrib/vhost-user-scsi/vhost-user-scsi.c |
22 | index XXXXXXX..XXXXXXX 100644 | 17 | index XXXXXXX..XXXXXXX 100644 |
23 | --- a/block/backup.c | 18 | --- a/contrib/vhost-user-scsi/vhost-user-scsi.c |
24 | +++ b/block/backup.c | 19 | +++ b/contrib/vhost-user-scsi/vhost-user-scsi.c |
25 | @@ -XXX,XX +XXX,XX @@ typedef struct BackupBlockJob { | 20 | @@ -XXX,XX +XXX,XX @@ fail: |
26 | QLIST_HEAD(, CowRequest) inflight_reqs; | 21 | |
27 | 22 | /** vhost-user-scsi **/ | |
28 | HBitmap *copy_bitmap; | 23 | |
29 | + bool use_copy_range; | 24 | +static int opt_fdnum = -1; |
30 | + int64_t copy_range_size; | 25 | +static char *opt_socket_path; |
31 | } BackupBlockJob; | 26 | +static gboolean opt_print_caps; |
32 | 27 | +static char *iscsi_uri; | |
33 | static const BlockJobDriver backup_job_driver; | ||
34 | @@ -XXX,XX +XXX,XX @@ static void cow_request_end(CowRequest *req) | ||
35 | qemu_co_queue_restart_all(&req->wait_queue); | ||
36 | } | ||
37 | |||
38 | +/* Copy range to target with a bounce buffer and return the bytes copied. If | ||
39 | + * error occured, return a negative error number */ | ||
40 | +static int coroutine_fn backup_cow_with_bounce_buffer(BackupBlockJob *job, | ||
41 | + int64_t start, | ||
42 | + int64_t end, | ||
43 | + bool is_write_notifier, | ||
44 | + bool *error_is_read, | ||
45 | + void **bounce_buffer) | ||
46 | +{ | ||
47 | + int ret; | ||
48 | + struct iovec iov; | ||
49 | + QEMUIOVector qiov; | ||
50 | + BlockBackend *blk = job->common.blk; | ||
51 | + int nbytes; | ||
52 | + | 28 | + |
53 | + hbitmap_reset(job->copy_bitmap, start / job->cluster_size, 1); | 29 | +static GOptionEntry entries[] = { |
54 | + nbytes = MIN(job->cluster_size, job->len - start); | 30 | + { "print-capabilities", 'c', 0, G_OPTION_ARG_NONE, &opt_print_caps, |
55 | + if (!*bounce_buffer) { | 31 | + "Print capabilities", NULL }, |
56 | + *bounce_buffer = blk_blockalign(blk, job->cluster_size); | 32 | + { "fd", 'f', 0, G_OPTION_ARG_INT, &opt_fdnum, |
57 | + } | 33 | + "Use inherited fd socket", "FDNUM" }, |
58 | + iov.iov_base = *bounce_buffer; | 34 | + { "iscsi-uri", 'i', 0, G_OPTION_ARG_FILENAME, &iscsi_uri, |
59 | + iov.iov_len = nbytes; | 35 | + "iSCSI URI to connect to", "FDNUM" }, |
60 | + qemu_iovec_init_external(&qiov, &iov, 1); | 36 | + { "socket-path", 's', 0, G_OPTION_ARG_FILENAME, &opt_socket_path, |
37 | + "Use UNIX socket path", "PATH" }, | ||
38 | + { NULL, } | ||
39 | +}; | ||
61 | + | 40 | + |
62 | + ret = blk_co_preadv(blk, start, qiov.size, &qiov, | 41 | int main(int argc, char **argv) |
63 | + is_write_notifier ? BDRV_REQ_NO_SERIALISING : 0); | 42 | { |
64 | + if (ret < 0) { | 43 | VusDev *vdev_scsi = NULL; |
65 | + trace_backup_do_cow_read_fail(job, start, ret); | 44 | - char *unix_fn = NULL; |
66 | + if (error_is_read) { | 45 | - char *iscsi_uri = NULL; |
67 | + *error_is_read = true; | 46 | - int lsock = -1, csock = -1, opt, err = EXIT_SUCCESS; |
68 | + } | 47 | + int lsock = -1, csock = -1, err = EXIT_SUCCESS; |
69 | + goto fail; | 48 | |
49 | - while ((opt = getopt(argc, argv, "u:i:")) != -1) { | ||
50 | - switch (opt) { | ||
51 | - case 'h': | ||
52 | - goto help; | ||
53 | - case 'u': | ||
54 | - unix_fn = g_strdup(optarg); | ||
55 | - break; | ||
56 | - case 'i': | ||
57 | - iscsi_uri = g_strdup(optarg); | ||
58 | - break; | ||
59 | - default: | ||
60 | - goto help; | ||
61 | - } | ||
62 | + GError *error = NULL; | ||
63 | + GOptionContext *context; | ||
64 | + | ||
65 | + context = g_option_context_new(NULL); | ||
66 | + g_option_context_add_main_entries(context, entries, NULL); | ||
67 | + if (!g_option_context_parse(context, &argc, &argv, &error)) { | ||
68 | + g_printerr("Option parsing failed: %s\n", error->message); | ||
69 | + exit(EXIT_FAILURE); | ||
70 | + } | 70 | + } |
71 | + | 71 | + |
72 | + if (qemu_iovec_is_zero(&qiov)) { | 72 | + if (opt_print_caps) { |
73 | + ret = blk_co_pwrite_zeroes(job->target, start, | 73 | + g_print("{\n"); |
74 | + qiov.size, BDRV_REQ_MAY_UNMAP); | 74 | + g_print(" \"type\": \"scsi\"\n"); |
75 | + g_print("}\n"); | ||
76 | + goto out; | ||
77 | } | ||
78 | - if (!unix_fn || !iscsi_uri) { | ||
79 | + | ||
80 | + if (!iscsi_uri) { | ||
81 | goto help; | ||
82 | } | ||
83 | |||
84 | - lsock = unix_sock_new(unix_fn); | ||
85 | - if (lsock < 0) { | ||
86 | - goto err; | ||
87 | + if (opt_socket_path) { | ||
88 | + lsock = unix_sock_new(opt_socket_path); | ||
89 | + if (lsock < 0) { | ||
90 | + exit(EXIT_FAILURE); | ||
91 | + } | ||
92 | + } else if (opt_fdnum < 0) { | ||
93 | + g_print("%s\n", g_option_context_get_help(context, true, NULL)); | ||
94 | + exit(EXIT_FAILURE); | ||
75 | + } else { | 95 | + } else { |
76 | + ret = blk_co_pwritev(job->target, start, | 96 | + lsock = opt_fdnum; |
77 | + qiov.size, &qiov, | ||
78 | + job->compress ? BDRV_REQ_WRITE_COMPRESSED : 0); | ||
79 | + } | ||
80 | + if (ret < 0) { | ||
81 | + trace_backup_do_cow_write_fail(job, start, ret); | ||
82 | + if (error_is_read) { | ||
83 | + *error_is_read = false; | ||
84 | + } | ||
85 | + goto fail; | ||
86 | + } | ||
87 | + | ||
88 | + return nbytes; | ||
89 | +fail: | ||
90 | + hbitmap_set(job->copy_bitmap, start / job->cluster_size, 1); | ||
91 | + return ret; | ||
92 | + | ||
93 | +} | ||
94 | + | ||
95 | +/* Copy range to target and return the bytes copied. If error occured, return a | ||
96 | + * negative error number. */ | ||
97 | +static int coroutine_fn backup_cow_with_offload(BackupBlockJob *job, | ||
98 | + int64_t start, | ||
99 | + int64_t end, | ||
100 | + bool is_write_notifier) | ||
101 | +{ | ||
102 | + int ret; | ||
103 | + int nr_clusters; | ||
104 | + BlockBackend *blk = job->common.blk; | ||
105 | + int nbytes; | ||
106 | + | ||
107 | + assert(QEMU_IS_ALIGNED(job->copy_range_size, job->cluster_size)); | ||
108 | + nbytes = MIN(job->copy_range_size, end - start); | ||
109 | + nr_clusters = DIV_ROUND_UP(nbytes, job->cluster_size); | ||
110 | + hbitmap_reset(job->copy_bitmap, start / job->cluster_size, | ||
111 | + nr_clusters); | ||
112 | + ret = blk_co_copy_range(blk, start, job->target, start, nbytes, | ||
113 | + is_write_notifier ? BDRV_REQ_NO_SERIALISING : 0); | ||
114 | + if (ret < 0) { | ||
115 | + trace_backup_do_cow_copy_range_fail(job, start, ret); | ||
116 | + hbitmap_set(job->copy_bitmap, start / job->cluster_size, | ||
117 | + nr_clusters); | ||
118 | + return ret; | ||
119 | + } | ||
120 | + | ||
121 | + return nbytes; | ||
122 | +} | ||
123 | + | ||
124 | static int coroutine_fn backup_do_cow(BackupBlockJob *job, | ||
125 | int64_t offset, uint64_t bytes, | ||
126 | bool *error_is_read, | ||
127 | bool is_write_notifier) | ||
128 | { | ||
129 | - BlockBackend *blk = job->common.blk; | ||
130 | CowRequest cow_request; | ||
131 | - struct iovec iov; | ||
132 | - QEMUIOVector bounce_qiov; | ||
133 | - void *bounce_buffer = NULL; | ||
134 | int ret = 0; | ||
135 | int64_t start, end; /* bytes */ | ||
136 | - int n; /* bytes */ | ||
137 | + void *bounce_buffer = NULL; | ||
138 | |||
139 | qemu_co_rwlock_rdlock(&job->flush_rwlock); | ||
140 | |||
141 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_do_cow(BackupBlockJob *job, | ||
142 | wait_for_overlapping_requests(job, start, end); | ||
143 | cow_request_begin(&cow_request, job, start, end); | ||
144 | |||
145 | - for (; start < end; start += job->cluster_size) { | ||
146 | + while (start < end) { | ||
147 | if (!hbitmap_get(job->copy_bitmap, start / job->cluster_size)) { | ||
148 | trace_backup_do_cow_skip(job, start); | ||
149 | + start += job->cluster_size; | ||
150 | continue; /* already copied */ | ||
151 | } | ||
152 | - hbitmap_reset(job->copy_bitmap, start / job->cluster_size, 1); | ||
153 | |||
154 | trace_backup_do_cow_process(job, start); | ||
155 | |||
156 | - n = MIN(job->cluster_size, job->len - start); | ||
157 | - | ||
158 | - if (!bounce_buffer) { | ||
159 | - bounce_buffer = blk_blockalign(blk, job->cluster_size); | ||
160 | - } | ||
161 | - iov.iov_base = bounce_buffer; | ||
162 | - iov.iov_len = n; | ||
163 | - qemu_iovec_init_external(&bounce_qiov, &iov, 1); | ||
164 | - | ||
165 | - ret = blk_co_preadv(blk, start, bounce_qiov.size, &bounce_qiov, | ||
166 | - is_write_notifier ? BDRV_REQ_NO_SERIALISING : 0); | ||
167 | - if (ret < 0) { | ||
168 | - trace_backup_do_cow_read_fail(job, start, ret); | ||
169 | - if (error_is_read) { | ||
170 | - *error_is_read = true; | ||
171 | + if (job->use_copy_range) { | ||
172 | + ret = backup_cow_with_offload(job, start, end, is_write_notifier); | ||
173 | + if (ret < 0) { | ||
174 | + job->use_copy_range = false; | ||
175 | } | ||
176 | - hbitmap_set(job->copy_bitmap, start / job->cluster_size, 1); | ||
177 | - goto out; | ||
178 | } | ||
179 | - | ||
180 | - if (buffer_is_zero(iov.iov_base, iov.iov_len)) { | ||
181 | - ret = blk_co_pwrite_zeroes(job->target, start, | ||
182 | - bounce_qiov.size, BDRV_REQ_MAY_UNMAP); | ||
183 | - } else { | ||
184 | - ret = blk_co_pwritev(job->target, start, | ||
185 | - bounce_qiov.size, &bounce_qiov, | ||
186 | - job->compress ? BDRV_REQ_WRITE_COMPRESSED : 0); | ||
187 | + if (!job->use_copy_range) { | ||
188 | + ret = backup_cow_with_bounce_buffer(job, start, end, is_write_notifier, | ||
189 | + error_is_read, &bounce_buffer); | ||
190 | } | ||
191 | if (ret < 0) { | ||
192 | - trace_backup_do_cow_write_fail(job, start, ret); | ||
193 | - if (error_is_read) { | ||
194 | - *error_is_read = false; | ||
195 | - } | ||
196 | - hbitmap_set(job->copy_bitmap, start / job->cluster_size, 1); | ||
197 | - goto out; | ||
198 | + break; | ||
199 | } | ||
200 | |||
201 | /* Publish progress, guest I/O counts as progress too. Note that the | ||
202 | * offset field is an opaque progress value, it is not a disk offset. | ||
203 | */ | ||
204 | - job->bytes_read += n; | ||
205 | - job_progress_update(&job->common.job, n); | ||
206 | + start += ret; | ||
207 | + job->bytes_read += ret; | ||
208 | + job_progress_update(&job->common.job, ret); | ||
209 | + ret = 0; | ||
210 | } | 97 | } |
211 | 98 | ||
212 | -out: | 99 | csock = accept(lsock, NULL, NULL); |
213 | if (bounce_buffer) { | 100 | @@ -XXX,XX +XXX,XX @@ out: |
214 | qemu_vfree(bounce_buffer); | 101 | if (vdev_scsi) { |
102 | g_main_loop_unref(vdev_scsi->loop); | ||
103 | g_free(vdev_scsi); | ||
104 | - unlink(unix_fn); | ||
105 | + unlink(opt_socket_path); | ||
215 | } | 106 | } |
216 | @@ -XXX,XX +XXX,XX @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs, | 107 | if (csock >= 0) { |
217 | } else { | 108 | close(csock); |
218 | job->cluster_size = MAX(BACKUP_CLUSTER_SIZE_DEFAULT, bdi.cluster_size); | 109 | @@ -XXX,XX +XXX,XX @@ out: |
110 | if (lsock >= 0) { | ||
111 | close(lsock); | ||
219 | } | 112 | } |
220 | + job->use_copy_range = true; | 113 | - g_free(unix_fn); |
221 | + job->copy_range_size = MIN_NON_ZERO(blk_get_max_transfer(job->common.blk), | 114 | + g_free(opt_socket_path); |
222 | + blk_get_max_transfer(job->target)); | 115 | g_free(iscsi_uri); |
223 | + job->copy_range_size = MAX(job->cluster_size, | 116 | |
224 | + QEMU_ALIGN_UP(job->copy_range_size, | 117 | return err; |
225 | + job->cluster_size)); | 118 | @@ -XXX,XX +XXX,XX @@ err: |
226 | 119 | goto out; | |
227 | /* Required permissions are already taken with target's blk_new() */ | 120 | |
228 | block_job_add_bdrv(&job->common, "target", target, 0, BLK_PERM_ALL, | 121 | help: |
229 | diff --git a/block/trace-events b/block/trace-events | 122 | - fprintf(stderr, "Usage: %s [ -u unix_sock_path -i iscsi_uri ] | [ -h ]\n", |
230 | index XXXXXXX..XXXXXXX 100644 | 123 | + fprintf(stderr, "Usage: %s [ -s socket-path -i iscsi-uri -f fd -p print-capabilities ] | [ -h ]\n", |
231 | --- a/block/trace-events | 124 | argv[0]); |
232 | +++ b/block/trace-events | 125 | - fprintf(stderr, " -u path to unix socket\n"); |
233 | @@ -XXX,XX +XXX,XX @@ backup_do_cow_skip(void *job, int64_t start) "job %p start %"PRId64 | 126 | - fprintf(stderr, " -i iscsi uri for lun 0\n"); |
234 | backup_do_cow_process(void *job, int64_t start) "job %p start %"PRId64 | 127 | + fprintf(stderr, " -s, --socket-path=SOCKET_PATH path to unix socket\n"); |
235 | backup_do_cow_read_fail(void *job, int64_t start, int ret) "job %p start %"PRId64" ret %d" | 128 | + fprintf(stderr, " -i, --iscsi-uri=ISCSI_URI iscsi uri for lun 0\n"); |
236 | backup_do_cow_write_fail(void *job, int64_t start, int ret) "job %p start %"PRId64" ret %d" | 129 | + fprintf(stderr, " -f, --fd=FILE_DESCRIPTOR file-descriptor\n"); |
237 | +backup_do_cow_copy_range_fail(void *job, int64_t start, int ret) "job %p start %"PRId64" ret %d" | 130 | + fprintf(stderr, " -p, --print-capabilities=PRINT_CAPABILITIES denotes print-capabilities\n"); |
238 | 131 | fprintf(stderr, " -h print help and quit\n"); | |
239 | # blockdev.c | 132 | |
240 | qmp_block_job_cancel(void *job) "job %p" | 133 | goto err; |
241 | -- | 134 | -- |
242 | 2.17.1 | 135 | 2.35.1 |
243 | |||
244 | diff view generated by jsdifflib |
1 | From: Fam Zheng <famz@redhat.com> | 1 | The GLib documentation says "a NULL-terminated array of GOptionEntrys" |
---|---|---|---|
2 | so we'd better make sure there is a terminator that lets | ||
3 | g_option_context_add_main_entries() know when the end of the array has | ||
4 | been reached. | ||
2 | 5 | ||
3 | This semantics is needed by drive-backup so implement it before using | 6 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> |
4 | this API there. | 7 | Reviewed-by: Michael S. Tsirkin <mst@redhat.com> |
8 | Message-id: 20220411150057.3009667-1-stefanha@redhat.com | ||
9 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
10 | --- | ||
11 | contrib/vhost-user-blk/vhost-user-blk.c | 3 ++- | ||
12 | 1 file changed, 2 insertions(+), 1 deletion(-) | ||
5 | 13 | ||
6 | Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> | 14 | diff --git a/contrib/vhost-user-blk/vhost-user-blk.c b/contrib/vhost-user-blk/vhost-user-blk.c |
7 | Signed-off-by: Fam Zheng <famz@redhat.com> | ||
8 | Message-id: 20180703023758.14422-3-famz@redhat.com | ||
9 | Signed-off-by: Jeff Cody <jcody@redhat.com> | ||
10 | --- | ||
11 | block/io.c | 6 ++++-- | ||
12 | include/block/block.h | 5 +++-- | ||
13 | 2 files changed, 7 insertions(+), 4 deletions(-) | ||
14 | |||
15 | diff --git a/block/io.c b/block/io.c | ||
16 | index XXXXXXX..XXXXXXX 100644 | 15 | index XXXXXXX..XXXXXXX 100644 |
17 | --- a/block/io.c | 16 | --- a/contrib/vhost-user-blk/vhost-user-blk.c |
18 | +++ b/block/io.c | 17 | +++ b/contrib/vhost-user-blk/vhost-user-blk.c |
19 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_copy_range_internal(BdrvChild *src, | 18 | @@ -XXX,XX +XXX,XX @@ static GOptionEntry entries[] = { |
20 | tracked_request_begin(&dst_req, dst->bs, dst_offset, | 19 | {"blk-file", 'b', 0, G_OPTION_ARG_FILENAME, &opt_blk_file, |
21 | bytes, BDRV_TRACKED_WRITE); | 20 | "block device or file path", "PATH"}, |
22 | 21 | { "read-only", 'r', 0, G_OPTION_ARG_NONE, &opt_read_only, | |
23 | - wait_serialising_requests(&src_req); | 22 | - "Enable read-only", NULL } |
24 | - wait_serialising_requests(&dst_req); | 23 | + "Enable read-only", NULL }, |
25 | + if (!(flags & BDRV_REQ_NO_SERIALISING)) { | 24 | + { NULL, }, |
26 | + wait_serialising_requests(&src_req); | 25 | }; |
27 | + wait_serialising_requests(&dst_req); | 26 | |
28 | + } | 27 | int main(int argc, char **argv) |
29 | if (recurse_src) { | ||
30 | ret = src->bs->drv->bdrv_co_copy_range_from(src->bs, | ||
31 | src, src_offset, | ||
32 | diff --git a/include/block/block.h b/include/block/block.h | ||
33 | index XXXXXXX..XXXXXXX 100644 | ||
34 | --- a/include/block/block.h | ||
35 | +++ b/include/block/block.h | ||
36 | @@ -XXX,XX +XXX,XX @@ void bdrv_unregister_buf(BlockDriverState *bs, void *host); | ||
37 | * @dst: Destination child to copy data to | ||
38 | * @dst_offset: offset in @dst image to write data | ||
39 | * @bytes: number of bytes to copy | ||
40 | - * @flags: request flags. Must be one of: | ||
41 | - * 0 - actually read data from src; | ||
42 | + * @flags: request flags. Supported flags: | ||
43 | * BDRV_REQ_ZERO_WRITE - treat the @src range as zero data and do zero | ||
44 | * write on @dst as if bdrv_co_pwrite_zeroes is | ||
45 | * called. Used to simplify caller code, or | ||
46 | * during BlockDriver.bdrv_co_copy_range_from() | ||
47 | * recursion. | ||
48 | + * BDRV_REQ_NO_SERIALISING - do not serialize with other overlapping | ||
49 | + * requests currently in flight. | ||
50 | * | ||
51 | * Returns: 0 if succeeded; negative error code if failed. | ||
52 | **/ | ||
53 | -- | 28 | -- |
54 | 2.17.1 | 29 | 2.35.1 |
55 | |||
56 | diff view generated by jsdifflib |
1 | From: Fam Zheng <famz@redhat.com> | 1 | From: Liu Yiding <liuyd.fnst@fujitsu.com> |
---|---|---|---|
2 | 2 | ||
3 | src may be NULL if BDRV_REQ_ZERO_WRITE flag is set, in this case only | 3 | virtiofsd has introduced killpriv_v2/no_killpriv_v2 for a while. Add |
4 | check dst and dst->bs. This bug was introduced when moving in the | 4 | description of it to docs/helper. |
5 | request tracking code from bdrv_co_copy_range, in 37aec7d75eb. | ||
6 | 5 | ||
7 | This especially fixes the possible segfault when initializing src_bs | 6 | Signed-off-by: Liu Yiding <liuyd.fnst@fujitsu.com> |
8 | with a NULL src. | 7 | Message-Id: <20220421095151.2231099-1-liuyd.fnst@fujitsu.com> |
9 | 8 | ||
10 | Signed-off-by: Fam Zheng <famz@redhat.com> | 9 | [Small documentation fixes: s/as client supports/as the client supports/ |
11 | Message-id: 20180703023758.14422-2-famz@redhat.com | 10 | and s/. /. /. |
12 | Reviewed-by: Jeff Cody <jcody@redhat.com> | 11 | --Stefan] |
13 | Signed-off-by: Jeff Cody <jcody@redhat.com> | 12 | |
13 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
14 | --- | 14 | --- |
15 | block/io.c | 29 +++++++++++++++-------------- | 15 | docs/tools/virtiofsd.rst | 5 +++++ |
16 | 1 file changed, 15 insertions(+), 14 deletions(-) | 16 | tools/virtiofsd/helper.c | 3 +++ |
17 | 2 files changed, 8 insertions(+) | ||
17 | 18 | ||
18 | diff --git a/block/io.c b/block/io.c | 19 | diff --git a/docs/tools/virtiofsd.rst b/docs/tools/virtiofsd.rst |
19 | index XXXXXXX..XXXXXXX 100644 | 20 | index XXXXXXX..XXXXXXX 100644 |
20 | --- a/block/io.c | 21 | --- a/docs/tools/virtiofsd.rst |
21 | +++ b/block/io.c | 22 | +++ b/docs/tools/virtiofsd.rst |
22 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_copy_range_internal(BdrvChild *src, | 23 | @@ -XXX,XX +XXX,XX @@ Options |
23 | bool recurse_src) | 24 | label. Server will try to set that label on newly created file |
24 | { | 25 | atomically wherever possible. |
25 | BdrvTrackedRequest src_req, dst_req; | 26 | |
26 | - BlockDriverState *src_bs = src->bs; | 27 | + * killpriv_v2|no_killpriv_v2 - |
27 | - BlockDriverState *dst_bs = dst->bs; | 28 | + Enable/disable ``FUSE_HANDLE_KILLPRIV_V2`` support. KILLPRIV_V2 is enabled |
28 | int ret; | 29 | + by default as long as the client supports it. Enabling this option helps |
29 | 30 | + with performance in write path. | |
30 | - if (!src || !dst || !src->bs || !dst->bs) { | ||
31 | + if (!dst || !dst->bs) { | ||
32 | return -ENOMEDIUM; | ||
33 | } | ||
34 | - ret = bdrv_check_byte_request(src->bs, src_offset, bytes); | ||
35 | - if (ret) { | ||
36 | - return ret; | ||
37 | - } | ||
38 | - | ||
39 | ret = bdrv_check_byte_request(dst->bs, dst_offset, bytes); | ||
40 | if (ret) { | ||
41 | return ret; | ||
42 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_copy_range_internal(BdrvChild *src, | ||
43 | return bdrv_co_pwrite_zeroes(dst, dst_offset, bytes, flags); | ||
44 | } | ||
45 | |||
46 | + if (!src || !src->bs) { | ||
47 | + return -ENOMEDIUM; | ||
48 | + } | ||
49 | + ret = bdrv_check_byte_request(src->bs, src_offset, bytes); | ||
50 | + if (ret) { | ||
51 | + return ret; | ||
52 | + } | ||
53 | + | 31 | + |
54 | if (!src->bs->drv->bdrv_co_copy_range_from | 32 | .. option:: --socket-path=PATH |
55 | || !dst->bs->drv->bdrv_co_copy_range_to | 33 | |
56 | || src->bs->encrypted || dst->bs->encrypted) { | 34 | Listen on vhost-user UNIX domain socket at PATH. |
57 | return -ENOTSUP; | 35 | diff --git a/tools/virtiofsd/helper.c b/tools/virtiofsd/helper.c |
58 | } | 36 | index XXXXXXX..XXXXXXX 100644 |
59 | - bdrv_inc_in_flight(src_bs); | 37 | --- a/tools/virtiofsd/helper.c |
60 | - bdrv_inc_in_flight(dst_bs); | 38 | +++ b/tools/virtiofsd/helper.c |
61 | - tracked_request_begin(&src_req, src_bs, src_offset, | 39 | @@ -XXX,XX +XXX,XX @@ void fuse_cmdline_help(void) |
62 | + bdrv_inc_in_flight(src->bs); | 40 | " -o announce_submounts Announce sub-mount points to the guest\n" |
63 | + bdrv_inc_in_flight(dst->bs); | 41 | " -o posix_acl/no_posix_acl Enable/Disable posix_acl. (default: disabled)\n" |
64 | + tracked_request_begin(&src_req, src->bs, src_offset, | 42 | " -o security_label/no_security_label Enable/Disable security label. (default: disabled)\n" |
65 | bytes, BDRV_TRACKED_READ); | 43 | + " -o killpriv_v2/no_killpriv_v2\n" |
66 | - tracked_request_begin(&dst_req, dst_bs, dst_offset, | 44 | + " Enable/Disable FUSE_HANDLE_KILLPRIV_V2.\n" |
67 | + tracked_request_begin(&dst_req, dst->bs, dst_offset, | 45 | + " (default: enabled as long as client supports it)\n" |
68 | bytes, BDRV_TRACKED_WRITE); | 46 | ); |
69 | |||
70 | wait_serialising_requests(&src_req); | ||
71 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_copy_range_internal(BdrvChild *src, | ||
72 | } | ||
73 | tracked_request_end(&src_req); | ||
74 | tracked_request_end(&dst_req); | ||
75 | - bdrv_dec_in_flight(src_bs); | ||
76 | - bdrv_dec_in_flight(dst_bs); | ||
77 | + bdrv_dec_in_flight(src->bs); | ||
78 | + bdrv_dec_in_flight(dst->bs); | ||
79 | return ret; | ||
80 | } | 47 | } |
81 | 48 | ||
82 | -- | 49 | -- |
83 | 2.17.1 | 50 | 2.35.1 |
84 | |||
85 | diff view generated by jsdifflib |