Revision adcbebaa

b/block-raw-posix.c
77 77
typedef struct BDRVRawState {
78 78
    int fd;
79 79
    int type;
80
    int open_flags;
80 81
    unsigned int lseek_err_cnt;
81 82
#if defined(__linux__)
82 83
    /* linux floppy specific */
83
    int fd_open_flags;
84 84
    int64_t fd_open_time;
85 85
    int64_t fd_error_time;
86 86
    int fd_got_error;
......
111 111
        open_flags |= O_DIRECT;
112 112
#endif
113 113

  
114
    s->open_flags = open_flags;
114 115
    s->type = FTYPE_FILE;
115 116

  
116 117
    fd = open(filename, open_flags, 0644);
......
141 142
#endif
142 143
*/
143 144

  
144
static int raw_pread(BlockDriverState *bs, int64_t offset,
145
/* 
146
 * offset and count are in bytes, but must be multiples of 512 for files 
147
 * opened with O_DIRECT. buf must be aligned to 512 bytes then.
148
 *
149
 * This function may be called without alignment if the caller ensures
150
 * that O_DIRECT is not in effect.
151
 */
152
static int raw_pread_aligned(BlockDriverState *bs, int64_t offset,
145 153
                     uint8_t *buf, int count)
146 154
{
147 155
    BDRVRawState *s = bs->opaque;
......
194 202
    return ret;
195 203
}
196 204

  
197
static int raw_pwrite(BlockDriverState *bs, int64_t offset,
205
/* 
206
 * offset and count are in bytes, but must be multiples of 512 for files 
207
 * opened with O_DIRECT. buf must be aligned to 512 bytes then.
208
 *
209
 * This function may be called without alignment if the caller ensures
210
 * that O_DIRECT is not in effect.
211
 */
212
static int raw_pwrite_aligned(BlockDriverState *bs, int64_t offset,
198 213
                      const uint8_t *buf, int count)
199 214
{
200 215
    BDRVRawState *s = bs->opaque;
......
230 245
    return ret;
231 246
}
232 247

  
248

  
249
#ifdef O_DIRECT
250
/* 
251
 * offset and count are in bytes and possibly not aligned. For files opened 
252
 * with O_DIRECT, necessary alignments are ensured before calling 
253
 * raw_pread_aligned to do the actual read.
254
 */
255
static int raw_pread(BlockDriverState *bs, int64_t offset,
256
                     uint8_t *buf, int count)
257
{
258
    BDRVRawState *s = bs->opaque;
259

  
260
    if (unlikely((s->open_flags & O_DIRECT) &&
261
            (offset % 512 || count % 512 || (uintptr_t) buf % 512))) {
262

  
263
        int ret;
264

  
265
        // Temporarily disable O_DIRECT for unaligned access
266
        fcntl(s->fd, F_SETFL, s->open_flags & ~O_DIRECT);
267
        ret = raw_pread_aligned(bs, offset, buf, count);
268
        fcntl(s->fd, F_SETFL, s->open_flags);
269

  
270
        return ret;
271

  
272
    } else {
273
        return raw_pread_aligned(bs, offset, buf, count);
274
    }
275
}
276

  
277
/* 
278
 * offset and count are in bytes and possibly not aligned. For files opened 
279
 * with O_DIRECT, necessary alignments are ensured before calling 
280
 * raw_pwrite_aligned to do the actual write.
281
 */
282
static int raw_pwrite(BlockDriverState *bs, int64_t offset,
283
                      const uint8_t *buf, int count)
284
{
285
    BDRVRawState *s = bs->opaque;
286

  
287
    if (unlikely((s->open_flags & O_DIRECT) &&
288
            (offset % 512 || count % 512 || (uintptr_t) buf % 512))) {
289

  
290
        int ret;
291

  
292
        // Temporarily disable O_DIRECT for unaligned access
293
        fcntl(s->fd, F_SETFL, s->open_flags & ~O_DIRECT);
294
        ret = raw_pwrite_aligned(bs, offset, buf, count);
295
        fcntl(s->fd, F_SETFL, s->open_flags);
296

  
297
        return ret;
298
    } else {
299
        return raw_pwrite_aligned(bs, offset, buf, count);
300
    }
301
}
302

  
303
#else
304
#define raw_pread raw_pread_aligned
305
#define raw_pwrite raw_pwrite_aligned
306
#endif
307

  
308

  
233 309
/***********************************************************/
234 310
/* Unix AIO using POSIX AIO */
235 311

  
......
402 478
        BlockDriverCompletionFunc *cb, void *opaque)
403 479
{
404 480
    RawAIOCB *acb;
481
    BDRVRawState *s = bs->opaque;
482

  
483
    /* 
484
     * If O_DIRECT is used and the buffer is not aligned fall back
485
     * to synchronous IO.
486
     */
487
    if (unlikely((s->open_flags & O_DIRECT) && ((uintptr_t) buf % 512))) {
488
        int ret;
489

  
490
        acb = qemu_aio_get(bs, cb, opaque);
491
        ret = raw_pread(bs, 512 * sector_num, buf, 512 * nb_sectors);
492
        acb->common.cb(acb->common.opaque, ret);
493
        qemu_aio_release(acb);
494
        return &acb->common;
495
    }
405 496

  
406 497
    acb = raw_aio_setup(bs, sector_num, buf, nb_sectors, cb, opaque);
407 498
    if (!acb)
408 499
        return NULL;
500

  
409 501
    if (aio_read(&acb->aiocb) < 0) {
410 502
        qemu_aio_release(acb);
411 503
        return NULL;
......
418 510
        BlockDriverCompletionFunc *cb, void *opaque)
419 511
{
420 512
    RawAIOCB *acb;
513
    BDRVRawState *s = bs->opaque;
514

  
515
    /* 
516
     * If O_DIRECT is used and the buffer is not aligned fall back
517
     * to synchronous IO.
518
     */
519
    if (unlikely((s->open_flags & O_DIRECT) && ((uintptr_t) buf % 512))) {
520
        int ret;
521

  
522
        acb = qemu_aio_get(bs, cb, opaque);
523
        ret = raw_pwrite(bs, 512 * sector_num, buf, 512 * nb_sectors);
524
        acb->common.cb(acb->common.opaque, ret);
525
        qemu_aio_release(acb);
526
        return &acb->common;
527
    }
421 528

  
422 529
    acb = raw_aio_setup(bs, sector_num, (uint8_t*)buf, nb_sectors, cb, opaque);
423 530
    if (!acb)
......
679 786
        s->type = FTYPE_CD;
680 787
    } else if (strstart(filename, "/dev/fd", NULL)) {
681 788
        s->type = FTYPE_FD;
682
        s->fd_open_flags = open_flags;
789
        s->open_flags = open_flags;
683 790
        /* open will not fail even if no floppy is inserted */
684 791
        open_flags |= O_NONBLOCK;
685 792
    } else if (strstart(filename, "/dev/sg", NULL)) {
......
734 841
#endif
735 842
            return -EIO;
736 843
        }
737
        s->fd = open(bs->filename, s->fd_open_flags);
844
        s->fd = open(bs->filename, s->open_flags);
738 845
        if (s->fd < 0) {
739 846
            s->fd_error_time = qemu_get_clock(rt_clock);
740 847
            s->fd_got_error = 1;
......
831 938
                close(s->fd);
832 939
                s->fd = -1;
833 940
            }
834
            fd = open(bs->filename, s->fd_open_flags | O_NONBLOCK);
941
            fd = open(bs->filename, s->open_flags | O_NONBLOCK);
835 942
            if (fd >= 0) {
836 943
                if (ioctl(fd, FDEJECT, 0) < 0)
837 944
                    perror("FDEJECT");

Also available in: Unified diff