block.c (cf8074b3825f7229a20c60e679511592bde41340) block.c (8d3b1a2d0b34a95800c482e1414c63f469ac4973)
1/*
2 * QEMU System Emulator block driver
3 *
4 * Copyright (c) 2003 Fabrice Bellard
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights

--- 2117 unchanged lines hidden (view full) ---

2126 rwco->nb_sectors, rwco->qiov, 0);
2127 } else {
2128 rwco->ret = bdrv_co_do_writev(rwco->bs, rwco->sector_num,
2129 rwco->nb_sectors, rwco->qiov, 0);
2130 }
2131}
2132
2133/*
1/*
2 * QEMU System Emulator block driver
3 *
4 * Copyright (c) 2003 Fabrice Bellard
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights

--- 2117 unchanged lines hidden (view full) ---

2126 rwco->nb_sectors, rwco->qiov, 0);
2127 } else {
2128 rwco->ret = bdrv_co_do_writev(rwco->bs, rwco->sector_num,
2129 rwco->nb_sectors, rwco->qiov, 0);
2130 }
2131}
2132
2133/*
2134 * Process a synchronous request using coroutines
2134 * Process a vectored synchronous request using coroutines
2135 */
2135 */
2136static int bdrv_rw_co(BlockDriverState *bs, int64_t sector_num, uint8_t *buf,
2137 int nb_sectors, bool is_write)
2136static int bdrv_rwv_co(BlockDriverState *bs, int64_t sector_num,
2137 QEMUIOVector *qiov, bool is_write)
2138{
2138{
2139 QEMUIOVector qiov;
2140 struct iovec iov = {
2141 .iov_base = (void *)buf,
2142 .iov_len = nb_sectors * BDRV_SECTOR_SIZE,
2143 };
2144 Coroutine *co;
2145 RwCo rwco = {
2146 .bs = bs,
2147 .sector_num = sector_num,
2139 Coroutine *co;
2140 RwCo rwco = {
2141 .bs = bs,
2142 .sector_num = sector_num,
2148 .nb_sectors = nb_sectors,
2149 .qiov = &qiov,
2143 .nb_sectors = qiov->size >> BDRV_SECTOR_BITS,
2144 .qiov = qiov,
2150 .is_write = is_write,
2151 .ret = NOT_DONE,
2152 };
2145 .is_write = is_write,
2146 .ret = NOT_DONE,
2147 };
2148 assert((qiov->size & (BDRV_SECTOR_SIZE - 1)) == 0);
2153
2149
2154 qemu_iovec_init_external(&qiov, &iov, 1);
2155
2156 /**
2157 * In sync call context, when the vcpu is blocked, this throttling timer
2158 * will not fire; so the I/O throttling function has to be disabled here
2159 * if it has been enabled.
2160 */
2161 if (bs->io_limits_enabled) {
2162 fprintf(stderr, "Disabling I/O throttling on '%s' due "
2163 "to synchronous I/O.\n", bdrv_get_device_name(bs));

--- 8 unchanged lines hidden (view full) ---

2172 qemu_coroutine_enter(co, &rwco);
2173 while (rwco.ret == NOT_DONE) {
2174 qemu_aio_wait();
2175 }
2176 }
2177 return rwco.ret;
2178}
2179
2150 /**
2151 * In sync call context, when the vcpu is blocked, this throttling timer
2152 * will not fire; so the I/O throttling function has to be disabled here
2153 * if it has been enabled.
2154 */
2155 if (bs->io_limits_enabled) {
2156 fprintf(stderr, "Disabling I/O throttling on '%s' due "
2157 "to synchronous I/O.\n", bdrv_get_device_name(bs));

--- 8 unchanged lines hidden (view full) ---

2166 qemu_coroutine_enter(co, &rwco);
2167 while (rwco.ret == NOT_DONE) {
2168 qemu_aio_wait();
2169 }
2170 }
2171 return rwco.ret;
2172}
2173
2174/*
2175 * Process a synchronous request using coroutines
2176 */
2177static int bdrv_rw_co(BlockDriverState *bs, int64_t sector_num, uint8_t *buf,
2178 int nb_sectors, bool is_write)
2179{
2180 QEMUIOVector qiov;
2181 struct iovec iov = {
2182 .iov_base = (void *)buf,
2183 .iov_len = nb_sectors * BDRV_SECTOR_SIZE,
2184 };
2185
2186 qemu_iovec_init_external(&qiov, &iov, 1);
2187 return bdrv_rwv_co(bs, sector_num, &qiov, is_write);
2188}
2189
2180/* return < 0 if error. See bdrv_write() for the return codes */
2181int bdrv_read(BlockDriverState *bs, int64_t sector_num,
2182 uint8_t *buf, int nb_sectors)
2183{
2184 return bdrv_rw_co(bs, sector_num, buf, nb_sectors, false);
2185}
2186
2187/* Just like bdrv_read(), but with I/O throttling temporarily disabled */

