Revision 221f715d

b/block-raw-posix.c
1209 1209

  
1210 1210
    return ioctl(s->fd, req, buf);
1211 1211
}
1212

  
1213
static BlockDriverAIOCB *raw_aio_ioctl(BlockDriverState *bs,
1214
        unsigned long int req, void *buf,
1215
        BlockDriverCompletionFunc *cb, void *opaque)
1216
{
1217
    RawAIOCB *acb;
1218

  
1219
    acb = raw_aio_setup(bs, 0, buf, 0, cb, opaque);
1220
    if (!acb)
1221
        return NULL;
1222

  
1223
    acb->aiocb.aio_ioctl_cmd = req;
1224
    if (qemu_paio_ioctl(&acb->aiocb) < 0) {
1225
        raw_aio_remove(acb);
1226
        return NULL;
1227
    }
1228

  
1229
    return &acb->common;
1230
}
1231

  
1212 1232
#elif defined(__FreeBSD__)
1213 1233

  
1214 1234
static int fd_open(BlockDriverState *bs)
......
1349 1369
{
1350 1370
    return -ENOTSUP;
1351 1371
}
1352
#endif /* !linux && !FreeBSD */
1353

  
1354
static int raw_sg_send_command(BlockDriverState *bs, void *buf, int count)
1355
{
1356
    return raw_pwrite(bs, -1, buf, count);
1357
}
1358

  
1359
static int raw_sg_recv_response(BlockDriverState *bs, void *buf, int count)
1360
{
1361
    return raw_pread(bs, -1, buf, count);
1362
}
1363

  
1364
static BlockDriverAIOCB *raw_sg_aio_read(BlockDriverState *bs,
1365
                                         void *buf, int count,
1366
                                         BlockDriverCompletionFunc *cb,
1367
                                         void *opaque)
1368
{
1369
    return raw_aio_read(bs, 0, buf, -(int64_t)count, cb, opaque);
1370
}
1371 1372

  
1372
static BlockDriverAIOCB *raw_sg_aio_write(BlockDriverState *bs,
1373
                                          void *buf, int count,
1374
                                          BlockDriverCompletionFunc *cb,
1375
                                          void *opaque)
1373
static BlockDriverAIOCB *raw_aio_ioctl(BlockDriverState *bs,
1374
        unsigned long int req, void *buf,
1375
        BlockDriverCompletionFunc *cb, void *opaque)
1376 1376
{
1377
    return raw_aio_write(bs, 0, buf, -(int64_t)count, cb, opaque);
1377
    return -ENOTSUP;
1378 1378
}
1379
#endif /* !linux && !FreeBSD */
1379 1380

  
1380 1381
BlockDriver bdrv_host_device = {
1381 1382
    .format_name	= "host_device",
......
1402 1403
    .bdrv_set_locked	= raw_set_locked,
1403 1404
    /* generic scsi device */
1404 1405
    .bdrv_ioctl		= raw_ioctl,
1405
    .bdrv_sg_send_command  = raw_sg_send_command,
1406
    .bdrv_sg_recv_response = raw_sg_recv_response,
1407
    .bdrv_sg_aio_read      = raw_sg_aio_read,
1408
    .bdrv_sg_aio_write     = raw_sg_aio_write,
1406
    .bdrv_aio_ioctl	= raw_aio_ioctl,
1409 1407
};
b/block.c
1633 1633
    return -ENOTSUP;
1634 1634
}
1635 1635

  
1636
int bdrv_sg_send_command(BlockDriverState *bs, void *buf, int count)
1637
{
1638
    return bs->drv->bdrv_sg_send_command(bs, buf, count);
1639
}
1640

  
1641
int bdrv_sg_recv_response(BlockDriverState *bs, void *buf, int count)
1642
{
1643
    return bs->drv->bdrv_sg_recv_response(bs, buf, count);
1644
}
1645

  
1646
BlockDriverAIOCB *bdrv_sg_aio_read(BlockDriverState *bs, void *buf, int count,
1647
                                   BlockDriverCompletionFunc *cb, void *opaque)
1636
BlockDriverAIOCB *bdrv_aio_ioctl(BlockDriverState *bs,
1637
        unsigned long int req, void *buf,
1638
        BlockDriverCompletionFunc *cb, void *opaque)
