Revision 6dd2db52

b/block-raw-posix.c
77 77
typedef struct BDRVRawState {
78 78
    int fd;
79 79
    int type;
80
    int open_flags;
81 80
    unsigned int lseek_err_cnt;
82 81
#if defined(__linux__)
83 82
    /* 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;
115 114
    s->type = FTYPE_FILE;
116 115

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

  
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,
144
static int raw_pread(BlockDriverState *bs, int64_t offset,
153 145
                     uint8_t *buf, int count)
154 146
{
155 147
    BDRVRawState *s = bs->opaque;
......
202 194
    return ret;
203 195
}
204 196

  
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,
197
static int raw_pwrite(BlockDriverState *bs, int64_t offset,
213 198
                      const uint8_t *buf, int count)
214 199
{
215 200
    BDRVRawState *s = bs->opaque;
......
245 230
    return ret;
246 231
}
247 232

  
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

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

  
......
478 402
        BlockDriverCompletionFunc *cb, void *opaque)
479 403
{
480 404
    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
    }
496 405

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

  
501 409
    if (aio_read(&acb->aiocb) < 0) {
502 410
        qemu_aio_release(acb);
503 411
        return NULL;
......
510 418
        BlockDriverCompletionFunc *cb, void *opaque)
511 419
{
512 420
    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
    }
528 421

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

Also available in: Unified diff