ia64/xen-unstable

view tools/blktap2/drivers/block-aio.c @ 19817:b7f73a7f3078

blktap2: portability fixes for NetBSD

- Use standard off_t and lseek() instead of non-portable off64_t and
lseek64()
- Use uuid API as documented in DCE 1.1 RPC specification
- Add NetBSD implementation for blk_getimagesize() and
blk_getsectorsize()
- Use blk_getimagesize() and blk_getsectorsize()
- Fix uuid header check

Signed-off-by: Christoph Egger <Christoph.Egger@amd.com>
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Tue Jun 23 17:24:14 2009 +0100 (2009-06-23)
parents 1c627434605e
children
line source
1 /*
2 * Copyright (c) 2007, XenSource Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of XenSource Inc. nor the names of its contributors
13 * may be used to endorse or promote products derived from this software
14 * without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
20 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
30 #include <errno.h>
31 #include <libaio.h>
32 #include <fcntl.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <unistd.h>
36 #include <sys/statvfs.h>
37 #include <sys/stat.h>
38 #include <sys/ioctl.h>
40 #include "blk.h"
41 #include "tapdisk.h"
42 #include "tapdisk-driver.h"
43 #include "tapdisk-interface.h"
45 #define MAX_AIO_REQS TAPDISK_DATA_REQUESTS
47 struct tdaio_state;
49 struct aio_request {
50 td_request_t treq;
51 struct tiocb tiocb;
52 struct tdaio_state *state;
53 };
55 struct tdaio_state {
56 int fd;
57 td_driver_t *driver;
59 int aio_free_count;
60 struct aio_request aio_requests[MAX_AIO_REQS];
61 struct aio_request *aio_free_list[MAX_AIO_REQS];
62 };
64 /*Get Image size, secsize*/
65 static int tdaio_get_image_info(int fd, td_disk_info_t *info)
66 {
67 int ret;
68 long size;
69 unsigned long total_size;
70 struct statvfs statBuf;
71 struct stat stat;
73 ret = fstat(fd, &stat);
74 if (ret != 0) {
75 DPRINTF("ERROR: fstat failed, Couldn't stat image");
76 return -EINVAL;
77 }
79 if (S_ISBLK(stat.st_mode)) {
80 /*Accessing block device directly*/
81 info->size = 0;
82 if (blk_getimagesize(fd, &info->size) != 0)
83 return -EINVAL;
85 DPRINTF("Image size: \n\tpre sector_shift [%llu]\n\tpost "
86 "sector_shift [%llu]\n",
87 (long long unsigned)(info->size << SECTOR_SHIFT),
88 (long long unsigned)info->size);
90 /*Get the sector size*/
91 if (blk_getsectorsize(fd, &info->sector_size) != 0)
92 info->sector_size = DEFAULT_SECTOR_SIZE;
94 } else {
95 /*Local file? try fstat instead*/
96 info->size = (stat.st_size >> SECTOR_SHIFT);
97 info->sector_size = DEFAULT_SECTOR_SIZE;
98 DPRINTF("Image size: \n\tpre sector_shift [%llu]\n\tpost "
99 "sector_shift [%llu]\n",
100 (long long unsigned)(info->size << SECTOR_SHIFT),
101 (long long unsigned)info->size);
102 }
104 if (info->size == 0) {
105 info->size =((uint64_t) 16836057);
106 info->sector_size = DEFAULT_SECTOR_SIZE;
107 }
108 info->info = 0;
110 return 0;
111 }
113 /* Open the disk file and initialize aio state. */
114 int tdaio_open(td_driver_t *driver, const char *name, td_flag_t flags)
115 {
116 int i, fd, ret, o_flags;
117 struct tdaio_state *prv;
119 ret = 0;
120 prv = (struct tdaio_state *)driver->data;
122 DPRINTF("block-aio open('%s')", name);
124 memset(prv, 0, sizeof(struct tdaio_state));
126 prv->aio_free_count = MAX_AIO_REQS;
127 for (i = 0; i < MAX_AIO_REQS; i++)
128 prv->aio_free_list[i] = &prv->aio_requests[i];
130 /* Open the file */
131 o_flags = O_DIRECT | O_LARGEFILE |
132 ((flags & TD_OPEN_RDONLY) ? O_RDONLY : O_RDWR);
133 fd = open(name, o_flags);
135 if ( (fd == -1) && (errno == EINVAL) ) {
137 /* Maybe O_DIRECT isn't supported. */
138 o_flags &= ~O_DIRECT;
139 fd = open(name, o_flags);
140 if (fd != -1) DPRINTF("WARNING: Accessing image without"
141 "O_DIRECT! (%s)\n", name);
143 } else if (fd != -1) DPRINTF("open(%s) with O_DIRECT\n", name);
145 if (fd == -1) {
146 DPRINTF("Unable to open [%s] (%d)!\n", name, 0 - errno);
147 ret = 0 - errno;
148 goto done;
149 }
151 ret = tdaio_get_image_info(fd, &driver->info);
152 if (ret) {
153 close(fd);
154 goto done;
155 }
157 prv->fd = fd;
159 done:
160 return ret;
161 }
163 void tdaio_complete(void *arg, struct tiocb *tiocb, int err)
164 {
165 struct aio_request *aio = (struct aio_request *)arg;
166 struct tdaio_state *prv = aio->state;
168 td_complete_request(aio->treq, err);
169 prv->aio_free_list[prv->aio_free_count++] = aio;
170 }
172 void tdaio_queue_read(td_driver_t *driver, td_request_t treq)
173 {
174 int size;
175 uint64_t offset;
176 struct aio_request *aio;
177 struct tdaio_state *prv;
179 prv = (struct tdaio_state *)driver->data;
180 size = treq.secs * driver->info.sector_size;
181 offset = treq.sec * (uint64_t)driver->info.sector_size;
183 if (prv->aio_free_count == 0)
184 goto fail;
186 aio = prv->aio_free_list[--prv->aio_free_count];
187 aio->treq = treq;
188 aio->state = prv;
190 td_prep_read(&aio->tiocb, prv->fd, treq.buf,
191 size, offset, tdaio_complete, aio);
192 td_queue_tiocb(driver, &aio->tiocb);
194 return;
196 fail:
197 td_complete_request(treq, -EBUSY);
198 }
200 void tdaio_queue_write(td_driver_t *driver, td_request_t treq)
201 {
202 int size;
203 uint64_t offset;
204 struct aio_request *aio;
205 struct tdaio_state *prv;
207 prv = (struct tdaio_state *)driver->data;
208 size = treq.secs * driver->info.sector_size;
209 offset = treq.sec * (uint64_t)driver->info.sector_size;
211 if (prv->aio_free_count == 0)
212 goto fail;
214 aio = prv->aio_free_list[--prv->aio_free_count];
215 aio->treq = treq;
216 aio->state = prv;
218 td_prep_write(&aio->tiocb, prv->fd, treq.buf,
219 size, offset, tdaio_complete, aio);
220 td_queue_tiocb(driver, &aio->tiocb);
222 return;
224 fail:
225 td_complete_request(treq, -EBUSY);
226 }
228 int tdaio_close(td_driver_t *driver)
229 {
230 struct tdaio_state *prv = (struct tdaio_state *)driver->data;
232 close(prv->fd);
234 return 0;
235 }
237 int tdaio_get_parent_id(td_driver_t *driver, td_disk_id_t *id)
238 {
239 return TD_NO_PARENT;
240 }
242 int tdaio_validate_parent(td_driver_t *driver,
243 td_driver_t *pdriver, td_flag_t flags)
244 {
245 return -EINVAL;
246 }
248 struct tap_disk tapdisk_aio = {
249 .disk_type = "tapdisk_aio",
250 .flags = 0,
251 .private_data_size = sizeof(struct tdaio_state),
252 .td_open = tdaio_open,
253 .td_close = tdaio_close,
254 .td_queue_read = tdaio_queue_read,
255 .td_queue_write = tdaio_queue_write,
256 .td_get_parent_id = tdaio_get_parent_id,
257 .td_validate_parent = tdaio_validate_parent,
258 .td_debug = NULL,
259 };