1648 1639
{
1649
    return bs->drv->bdrv_sg_aio_read(bs, buf, count, cb, opaque);
1650
}
1640
    BlockDriver *drv = bs->drv;
1651 1641

  
1652
BlockDriverAIOCB *bdrv_sg_aio_write(BlockDriverState *bs, void *buf, int count,
1653
                                    BlockDriverCompletionFunc *cb, void *opaque)
1654
{
1655
    return bs->drv->bdrv_sg_aio_write(bs, buf, count, cb, opaque);
1642
    if (drv && drv->bdrv_aio_ioctl)
1643
        return drv->bdrv_aio_ioctl(bs, req, buf, cb, opaque);
1644
    return NULL;
1656 1645
}
b/block.h
102 102
void bdrv_aio_cancel(BlockDriverAIOCB *acb);
103 103

  
104 104
/* sg packet commands */
105
int bdrv_sg_send_command(BlockDriverState *bs, void *buf, int count);
106
int bdrv_sg_recv_response(BlockDriverState *bs, void *buf, int count);
107
BlockDriverAIOCB *bdrv_sg_aio_read(BlockDriverState *bs, void *buf, int count,
108
                                   BlockDriverCompletionFunc *cb, void *opaque);
109
BlockDriverAIOCB *bdrv_sg_aio_write(BlockDriverState *bs, void *buf, int count,
110
                                    BlockDriverCompletionFunc *cb, void *opaque);
105
int bdrv_ioctl(BlockDriverState *bs, unsigned long int req, void *buf);
106
BlockDriverAIOCB *bdrv_aio_ioctl(BlockDriverState *bs,
107
        unsigned long int req, void *buf,
108
        BlockDriverCompletionFunc *cb, void *opaque);
111 109

  
112 110
/* Ensure contents are flushed to disk.  */
113 111
void bdrv_flush(BlockDriverState *bs);
......
169 167
int bdrv_snapshot_list(BlockDriverState *bs,
170 168
                       QEMUSnapshotInfo **psn_info);
171 169
char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn);
172
int bdrv_ioctl(BlockDriverState *bs, unsigned long int req, void *buf);
173 170

  
174 171
char *get_human_readable_size(char *buf, int buf_size, int64_t size);
175 172
int path_is_absolute(const char *path);
b/block_int.h
86 86

  
87 87
    /* to control generic scsi devices */
88 88
    int (*bdrv_ioctl)(BlockDriverState *bs, unsigned long int req, void *buf);
89
    int (*bdrv_sg_send_command)(BlockDriverState *bs, void *buf, int count);
90
    int (*bdrv_sg_recv_response)(BlockDriverState *bs, void *buf, int count);
91
    BlockDriverAIOCB *(*bdrv_sg_aio_read)(BlockDriverState *bs,
92
                                          void *buf, int count,
93
                                          BlockDriverCompletionFunc *cb,
94
                                          void *opaque);
95
    BlockDriverAIOCB *(*bdrv_sg_aio_write)(BlockDriverState *bs,
96
                                           void *buf, int count,
97
                                           BlockDriverCompletionFunc *cb,
98
                                           void *opaque);
89
    BlockDriverAIOCB *(*bdrv_aio_ioctl)(BlockDriverState *bs,
90
        unsigned long int req, void *buf,
91
        BlockDriverCompletionFunc *cb, void *opaque);
99 92

  
100 93
    AIOPool aio_pool;
101 94
    struct BlockDriver *next;
b/hw/scsi-generic.c
201 201
                           SCSIRequest *r, int direction,
202 202
			   BlockDriverCompletionFunc *complete)
