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 --- |