--- 17 unchanged lines hidden (view full) ---

2205 -EACCES Trying to write a read-only device
2206*/
2207int bdrv_write(BlockDriverState *bs, int64_t sector_num,
2208 const uint8_t *buf, int nb_sectors)
2209{
2210 return bdrv_rw_co(bs, sector_num, (uint8_t *)buf, nb_sectors, true);
2211}
2212
2190/* return < 0 if error. See bdrv_write() for the return codes */
2191int bdrv_read(BlockDriverState *bs, int64_t sector_num,
2192 uint8_t *buf, int nb_sectors)
2193{
2194 return bdrv_rw_co(bs, sector_num, buf, nb_sectors, false);
2195}
2196
2197/* Just like bdrv_read(), but with I/O throttling temporarily disabled */

--- 17 unchanged lines hidden (view full) ---

2215 -EACCES Trying to write a read-only device
2216*/
2217int bdrv_write(BlockDriverState *bs, int64_t sector_num,
2218 const uint8_t *buf, int nb_sectors)
2219{
2220 return bdrv_rw_co(bs, sector_num, (uint8_t *)buf, nb_sectors, true);
2221}
2222
2223int bdrv_writev(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *qiov)
2224{
2225 return bdrv_rwv_co(bs, sector_num, qiov, true);
2226}
2227
2213int bdrv_pread(BlockDriverState *bs, int64_t offset,
2214 void *buf, int count1)
2215{
2216 uint8_t tmp_buf[BDRV_SECTOR_SIZE];
2217 int len, nb_sectors, count;
2218 int64_t sector_num;
2219 int ret;
2220

--- 29 unchanged lines hidden (view full) ---

2250 if (count > 0) {
2251 if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
2252 return ret;
2253 memcpy(buf, tmp_buf, count);
2254 }
2255 return count1;
2256}
2257
2228int bdrv_pread(BlockDriverState *bs, int64_t offset,
2229 void *buf, int count1)
2230{
2231 uint8_t tmp_buf[BDRV_SECTOR_SIZE];
2232 int len, nb_sectors, count;
2233 int64_t sector_num;
2234 int ret;
2235

--- 29 unchanged lines hidden (view full) ---

2265 if (count > 0) {
2266 if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
2267 return ret;
2268 memcpy(buf, tmp_buf, count);
2269 }
2270 return count1;
2271}
2272
2258int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
2259 const void *buf, int count1)
2273int bdrv_pwritev(BlockDriverState *bs, int64_t offset, QEMUIOVector *qiov)
2260{
2261 uint8_t tmp_buf[BDRV_SECTOR_SIZE];
2262 int len, nb_sectors, count;
2263 int64_t sector_num;
2264 int ret;
2265
2274{
2275 uint8_t tmp_buf[BDRV_SECTOR_SIZE];
2276 int len, nb_sectors, count;
2277 int64_t sector_num;
2278 int ret;
2279
2266 count = count1;
2280 count = qiov->size;
2281
2267 /* first write to align to sector start */
2268 len = (BDRV_SECTOR_SIZE - offset) & (BDRV_SECTOR_SIZE - 1);
2269 if (len > count)
2270 len = count;
2271 sector_num = offset >> BDRV_SECTOR_BITS;
2272 if (len > 0) {
2273 if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
2274 return ret;
2282 /* first write to align to sector start */
2283 len = (BDRV_SECTOR_SIZE - offset) & (BDRV_SECTOR_SIZE - 1);
2284 if (len > count)
2285 len = count;
2286 sector_num = offset >> BDRV_SECTOR_BITS;
2287 if (len > 0) {
2288 if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
2289 return ret;
2275 memcpy(tmp_buf + (offset & (BDRV_SECTOR_SIZE - 1)), buf, len);
2290 qemu_iovec_to_buf(qiov, 0, tmp_buf + (offset & (BDRV_SECTOR_SIZE - 1)),
2291 len);
2276 if ((ret = bdrv_write(bs, sector_num, tmp_buf, 1)) < 0)
2277 return ret;
2278 count -= len;
2279 if (count == 0)
2292 if ((ret = bdrv_write(bs, sector_num, tmp_buf, 1)) < 0)
2293 return ret;
2294 count -= len;
2295 if (count == 0)
2280 return count1;
2296 return qiov->size;
2281 sector_num++;
2297 sector_num++;
2282 buf += len;
2283 }
2284
2285 /* write the sectors "in place" */
2286 nb_sectors = count >> BDRV_SECTOR_BITS;
2287 if (nb_sectors > 0) {
2298 }
2299
2300 /* write the sectors "in place" */
2301 nb_sectors = count >> BDRV_SECTOR_BITS;
2302 if (nb_sectors > 0) {
2288 if ((ret = bdrv_write(bs, sector_num, buf, nb_sectors)) < 0)
2303 QEMUIOVector qiov_inplace;
2304
2305 qemu_iovec_init(&qiov_inplace, qiov->niov);
2306 qemu_iovec_concat(&qiov_inplace, qiov, len,
2307 nb_sectors << BDRV_SECTOR_BITS);
2308 ret = bdrv_writev(bs, sector_num, &qiov_inplace);
2309 qemu_iovec_destroy(&qiov_inplace);
2310 if (ret < 0) {
2289 return ret;
2311 return ret;
2312 }
2313
2290 sector_num += nb_sectors;
2291 len = nb_sectors << BDRV_SECTOR_BITS;
2314 sector_num += nb_sectors;
2315 len = nb_sectors << BDRV_SECTOR_BITS;
2292 buf += len;
2293 count -= len;
2294 }
2295
2296 /* add data from the last sector */
2297 if (count > 0) {
2298 if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
2299 return ret;
2316 count -= len;
2317 }
2318
2319 /* add data from the last sector */
2320 if (count > 0) {
2321 if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
2322 return ret;
2300 memcpy(tmp_buf, buf, count);
2323 qemu_iovec_to_buf(qiov, qiov->size - count, tmp_buf, count);
2301 if ((ret = bdrv_write(bs, sector_num, tmp_buf, 1)) < 0)
2302 return ret;
2303 }
2324 if ((ret = bdrv_write(bs, sector_num, tmp_buf, 1)) < 0)
2325 return ret;
2326 }
2304 return count1;
2327 return qiov->size;
2305}
2306
2328}
2329
2330int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
2331 const void *buf, int count1)
2332{
2333 QEMUIOVector qiov;
2334 struct iovec iov = {
2335 .iov_base = (void *) buf,
2336 .iov_len = count1,
2337 };
2338
2339 qemu_iovec_init_external(&qiov, &iov, 1);
2340 return bdrv_pwritev(bs, offset, &qiov);
2341}
2342
2307/*
2308 * Writes to the file and ensures that no writes are reordered across this
2309 * request (acts as a barrier)
2310 *
2311 * Returns 0 on success, -errno in error cases.
2312 */
2313int bdrv_pwrite_sync(BlockDriverState *bs, int64_t offset,
2314 const void *buf, int count)

--- 2484 unchanged lines hidden ---
2343/*
2344 * Writes to the file and ensures that no writes are reordered across this
2345 * request (acts as a barrier)
2346 *
2347 * Returns 0 on success, -errno in error cases.
2348 */
2349int bdrv_pwrite_sync(BlockDriverState *bs, int64_t offset,
2350 const void *buf, int count)

--- 2484 unchanged lines hidden ---