203 203
{
204
    int ret;
205

  
206 204
    r->io_header.interface_id = 'S';
207 205
    r->io_header.dxfer_direction = direction;
208 206
    r->io_header.dxferp = r->buf;
......
215 213
    r->io_header.usr_ptr = r;
216 214
    r->io_header.flags |= SG_FLAG_DIRECT_IO;
217 215

  
218
    ret = bdrv_sg_send_command(bdrv, &r->io_header, sizeof(r->io_header));
219
    if (ret < 0) {
220
        BADF("execute_command: write failed ! (%d)\n", errno);
221
        return -1;
222
    }
223
    if (complete == NULL) {
224
        int ret;
225
        r->aiocb = NULL;
226
        while ((ret = bdrv_sg_recv_response(bdrv, &r->io_header,
227
                                            sizeof(r->io_header))) < 0 &&
228
               ret == -EINTR)
229
            ;
230
        if (ret < 0) {
231
            BADF("execute_command: read failed !\n");
232
            return -1;
233
        }
234
        return 0;
235
    }
236

  
237
    r->aiocb = bdrv_sg_aio_read(bdrv, (uint8_t*)&r->io_header,
238
                                sizeof(r->io_header), complete, r);
216
    r->aiocb = bdrv_aio_ioctl(bdrv, SG_IO, &r->io_header, complete, r);
239 217
    if (r->aiocb == NULL) {
240 218
        BADF("execute_command: read failed !\n");
241 219
        return -1;
......
637 615
    io_header.sbp = sensebuf;
638 616
    io_header.timeout = 6000; /* XXX */
639 617

  
640
    ret = bdrv_sg_send_command(bdrv, &io_header, sizeof(io_header));
641
    if (ret < 0)
642
        return -1;
643

  
644
    while ((ret = bdrv_sg_recv_response(bdrv, &io_header, sizeof(io_header))) < 0 &&
645
           ret == -EINTR)
646
        ;
647

  
618
    ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
648 619
    if (ret < 0)
649 620
        return -1;
650 621

  
......
675 646
    io_header.sbp = sensebuf;
676 647
    io_header.timeout = 6000; /* XXX */
677 648

  
678
    ret = bdrv_sg_send_command(bdrv, &io_header, sizeof(io_header));
679
    if (ret < 0)
680
        return -1;
681

  
682
    while ((ret = bdrv_sg_recv_response(bdrv, &io_header, sizeof(io_header))) < 0 &&
683
           ret == -EINTR)
684
        ;
685

  
649
    ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
686 650
    if (ret < 0)
687 651
        return -1;
688 652

  
b/posix-aio-compat.c
11 11
 *
12 12
 */
13 13

  
14
#include <sys/ioctl.h>
14 15
#include <pthread.h>
15 16
#include <unistd.h>
16 17
#include <errno.h>
......
75 76
    if (ret) die2(ret, "pthread_create");
76 77
}
77 78

  
79
static size_t handle_aiocb_readwrite(struct qemu_paiocb *aiocb)
80
{
81
    size_t offset = 0;
82
    ssize_t len;
83

  
84
    while (offset < aiocb->aio_nbytes) {
85
        if (aiocb->aio_type == QEMU_PAIO_WRITE)
86
            len = pwrite(aiocb->aio_fildes,
87
                         (const char *)aiocb->aio_buf + offset,
88
                         aiocb->aio_nbytes - offset,
89
                         aiocb->aio_offset + offset);
90
        else
91
            len = pread(aiocb->aio_fildes,
92
                        (char *)aiocb->aio_buf + offset,
93
                        aiocb->aio_nbytes - offset,
94
                        aiocb->aio_offset + offset);
95

  
96
        if (len == -1 && errno == EINTR)
97
            continue;
98
        else if (len == -1) {
99
            offset = -errno;
100
            break;
101
        } else if (len == 0)
102
            break;
103

  
104
        offset += len;
105
    }
106

  
107
    return offset;
108
}
109

  
110
static size_t handle_aiocb_ioctl(struct qemu_paiocb *aiocb)
111
{
112
	int ret;
113

  
114
	ret = ioctl(aiocb->aio_fildes, aiocb->aio_ioctl_cmd, aiocb->aio_buf);
115
	if (ret == -1)
116
		return -errno;
117
	return ret;
118
}
119

  
78 120
static void *aio_thread(void *unused)
79 121
{
80 122
    pid_t pid;
......
88 130

  
89 131
    while (1) {
90 132
        struct qemu_paiocb *aiocb;
91
        size_t offset;
92
        int ret = 0;
133
        size_t ret = 0;
93 134
        qemu_timeval tv;
94 135
        struct timespec ts;
95 136

  
......
109 150

  
110 151
        aiocb = TAILQ_FIRST(&request_list);
111 152
        TAILQ_REMOVE(&request_list, aiocb, node);
112

  
113
        offset = 0;
114 153
        aiocb->active = 1;
115

  
116 154
        idle_threads--;
117 155
        mutex_unlock(&lock);
118 156

  
119
        while (offset < aiocb->aio_nbytes) {
120
            ssize_t len;
121

  
122
            if (aiocb->is_write)
123
                len = pwrite(aiocb->aio_fildes,
124
                             (const char *)aiocb->aio_buf + offset,
125
                             aiocb->aio_nbytes - offset,
126
                             aiocb->aio_offset + offset);
127
            else
128
                len = pread(aiocb->aio_fildes,
129
                            (char *)aiocb->aio_buf + offset,
130
                            aiocb->aio_nbytes - offset,
131
                            aiocb->aio_offset + offset);
132

  
133
            if (len == -1 && errno == EINTR)
134
                continue;
135
            else if (len == -1) {
136
                offset = -errno;
137
                break;
138
            } else if (len == 0)
139
                break;
140

  
141
            offset += len;
142
        }
157
        switch (aiocb->aio_type) {
158
        case QEMU_PAIO_READ:
159
        case QEMU_PAIO_WRITE:
160
		ret = handle_aiocb_readwrite(aiocb);
161
		break;
162
        case QEMU_PAIO_IOCTL:
163
		ret = handle_aiocb_ioctl(aiocb);
164
		break;
165
	default:
166
		fprintf(stderr, "invalid aio request (0x%x)\n", aiocb->aio_type);
167
		ret = -EINVAL;
168
		break;
169
	}
143 170

  
144 171
        mutex_lock(&lock);
145
        aiocb->ret = offset;
172
        aiocb->ret = ret;
146 173
        idle_threads++;
147 174
        mutex_unlock(&lock);
148 175

  
......
178 205
    return 0;
179 206
}
180 207

  
181
static int qemu_paio_submit(struct qemu_paiocb *aiocb, int is_write)
208
static int qemu_paio_submit(struct qemu_paiocb *aiocb, int type)
182 209
{
183
    aiocb->is_write = is_write;
210
    aiocb->aio_type = type;
184 211
    aiocb->ret = -EINPROGRESS;
185 212
    aiocb->active = 0;
186 213
    mutex_lock(&lock);
......
195 222

  
196 223
int qemu_paio_read(struct qemu_paiocb *aiocb)
197 224
{
198
    return qemu_paio_submit(aiocb, 0);
225
    return qemu_paio_submit(aiocb, QEMU_PAIO_READ);
199 226
}
200 227

  
201 228
int qemu_paio_write(struct qemu_paiocb *aiocb)
202 229
{
203
    return qemu_paio_submit(aiocb, 1);
230
    return qemu_paio_submit(aiocb, QEMU_PAIO_WRITE);
231
}
232

  
233
int qemu_paio_ioctl(struct qemu_paiocb *aiocb)
234
{
235
    return qemu_paio_submit(aiocb, QEMU_PAIO_IOCTL);
204 236
}
205 237

  
206 238
ssize_t qemu_paio_return(struct qemu_paiocb *aiocb)
b/posix-aio-compat.h
29 29
    int aio_fildes;
30 30
    void *aio_buf;
31 31
    size_t aio_nbytes;
32
#define aio_ioctl_cmd   aio_nbytes /* for QEMU_PAIO_IOCTL */
32 33
    int ev_signo;
33 34
    off_t aio_offset;
34 35

  
35 36
    /* private */
36 37
    TAILQ_ENTRY(qemu_paiocb) node;
37
    int is_write;
38
    int aio_type;
39
#define QEMU_PAIO_READ         0x01
40
#define QEMU_PAIO_WRITE        0x02
41
#define QEMU_PAIO_IOCTL        0x03
38 42
    ssize_t ret;
39 43
    int active;
40 44
};
......
49 53
int qemu_paio_init(struct qemu_paioinit *aioinit);
50 54
int qemu_paio_read(struct qemu_paiocb *aiocb);
51 55
int qemu_paio_write(struct qemu_paiocb *aiocb);
56
int qemu_paio_ioctl(struct qemu_paiocb *aiocb);
52 57
int qemu_paio_error(struct qemu_paiocb *aiocb);
53 58
ssize_t qemu_paio_return(struct qemu_paiocb *aiocb);
54 59
int qemu_paio_cancel(int fd, struct qemu_paiocb *aiocb);

Also available in: Unified diff