aio.c (304:80feb3217668) | aio.c (1885:7bbaa5935f99) |
---|---|
1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the | 1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the |
5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. | 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. |
8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ | 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ |
21 |
|
22/* | 22/* |
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. | 23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. |
24 * Use is subject to license terms. 25 */ 26 27#pragma ident "%Z%%M% %I% %E% SMI" 28 29/* 30 * Kernel asynchronous I/O. 31 * This is only for raw devices now (as of Nov. 1993). --- 34 unchanged lines hidden (view full) --- 66#define AIO_64 0 67#define AIO_32 1 68#define AIO_LARGEFILE 2 69 70/* 71 * implementation specific functions (private) 72 */ 73#ifdef _LP64 | 24 * Use is subject to license terms. 25 */ 26 27#pragma ident "%Z%%M% %I% %E% SMI" 28 29/* 30 * Kernel asynchronous I/O. 31 * This is only for raw devices now (as of Nov. 1993). --- 34 unchanged lines hidden (view full) --- 66#define AIO_64 0 67#define AIO_32 1 68#define AIO_LARGEFILE 2 69 70/* 71 * implementation specific functions (private) 72 */ 73#ifdef _LP64 |
74static int alio(int, int, aiocb_t **, int, struct sigevent *); | 74static int alio(int, aiocb_t **, int, struct sigevent *); |
75#endif 76static int aionotify(void); 77static int aioinit(void); 78static int aiostart(void); 79static void alio_cleanup(aio_t *, aiocb_t **, int, int); 80static int (*check_vp(struct vnode *, int))(vnode_t *, struct aio_req *, 81 cred_t *); 82static void lio_set_error(aio_req_t *); 83static aio_t *aio_aiop_alloc(); 84static int aio_req_alloc(aio_req_t **, aio_result_t *); 85static int aio_lio_alloc(aio_lio_t **); 86static aio_req_t *aio_req_done(void *); 87static aio_req_t *aio_req_remove(aio_req_t *); 88static int aio_req_find(aio_result_t *, aio_req_t **); 89static int aio_hash_insert(struct aio_req_t *, aio_t *); 90static int aio_req_setup(aio_req_t **, aio_t *, aiocb_t *, | 75#endif 76static int aionotify(void); 77static int aioinit(void); 78static int aiostart(void); 79static void alio_cleanup(aio_t *, aiocb_t **, int, int); 80static int (*check_vp(struct vnode *, int))(vnode_t *, struct aio_req *, 81 cred_t *); 82static void lio_set_error(aio_req_t *); 83static aio_t *aio_aiop_alloc(); 84static int aio_req_alloc(aio_req_t **, aio_result_t *); 85static int aio_lio_alloc(aio_lio_t **); 86static aio_req_t *aio_req_done(void *); 87static aio_req_t *aio_req_remove(aio_req_t *); 88static int aio_req_find(aio_result_t *, aio_req_t **); 89static int aio_hash_insert(struct aio_req_t *, aio_t *); 90static int aio_req_setup(aio_req_t **, aio_t *, aiocb_t *, |
91 aio_result_t *, int, vnode_t *); | 91 aio_result_t *, vnode_t *); |
92static int aio_cleanup_thread(aio_t *); 93static aio_lio_t *aio_list_get(aio_result_t *); 94static void lio_set_uerror(void *, int); 95extern void aio_zerolen(aio_req_t *); 96static int aiowait(struct timeval *, int, long *); 97static int aiowaitn(void *, uint_t, uint_t *, timespec_t *); 98static int aio_unlock_requests(caddr_t iocblist, int iocb_index, 99 aio_req_t *reqlist, aio_t *aiop, model_t model); 100static int aio_reqlist_concat(aio_t *aiop, aio_req_t **reqlist, int max); 101static int aiosuspend(void *, int, struct timespec *, int, 102 long *, int); 103static int aliowait(int, void *, int, void *, int); 104static int aioerror(void *, int); 105static int aio_cancel(int, void *, long *, int); 106static int arw(int, int, char *, int, offset_t, aio_result_t *, int); 107static int aiorw(int, void *, int, int); 108 109static int alioLF(int, void *, int, void *); | 92static int aio_cleanup_thread(aio_t *); 93static aio_lio_t *aio_list_get(aio_result_t *); 94static void lio_set_uerror(void *, int); 95extern void aio_zerolen(aio_req_t *); 96static int aiowait(struct timeval *, int, long *); 97static int aiowaitn(void *, uint_t, uint_t *, timespec_t *); 98static int aio_unlock_requests(caddr_t iocblist, int iocb_index, 99 aio_req_t *reqlist, aio_t *aiop, model_t model); 100static int aio_reqlist_concat(aio_t *aiop, aio_req_t **reqlist, int max); 101static int aiosuspend(void *, int, struct timespec *, int, 102 long *, int); 103static int aliowait(int, void *, int, void *, int); 104static int aioerror(void *, int); 105static int aio_cancel(int, void *, long *, int); 106static int arw(int, int, char *, int, offset_t, aio_result_t *, int); 107static int aiorw(int, void *, int, int); 108 109static int alioLF(int, void *, int, void *); |
110static int aio_req_setupLF(aio_req_t **, aio_t *, 111 aiocb64_32_t *, aio_result_t *, int, vnode_t *); | 110static int aio_req_setupLF(aio_req_t **, aio_t *, aiocb64_32_t *, 111 aio_result_t *, vnode_t *); |
112static int alio32(int, void *, int, void *); 113static int driver_aio_write(vnode_t *vp, struct aio_req *aio, cred_t *cred_p); 114static int driver_aio_read(vnode_t *vp, struct aio_req *aio, cred_t *cred_p); 115 116#ifdef _SYSCALL32_IMPL 117static void aiocb_LFton(aiocb64_32_t *, aiocb_t *); 118void aiocb_32ton(aiocb32_t *, aiocb_t *); 119#endif /* _SYSCALL32_IMPL */ --- 131 unchanged lines hidden (view full) --- 251 break; 252 case AIOINIT: 253 error = aioinit(); 254 break; 255 case AIOSTART: 256 error = aiostart(); 257 break; 258 case AIOLIO: | 112static int alio32(int, void *, int, void *); 113static int driver_aio_write(vnode_t *vp, struct aio_req *aio, cred_t *cred_p); 114static int driver_aio_read(vnode_t *vp, struct aio_req *aio, cred_t *cred_p); 115 116#ifdef _SYSCALL32_IMPL 117static void aiocb_LFton(aiocb64_32_t *, aiocb_t *); 118void aiocb_32ton(aiocb32_t *, aiocb_t *); 119#endif /* _SYSCALL32_IMPL */ --- 131 unchanged lines hidden (view full) --- 251 break; 252 case AIOINIT: 253 error = aioinit(); 254 break; 255 case AIOSTART: 256 error = aiostart(); 257 break; 258 case AIOLIO: |
259 error = alio((int)a0, (int)a1, (aiocb_t **)a2, (int)a3, | 259 error = alio((int)a1, (aiocb_t **)a2, (int)a3, |
260 (struct sigevent *)a4); 261 break; 262 case AIOLIOWAIT: 263 error = aliowait((int)a1, (void *)a2, (int)a3, 264 (struct sigevent *)a4, AIO_64); 265 break; 266 case AIOSUSPEND: 267 error = aiosuspend((void *)a1, (int)a2, (timespec_t *)a3, --- 886 unchanged lines hidden (view full) --- 1154 * Allocate an event port structure (port_alloc_event()) and store the 1155 * delivered user pointer (portnfy_user) in the portkev_user field of the 1156 * port_kevent_t structure.. 1157 * The aio_req_portkev pointer in the aio_req_t structure was added to identify 1158 * the port association. 1159 */ 1160 1161static int | 260 (struct sigevent *)a4); 261 break; 262 case AIOLIOWAIT: 263 error = aliowait((int)a1, (void *)a2, (int)a3, 264 (struct sigevent *)a4, AIO_64); 265 break; 266 case AIOSUSPEND: 267 error = aiosuspend((void *)a1, (int)a2, (timespec_t *)a3, --- 886 unchanged lines hidden (view full) --- 1154 * Allocate an event port structure (port_alloc_event()) and store the 1155 * delivered user pointer (portnfy_user) in the portkev_user field of the 1156 * port_kevent_t structure.. 1157 * The aio_req_portkev pointer in the aio_req_t structure was added to identify 1158 * the port association. 1159 */ 1160 1161static int |
1162aio_req_assoc_port_rw(port_notify_t *pntfy, aiocb_t *cbp, aio_req_t *reqp) | 1162aio_req_assoc_port_rw(port_notify_t *pntfy, aiocb_t *cbp, 1163 aio_req_t *reqp, int event) |
1163{ 1164 port_kevent_t *pkevp = NULL; 1165 int error; 1166 1167 error = port_alloc_event(pntfy->portnfy_port, PORT_ALLOC_DEFAULT, 1168 PORT_SOURCE_AIO, &pkevp); 1169 if (error) { 1170 if ((error == ENOMEM) || (error == EAGAIN)) 1171 error = EAGAIN; 1172 else 1173 error = EINVAL; 1174 } else { 1175 port_init_event(pkevp, (uintptr_t)cbp, pntfy->portnfy_user, 1176 aio_port_callback, reqp); | 1164{ 1165 port_kevent_t *pkevp = NULL; 1166 int error; 1167 1168 error = port_alloc_event(pntfy->portnfy_port, PORT_ALLOC_DEFAULT, 1169 PORT_SOURCE_AIO, &pkevp); 1170 if (error) { 1171 if ((error == ENOMEM) || (error == EAGAIN)) 1172 error = EAGAIN; 1173 else 1174 error = EINVAL; 1175 } else { 1176 port_init_event(pkevp, (uintptr_t)cbp, pntfy->portnfy_user, 1177 aio_port_callback, reqp); |
1178 pkevp->portkev_events = event; |
|
1177 reqp->aio_req_portkev = pkevp; 1178 reqp->aio_req_port = pntfy->portnfy_port; 1179 } 1180 return (error); 1181} 1182 | 1179 reqp->aio_req_portkev = pkevp; 1180 reqp->aio_req_port = pntfy->portnfy_port; 1181 } 1182 return (error); 1183} 1184 |
1183/* 1184 * Associate an aiocb with a port. 1185 * This function is used by lio_listio() to associate a transaction with a port. 1186 * Allocate an event port structure (port_alloc_event()) and store the 1187 * delivered user pointer (portnfy_user) in the portkev_user field of the 1188 * The aio_req_portkev pointer in the aio_req_t structure was added to identify 1189 * the port association. 1190 * The event port notification can be requested attaching the port_notify_t 1191 * structure to the sigevent argument of lio_listio() or attaching the 1192 * port_notify_t structure to the sigevent structure which is embedded in the 1193 * aiocb. 1194 * The attachement to the global sigevent structure is valid for all aiocbs 1195 * in the list. 1196 */ 1197 1198static int 1199aio_req_assoc_port(struct sigevent *sigev, void *user, aiocb_t *cbp, 1200 aio_req_t *reqp, port_kevent_t *pkevtp) 1201{ 1202 port_kevent_t *pkevp = NULL; 1203 port_notify_t pntfy; 1204 int error; 1205 1206 if (sigev->sigev_notify == SIGEV_PORT) { 1207 /* aiocb has an own port notification embedded */ 1208 if (copyin((void *)sigev->sigev_value.sival_ptr, &pntfy, 1209 sizeof (port_notify_t))) 1210 return (EFAULT); 1211 1212 error = port_alloc_event(pntfy.portnfy_port, PORT_ALLOC_DEFAULT, 1213 PORT_SOURCE_AIO, &pkevp); 1214 if (error) { 1215 if ((error == ENOMEM) || (error == EAGAIN)) 1216 return (EAGAIN); 1217 else 1218 return (EINVAL); 1219 } 1220 /* use this values instead of the global values in port */ 1221 1222 port_init_event(pkevp, (uintptr_t)cbp, pntfy.portnfy_user, 1223 aio_port_callback, reqp); 1224 reqp->aio_req_port = pntfy.portnfy_port; 1225 } else { 1226 /* use global port notification */ 1227 error = port_dup_event(pkevtp, &pkevp, PORT_ALLOC_DEFAULT); 1228 if (error) 1229 return (EAGAIN); 1230 port_init_event(pkevp, (uintptr_t)cbp, user, aio_port_callback, 1231 reqp); 1232 } 1233 reqp->aio_req_portkev = pkevp; 1234 return (0); 1235} 1236 1237/* 1238 * Same comments as in aio_req_assoc_port(), see above. 1239 */ 1240 1241static int 1242aio_req_assoc_port32(struct sigevent32 *sigev, void *user, aiocb_t *cbp, 1243 aio_req_t *reqp, port_kevent_t *pkevtp) 1244{ 1245 port_kevent_t *pkevp = NULL; 1246 port_notify32_t pntfy; 1247 int error; 1248 1249 if (sigev->sigev_notify == SIGEV_PORT) { 1250 if (copyin((void *)(uintptr_t)sigev->sigev_value.sival_int, 1251 &pntfy, sizeof (port_notify32_t))) 1252 return (EFAULT); 1253 1254 error = port_alloc_event(pntfy.portnfy_port, 1255 PORT_ALLOC_DEFAULT, PORT_SOURCE_AIO, &pkevp); 1256 if (error) { 1257 if ((error == ENOMEM) || (error == EAGAIN)) 1258 return (EAGAIN); 1259 else 1260 return (EINVAL); 1261 } 1262 /* use this values instead of the global values in port */ 1263 1264 port_init_event(pkevp, (uintptr_t)cbp, 1265 (void *)(uintptr_t)pntfy.portnfy_user, 1266 aio_port_callback, reqp); 1267 reqp->aio_req_port = pntfy.portnfy_port; 1268 } else { 1269 error = port_dup_event(pkevtp, &pkevp, PORT_ALLOC_DEFAULT); 1270 if (error) 1271 return (EAGAIN); 1272 port_init_event(pkevp, (uintptr_t)cbp, user, aio_port_callback, 1273 reqp); 1274 } 1275 reqp->aio_req_portkev = pkevp; 1276 return (0); 1277} 1278 1279 | |
1280#ifdef _LP64 1281 1282/* 1283 * Asynchronous list IO. A chain of aiocb's are copied in 1284 * one at a time. If the aiocb is invalid, it is skipped. 1285 * For each aiocb, the appropriate driver entry point is 1286 * called. Optimize for the common case where the list 1287 * of requests is to the same file descriptor. 1288 * 1289 * One possible optimization is to define a new driver entry 1290 * point that supports a list of IO requests. Whether this 1291 * improves performance depends somewhat on the driver's 1292 * locking strategy. Processing a list could adversely impact 1293 * the driver's interrupt latency. 1294 */ | 1185#ifdef _LP64 1186 1187/* 1188 * Asynchronous list IO. A chain of aiocb's are copied in 1189 * one at a time. If the aiocb is invalid, it is skipped. 1190 * For each aiocb, the appropriate driver entry point is 1191 * called. Optimize for the common case where the list 1192 * of requests is to the same file descriptor. 1193 * 1194 * One possible optimization is to define a new driver entry 1195 * point that supports a list of IO requests. Whether this 1196 * improves performance depends somewhat on the driver's 1197 * locking strategy. Processing a list could adversely impact 1198 * the driver's interrupt latency. 1199 */ |
1295/*ARGSUSED*/ | |
1296static int 1297alio( | 1200static int 1201alio( |
1298 int opcode, 1299 int mode_arg, 1300 aiocb_t **aiocb_arg, 1301 int nent, 1302 struct sigevent *sigev) 1303 | 1202 int mode_arg, 1203 aiocb_t **aiocb_arg, 1204 int nent, 1205 struct sigevent *sigev) |
1304{ 1305 file_t *fp; 1306 file_t *prev_fp = NULL; 1307 int prev_mode = -1; 1308 struct vnode *vp; 1309 aio_lio_t *head; 1310 aio_req_t *reqp; 1311 aio_t *aiop; 1312 caddr_t cbplist; | 1206{ 1207 file_t *fp; 1208 file_t *prev_fp = NULL; 1209 int prev_mode = -1; 1210 struct vnode *vp; 1211 aio_lio_t *head; 1212 aio_req_t *reqp; 1213 aio_t *aiop; 1214 caddr_t cbplist; |
1313 aiocb_t *cbp, **ucbp; | |
1314 aiocb_t cb; 1315 aiocb_t *aiocb = &cb; | 1215 aiocb_t cb; 1216 aiocb_t *aiocb = &cb; |
1217 aiocb_t *cbp; 1218 aiocb_t **ucbp; |
|
1316 struct sigevent sigevk; 1317 sigqueue_t *sqp; 1318 int (*aio_func)(); 1319 int mode; 1320 int error = 0; 1321 int aio_errors = 0; 1322 int i; 1323 size_t ssize; 1324 int deadhead = 0; 1325 int aio_notsupported = 0; | 1219 struct sigevent sigevk; 1220 sigqueue_t *sqp; 1221 int (*aio_func)(); 1222 int mode; 1223 int error = 0; 1224 int aio_errors = 0; 1225 int i; 1226 size_t ssize; 1227 int deadhead = 0; 1228 int aio_notsupported = 0; |
1326 int aio_use_port = 0; | 1229 int lio_head_port; 1230 int aio_port; 1231 int aio_thread; |
1327 port_kevent_t *pkevtp = NULL; 1328 port_notify_t pnotify; | 1232 port_kevent_t *pkevtp = NULL; 1233 port_notify_t pnotify; |
1234 int event; |
|
1329 1330 aiop = curproc->p_aio; 1331 if (aiop == NULL || nent <= 0 || nent > _AIO_LISTIO_MAX) 1332 return (EINVAL); 1333 1334 ssize = (sizeof (aiocb_t *) * nent); 1335 cbplist = kmem_alloc(ssize, KM_SLEEP); 1336 ucbp = (aiocb_t **)cbplist; 1337 | 1235 1236 aiop = curproc->p_aio; 1237 if (aiop == NULL || nent <= 0 || nent > _AIO_LISTIO_MAX) 1238 return (EINVAL); 1239 1240 ssize = (sizeof (aiocb_t *) * nent); 1241 cbplist = kmem_alloc(ssize, KM_SLEEP); 1242 ucbp = (aiocb_t **)cbplist; 1243 |
1338 if (copyin(aiocb_arg, cbplist, sizeof (aiocb_t *) * nent)) { | 1244 if (copyin(aiocb_arg, cbplist, ssize) || 1245 (sigev && copyin(sigev, &sigevk, sizeof (struct sigevent)))) { |
1339 kmem_free(cbplist, ssize); 1340 return (EFAULT); 1341 } 1342 | 1246 kmem_free(cbplist, ssize); 1247 return (EFAULT); 1248 } 1249 |
1343 if (sigev) { 1344 if (copyin(sigev, &sigevk, sizeof (struct sigevent))) { 1345 kmem_free(cbplist, ssize); 1346 return (EFAULT); 1347 } 1348 } 1349 1350 /* 1351 * a list head should be allocated if notification is 1352 * enabled for this list. 1353 */ 1354 head = NULL; 1355 | |
1356 /* Event Ports */ | 1250 /* Event Ports */ |
1357 1358 if (sigev && sigevk.sigev_notify == SIGEV_PORT) { 1359 /* Use port for completion notification */ 1360 if (copyin(sigevk.sigev_value.sival_ptr, &pnotify, 1361 sizeof (port_notify_t))) { | 1251 if (sigev && 1252 (sigevk.sigev_notify == SIGEV_THREAD || 1253 sigevk.sigev_notify == SIGEV_PORT)) { 1254 if (sigevk.sigev_notify == SIGEV_THREAD) { 1255 pnotify.portnfy_port = sigevk.sigev_signo; 1256 pnotify.portnfy_user = sigevk.sigev_value.sival_ptr; 1257 } else if (copyin(sigevk.sigev_value.sival_ptr, 1258 &pnotify, sizeof (pnotify))) { |
1362 kmem_free(cbplist, ssize); 1363 return (EFAULT); 1364 } | 1259 kmem_free(cbplist, ssize); 1260 return (EFAULT); 1261 } |
1365 /* use event ports for the list of aiocbs */ 1366 aio_use_port = 1; | |
1367 error = port_alloc_event(pnotify.portnfy_port, | 1262 error = port_alloc_event(pnotify.portnfy_port, |
1368 PORT_ALLOC_PRIVATE, PORT_SOURCE_AIO, &pkevtp); | 1263 PORT_ALLOC_DEFAULT, PORT_SOURCE_AIO, &pkevtp); |
1369 if (error) { | 1264 if (error) { |
1370 if ((error == ENOMEM) || (error == EAGAIN)) | 1265 if (error == ENOMEM || error == EAGAIN) |
1371 error = EAGAIN; 1372 else 1373 error = EINVAL; 1374 kmem_free(cbplist, ssize); 1375 return (error); 1376 } | 1266 error = EAGAIN; 1267 else 1268 error = EINVAL; 1269 kmem_free(cbplist, ssize); 1270 return (error); 1271 } |
1377 } else if ((mode_arg == LIO_WAIT) || sigev) { | 1272 lio_head_port = pnotify.portnfy_port; 1273 } 1274 1275 /* 1276 * a list head should be allocated if notification is 1277 * enabled for this list. 1278 */ 1279 head = NULL; 1280 1281 if (mode_arg == LIO_WAIT || sigev) { |
1378 mutex_enter(&aiop->aio_mutex); 1379 error = aio_lio_alloc(&head); 1380 mutex_exit(&aiop->aio_mutex); 1381 if (error) 1382 goto done; 1383 deadhead = 1; 1384 head->lio_nent = nent; 1385 head->lio_refcnt = nent; | 1282 mutex_enter(&aiop->aio_mutex); 1283 error = aio_lio_alloc(&head); 1284 mutex_exit(&aiop->aio_mutex); 1285 if (error) 1286 goto done; 1287 deadhead = 1; 1288 head->lio_nent = nent; 1289 head->lio_refcnt = nent; |
1386 if (sigev && (sigevk.sigev_notify == SIGEV_SIGNAL) && 1387 (sigevk.sigev_signo > 0 && sigevk.sigev_signo < NSIG)) { | 1290 head->lio_port = -1; 1291 head->lio_portkev = NULL; 1292 if (sigev && sigevk.sigev_notify == SIGEV_SIGNAL && 1293 sigevk.sigev_signo > 0 && sigevk.sigev_signo < NSIG) { |
1388 sqp = kmem_zalloc(sizeof (sigqueue_t), KM_NOSLEEP); 1389 if (sqp == NULL) { 1390 error = EAGAIN; 1391 goto done; 1392 } 1393 sqp->sq_func = NULL; 1394 sqp->sq_next = NULL; 1395 sqp->sq_info.si_code = SI_ASYNCIO; 1396 sqp->sq_info.si_pid = curproc->p_pid; 1397 sqp->sq_info.si_ctid = PRCTID(curproc); 1398 sqp->sq_info.si_zoneid = getzoneid(); 1399 sqp->sq_info.si_uid = crgetuid(curproc->p_cred); 1400 sqp->sq_info.si_signo = sigevk.sigev_signo; 1401 sqp->sq_info.si_value = sigevk.sigev_value; 1402 head->lio_sigqp = sqp; 1403 } else { 1404 head->lio_sigqp = NULL; 1405 } | 1294 sqp = kmem_zalloc(sizeof (sigqueue_t), KM_NOSLEEP); 1295 if (sqp == NULL) { 1296 error = EAGAIN; 1297 goto done; 1298 } 1299 sqp->sq_func = NULL; 1300 sqp->sq_next = NULL; 1301 sqp->sq_info.si_code = SI_ASYNCIO; 1302 sqp->sq_info.si_pid = curproc->p_pid; 1303 sqp->sq_info.si_ctid = PRCTID(curproc); 1304 sqp->sq_info.si_zoneid = getzoneid(); 1305 sqp->sq_info.si_uid = crgetuid(curproc->p_cred); 1306 sqp->sq_info.si_signo = sigevk.sigev_signo; 1307 sqp->sq_info.si_value = sigevk.sigev_value; 1308 head->lio_sigqp = sqp; 1309 } else { 1310 head->lio_sigqp = NULL; 1311 } |
1312 if (pkevtp) { 1313 /* 1314 * Prepare data to send when list of aiocb's 1315 * has completed. 1316 */ 1317 port_init_event(pkevtp, (uintptr_t)sigev, 1318 (void *)(uintptr_t)pnotify.portnfy_user, 1319 NULL, head); 1320 pkevtp->portkev_events = AIOLIO; 1321 head->lio_portkev = pkevtp; 1322 head->lio_port = pnotify.portnfy_port; 1323 } |
|
1406 } 1407 1408 for (i = 0; i < nent; i++, ucbp++) { 1409 1410 cbp = *ucbp; 1411 /* skip entry if it can't be copied. */ | 1324 } 1325 1326 for (i = 0; i < nent; i++, ucbp++) { 1327 1328 cbp = *ucbp; 1329 /* skip entry if it can't be copied. */ |
1412 if (cbp == NULL || copyin(cbp, aiocb, sizeof (aiocb_t))) { | 1330 if (cbp == NULL || copyin(cbp, aiocb, sizeof (*aiocb))) { |
1413 if (head) { 1414 mutex_enter(&aiop->aio_mutex); 1415 head->lio_nent--; 1416 head->lio_refcnt--; 1417 mutex_exit(&aiop->aio_mutex); 1418 } 1419 continue; 1420 } 1421 1422 /* skip if opcode for aiocb is LIO_NOP */ | 1331 if (head) { 1332 mutex_enter(&aiop->aio_mutex); 1333 head->lio_nent--; 1334 head->lio_refcnt--; 1335 mutex_exit(&aiop->aio_mutex); 1336 } 1337 continue; 1338 } 1339 1340 /* skip if opcode for aiocb is LIO_NOP */ |
1423 | |
1424 mode = aiocb->aio_lio_opcode; 1425 if (mode == LIO_NOP) { 1426 cbp = NULL; 1427 if (head) { 1428 mutex_enter(&aiop->aio_mutex); 1429 head->lio_nent--; 1430 head->lio_refcnt--; 1431 mutex_exit(&aiop->aio_mutex); --- 9 unchanged lines hidden (view full) --- 1441 head->lio_nent--; 1442 head->lio_refcnt--; 1443 mutex_exit(&aiop->aio_mutex); 1444 } 1445 aio_errors++; 1446 continue; 1447 } 1448 | 1341 mode = aiocb->aio_lio_opcode; 1342 if (mode == LIO_NOP) { 1343 cbp = NULL; 1344 if (head) { 1345 mutex_enter(&aiop->aio_mutex); 1346 head->lio_nent--; 1347 head->lio_refcnt--; 1348 mutex_exit(&aiop->aio_mutex); --- 9 unchanged lines hidden (view full) --- 1358 head->lio_nent--; 1359 head->lio_refcnt--; 1360 mutex_exit(&aiop->aio_mutex); 1361 } 1362 aio_errors++; 1363 continue; 1364 } 1365 |
1449 vp = fp->f_vnode; 1450 | |
1451 /* 1452 * check the permission of the partition 1453 */ | 1366 /* 1367 * check the permission of the partition 1368 */ |
1454 mode = aiocb->aio_lio_opcode; | |
1455 if ((fp->f_flag & mode) == 0) { 1456 releasef(aiocb->aio_fildes); 1457 lio_set_uerror(&cbp->aio_resultp, EBADF); 1458 if (head) { 1459 mutex_enter(&aiop->aio_mutex); 1460 head->lio_nent--; 1461 head->lio_refcnt--; 1462 mutex_exit(&aiop->aio_mutex); 1463 } 1464 aio_errors++; 1465 continue; 1466 } 1467 1468 /* | 1369 if ((fp->f_flag & mode) == 0) { 1370 releasef(aiocb->aio_fildes); 1371 lio_set_uerror(&cbp->aio_resultp, EBADF); 1372 if (head) { 1373 mutex_enter(&aiop->aio_mutex); 1374 head->lio_nent--; 1375 head->lio_refcnt--; 1376 mutex_exit(&aiop->aio_mutex); 1377 } 1378 aio_errors++; 1379 continue; 1380 } 1381 1382 /* |
1469 * common case where requests are to the same fd for the 1470 * same r/w operation. | 1383 * common case where requests are to the same fd 1384 * for the same r/w operation. |
1471 * for UFS, need to set EBADFD 1472 */ | 1385 * for UFS, need to set EBADFD 1386 */ |
1473 if ((fp != prev_fp) || (mode != prev_mode)) { | 1387 vp = fp->f_vnode; 1388 if (fp != prev_fp || mode != prev_mode) { |
1474 aio_func = check_vp(vp, mode); 1475 if (aio_func == NULL) { 1476 prev_fp = NULL; 1477 releasef(aiocb->aio_fildes); 1478 lio_set_uerror(&cbp->aio_resultp, EBADFD); 1479 aio_notsupported++; 1480 if (head) { 1481 mutex_enter(&aiop->aio_mutex); 1482 head->lio_nent--; 1483 head->lio_refcnt--; 1484 mutex_exit(&aiop->aio_mutex); 1485 } 1486 continue; 1487 } else { 1488 prev_fp = fp; 1489 prev_mode = mode; 1490 } 1491 } 1492 | 1389 aio_func = check_vp(vp, mode); 1390 if (aio_func == NULL) { 1391 prev_fp = NULL; 1392 releasef(aiocb->aio_fildes); 1393 lio_set_uerror(&cbp->aio_resultp, EBADFD); 1394 aio_notsupported++; 1395 if (head) { 1396 mutex_enter(&aiop->aio_mutex); 1397 head->lio_nent--; 1398 head->lio_refcnt--; 1399 mutex_exit(&aiop->aio_mutex); 1400 } 1401 continue; 1402 } else { 1403 prev_fp = fp; 1404 prev_mode = mode; 1405 } 1406 } 1407 |
1493 if (error = aio_req_setup(&reqp, aiop, aiocb, 1494 &cbp->aio_resultp, aio_use_port, vp)) { | 1408 error = aio_req_setup(&reqp, aiop, aiocb, 1409 &cbp->aio_resultp, vp); 1410 if (error) { |
1495 releasef(aiocb->aio_fildes); 1496 lio_set_uerror(&cbp->aio_resultp, error); 1497 if (head) { 1498 mutex_enter(&aiop->aio_mutex); 1499 head->lio_nent--; 1500 head->lio_refcnt--; 1501 mutex_exit(&aiop->aio_mutex); 1502 } --- 8 unchanged lines hidden (view full) --- 1511 * Set the errno field now before sending the request to 1512 * the driver to avoid a race condition 1513 */ 1514 (void) suword32(&cbp->aio_resultp.aio_errno, 1515 EINPROGRESS); 1516 1517 reqp->aio_req_iocb.iocb = (caddr_t)cbp; 1518 | 1411 releasef(aiocb->aio_fildes); 1412 lio_set_uerror(&cbp->aio_resultp, error); 1413 if (head) { 1414 mutex_enter(&aiop->aio_mutex); 1415 head->lio_nent--; 1416 head->lio_refcnt--; 1417 mutex_exit(&aiop->aio_mutex); 1418 } --- 8 unchanged lines hidden (view full) --- 1427 * Set the errno field now before sending the request to 1428 * the driver to avoid a race condition 1429 */ 1430 (void) suword32(&cbp->aio_resultp.aio_errno, 1431 EINPROGRESS); 1432 1433 reqp->aio_req_iocb.iocb = (caddr_t)cbp; 1434 |
1519 if (aio_use_port) { 1520 reqp->aio_req_port = pnotify.portnfy_port; 1521 error = aio_req_assoc_port(&aiocb->aio_sigevent, 1522 pnotify.portnfy_user, cbp, reqp, pkevtp); | 1435 event = (mode == LIO_READ)? AIOAREAD : AIOAWRITE; 1436 aio_port = (aiocb->aio_sigevent.sigev_notify == SIGEV_PORT); 1437 aio_thread = (aiocb->aio_sigevent.sigev_notify == SIGEV_THREAD); 1438 if (aio_port | aio_thread) { 1439 port_kevent_t *lpkevp; 1440 /* 1441 * Prepare data to send with each aiocb completed. 1442 */ 1443 if (aio_port) { 1444 void *paddr = 1445 aiocb->aio_sigevent.sigev_value.sival_ptr; 1446 if (copyin(paddr, &pnotify, sizeof (pnotify))) 1447 error = EFAULT; 1448 } else { /* aio_thread */ 1449 pnotify.portnfy_port = 1450 aiocb->aio_sigevent.sigev_signo; 1451 pnotify.portnfy_user = 1452 aiocb->aio_sigevent.sigev_value.sival_ptr; 1453 } 1454 if (error) 1455 /* EMPTY */; 1456 else if (pkevtp != NULL && 1457 pnotify.portnfy_port == lio_head_port) 1458 error = port_dup_event(pkevtp, &lpkevp, 1459 PORT_ALLOC_DEFAULT); 1460 else 1461 error = port_alloc_event(pnotify.portnfy_port, 1462 PORT_ALLOC_DEFAULT, PORT_SOURCE_AIO, 1463 &lpkevp); 1464 if (error == 0) { 1465 port_init_event(lpkevp, (uintptr_t)cbp, 1466 (void *)(uintptr_t)pnotify.portnfy_user, 1467 aio_port_callback, reqp); 1468 lpkevp->portkev_events = event; 1469 reqp->aio_req_portkev = lpkevp; 1470 reqp->aio_req_port = pnotify.portnfy_port; 1471 } |
1523 } 1524 1525 /* 1526 * send the request to driver. | 1472 } 1473 1474 /* 1475 * send the request to driver. |
1527 * Clustering: If PXFS vnode, call PXFS function. | |
1528 */ 1529 if (error == 0) { 1530 if (aiocb->aio_nbytes == 0) { 1531 clear_active_fd(aiocb->aio_fildes); 1532 aio_zerolen(reqp); 1533 continue; 1534 } 1535 error = (*aio_func)(vp, (aio_req_t *)&reqp->aio_req, 1536 CRED()); 1537 } | 1476 */ 1477 if (error == 0) { 1478 if (aiocb->aio_nbytes == 0) { 1479 clear_active_fd(aiocb->aio_fildes); 1480 aio_zerolen(reqp); 1481 continue; 1482 } 1483 error = (*aio_func)(vp, (aio_req_t *)&reqp->aio_req, 1484 CRED()); 1485 } |
1486 |
|
1538 /* 1539 * the fd's ref count is not decremented until the IO has 1540 * completed unless there was an error. 1541 */ 1542 if (error) { 1543 releasef(aiocb->aio_fildes); 1544 lio_set_uerror(&cbp->aio_resultp, error); 1545 if (head) { --- 7 unchanged lines hidden (view full) --- 1553 else 1554 aio_errors++; 1555 lio_set_error(reqp); 1556 } else { 1557 clear_active_fd(aiocb->aio_fildes); 1558 } 1559 } 1560 | 1487 /* 1488 * the fd's ref count is not decremented until the IO has 1489 * completed unless there was an error. 1490 */ 1491 if (error) { 1492 releasef(aiocb->aio_fildes); 1493 lio_set_uerror(&cbp->aio_resultp, error); 1494 if (head) { --- 7 unchanged lines hidden (view full) --- 1502 else 1503 aio_errors++; 1504 lio_set_error(reqp); 1505 } else { 1506 clear_active_fd(aiocb->aio_fildes); 1507 } 1508 } 1509 |
1561 if (pkevtp) 1562 port_free_event(pkevtp); 1563 | |
1564 if (aio_notsupported) { 1565 error = ENOTSUP; 1566 } else if (aio_errors) { 1567 /* 1568 * return EIO if any request failed 1569 */ 1570 error = EIO; 1571 } --- 11 unchanged lines hidden (view full) --- 1583 alio_cleanup(aiop, (aiocb_t **)cbplist, nent, AIO_64); 1584 } 1585 1586done: 1587 kmem_free(cbplist, ssize); 1588 if (deadhead) { 1589 if (head->lio_sigqp) 1590 kmem_free(head->lio_sigqp, sizeof (sigqueue_t)); | 1510 if (aio_notsupported) { 1511 error = ENOTSUP; 1512 } else if (aio_errors) { 1513 /* 1514 * return EIO if any request failed 1515 */ 1516 error = EIO; 1517 } --- 11 unchanged lines hidden (view full) --- 1529 alio_cleanup(aiop, (aiocb_t **)cbplist, nent, AIO_64); 1530 } 1531 1532done: 1533 kmem_free(cbplist, ssize); 1534 if (deadhead) { 1535 if (head->lio_sigqp) 1536 kmem_free(head->lio_sigqp, sizeof (sigqueue_t)); |
1537 if (head->lio_portkev) 1538 port_free_event(head->lio_portkev); |
|
1591 kmem_free(head, sizeof (aio_lio_t)); 1592 } 1593 return (error); 1594} 1595 1596#endif /* _LP64 */ 1597 1598/* --- 184 unchanged lines hidden (view full) --- 1783 * each request is also freed. 1784 */ 1785static void 1786alio_cleanup(aio_t *aiop, aiocb_t **cbp, int nent, int run_mode) 1787{ 1788 int i; 1789 aio_req_t *reqp; 1790 aio_result_t *resultp; | 1539 kmem_free(head, sizeof (aio_lio_t)); 1540 } 1541 return (error); 1542} 1543 1544#endif /* _LP64 */ 1545 1546/* --- 184 unchanged lines hidden (view full) --- 1731 * each request is also freed. 1732 */ 1733static void 1734alio_cleanup(aio_t *aiop, aiocb_t **cbp, int nent, int run_mode) 1735{ 1736 int i; 1737 aio_req_t *reqp; 1738 aio_result_t *resultp; |
1791 aiocb64_32_t *aiocb_64; | 1739 aiocb64_32_t *aiocb_64; |
1792 1793 for (i = 0; i < nent; i++) { 1794 if (get_udatamodel() == DATAMODEL_NATIVE) { 1795 if (cbp[i] == NULL) 1796 continue; 1797 if (run_mode == AIO_LARGEFILE) { 1798 aiocb_64 = (aiocb64_32_t *)cbp[i]; | 1740 1741 for (i = 0; i < nent; i++) { 1742 if (get_udatamodel() == DATAMODEL_NATIVE) { 1743 if (cbp[i] == NULL) 1744 continue; 1745 if (run_mode == AIO_LARGEFILE) { 1746 aiocb_64 = (aiocb64_32_t *)cbp[i]; |
1799 resultp = (aio_result_t *)&aiocb_64-> 1800 aio_resultp; | 1747 resultp = (aio_result_t *) 1748 &aiocb_64->aio_resultp; |
1801 } else 1802 resultp = &cbp[i]->aio_resultp; 1803 } 1804#ifdef _SYSCALL32_IMPL 1805 else { | 1749 } else 1750 resultp = &cbp[i]->aio_resultp; 1751 } 1752#ifdef _SYSCALL32_IMPL 1753 else { |
1806 aiocb32_t *aiocb_32; 1807 caddr32_t *cbp32; | 1754 aiocb32_t *aiocb_32; 1755 caddr32_t *cbp32; |
1808 1809 cbp32 = (caddr32_t *)cbp; 1810 if (cbp32[i] == NULL) 1811 continue; 1812 if (run_mode == AIO_32) { 1813 aiocb_32 = (aiocb32_t *)(uintptr_t)cbp32[i]; 1814 resultp = (aio_result_t *)&aiocb_32-> 1815 aio_resultp; --- 19 unchanged lines hidden (view full) --- 1835 mutex_enter(&aiop->aio_mutex); 1836 aio_req_free(aiop, reqp); 1837 mutex_exit(&aiop->aio_mutex); 1838 } 1839 } 1840} 1841 1842/* | 1756 1757 cbp32 = (caddr32_t *)cbp; 1758 if (cbp32[i] == NULL) 1759 continue; 1760 if (run_mode == AIO_32) { 1761 aiocb_32 = (aiocb32_t *)(uintptr_t)cbp32[i]; 1762 resultp = (aio_result_t *)&aiocb_32-> 1763 aio_resultp; --- 19 unchanged lines hidden (view full) --- 1783 mutex_enter(&aiop->aio_mutex); 1784 aio_req_free(aiop, reqp); 1785 mutex_exit(&aiop->aio_mutex); 1786 } 1787 } 1788} 1789 1790/* |
1843 * write out the results for an aio request that is 1844 * done. | 1791 * Write out the results for an aio request that is done. |
1845 */ 1846static int 1847aioerror(void *cb, int run_mode) 1848{ 1849 aio_result_t *resultp; 1850 aio_t *aiop; 1851 aio_req_t *reqp; 1852 int retval; --- 182 unchanged lines hidden (view full) --- 2035 return (EBADFD); 2036 } 2037#ifdef _LP64 2038 aiocb.aio_fildes = fdes; 2039 aiocb.aio_buf = bufp; 2040 aiocb.aio_nbytes = bufsize; 2041 aiocb.aio_offset = offset; 2042 aiocb.aio_sigevent.sigev_notify = 0; | 1792 */ 1793static int 1794aioerror(void *cb, int run_mode) 1795{ 1796 aio_result_t *resultp; 1797 aio_t *aiop; 1798 aio_req_t *reqp; 1799 int retval; --- 182 unchanged lines hidden (view full) --- 1982 return (EBADFD); 1983 } 1984#ifdef _LP64 1985 aiocb.aio_fildes = fdes; 1986 aiocb.aio_buf = bufp; 1987 aiocb.aio_nbytes = bufsize; 1988 aiocb.aio_offset = offset; 1989 aiocb.aio_sigevent.sigev_notify = 0; |
2043 error = aio_req_setup(&reqp, aiop, &aiocb, resultp, 0, vp); | 1990 error = aio_req_setup(&reqp, aiop, &aiocb, resultp, vp); |
2044#else 2045 aiocb64.aio_fildes = fdes; 2046 aiocb64.aio_buf = (caddr32_t)bufp; 2047 aiocb64.aio_nbytes = bufsize; 2048 aiocb64.aio_offset = offset; 2049 aiocb64.aio_sigevent.sigev_notify = 0; | 1991#else 1992 aiocb64.aio_fildes = fdes; 1993 aiocb64.aio_buf = (caddr32_t)bufp; 1994 aiocb64.aio_nbytes = bufsize; 1995 aiocb64.aio_offset = offset; 1996 aiocb64.aio_sigevent.sigev_notify = 0; |
2050 error = aio_req_setupLF(&reqp, aiop, &aiocb64, resultp, 0, vp); | 1997 error = aio_req_setupLF(&reqp, aiop, &aiocb64, resultp, vp); |
2051#endif 2052 if (error) { 2053 releasef(fdes); 2054 return (error); 2055 } 2056 2057 /* 2058 * enable polling on this request if the opcode has --- 4 unchanged lines hidden (view full) --- 2063 2064 if (bufsize == 0) { 2065 clear_active_fd(fdes); 2066 aio_zerolen(reqp); 2067 return (0); 2068 } 2069 /* 2070 * send the request to driver. | 1998#endif 1999 if (error) { 2000 releasef(fdes); 2001 return (error); 2002 } 2003 2004 /* 2005 * enable polling on this request if the opcode has --- 4 unchanged lines hidden (view full) --- 2010 2011 if (bufsize == 0) { 2012 clear_active_fd(fdes); 2013 aio_zerolen(reqp); 2014 return (0); 2015 } 2016 /* 2017 * send the request to driver. |
2071 * Clustering: If PXFS vnode, call PXFS function. | |
2072 */ 2073 error = (*aio_func)(vp, (aio_req_t *)&reqp->aio_req, CRED()); 2074 /* 2075 * the fd is stored in the aio_req_t by aio_req_setup(), and 2076 * is released by the aio_cleanup_thread() when the IO has 2077 * completed. 2078 */ 2079 if (error) { --- 6 unchanged lines hidden (view full) --- 2086 mutex_exit(&aiop->aio_mutex); 2087 return (error); 2088 } 2089 clear_active_fd(fdes); 2090 return (0); 2091} 2092 2093/* | 2018 */ 2019 error = (*aio_func)(vp, (aio_req_t *)&reqp->aio_req, CRED()); 2020 /* 2021 * the fd is stored in the aio_req_t by aio_req_setup(), and 2022 * is released by the aio_cleanup_thread() when the IO has 2023 * completed. 2024 */ 2025 if (error) { --- 6 unchanged lines hidden (view full) --- 2032 mutex_exit(&aiop->aio_mutex); 2033 return (error); 2034 } 2035 clear_active_fd(fdes); 2036 return (0); 2037} 2038 2039/* |
2094 * Take request out of the port pending queue ... 2095 */ 2096 2097void 2098aio_deq_port_pending(aio_t *aiop, aio_req_t *reqp) 2099{ 2100 ASSERT(MUTEX_HELD(&aiop->aio_mutex)); 2101 if (reqp->aio_req_prev == NULL) 2102 /* first request */ 2103 aiop->aio_portpending = reqp->aio_req_next; 2104 else 2105 reqp->aio_req_prev->aio_req_next = reqp->aio_req_next; 2106 if (reqp->aio_req_next != NULL) 2107 reqp->aio_req_next->aio_req_prev = reqp->aio_req_prev; 2108} 2109 2110/* | |
2111 * posix version of asynchronous read and write 2112 */ | 2040 * posix version of asynchronous read and write 2041 */ |
2113static int | 2042static int |
2114aiorw( 2115 int opcode, 2116 void *aiocb_arg, 2117 int mode, 2118 int run_mode) 2119{ 2120#ifdef _SYSCALL32_IMPL 2121 aiocb32_t aiocb32; --- 35 unchanged lines hidden (view full) --- 2157 * We come here only when we make largefile 2158 * call on 32 bit kernel using 32 bit library. 2159 */ 2160 if (copyin(aiocb_arg, &aiocb64, sizeof (aiocb64_32_t))) 2161 return (EFAULT); 2162 bufsize = aiocb64.aio_nbytes; 2163 resultp = (aio_result_t *)&(((aiocb64_32_t *)aiocb_arg) 2164 ->aio_resultp); | 2043aiorw( 2044 int opcode, 2045 void *aiocb_arg, 2046 int mode, 2047 int run_mode) 2048{ 2049#ifdef _SYSCALL32_IMPL 2050 aiocb32_t aiocb32; --- 35 unchanged lines hidden (view full) --- 2086 * We come here only when we make largefile 2087 * call on 32 bit kernel using 32 bit library. 2088 */ 2089 if (copyin(aiocb_arg, &aiocb64, sizeof (aiocb64_32_t))) 2090 return (EFAULT); 2091 bufsize = aiocb64.aio_nbytes; 2092 resultp = (aio_result_t *)&(((aiocb64_32_t *)aiocb_arg) 2093 ->aio_resultp); |
2165 if ((fp = getf(fd = aiocb64.aio_fildes)) == NULL) { | 2094 if ((fp = getf(fd = aiocb64.aio_fildes)) == NULL) |
2166 return (EBADF); | 2095 return (EBADF); |
2167 } | |
2168 sigev = (struct sigevent *)&aiocb64.aio_sigevent; 2169 } 2170 2171 if (sigev->sigev_notify == SIGEV_PORT) { 2172 if (copyin((void *)sigev->sigev_value.sival_ptr, 2173 &pntfy, sizeof (port_notify_t))) { 2174 releasef(fd); 2175 return (EFAULT); 2176 } 2177 aio_use_port = 1; | 2096 sigev = (struct sigevent *)&aiocb64.aio_sigevent; 2097 } 2098 2099 if (sigev->sigev_notify == SIGEV_PORT) { 2100 if (copyin((void *)sigev->sigev_value.sival_ptr, 2101 &pntfy, sizeof (port_notify_t))) { 2102 releasef(fd); 2103 return (EFAULT); 2104 } 2105 aio_use_port = 1; |
2106 } else if (sigev->sigev_notify == SIGEV_THREAD) { 2107 pntfy.portnfy_port = aiocb.aio_sigevent.sigev_signo; 2108 pntfy.portnfy_user = 2109 aiocb.aio_sigevent.sigev_value.sival_ptr; 2110 aio_use_port = 1; |
|
2178 } 2179 } 2180#ifdef _SYSCALL32_IMPL 2181 else { 2182 if (run_mode == AIO_32) { 2183 /* 32 bit system call is being made on 64 bit kernel */ 2184 if (copyin(aiocb_arg, &aiocb32, sizeof (aiocb32_t))) 2185 return (EFAULT); --- 25 unchanged lines hidden (view full) --- 2211 if (sigev32->sigev_notify == SIGEV_PORT) { 2212 if (copyin( 2213 (void *)(uintptr_t)sigev32->sigev_value.sival_ptr, 2214 &pntfy32, sizeof (port_notify32_t))) { 2215 releasef(fd); 2216 return (EFAULT); 2217 } 2218 pntfy.portnfy_port = pntfy32.portnfy_port; | 2111 } 2112 } 2113#ifdef _SYSCALL32_IMPL 2114 else { 2115 if (run_mode == AIO_32) { 2116 /* 32 bit system call is being made on 64 bit kernel */ 2117 if (copyin(aiocb_arg, &aiocb32, sizeof (aiocb32_t))) 2118 return (EFAULT); --- 25 unchanged lines hidden (view full) --- 2144 if (sigev32->sigev_notify == SIGEV_PORT) { 2145 if (copyin( 2146 (void *)(uintptr_t)sigev32->sigev_value.sival_ptr, 2147 &pntfy32, sizeof (port_notify32_t))) { 2148 releasef(fd); 2149 return (EFAULT); 2150 } 2151 pntfy.portnfy_port = pntfy32.portnfy_port; |
2219 pntfy.portnfy_user = 2220 (void *)(uintptr_t)pntfy32.portnfy_user; | 2152 pntfy.portnfy_user = (void *)(uintptr_t) 2153 pntfy32.portnfy_user; |
2221 aio_use_port = 1; | 2154 aio_use_port = 1; |
2155 } else if (sigev32->sigev_notify == SIGEV_THREAD) { 2156 pntfy.portnfy_port = sigev32->sigev_signo; 2157 pntfy.portnfy_user = (void *)(uintptr_t) 2158 sigev32->sigev_value.sival_ptr; 2159 aio_use_port = 1; |
|
2222 } 2223 } 2224#endif /* _SYSCALL32_IMPL */ 2225 2226 /* 2227 * check the permission of the partition 2228 */ 2229 2230 if ((fp->f_flag & mode) == 0) { 2231 releasef(fd); 2232 return (EBADF); 2233 } 2234 2235 vp = fp->f_vnode; 2236 aio_func = check_vp(vp, mode); 2237 if (aio_func == NULL) { 2238 releasef(fd); 2239 return (EBADFD); 2240 } | 2160 } 2161 } 2162#endif /* _SYSCALL32_IMPL */ 2163 2164 /* 2165 * check the permission of the partition 2166 */ 2167 2168 if ((fp->f_flag & mode) == 0) { 2169 releasef(fd); 2170 return (EBADF); 2171 } 2172 2173 vp = fp->f_vnode; 2174 aio_func = check_vp(vp, mode); 2175 if (aio_func == NULL) { 2176 releasef(fd); 2177 return (EBADFD); 2178 } |
2241 if ((model == DATAMODEL_NATIVE) && (run_mode == AIO_LARGEFILE)) 2242 error = aio_req_setupLF(&reqp, aiop, &aiocb64, resultp, 2243 aio_use_port, vp); | 2179 if (run_mode == AIO_LARGEFILE) 2180 error = aio_req_setupLF(&reqp, aiop, &aiocb64, resultp, vp); |
2244 else | 2181 else |
2245 error = aio_req_setup(&reqp, aiop, &aiocb, resultp, 2246 aio_use_port, vp); | 2182 error = aio_req_setup(&reqp, aiop, &aiocb, resultp, vp); |
2247 2248 if (error) { 2249 releasef(fd); 2250 return (error); 2251 } 2252 /* 2253 * enable polling on this request if the opcode has 2254 * the AIO poll bit set 2255 */ 2256 if (opcode & AIO_POLL_BIT) 2257 reqp->aio_req_flags |= AIO_POLL; 2258 2259 if (model == DATAMODEL_NATIVE) 2260 reqp->aio_req_iocb.iocb = aiocb_arg; 2261#ifdef _SYSCALL32_IMPL 2262 else 2263 reqp->aio_req_iocb.iocb32 = (caddr32_t)(uintptr_t)aiocb_arg; 2264#endif 2265 | 2183 2184 if (error) { 2185 releasef(fd); 2186 return (error); 2187 } 2188 /* 2189 * enable polling on this request if the opcode has 2190 * the AIO poll bit set 2191 */ 2192 if (opcode & AIO_POLL_BIT) 2193 reqp->aio_req_flags |= AIO_POLL; 2194 2195 if (model == DATAMODEL_NATIVE) 2196 reqp->aio_req_iocb.iocb = aiocb_arg; 2197#ifdef _SYSCALL32_IMPL 2198 else 2199 reqp->aio_req_iocb.iocb32 = (caddr32_t)(uintptr_t)aiocb_arg; 2200#endif 2201 |
2266 if (aio_use_port) 2267 error = aio_req_assoc_port_rw(&pntfy, aiocb_arg, reqp); | 2202 if (aio_use_port) { 2203 int event = (run_mode == AIO_LARGEFILE)? 2204 ((mode == FREAD)? AIOAREAD64 : AIOAWRITE64) : 2205 ((mode == FREAD)? AIOAREAD : AIOAWRITE); 2206 error = aio_req_assoc_port_rw(&pntfy, aiocb_arg, reqp, event); 2207 } |
2268 2269 /* 2270 * send the request to driver. | 2208 2209 /* 2210 * send the request to driver. |
2271 * Clustering: If PXFS vnode, call PXFS function. | |
2272 */ 2273 if (error == 0) { 2274 if (bufsize == 0) { 2275 clear_active_fd(fd); 2276 aio_zerolen(reqp); 2277 return (0); 2278 } 2279 error = (*aio_func)(vp, (aio_req_t *)&reqp->aio_req, CRED()); 2280 } 2281 2282 /* 2283 * the fd is stored in the aio_req_t by aio_req_setup(), and 2284 * is released by the aio_cleanup_thread() when the IO has 2285 * completed. 2286 */ 2287 if (error) { 2288 releasef(fd); 2289 mutex_enter(&aiop->aio_mutex); | 2211 */ 2212 if (error == 0) { 2213 if (bufsize == 0) { 2214 clear_active_fd(fd); 2215 aio_zerolen(reqp); 2216 return (0); 2217 } 2218 error = (*aio_func)(vp, (aio_req_t *)&reqp->aio_req, CRED()); 2219 } 2220 2221 /* 2222 * the fd is stored in the aio_req_t by aio_req_setup(), and 2223 * is released by the aio_cleanup_thread() when the IO has 2224 * completed. 2225 */ 2226 if (error) { 2227 releasef(fd); 2228 mutex_enter(&aiop->aio_mutex); |
2290 aio_deq_port_pending(aiop, reqp); | 2229 aio_deq(&aiop->aio_portpending, reqp); |
2291 aio_req_free(aiop, reqp); 2292 aiop->aio_pending--; 2293 if (aiop->aio_flags & AIO_REQ_BLOCK) 2294 cv_signal(&aiop->aio_cleanupcv); 2295 mutex_exit(&aiop->aio_mutex); 2296 return (error); 2297 } 2298 clear_active_fd(fd); --- 8 unchanged lines hidden (view full) --- 2307lio_set_error(aio_req_t *reqp) 2308{ 2309 aio_t *aiop = curproc->p_aio; 2310 2311 if (aiop == NULL) 2312 return; 2313 2314 mutex_enter(&aiop->aio_mutex); | 2230 aio_req_free(aiop, reqp); 2231 aiop->aio_pending--; 2232 if (aiop->aio_flags & AIO_REQ_BLOCK) 2233 cv_signal(&aiop->aio_cleanupcv); 2234 mutex_exit(&aiop->aio_mutex); 2235 return (error); 2236 } 2237 clear_active_fd(fd); --- 8 unchanged lines hidden (view full) --- 2246lio_set_error(aio_req_t *reqp) 2247{ 2248 aio_t *aiop = curproc->p_aio; 2249 2250 if (aiop == NULL) 2251 return; 2252 2253 mutex_enter(&aiop->aio_mutex); |
2315 aio_deq_port_pending(aiop, reqp); | 2254 aio_deq(&aiop->aio_portpending, reqp); |
2316 aiop->aio_pending--; 2317 /* request failed, AIO_PHYSIODONE set to aviod physio cleanup. */ 2318 reqp->aio_req_flags |= AIO_PHYSIODONE; 2319 /* 2320 * Need to free the request now as its never 2321 * going to get on the done queue 2322 * 2323 * Note: aio_outstanding is decremented in --- 74 unchanged lines hidden (view full) --- 2398 2399/* 2400 * remove a request from the done queue. 2401 */ 2402static aio_req_t * 2403aio_req_remove(aio_req_t *reqp) 2404{ 2405 aio_t *aiop = curproc->p_aio; | 2255 aiop->aio_pending--; 2256 /* request failed, AIO_PHYSIODONE set to aviod physio cleanup. */ 2257 reqp->aio_req_flags |= AIO_PHYSIODONE; 2258 /* 2259 * Need to free the request now as its never 2260 * going to get on the done queue 2261 * 2262 * Note: aio_outstanding is decremented in --- 74 unchanged lines hidden (view full) --- 2337 2338/* 2339 * remove a request from the done queue. 2340 */ 2341static aio_req_t * 2342aio_req_remove(aio_req_t *reqp) 2343{ 2344 aio_t *aiop = curproc->p_aio; |
2406 aio_req_t *head; | |
2407 2408 ASSERT(MUTEX_HELD(&aiop->aio_mutex)); 2409 | 2345 2346 ASSERT(MUTEX_HELD(&aiop->aio_mutex)); 2347 |
2410 if (reqp) { | 2348 if (reqp != NULL) { |
2411 ASSERT(reqp->aio_req_flags & AIO_DONEQ); 2412 if (reqp->aio_req_next == reqp) { 2413 /* only one request on queue */ 2414 if (reqp == aiop->aio_doneq) { 2415 aiop->aio_doneq = NULL; 2416 } else { 2417 ASSERT(reqp == aiop->aio_cleanupq); 2418 aiop->aio_cleanupq = NULL; --- 7 unchanged lines hidden (view full) --- 2426 */ 2427 if (reqp == aiop->aio_doneq) 2428 aiop->aio_doneq = reqp->aio_req_next; 2429 2430 if (reqp == aiop->aio_cleanupq) 2431 aiop->aio_cleanupq = reqp->aio_req_next; 2432 } 2433 reqp->aio_req_flags &= ~AIO_DONEQ; | 2349 ASSERT(reqp->aio_req_flags & AIO_DONEQ); 2350 if (reqp->aio_req_next == reqp) { 2351 /* only one request on queue */ 2352 if (reqp == aiop->aio_doneq) { 2353 aiop->aio_doneq = NULL; 2354 } else { 2355 ASSERT(reqp == aiop->aio_cleanupq); 2356 aiop->aio_cleanupq = NULL; --- 7 unchanged lines hidden (view full) --- 2364 */ 2365 if (reqp == aiop->aio_doneq) 2366 aiop->aio_doneq = reqp->aio_req_next; 2367 2368 if (reqp == aiop->aio_cleanupq) 2369 aiop->aio_cleanupq = reqp->aio_req_next; 2370 } 2371 reqp->aio_req_flags &= ~AIO_DONEQ; |
2434 return (reqp); 2435 } 2436 2437 if (aiop->aio_doneq) { 2438 head = aiop->aio_doneq; 2439 ASSERT(head->aio_req_flags & AIO_DONEQ); 2440 if (head == head->aio_req_next) { | 2372 reqp->aio_req_next = NULL; 2373 reqp->aio_req_prev = NULL; 2374 } else if ((reqp = aiop->aio_doneq) != NULL) { 2375 ASSERT(reqp->aio_req_flags & AIO_DONEQ); 2376 if (reqp == reqp->aio_req_next) { |
2441 /* only one request on queue */ 2442 aiop->aio_doneq = NULL; 2443 } else { | 2377 /* only one request on queue */ 2378 aiop->aio_doneq = NULL; 2379 } else { |
2444 head->aio_req_prev->aio_req_next = head->aio_req_next; 2445 head->aio_req_next->aio_req_prev = head->aio_req_prev; 2446 aiop->aio_doneq = head->aio_req_next; | 2380 reqp->aio_req_prev->aio_req_next = reqp->aio_req_next; 2381 reqp->aio_req_next->aio_req_prev = reqp->aio_req_prev; 2382 aiop->aio_doneq = reqp->aio_req_next; |
2447 } | 2383 } |
2448 head->aio_req_flags &= ~AIO_DONEQ; 2449 return (head); | 2384 reqp->aio_req_flags &= ~AIO_DONEQ; 2385 reqp->aio_req_next = NULL; 2386 reqp->aio_req_prev = NULL; |
2450 } | 2387 } |
2451 return (NULL); | 2388 if (aiop->aio_doneq == NULL && (aiop->aio_flags & AIO_WAITN)) 2389 cv_broadcast(&aiop->aio_waitcv); 2390 return (reqp); |
2452} 2453 2454static int 2455aio_req_setup( 2456 aio_req_t **reqpp, 2457 aio_t *aiop, 2458 aiocb_t *arg, 2459 aio_result_t *resultp, | 2391} 2392 2393static int 2394aio_req_setup( 2395 aio_req_t **reqpp, 2396 aio_t *aiop, 2397 aiocb_t *arg, 2398 aio_result_t *resultp, |
2460 int port, | |
2461 vnode_t *vp) 2462{ | 2399 vnode_t *vp) 2400{ |
2401 sigqueue_t *sqp = NULL; |
|
2463 aio_req_t *reqp; | 2402 aio_req_t *reqp; |
2464 sigqueue_t *sqp; | |
2465 struct uio *uio; | 2403 struct uio *uio; |
2466 | |
2467 struct sigevent *sigev; 2468 int error; 2469 2470 sigev = &arg->aio_sigevent; | 2404 struct sigevent *sigev; 2405 int error; 2406 2407 sigev = &arg->aio_sigevent; |
2471 if ((sigev->sigev_notify == SIGEV_SIGNAL) && 2472 (sigev->sigev_signo > 0 && sigev->sigev_signo < NSIG)) { | 2408 if (sigev->sigev_notify == SIGEV_SIGNAL && 2409 sigev->sigev_signo > 0 && sigev->sigev_signo < NSIG) { |
2473 sqp = kmem_zalloc(sizeof (sigqueue_t), KM_NOSLEEP); 2474 if (sqp == NULL) 2475 return (EAGAIN); 2476 sqp->sq_func = NULL; 2477 sqp->sq_next = NULL; 2478 sqp->sq_info.si_code = SI_ASYNCIO; 2479 sqp->sq_info.si_pid = curproc->p_pid; 2480 sqp->sq_info.si_ctid = PRCTID(curproc); 2481 sqp->sq_info.si_zoneid = getzoneid(); 2482 sqp->sq_info.si_uid = crgetuid(curproc->p_cred); 2483 sqp->sq_info.si_signo = sigev->sigev_signo; 2484 sqp->sq_info.si_value = sigev->sigev_value; | 2410 sqp = kmem_zalloc(sizeof (sigqueue_t), KM_NOSLEEP); 2411 if (sqp == NULL) 2412 return (EAGAIN); 2413 sqp->sq_func = NULL; 2414 sqp->sq_next = NULL; 2415 sqp->sq_info.si_code = SI_ASYNCIO; 2416 sqp->sq_info.si_pid = curproc->p_pid; 2417 sqp->sq_info.si_ctid = PRCTID(curproc); 2418 sqp->sq_info.si_zoneid = getzoneid(); 2419 sqp->sq_info.si_uid = crgetuid(curproc->p_cred); 2420 sqp->sq_info.si_signo = sigev->sigev_signo; 2421 sqp->sq_info.si_value = sigev->sigev_value; |
2485 } else 2486 sqp = NULL; | 2422 } |
2487 2488 mutex_enter(&aiop->aio_mutex); 2489 2490 if (aiop->aio_flags & AIO_REQ_BLOCK) { 2491 mutex_exit(&aiop->aio_mutex); 2492 if (sqp) 2493 kmem_free(sqp, sizeof (sigqueue_t)); 2494 return (EIO); --- 6 unchanged lines hidden (view full) --- 2501 mutex_exit(&aiop->aio_mutex); 2502 if (sqp) 2503 kmem_free(sqp, sizeof (sigqueue_t)); 2504 return (error); 2505 } 2506 aiop->aio_pending++; 2507 aiop->aio_outstanding++; 2508 reqp->aio_req_flags = AIO_PENDING; | 2423 2424 mutex_enter(&aiop->aio_mutex); 2425 2426 if (aiop->aio_flags & AIO_REQ_BLOCK) { 2427 mutex_exit(&aiop->aio_mutex); 2428 if (sqp) 2429 kmem_free(sqp, sizeof (sigqueue_t)); 2430 return (EIO); --- 6 unchanged lines hidden (view full) --- 2437 mutex_exit(&aiop->aio_mutex); 2438 if (sqp) 2439 kmem_free(sqp, sizeof (sigqueue_t)); 2440 return (error); 2441 } 2442 aiop->aio_pending++; 2443 aiop->aio_outstanding++; 2444 reqp->aio_req_flags = AIO_PENDING; |
2509 if (port) 2510 aio_enq_port_pending(aiop, reqp); | 2445 if (sigev->sigev_notify == SIGEV_THREAD || 2446 sigev->sigev_notify == SIGEV_PORT) 2447 aio_enq(&aiop->aio_portpending, reqp, 0); |
2511 mutex_exit(&aiop->aio_mutex); 2512 /* 2513 * initialize aio request. 2514 */ 2515 reqp->aio_req_fd = arg->aio_fildes; 2516 reqp->aio_req_sigqp = sqp; 2517 reqp->aio_req_iocb.iocb = NULL; | 2448 mutex_exit(&aiop->aio_mutex); 2449 /* 2450 * initialize aio request. 2451 */ 2452 reqp->aio_req_fd = arg->aio_fildes; 2453 reqp->aio_req_sigqp = sqp; 2454 reqp->aio_req_iocb.iocb = NULL; |
2455 reqp->aio_req_lio = NULL; |
|
2518 reqp->aio_req_buf.b_file = vp; 2519 uio = reqp->aio_req.aio_uio; 2520 uio->uio_iovcnt = 1; 2521 uio->uio_iov->iov_base = (caddr_t)arg->aio_buf; 2522 uio->uio_iov->iov_len = arg->aio_nbytes; 2523 uio->uio_loffset = arg->aio_offset; 2524 *reqpp = reqp; 2525 return (0); --- 26 unchanged lines hidden (view full) --- 2552aio_req_alloc(aio_req_t **nreqp, aio_result_t *resultp) 2553{ 2554 aio_req_t *reqp; 2555 aio_t *aiop = curproc->p_aio; 2556 2557 ASSERT(MUTEX_HELD(&aiop->aio_mutex)); 2558 2559 if ((reqp = aiop->aio_free) != NULL) { | 2456 reqp->aio_req_buf.b_file = vp; 2457 uio = reqp->aio_req.aio_uio; 2458 uio->uio_iovcnt = 1; 2459 uio->uio_iov->iov_base = (caddr_t)arg->aio_buf; 2460 uio->uio_iov->iov_len = arg->aio_nbytes; 2461 uio->uio_loffset = arg->aio_offset; 2462 *reqpp = reqp; 2463 return (0); --- 26 unchanged lines hidden (view full) --- 2490aio_req_alloc(aio_req_t **nreqp, aio_result_t *resultp) 2491{ 2492 aio_req_t *reqp; 2493 aio_t *aiop = curproc->p_aio; 2494 2495 ASSERT(MUTEX_HELD(&aiop->aio_mutex)); 2496 2497 if ((reqp = aiop->aio_free) != NULL) { |
2560 reqp->aio_req_flags = 0; | |
2561 aiop->aio_free = reqp->aio_req_next; | 2498 aiop->aio_free = reqp->aio_req_next; |
2562 /* 2563 * Clustering:This field has to be specifically 2564 * set to null so that the right thing can be 2565 * done in aphysio() 2566 */ 2567 reqp->aio_req_buf.b_iodone = NULL; | 2499 bzero(reqp, sizeof (*reqp)); |
2568 } else { 2569 /* 2570 * Check whether memory is getting tight. 2571 * This is a temporary mechanism to avoid memory 2572 * exhaustion by a single process until we come up 2573 * with a per process solution such as setrlimit(). 2574 */ 2575 if (freemem < desfree) 2576 return (EAGAIN); | 2500 } else { 2501 /* 2502 * Check whether memory is getting tight. 2503 * This is a temporary mechanism to avoid memory 2504 * exhaustion by a single process until we come up 2505 * with a per process solution such as setrlimit(). 2506 */ 2507 if (freemem < desfree) 2508 return (EAGAIN); |
2577 | |
2578 reqp = kmem_zalloc(sizeof (struct aio_req_t), KM_NOSLEEP); 2579 if (reqp == NULL) 2580 return (EAGAIN); | 2509 reqp = kmem_zalloc(sizeof (struct aio_req_t), KM_NOSLEEP); 2510 if (reqp == NULL) 2511 return (EAGAIN); |
2581 reqp->aio_req.aio_uio = &(reqp->aio_req_uio); 2582 reqp->aio_req.aio_uio->uio_iov = &(reqp->aio_req_iov); 2583 reqp->aio_req.aio_private = reqp; | |
2584 } | 2512 } |
2585 | 2513 reqp->aio_req.aio_uio = &reqp->aio_req_uio; 2514 reqp->aio_req.aio_uio->uio_iov = &reqp->aio_req_iov; 2515 reqp->aio_req.aio_private = reqp; |
2586 reqp->aio_req_buf.b_offset = -1; 2587 reqp->aio_req_resultp = resultp; 2588 if (aio_hash_insert(reqp, aiop)) { 2589 reqp->aio_req_next = aiop->aio_free; 2590 aiop->aio_free = reqp; 2591 return (EINVAL); 2592 } 2593 *nreqp = reqp; --- 70 unchanged lines hidden (view full) --- 2664 aiop->aio_flags |= AIO_CLEANUP; 2665 mutex_enter(&as->a_contents); 2666 if (aiop->aio_rqclnup) { 2667 aiop->aio_rqclnup = 0; 2668 rqclnup = 1; 2669 } 2670 2671 if ((rqclnup || AS_ISUNMAPWAIT(as)) && | 2516 reqp->aio_req_buf.b_offset = -1; 2517 reqp->aio_req_resultp = resultp; 2518 if (aio_hash_insert(reqp, aiop)) { 2519 reqp->aio_req_next = aiop->aio_free; 2520 aiop->aio_free = reqp; 2521 return (EINVAL); 2522 } 2523 *nreqp = reqp; --- 70 unchanged lines hidden (view full) --- 2594 aiop->aio_flags |= AIO_CLEANUP; 2595 mutex_enter(&as->a_contents); 2596 if (aiop->aio_rqclnup) { 2597 aiop->aio_rqclnup = 0; 2598 rqclnup = 1; 2599 } 2600 2601 if ((rqclnup || AS_ISUNMAPWAIT(as)) && |
2672 aiop->aio_doneq) { | 2602 aiop->aio_doneq) { |
2673 aio_req_t *doneqhead = aiop->aio_doneq; 2674 mutex_exit(&as->a_contents); 2675 aiop->aio_doneq = NULL; 2676 aio_cleanupq_concat(aiop, doneqhead, AIO_DONEQ); 2677 } else { 2678 mutex_exit(&as->a_contents); 2679 } 2680 } --- 293 unchanged lines hidden (view full) --- 2974 file_t *fp; 2975 file_t *prev_fp = NULL; 2976 int prev_mode = -1; 2977 struct vnode *vp; 2978 aio_lio_t *head; 2979 aio_req_t *reqp; 2980 aio_t *aiop; 2981 caddr_t cbplist; | 2603 aio_req_t *doneqhead = aiop->aio_doneq; 2604 mutex_exit(&as->a_contents); 2605 aiop->aio_doneq = NULL; 2606 aio_cleanupq_concat(aiop, doneqhead, AIO_DONEQ); 2607 } else { 2608 mutex_exit(&as->a_contents); 2609 } 2610 } --- 293 unchanged lines hidden (view full) --- 2904 file_t *fp; 2905 file_t *prev_fp = NULL; 2906 int prev_mode = -1; 2907 struct vnode *vp; 2908 aio_lio_t *head; 2909 aio_req_t *reqp; 2910 aio_t *aiop; 2911 caddr_t cbplist; |
2982 aiocb64_32_t *cbp; 2983 caddr32_t *ucbp; | |
2984 aiocb64_32_t cb64; 2985 aiocb64_32_t *aiocb = &cb64; | 2912 aiocb64_32_t cb64; 2913 aiocb64_32_t *aiocb = &cb64; |
2914 aiocb64_32_t *cbp; 2915 caddr32_t *ucbp; |
|
2986#ifdef _LP64 2987 aiocb_t aiocb_n; 2988#endif 2989 struct sigevent32 sigevk; 2990 sigqueue_t *sqp; 2991 int (*aio_func)(); 2992 int mode; | 2916#ifdef _LP64 2917 aiocb_t aiocb_n; 2918#endif 2919 struct sigevent32 sigevk; 2920 sigqueue_t *sqp; 2921 int (*aio_func)(); 2922 int mode; |
2993 int error = 0, aio_errors = 0; | 2923 int error = 0; 2924 int aio_errors = 0; |
2994 int i; 2995 size_t ssize; 2996 int deadhead = 0; 2997 int aio_notsupported = 0; | 2925 int i; 2926 size_t ssize; 2927 int deadhead = 0; 2928 int aio_notsupported = 0; |
2998 int aio_use_port = 0; | 2929 int lio_head_port; 2930 int aio_port; 2931 int aio_thread; |
2999 port_kevent_t *pkevtp = NULL; 3000 port_notify32_t pnotify; | 2932 port_kevent_t *pkevtp = NULL; 2933 port_notify32_t pnotify; |
2934 int event; |
|
3001 3002 aiop = curproc->p_aio; 3003 if (aiop == NULL || nent <= 0 || nent > _AIO_LISTIO_MAX) 3004 return (EINVAL); 3005 3006 ASSERT(get_udatamodel() == DATAMODEL_ILP32); 3007 3008 ssize = (sizeof (caddr32_t) * nent); 3009 cbplist = kmem_alloc(ssize, KM_SLEEP); 3010 ucbp = (caddr32_t *)cbplist; 3011 | 2935 2936 aiop = curproc->p_aio; 2937 if (aiop == NULL || nent <= 0 || nent > _AIO_LISTIO_MAX) 2938 return (EINVAL); 2939 2940 ASSERT(get_udatamodel() == DATAMODEL_ILP32); 2941 2942 ssize = (sizeof (caddr32_t) * nent); 2943 cbplist = kmem_alloc(ssize, KM_SLEEP); 2944 ucbp = (caddr32_t *)cbplist; 2945 |
3012 if (copyin(aiocb_arg, cbplist, ssize)) { | 2946 if (copyin(aiocb_arg, cbplist, ssize) || 2947 (sigev && copyin(sigev, &sigevk, sizeof (sigevk)))) { |
3013 kmem_free(cbplist, ssize); 3014 return (EFAULT); 3015 } 3016 | 2948 kmem_free(cbplist, ssize); 2949 return (EFAULT); 2950 } 2951 |
3017 if (sigev) { 3018 if (copyin(sigev, &sigevk, sizeof (sigevk))) { | 2952 /* Event Ports */ 2953 if (sigev && 2954 (sigevk.sigev_notify == SIGEV_THREAD || 2955 sigevk.sigev_notify == SIGEV_PORT)) { 2956 if (sigevk.sigev_notify == SIGEV_THREAD) { 2957 pnotify.portnfy_port = sigevk.sigev_signo; 2958 pnotify.portnfy_user = sigevk.sigev_value.sival_ptr; 2959 } else if (copyin( 2960 (void *)(uintptr_t)sigevk.sigev_value.sival_ptr, 2961 &pnotify, sizeof (pnotify))) { |
3019 kmem_free(cbplist, ssize); 3020 return (EFAULT); 3021 } | 2962 kmem_free(cbplist, ssize); 2963 return (EFAULT); 2964 } |
2965 error = port_alloc_event(pnotify.portnfy_port, 2966 PORT_ALLOC_DEFAULT, PORT_SOURCE_AIO, &pkevtp); 2967 if (error) { 2968 if (error == ENOMEM || error == EAGAIN) 2969 error = EAGAIN; 2970 else 2971 error = EINVAL; 2972 kmem_free(cbplist, ssize); 2973 return (error); 2974 } 2975 lio_head_port = pnotify.portnfy_port; |
|
3022 } 3023 3024 /* 3025 * a list head should be allocated if notification is 3026 * enabled for this list. 3027 */ 3028 head = NULL; 3029 | 2976 } 2977 2978 /* 2979 * a list head should be allocated if notification is 2980 * enabled for this list. 2981 */ 2982 head = NULL; 2983 |
3030 /* Event Ports */ 3031 3032 if (sigev && sigevk.sigev_notify == SIGEV_PORT) { 3033 /* Use PORT for completion notification */ 3034 if (copyin((void *)(uintptr_t)sigevk.sigev_value.sival_ptr, 3035 &pnotify, sizeof (port_notify32_t))) { 3036 kmem_free(cbplist, ssize); 3037 return (EFAULT); 3038 } 3039 /* use event ports for the list of aiocbs */ 3040 aio_use_port = 1; 3041 error = port_alloc_event(pnotify.portnfy_port, 3042 PORT_ALLOC_PRIVATE, PORT_SOURCE_AIO, &pkevtp); 3043 if (error) { 3044 if (error == ENOMEM) 3045 error = EAGAIN; 3046 kmem_free(cbplist, ssize); 3047 return (error); 3048 } 3049 } else if ((mode_arg == LIO_WAIT) || sigev) { | 2984 if (mode_arg == LIO_WAIT || sigev) { |
3050 mutex_enter(&aiop->aio_mutex); 3051 error = aio_lio_alloc(&head); 3052 mutex_exit(&aiop->aio_mutex); 3053 if (error) 3054 goto done; 3055 deadhead = 1; 3056 head->lio_nent = nent; 3057 head->lio_refcnt = nent; | 2985 mutex_enter(&aiop->aio_mutex); 2986 error = aio_lio_alloc(&head); 2987 mutex_exit(&aiop->aio_mutex); 2988 if (error) 2989 goto done; 2990 deadhead = 1; 2991 head->lio_nent = nent; 2992 head->lio_refcnt = nent; |
3058 if (sigev && (sigevk.sigev_notify == SIGEV_SIGNAL) && 3059 (sigevk.sigev_signo > 0 && sigevk.sigev_signo < NSIG)) { | 2993 head->lio_port = -1; 2994 head->lio_portkev = NULL; 2995 if (sigev && sigevk.sigev_notify == SIGEV_SIGNAL && 2996 sigevk.sigev_signo > 0 && sigevk.sigev_signo < NSIG) { |
3060 sqp = kmem_zalloc(sizeof (sigqueue_t), KM_NOSLEEP); 3061 if (sqp == NULL) { 3062 error = EAGAIN; 3063 goto done; 3064 } 3065 sqp->sq_func = NULL; 3066 sqp->sq_next = NULL; 3067 sqp->sq_info.si_code = SI_ASYNCIO; 3068 sqp->sq_info.si_pid = curproc->p_pid; 3069 sqp->sq_info.si_ctid = PRCTID(curproc); 3070 sqp->sq_info.si_zoneid = getzoneid(); 3071 sqp->sq_info.si_uid = crgetuid(curproc->p_cred); 3072 sqp->sq_info.si_signo = sigevk.sigev_signo; 3073 sqp->sq_info.si_value.sival_int = 3074 sigevk.sigev_value.sival_int; 3075 head->lio_sigqp = sqp; 3076 } else { 3077 head->lio_sigqp = NULL; 3078 } | 2997 sqp = kmem_zalloc(sizeof (sigqueue_t), KM_NOSLEEP); 2998 if (sqp == NULL) { 2999 error = EAGAIN; 3000 goto done; 3001 } 3002 sqp->sq_func = NULL; 3003 sqp->sq_next = NULL; 3004 sqp->sq_info.si_code = SI_ASYNCIO; 3005 sqp->sq_info.si_pid = curproc->p_pid; 3006 sqp->sq_info.si_ctid = PRCTID(curproc); 3007 sqp->sq_info.si_zoneid = getzoneid(); 3008 sqp->sq_info.si_uid = crgetuid(curproc->p_cred); 3009 sqp->sq_info.si_signo = sigevk.sigev_signo; 3010 sqp->sq_info.si_value.sival_int = 3011 sigevk.sigev_value.sival_int; 3012 head->lio_sigqp = sqp; 3013 } else { 3014 head->lio_sigqp = NULL; 3015 } |
3016 if (pkevtp) { 3017 /* 3018 * Prepare data to send when list of aiocb's 3019 * has completed. 3020 */ 3021 port_init_event(pkevtp, (uintptr_t)sigev, 3022 (void *)(uintptr_t)pnotify.portnfy_user, 3023 NULL, head); 3024 pkevtp->portkev_events = AIOLIO64; 3025 head->lio_portkev = pkevtp; 3026 head->lio_port = pnotify.portnfy_port; 3027 } |
|
3079 } 3080 3081 for (i = 0; i < nent; i++, ucbp++) { 3082 3083 cbp = (aiocb64_32_t *)(uintptr_t)*ucbp; 3084 /* skip entry if it can't be copied. */ | 3028 } 3029 3030 for (i = 0; i < nent; i++, ucbp++) { 3031 3032 cbp = (aiocb64_32_t *)(uintptr_t)*ucbp; 3033 /* skip entry if it can't be copied. */ |
3085 if (cbp == NULL || copyin(cbp, aiocb, sizeof (aiocb64_32_t))) { | 3034 if (cbp == NULL || copyin(cbp, aiocb, sizeof (*aiocb))) { |
3086 if (head) { 3087 mutex_enter(&aiop->aio_mutex); 3088 head->lio_nent--; 3089 head->lio_refcnt--; 3090 mutex_exit(&aiop->aio_mutex); 3091 } 3092 continue; 3093 } 3094 3095 /* skip if opcode for aiocb is LIO_NOP */ | 3035 if (head) { 3036 mutex_enter(&aiop->aio_mutex); 3037 head->lio_nent--; 3038 head->lio_refcnt--; 3039 mutex_exit(&aiop->aio_mutex); 3040 } 3041 continue; 3042 } 3043 3044 /* skip if opcode for aiocb is LIO_NOP */ |
3096 | |
3097 mode = aiocb->aio_lio_opcode; 3098 if (mode == LIO_NOP) { 3099 cbp = NULL; 3100 if (head) { 3101 mutex_enter(&aiop->aio_mutex); 3102 head->lio_nent--; 3103 head->lio_refcnt--; 3104 mutex_exit(&aiop->aio_mutex); --- 9 unchanged lines hidden (view full) --- 3114 head->lio_nent--; 3115 head->lio_refcnt--; 3116 mutex_exit(&aiop->aio_mutex); 3117 } 3118 aio_errors++; 3119 continue; 3120 } 3121 | 3045 mode = aiocb->aio_lio_opcode; 3046 if (mode == LIO_NOP) { 3047 cbp = NULL; 3048 if (head) { 3049 mutex_enter(&aiop->aio_mutex); 3050 head->lio_nent--; 3051 head->lio_refcnt--; 3052 mutex_exit(&aiop->aio_mutex); --- 9 unchanged lines hidden (view full) --- 3062 head->lio_nent--; 3063 head->lio_refcnt--; 3064 mutex_exit(&aiop->aio_mutex); 3065 } 3066 aio_errors++; 3067 continue; 3068 } 3069 |
3122 vp = fp->f_vnode; 3123 | |
3124 /* 3125 * check the permission of the partition 3126 */ | 3070 /* 3071 * check the permission of the partition 3072 */ |
3127 mode = aiocb->aio_lio_opcode; | |
3128 if ((fp->f_flag & mode) == 0) { 3129 releasef(aiocb->aio_fildes); 3130 lio_set_uerror(&cbp->aio_resultp, EBADF); 3131 if (head) { 3132 mutex_enter(&aiop->aio_mutex); 3133 head->lio_nent--; 3134 head->lio_refcnt--; 3135 mutex_exit(&aiop->aio_mutex); 3136 } 3137 aio_errors++; 3138 continue; 3139 } 3140 3141 /* 3142 * common case where requests are to the same fd 3143 * for the same r/w operation 3144 * for UFS, need to set EBADFD 3145 */ | 3073 if ((fp->f_flag & mode) == 0) { 3074 releasef(aiocb->aio_fildes); 3075 lio_set_uerror(&cbp->aio_resultp, EBADF); 3076 if (head) { 3077 mutex_enter(&aiop->aio_mutex); 3078 head->lio_nent--; 3079 head->lio_refcnt--; 3080 mutex_exit(&aiop->aio_mutex); 3081 } 3082 aio_errors++; 3083 continue; 3084 } 3085 3086 /* 3087 * common case where requests are to the same fd 3088 * for the same r/w operation 3089 * for UFS, need to set EBADFD 3090 */ |
3146 if ((fp != prev_fp) || (mode != prev_mode)) { | 3091 vp = fp->f_vnode; 3092 if (fp != prev_fp || mode != prev_mode) { |
3147 aio_func = check_vp(vp, mode); 3148 if (aio_func == NULL) { 3149 prev_fp = NULL; 3150 releasef(aiocb->aio_fildes); 3151 lio_set_uerror(&cbp->aio_resultp, EBADFD); 3152 aio_notsupported++; 3153 if (head) { 3154 mutex_enter(&aiop->aio_mutex); 3155 head->lio_nent--; 3156 head->lio_refcnt--; 3157 mutex_exit(&aiop->aio_mutex); 3158 } 3159 continue; 3160 } else { 3161 prev_fp = fp; 3162 prev_mode = mode; 3163 } 3164 } | 3093 aio_func = check_vp(vp, mode); 3094 if (aio_func == NULL) { 3095 prev_fp = NULL; 3096 releasef(aiocb->aio_fildes); 3097 lio_set_uerror(&cbp->aio_resultp, EBADFD); 3098 aio_notsupported++; 3099 if (head) { 3100 mutex_enter(&aiop->aio_mutex); 3101 head->lio_nent--; 3102 head->lio_refcnt--; 3103 mutex_exit(&aiop->aio_mutex); 3104 } 3105 continue; 3106 } else { 3107 prev_fp = fp; 3108 prev_mode = mode; 3109 } 3110 } |
3111 |
|
3165#ifdef _LP64 3166 aiocb_LFton(aiocb, &aiocb_n); 3167 error = aio_req_setup(&reqp, aiop, &aiocb_n, | 3112#ifdef _LP64 3113 aiocb_LFton(aiocb, &aiocb_n); 3114 error = aio_req_setup(&reqp, aiop, &aiocb_n, |
3168 (aio_result_t *)&cbp->aio_resultp, aio_use_port, vp); | 3115 (aio_result_t *)&cbp->aio_resultp, vp); |
3169#else 3170 error = aio_req_setupLF(&reqp, aiop, aiocb, | 3116#else 3117 error = aio_req_setupLF(&reqp, aiop, aiocb, |
3171 (aio_result_t *)&cbp->aio_resultp, aio_use_port, vp); | 3118 (aio_result_t *)&cbp->aio_resultp, vp); |
3172#endif /* _LP64 */ 3173 if (error) { 3174 releasef(aiocb->aio_fildes); | 3119#endif /* _LP64 */ 3120 if (error) { 3121 releasef(aiocb->aio_fildes); |
3122 lio_set_uerror(&cbp->aio_resultp, error); |
|
3175 if (head) { 3176 mutex_enter(&aiop->aio_mutex); 3177 head->lio_nent--; 3178 head->lio_refcnt--; 3179 mutex_exit(&aiop->aio_mutex); 3180 } 3181 aio_errors++; 3182 continue; --- 6 unchanged lines hidden (view full) --- 3189 * Set the errno field now before sending the request to 3190 * the driver to avoid a race condition 3191 */ 3192 (void) suword32(&cbp->aio_resultp.aio_errno, 3193 EINPROGRESS); 3194 3195 reqp->aio_req_iocb.iocb32 = *ucbp; 3196 | 3123 if (head) { 3124 mutex_enter(&aiop->aio_mutex); 3125 head->lio_nent--; 3126 head->lio_refcnt--; 3127 mutex_exit(&aiop->aio_mutex); 3128 } 3129 aio_errors++; 3130 continue; --- 6 unchanged lines hidden (view full) --- 3137 * Set the errno field now before sending the request to 3138 * the driver to avoid a race condition 3139 */ 3140 (void) suword32(&cbp->aio_resultp.aio_errno, 3141 EINPROGRESS); 3142 3143 reqp->aio_req_iocb.iocb32 = *ucbp; 3144 |
3197 if (aio_use_port) { 3198 reqp->aio_req_port = pnotify.portnfy_port; 3199 error = aio_req_assoc_port32(&aiocb->aio_sigevent, 3200 (void *)(uintptr_t)pnotify.portnfy_user, 3201 (aiocb_t *)(uintptr_t)*ucbp, reqp, pkevtp); | 3145 event = (mode == LIO_READ)? AIOAREAD64 : AIOAWRITE64; 3146 aio_port = (aiocb->aio_sigevent.sigev_notify == SIGEV_PORT); 3147 aio_thread = (aiocb->aio_sigevent.sigev_notify == SIGEV_THREAD); 3148 if (aio_port | aio_thread) { 3149 port_kevent_t *lpkevp; 3150 /* 3151 * Prepare data to send with each aiocb completed. 3152 */ 3153 if (aio_port) { 3154 void *paddr = (void *)(uintptr_t) 3155 aiocb->aio_sigevent.sigev_value.sival_ptr; 3156 if (copyin(paddr, &pnotify, sizeof (pnotify))) 3157 error = EFAULT; 3158 } else { /* aio_thread */ 3159 pnotify.portnfy_port = 3160 aiocb->aio_sigevent.sigev_signo; 3161 pnotify.portnfy_user = 3162 aiocb->aio_sigevent.sigev_value.sival_ptr; 3163 } 3164 if (error) 3165 /* EMPTY */; 3166 else if (pkevtp != NULL && 3167 pnotify.portnfy_port == lio_head_port) 3168 error = port_dup_event(pkevtp, &lpkevp, 3169 PORT_ALLOC_DEFAULT); 3170 else 3171 error = port_alloc_event(pnotify.portnfy_port, 3172 PORT_ALLOC_DEFAULT, PORT_SOURCE_AIO, 3173 &lpkevp); 3174 if (error == 0) { 3175 port_init_event(lpkevp, (uintptr_t)*ucbp, 3176 (void *)(uintptr_t)pnotify.portnfy_user, 3177 aio_port_callback, reqp); 3178 lpkevp->portkev_events = event; 3179 reqp->aio_req_portkev = lpkevp; 3180 reqp->aio_req_port = pnotify.portnfy_port; 3181 } |
3202 } 3203 3204 /* 3205 * send the request to driver. | 3182 } 3183 3184 /* 3185 * send the request to driver. |
3206 * Clustering: If PXFS vnode, call PXFS function. | |
3207 */ 3208 if (error == 0) { 3209 if (aiocb->aio_nbytes == 0) { 3210 clear_active_fd(aiocb->aio_fildes); 3211 aio_zerolen(reqp); 3212 continue; 3213 } 3214 error = (*aio_func)(vp, (aio_req_t *)&reqp->aio_req, --- 18 unchanged lines hidden (view full) --- 3233 else 3234 aio_errors++; 3235 lio_set_error(reqp); 3236 } else { 3237 clear_active_fd(aiocb->aio_fildes); 3238 } 3239 } 3240 | 3186 */ 3187 if (error == 0) { 3188 if (aiocb->aio_nbytes == 0) { 3189 clear_active_fd(aiocb->aio_fildes); 3190 aio_zerolen(reqp); 3191 continue; 3192 } 3193 error = (*aio_func)(vp, (aio_req_t *)&reqp->aio_req, --- 18 unchanged lines hidden (view full) --- 3212 else 3213 aio_errors++; 3214 lio_set_error(reqp); 3215 } else { 3216 clear_active_fd(aiocb->aio_fildes); 3217 } 3218 } 3219 |
3241 if (pkevtp) 3242 port_free_event(pkevtp); 3243 | |
3244 if (aio_notsupported) { 3245 error = ENOTSUP; 3246 } else if (aio_errors) { 3247 /* 3248 * return EIO if any request failed 3249 */ 3250 error = EIO; 3251 } --- 11 unchanged lines hidden (view full) --- 3263 alio_cleanup(aiop, (aiocb_t **)cbplist, nent, AIO_LARGEFILE); 3264 } 3265 3266done: 3267 kmem_free(cbplist, ssize); 3268 if (deadhead) { 3269 if (head->lio_sigqp) 3270 kmem_free(head->lio_sigqp, sizeof (sigqueue_t)); | 3220 if (aio_notsupported) { 3221 error = ENOTSUP; 3222 } else if (aio_errors) { 3223 /* 3224 * return EIO if any request failed 3225 */ 3226 error = EIO; 3227 } --- 11 unchanged lines hidden (view full) --- 3239 alio_cleanup(aiop, (aiocb_t **)cbplist, nent, AIO_LARGEFILE); 3240 } 3241 3242done: 3243 kmem_free(cbplist, ssize); 3244 if (deadhead) { 3245 if (head->lio_sigqp) 3246 kmem_free(head->lio_sigqp, sizeof (sigqueue_t)); |
3247 if (head->lio_portkev) 3248 port_free_event(head->lio_portkev); |
|
3271 kmem_free(head, sizeof (aio_lio_t)); 3272 } 3273 return (error); 3274} 3275 3276#ifdef _SYSCALL32_IMPL 3277static void 3278aiocb_LFton(aiocb64_32_t *src, aiocb_t *dest) --- 20 unchanged lines hidden (view full) --- 3299 dest->aio_lio_opcode = src->aio_lio_opcode; 3300 dest->aio_state = src->aio_state; 3301 dest->aio__pad[0] = src->aio__pad[0]; 3302} 3303#endif 3304 3305/* 3306 * This function is used only for largefile calls made by | 3249 kmem_free(head, sizeof (aio_lio_t)); 3250 } 3251 return (error); 3252} 3253 3254#ifdef _SYSCALL32_IMPL 3255static void 3256aiocb_LFton(aiocb64_32_t *src, aiocb_t *dest) --- 20 unchanged lines hidden (view full) --- 3277 dest->aio_lio_opcode = src->aio_lio_opcode; 3278 dest->aio_state = src->aio_state; 3279 dest->aio__pad[0] = src->aio__pad[0]; 3280} 3281#endif 3282 3283/* 3284 * This function is used only for largefile calls made by |
3307 * 32 bit applications on 32 bit kernel. | 3285 * 32 bit applications. |
3308 */ 3309static int 3310aio_req_setupLF( 3311 aio_req_t **reqpp, 3312 aio_t *aiop, 3313 aiocb64_32_t *arg, 3314 aio_result_t *resultp, | 3286 */ 3287static int 3288aio_req_setupLF( 3289 aio_req_t **reqpp, 3290 aio_t *aiop, 3291 aiocb64_32_t *arg, 3292 aio_result_t *resultp, |
3315 int port, | |
3316 vnode_t *vp) 3317{ | 3293 vnode_t *vp) 3294{ |
3295 sigqueue_t *sqp = NULL; |
|
3318 aio_req_t *reqp; | 3296 aio_req_t *reqp; |
3319 sigqueue_t *sqp; 3320 struct uio *uio; 3321 3322 struct sigevent *sigev; | 3297 struct uio *uio; 3298 struct sigevent32 *sigev; |
3323 int error; 3324 | 3299 int error; 3300 |
3325 sigev = (struct sigevent *)&arg->aio_sigevent; 3326 if ((sigev->sigev_notify == SIGEV_SIGNAL) && 3327 (sigev->sigev_signo > 0 && sigev->sigev_signo < NSIG)) { | 3301 sigev = &arg->aio_sigevent; 3302 if (sigev->sigev_notify == SIGEV_SIGNAL && 3303 sigev->sigev_signo > 0 && sigev->sigev_signo < NSIG) { |
3328 sqp = kmem_zalloc(sizeof (sigqueue_t), KM_NOSLEEP); 3329 if (sqp == NULL) 3330 return (EAGAIN); 3331 sqp->sq_func = NULL; 3332 sqp->sq_next = NULL; 3333 sqp->sq_info.si_code = SI_ASYNCIO; 3334 sqp->sq_info.si_pid = curproc->p_pid; 3335 sqp->sq_info.si_ctid = PRCTID(curproc); 3336 sqp->sq_info.si_zoneid = getzoneid(); 3337 sqp->sq_info.si_uid = crgetuid(curproc->p_cred); 3338 sqp->sq_info.si_signo = sigev->sigev_signo; | 3304 sqp = kmem_zalloc(sizeof (sigqueue_t), KM_NOSLEEP); 3305 if (sqp == NULL) 3306 return (EAGAIN); 3307 sqp->sq_func = NULL; 3308 sqp->sq_next = NULL; 3309 sqp->sq_info.si_code = SI_ASYNCIO; 3310 sqp->sq_info.si_pid = curproc->p_pid; 3311 sqp->sq_info.si_ctid = PRCTID(curproc); 3312 sqp->sq_info.si_zoneid = getzoneid(); 3313 sqp->sq_info.si_uid = crgetuid(curproc->p_cred); 3314 sqp->sq_info.si_signo = sigev->sigev_signo; |
3339 sqp->sq_info.si_value = sigev->sigev_value; 3340 } else 3341 sqp = NULL; | 3315 sqp->sq_info.si_value.sival_int = sigev->sigev_value.sival_int; 3316 } |
3342 3343 mutex_enter(&aiop->aio_mutex); 3344 3345 if (aiop->aio_flags & AIO_REQ_BLOCK) { 3346 mutex_exit(&aiop->aio_mutex); 3347 if (sqp) 3348 kmem_free(sqp, sizeof (sigqueue_t)); 3349 return (EIO); --- 6 unchanged lines hidden (view full) --- 3356 mutex_exit(&aiop->aio_mutex); 3357 if (sqp) 3358 kmem_free(sqp, sizeof (sigqueue_t)); 3359 return (error); 3360 } 3361 aiop->aio_pending++; 3362 aiop->aio_outstanding++; 3363 reqp->aio_req_flags = AIO_PENDING; | 3317 3318 mutex_enter(&aiop->aio_mutex); 3319 3320 if (aiop->aio_flags & AIO_REQ_BLOCK) { 3321 mutex_exit(&aiop->aio_mutex); 3322 if (sqp) 3323 kmem_free(sqp, sizeof (sigqueue_t)); 3324 return (EIO); --- 6 unchanged lines hidden (view full) --- 3331 mutex_exit(&aiop->aio_mutex); 3332 if (sqp) 3333 kmem_free(sqp, sizeof (sigqueue_t)); 3334 return (error); 3335 } 3336 aiop->aio_pending++; 3337 aiop->aio_outstanding++; 3338 reqp->aio_req_flags = AIO_PENDING; |
3364 if (port) 3365 aio_enq_port_pending(aiop, reqp); | 3339 if (sigev->sigev_notify == SIGEV_THREAD || 3340 sigev->sigev_notify == SIGEV_PORT) 3341 aio_enq(&aiop->aio_portpending, reqp, 0); |
3366 mutex_exit(&aiop->aio_mutex); 3367 /* 3368 * initialize aio request. 3369 */ 3370 reqp->aio_req_fd = arg->aio_fildes; 3371 reqp->aio_req_sigqp = sqp; 3372 reqp->aio_req_iocb.iocb = NULL; | 3342 mutex_exit(&aiop->aio_mutex); 3343 /* 3344 * initialize aio request. 3345 */ 3346 reqp->aio_req_fd = arg->aio_fildes; 3347 reqp->aio_req_sigqp = sqp; 3348 reqp->aio_req_iocb.iocb = NULL; |
3349 reqp->aio_req_lio = NULL; |
|
3373 reqp->aio_req_buf.b_file = vp; 3374 uio = reqp->aio_req.aio_uio; 3375 uio->uio_iovcnt = 1; 3376 uio->uio_iov->iov_base = (caddr_t)(uintptr_t)arg->aio_buf; 3377 uio->uio_iov->iov_len = arg->aio_nbytes; 3378 uio->uio_loffset = arg->aio_offset; 3379 *reqpp = reqp; 3380 return (0); 3381} 3382 3383/* 3384 * This routine is called when a non largefile call is made by a 32bit 3385 * process on a ILP32 or LP64 kernel. 3386 */ 3387static int 3388alio32( 3389 int mode_arg, 3390 void *aiocb_arg, 3391 int nent, | 3350 reqp->aio_req_buf.b_file = vp; 3351 uio = reqp->aio_req.aio_uio; 3352 uio->uio_iovcnt = 1; 3353 uio->uio_iov->iov_base = (caddr_t)(uintptr_t)arg->aio_buf; 3354 uio->uio_iov->iov_len = arg->aio_nbytes; 3355 uio->uio_loffset = arg->aio_offset; 3356 *reqpp = reqp; 3357 return (0); 3358} 3359 3360/* 3361 * This routine is called when a non largefile call is made by a 32bit 3362 * process on a ILP32 or LP64 kernel. 3363 */ 3364static int 3365alio32( 3366 int mode_arg, 3367 void *aiocb_arg, 3368 int nent, |
3392 void *sigev_arg) | 3369 void *sigev) |
3393{ 3394 file_t *fp; 3395 file_t *prev_fp = NULL; 3396 int prev_mode = -1; 3397 struct vnode *vp; 3398 aio_lio_t *head; 3399 aio_req_t *reqp; 3400 aio_t *aiop; | 3370{ 3371 file_t *fp; 3372 file_t *prev_fp = NULL; 3373 int prev_mode = -1; 3374 struct vnode *vp; 3375 aio_lio_t *head; 3376 aio_req_t *reqp; 3377 aio_t *aiop; |
3378 caddr_t cbplist; |
|
3401 aiocb_t cb; 3402 aiocb_t *aiocb = &cb; | 3379 aiocb_t cb; 3380 aiocb_t *aiocb = &cb; |
3403 caddr_t cbplist; | |
3404#ifdef _LP64 3405 aiocb32_t *cbp; 3406 caddr32_t *ucbp; 3407 aiocb32_t cb32; 3408 aiocb32_t *aiocb32 = &cb32; | 3381#ifdef _LP64 3382 aiocb32_t *cbp; 3383 caddr32_t *ucbp; 3384 aiocb32_t cb32; 3385 aiocb32_t *aiocb32 = &cb32; |
3409 struct sigevent32 sigev; | 3386 struct sigevent32 sigevk; |
3410#else 3411 aiocb_t *cbp, **ucbp; | 3387#else 3388 aiocb_t *cbp, **ucbp; |
3412 struct sigevent sigev; | 3389 struct sigevent sigevk; |
3413#endif 3414 sigqueue_t *sqp; 3415 int (*aio_func)(); 3416 int mode; | 3390#endif 3391 sigqueue_t *sqp; 3392 int (*aio_func)(); 3393 int mode; |
3417 int error = 0, aio_errors = 0; | 3394 int error = 0; 3395 int aio_errors = 0; |
3418 int i; 3419 size_t ssize; 3420 int deadhead = 0; 3421 int aio_notsupported = 0; | 3396 int i; 3397 size_t ssize; 3398 int deadhead = 0; 3399 int aio_notsupported = 0; |
3422 int aio_use_port = 0; | 3400 int lio_head_port; 3401 int aio_port; 3402 int aio_thread; |
3423 port_kevent_t *pkevtp = NULL; 3424#ifdef _LP64 3425 port_notify32_t pnotify; 3426#else 3427 port_notify_t pnotify; 3428#endif | 3403 port_kevent_t *pkevtp = NULL; 3404#ifdef _LP64 3405 port_notify32_t pnotify; 3406#else 3407 port_notify_t pnotify; 3408#endif |
3409 int event; 3410 |
|
3429 aiop = curproc->p_aio; 3430 if (aiop == NULL || nent <= 0 || nent > _AIO_LISTIO_MAX) 3431 return (EINVAL); 3432 3433#ifdef _LP64 3434 ssize = (sizeof (caddr32_t) * nent); 3435#else 3436 ssize = (sizeof (aiocb_t *) * nent); 3437#endif 3438 cbplist = kmem_alloc(ssize, KM_SLEEP); 3439 ucbp = (void *)cbplist; 3440 | 3411 aiop = curproc->p_aio; 3412 if (aiop == NULL || nent <= 0 || nent > _AIO_LISTIO_MAX) 3413 return (EINVAL); 3414 3415#ifdef _LP64 3416 ssize = (sizeof (caddr32_t) * nent); 3417#else 3418 ssize = (sizeof (aiocb_t *) * nent); 3419#endif 3420 cbplist = kmem_alloc(ssize, KM_SLEEP); 3421 ucbp = (void *)cbplist; 3422 |
3441 if (copyin(aiocb_arg, cbplist, ssize)) { | 3423 if (copyin(aiocb_arg, cbplist, ssize) || 3424 (sigev && copyin(sigev, &sigevk, sizeof (struct sigevent32)))) { |
3442 kmem_free(cbplist, ssize); 3443 return (EFAULT); 3444 } 3445 | 3425 kmem_free(cbplist, ssize); 3426 return (EFAULT); 3427 } 3428 |
3446 if (sigev_arg) { 3447 if (copyin(sigev_arg, &sigev, sizeof (struct sigevent32))) { 3448 kmem_free(cbplist, ssize); 3449 return (EFAULT); 3450 } 3451 } 3452 3453 /* 3454 * a list head should be allocated if notification is 3455 * enabled for this list. 3456 */ 3457 head = NULL; 3458 | |
3459 /* Event Ports */ | 3429 /* Event Ports */ |
3460 3461 if (sigev_arg && sigev.sigev_notify == SIGEV_PORT) { 3462 /* Use PORT for completion notification */ 3463 if (copyin((void *)(uintptr_t)sigev.sigev_value.sival_ptr, 3464 &pnotify, sizeof (port_notify32_t))) { | 3430 if (sigev && 3431 (sigevk.sigev_notify == SIGEV_THREAD || 3432 sigevk.sigev_notify == SIGEV_PORT)) { 3433 if (sigevk.sigev_notify == SIGEV_THREAD) { 3434 pnotify.portnfy_port = sigevk.sigev_signo; 3435 pnotify.portnfy_user = sigevk.sigev_value.sival_ptr; 3436 } else if (copyin( 3437 (void *)(uintptr_t)sigevk.sigev_value.sival_ptr, 3438 &pnotify, sizeof (pnotify))) { |
3465 kmem_free(cbplist, ssize); 3466 return (EFAULT); 3467 } | 3439 kmem_free(cbplist, ssize); 3440 return (EFAULT); 3441 } |
3468 /* use event ports for the list of aiocbs */ 3469 aio_use_port = 1; | |
3470 error = port_alloc_event(pnotify.portnfy_port, | 3442 error = port_alloc_event(pnotify.portnfy_port, |
3471 PORT_ALLOC_PRIVATE, PORT_SOURCE_AIO, &pkevtp); | 3443 PORT_ALLOC_DEFAULT, PORT_SOURCE_AIO, &pkevtp); |
3472 if (error) { | 3444 if (error) { |
3473 if ((error == ENOMEM) || (error == EAGAIN)) | 3445 if (error == ENOMEM || error == EAGAIN) |
3474 error = EAGAIN; 3475 else 3476 error = EINVAL; 3477 kmem_free(cbplist, ssize); 3478 return (error); 3479 } | 3446 error = EAGAIN; 3447 else 3448 error = EINVAL; 3449 kmem_free(cbplist, ssize); 3450 return (error); 3451 } |
3480 } else if ((mode_arg == LIO_WAIT) || sigev_arg) { | 3452 lio_head_port = pnotify.portnfy_port; 3453 } 3454 3455 /* 3456 * a list head should be allocated if notification is 3457 * enabled for this list. 3458 */ 3459 head = NULL; 3460 3461 if (mode_arg == LIO_WAIT || sigev) { |
3481 mutex_enter(&aiop->aio_mutex); 3482 error = aio_lio_alloc(&head); 3483 mutex_exit(&aiop->aio_mutex); 3484 if (error) 3485 goto done; 3486 deadhead = 1; 3487 head->lio_nent = nent; 3488 head->lio_refcnt = nent; | 3462 mutex_enter(&aiop->aio_mutex); 3463 error = aio_lio_alloc(&head); 3464 mutex_exit(&aiop->aio_mutex); 3465 if (error) 3466 goto done; 3467 deadhead = 1; 3468 head->lio_nent = nent; 3469 head->lio_refcnt = nent; |
3489 if (sigev_arg && (sigev.sigev_notify == SIGEV_SIGNAL) && 3490 (sigev.sigev_signo > 0 && sigev.sigev_signo < NSIG)) { | 3470 head->lio_port = -1; 3471 head->lio_portkev = NULL; 3472 if (sigev && sigevk.sigev_notify == SIGEV_SIGNAL && 3473 sigevk.sigev_signo > 0 && sigevk.sigev_signo < NSIG) { |
3491 sqp = kmem_zalloc(sizeof (sigqueue_t), KM_NOSLEEP); 3492 if (sqp == NULL) { 3493 error = EAGAIN; 3494 goto done; 3495 } 3496 sqp->sq_func = NULL; 3497 sqp->sq_next = NULL; 3498 sqp->sq_info.si_code = SI_ASYNCIO; 3499 sqp->sq_info.si_pid = curproc->p_pid; 3500 sqp->sq_info.si_ctid = PRCTID(curproc); 3501 sqp->sq_info.si_zoneid = getzoneid(); 3502 sqp->sq_info.si_uid = crgetuid(curproc->p_cred); | 3474 sqp = kmem_zalloc(sizeof (sigqueue_t), KM_NOSLEEP); 3475 if (sqp == NULL) { 3476 error = EAGAIN; 3477 goto done; 3478 } 3479 sqp->sq_func = NULL; 3480 sqp->sq_next = NULL; 3481 sqp->sq_info.si_code = SI_ASYNCIO; 3482 sqp->sq_info.si_pid = curproc->p_pid; 3483 sqp->sq_info.si_ctid = PRCTID(curproc); 3484 sqp->sq_info.si_zoneid = getzoneid(); 3485 sqp->sq_info.si_uid = crgetuid(curproc->p_cred); |
3503 sqp->sq_info.si_signo = sigev.sigev_signo; | 3486 sqp->sq_info.si_signo = sigevk.sigev_signo; |
3504 sqp->sq_info.si_value.sival_int = | 3487 sqp->sq_info.si_value.sival_int = |
3505 sigev.sigev_value.sival_int; | 3488 sigevk.sigev_value.sival_int; |
3506 head->lio_sigqp = sqp; 3507 } else { 3508 head->lio_sigqp = NULL; 3509 } | 3489 head->lio_sigqp = sqp; 3490 } else { 3491 head->lio_sigqp = NULL; 3492 } |
3493 if (pkevtp) { 3494 /* 3495 * Prepare data to send when list of aiocb's has 3496 * completed. 3497 */ 3498 port_init_event(pkevtp, (uintptr_t)sigev, 3499 (void *)(uintptr_t)pnotify.portnfy_user, 3500 NULL, head); 3501 pkevtp->portkev_events = AIOLIO; 3502 head->lio_portkev = pkevtp; 3503 head->lio_port = pnotify.portnfy_port; 3504 } |
|
3510 } 3511 3512 for (i = 0; i < nent; i++, ucbp++) { 3513 3514 /* skip entry if it can't be copied. */ 3515#ifdef _LP64 3516 cbp = (aiocb32_t *)(uintptr_t)*ucbp; | 3505 } 3506 3507 for (i = 0; i < nent; i++, ucbp++) { 3508 3509 /* skip entry if it can't be copied. */ 3510#ifdef _LP64 3511 cbp = (aiocb32_t *)(uintptr_t)*ucbp; |
3517 if (cbp == NULL || copyin(cbp, aiocb32, sizeof (aiocb32_t))) { | 3512 if (cbp == NULL || copyin(cbp, aiocb32, sizeof (*aiocb32))) |
3518#else 3519 cbp = (aiocb_t *)*ucbp; | 3513#else 3514 cbp = (aiocb_t *)*ucbp; |
3520 if (cbp == NULL || copyin(cbp, aiocb, sizeof (aiocb_t))) { | 3515 if (cbp == NULL || copyin(cbp, aiocb, sizeof (*aiocb))) |
3521#endif | 3516#endif |
3517 { |
|
3522 if (head) { 3523 mutex_enter(&aiop->aio_mutex); 3524 head->lio_nent--; 3525 head->lio_refcnt--; 3526 mutex_exit(&aiop->aio_mutex); 3527 } 3528 continue; 3529 } 3530#ifdef _LP64 3531 /* 3532 * copy 32 bit structure into 64 bit structure 3533 */ 3534 aiocb_32ton(aiocb32, aiocb); 3535#endif /* _LP64 */ 3536 3537 /* skip if opcode for aiocb is LIO_NOP */ | 3518 if (head) { 3519 mutex_enter(&aiop->aio_mutex); 3520 head->lio_nent--; 3521 head->lio_refcnt--; 3522 mutex_exit(&aiop->aio_mutex); 3523 } 3524 continue; 3525 } 3526#ifdef _LP64 3527 /* 3528 * copy 32 bit structure into 64 bit structure 3529 */ 3530 aiocb_32ton(aiocb32, aiocb); 3531#endif /* _LP64 */ 3532 3533 /* skip if opcode for aiocb is LIO_NOP */ |
3538 | |
3539 mode = aiocb->aio_lio_opcode; 3540 if (mode == LIO_NOP) { 3541 cbp = NULL; 3542 if (head) { 3543 mutex_enter(&aiop->aio_mutex); 3544 head->lio_nent--; 3545 head->lio_refcnt--; 3546 mutex_exit(&aiop->aio_mutex); --- 9 unchanged lines hidden (view full) --- 3556 head->lio_nent--; 3557 head->lio_refcnt--; 3558 mutex_exit(&aiop->aio_mutex); 3559 } 3560 aio_errors++; 3561 continue; 3562 } 3563 | 3534 mode = aiocb->aio_lio_opcode; 3535 if (mode == LIO_NOP) { 3536 cbp = NULL; 3537 if (head) { 3538 mutex_enter(&aiop->aio_mutex); 3539 head->lio_nent--; 3540 head->lio_refcnt--; 3541 mutex_exit(&aiop->aio_mutex); --- 9 unchanged lines hidden (view full) --- 3551 head->lio_nent--; 3552 head->lio_refcnt--; 3553 mutex_exit(&aiop->aio_mutex); 3554 } 3555 aio_errors++; 3556 continue; 3557 } 3558 |
3564 vp = fp->f_vnode; 3565 | |
3566 /* 3567 * check the permission of the partition 3568 */ | 3559 /* 3560 * check the permission of the partition 3561 */ |
3569 mode = aiocb->aio_lio_opcode; | |
3570 if ((fp->f_flag & mode) == 0) { 3571 releasef(aiocb->aio_fildes); 3572 lio_set_uerror(&cbp->aio_resultp, EBADF); 3573 if (head) { 3574 mutex_enter(&aiop->aio_mutex); 3575 head->lio_nent--; 3576 head->lio_refcnt--; 3577 mutex_exit(&aiop->aio_mutex); 3578 } 3579 aio_errors++; 3580 continue; 3581 } 3582 3583 /* 3584 * common case where requests are to the same fd 3585 * for the same r/w operation 3586 * for UFS, need to set EBADFD 3587 */ | 3562 if ((fp->f_flag & mode) == 0) { 3563 releasef(aiocb->aio_fildes); 3564 lio_set_uerror(&cbp->aio_resultp, EBADF); 3565 if (head) { 3566 mutex_enter(&aiop->aio_mutex); 3567 head->lio_nent--; 3568 head->lio_refcnt--; 3569 mutex_exit(&aiop->aio_mutex); 3570 } 3571 aio_errors++; 3572 continue; 3573 } 3574 3575 /* 3576 * common case where requests are to the same fd 3577 * for the same r/w operation 3578 * for UFS, need to set EBADFD 3579 */ |
3588 if ((fp != prev_fp) || (mode != prev_mode)) { | 3580 vp = fp->f_vnode; 3581 if (fp != prev_fp || mode != prev_mode) { |
3589 aio_func = check_vp(vp, mode); 3590 if (aio_func == NULL) { 3591 prev_fp = NULL; 3592 releasef(aiocb->aio_fildes); | 3582 aio_func = check_vp(vp, mode); 3583 if (aio_func == NULL) { 3584 prev_fp = NULL; 3585 releasef(aiocb->aio_fildes); |
3593 lio_set_uerror(&cbp->aio_resultp, 3594 EBADFD); | 3586 lio_set_uerror(&cbp->aio_resultp, EBADFD); |
3595 aio_notsupported++; 3596 if (head) { 3597 mutex_enter(&aiop->aio_mutex); 3598 head->lio_nent--; 3599 head->lio_refcnt--; 3600 mutex_exit(&aiop->aio_mutex); 3601 } 3602 continue; 3603 } else { 3604 prev_fp = fp; 3605 prev_mode = mode; 3606 } 3607 } | 3587 aio_notsupported++; 3588 if (head) { 3589 mutex_enter(&aiop->aio_mutex); 3590 head->lio_nent--; 3591 head->lio_refcnt--; 3592 mutex_exit(&aiop->aio_mutex); 3593 } 3594 continue; 3595 } else { 3596 prev_fp = fp; 3597 prev_mode = mode; 3598 } 3599 } |
3608 if (error = aio_req_setup(&reqp, aiop, aiocb, 3609 (aio_result_t *)&cbp->aio_resultp, aio_use_port, vp)) { | 3600 3601 error = aio_req_setup(&reqp, aiop, aiocb, 3602 (aio_result_t *)&cbp->aio_resultp, vp); 3603 if (error) { |
3610 releasef(aiocb->aio_fildes); 3611 lio_set_uerror(&cbp->aio_resultp, error); 3612 if (head) { 3613 mutex_enter(&aiop->aio_mutex); 3614 head->lio_nent--; 3615 head->lio_refcnt--; 3616 mutex_exit(&aiop->aio_mutex); 3617 } --- 6 unchanged lines hidden (view full) --- 3624 3625 /* 3626 * Set the errno field now before sending the request to 3627 * the driver to avoid a race condition 3628 */ 3629 (void) suword32(&cbp->aio_resultp.aio_errno, 3630 EINPROGRESS); 3631 | 3604 releasef(aiocb->aio_fildes); 3605 lio_set_uerror(&cbp->aio_resultp, error); 3606 if (head) { 3607 mutex_enter(&aiop->aio_mutex); 3608 head->lio_nent--; 3609 head->lio_refcnt--; 3610 mutex_exit(&aiop->aio_mutex); 3611 } --- 6 unchanged lines hidden (view full) --- 3618 3619 /* 3620 * Set the errno field now before sending the request to 3621 * the driver to avoid a race condition 3622 */ 3623 (void) suword32(&cbp->aio_resultp.aio_errno, 3624 EINPROGRESS); 3625 |
3632 reqp->aio_req_iocb.iocb32 = ((caddr32_t *)cbplist)[i]; | 3626 reqp->aio_req_iocb.iocb32 = (caddr32_t)(uintptr_t)cbp; |
3633 | 3627 |
3634 if (aio_use_port) { 3635 reqp->aio_req_port = pnotify.portnfy_port; | 3628 event = (mode == LIO_READ)? AIOAREAD : AIOAWRITE; 3629 aio_port = (aiocb->aio_sigevent.sigev_notify == SIGEV_PORT); 3630 aio_thread = (aiocb->aio_sigevent.sigev_notify == SIGEV_THREAD); 3631 if (aio_port | aio_thread) { 3632 port_kevent_t *lpkevp; 3633 /* 3634 * Prepare data to send with each aiocb completed. 3635 */ |
3636#ifdef _LP64 | 3636#ifdef _LP64 |
3637 error = aio_req_assoc_port32(&aiocb32->aio_sigevent, 3638 (void *)(uintptr_t)pnotify.portnfy_user, 3639 (aiocb_t *)(uintptr_t)(((caddr32_t *)cbplist)[i]), 3640 reqp, pkevtp); | 3637 if (aio_port) { 3638 void *paddr = (void *)(uintptr_t) 3639 aiocb32->aio_sigevent.sigev_value.sival_ptr; 3640 if (copyin(paddr, &pnotify, sizeof (pnotify))) 3641 error = EFAULT; 3642 } else { /* aio_thread */ 3643 pnotify.portnfy_port = 3644 aiocb32->aio_sigevent.sigev_signo; 3645 pnotify.portnfy_user = 3646 aiocb32->aio_sigevent.sigev_value.sival_ptr; 3647 } |
3641#else | 3648#else |
3642 error = aio_req_assoc_port(&aiocb->aio_sigevent, 3643 pnotify.portnfy_user, 3644 (aiocb_t *)(((caddr32_t *)cbplist)[i]), 3645 reqp, pkevtp); | 3649 if (aio_port) { 3650 void *paddr = 3651 aiocb->aio_sigevent.sigev_value.sival_ptr; 3652 if (copyin(paddr, &pnotify, sizeof (pnotify))) 3653 error = EFAULT; 3654 } else { /* aio_thread */ 3655 pnotify.portnfy_port = 3656 aiocb->aio_sigevent.sigev_signo; 3657 pnotify.portnfy_user = 3658 aiocb->aio_sigevent.sigev_value.sival_ptr; 3659 } |
3646#endif | 3660#endif |
3661 if (error) 3662 /* EMPTY */; 3663 else if (pkevtp != NULL && 3664 pnotify.portnfy_port == lio_head_port) 3665 error = port_dup_event(pkevtp, &lpkevp, 3666 PORT_ALLOC_DEFAULT); 3667 else 3668 error = port_alloc_event(pnotify.portnfy_port, 3669 PORT_ALLOC_DEFAULT, PORT_SOURCE_AIO, 3670 &lpkevp); 3671 if (error == 0) { 3672 port_init_event(lpkevp, (uintptr_t)cbp, 3673 (void *)(uintptr_t)pnotify.portnfy_user, 3674 aio_port_callback, reqp); 3675 lpkevp->portkev_events = event; 3676 reqp->aio_req_portkev = lpkevp; 3677 reqp->aio_req_port = pnotify.portnfy_port; 3678 } |
|
3647 } 3648 3649 /* 3650 * send the request to driver. | 3679 } 3680 3681 /* 3682 * send the request to driver. |
3651 * Clustering: If PXFS vnode, call PXFS function. | |
3652 */ 3653 if (error == 0) { 3654 if (aiocb->aio_nbytes == 0) { 3655 clear_active_fd(aiocb->aio_fildes); 3656 aio_zerolen(reqp); 3657 continue; 3658 } 3659 error = (*aio_func)(vp, (aio_req_t *)&reqp->aio_req, --- 18 unchanged lines hidden (view full) --- 3678 else 3679 aio_errors++; 3680 lio_set_error(reqp); 3681 } else { 3682 clear_active_fd(aiocb->aio_fildes); 3683 } 3684 } 3685 | 3683 */ 3684 if (error == 0) { 3685 if (aiocb->aio_nbytes == 0) { 3686 clear_active_fd(aiocb->aio_fildes); 3687 aio_zerolen(reqp); 3688 continue; 3689 } 3690 error = (*aio_func)(vp, (aio_req_t *)&reqp->aio_req, --- 18 unchanged lines hidden (view full) --- 3709 else 3710 aio_errors++; 3711 lio_set_error(reqp); 3712 } else { 3713 clear_active_fd(aiocb->aio_fildes); 3714 } 3715 } 3716 |
3686 if (pkevtp) 3687 port_free_event(pkevtp); 3688 | |
3689 if (aio_notsupported) { 3690 error = ENOTSUP; 3691 } else if (aio_errors) { 3692 /* 3693 * return EIO if any request failed 3694 */ 3695 error = EIO; 3696 } --- 11 unchanged lines hidden (view full) --- 3708 alio_cleanup(aiop, (aiocb_t **)cbplist, nent, AIO_32); 3709 } 3710 3711done: 3712 kmem_free(cbplist, ssize); 3713 if (deadhead) { 3714 if (head->lio_sigqp) 3715 kmem_free(head->lio_sigqp, sizeof (sigqueue_t)); | 3717 if (aio_notsupported) { 3718 error = ENOTSUP; 3719 } else if (aio_errors) { 3720 /* 3721 * return EIO if any request failed 3722 */ 3723 error = EIO; 3724 } --- 11 unchanged lines hidden (view full) --- 3736 alio_cleanup(aiop, (aiocb_t **)cbplist, nent, AIO_32); 3737 } 3738 3739done: 3740 kmem_free(cbplist, ssize); 3741 if (deadhead) { 3742 if (head->lio_sigqp) 3743 kmem_free(head->lio_sigqp, sizeof (sigqueue_t)); |
3744 if (head->lio_portkev) 3745 port_free_event(head->lio_portkev); |
|
3716 kmem_free(head, sizeof (aio_lio_t)); 3717 } 3718 return (error); 3719} 3720 3721 3722#ifdef _SYSCALL32_IMPL 3723void --- 78 unchanged lines hidden --- | 3746 kmem_free(head, sizeof (aio_lio_t)); 3747 } 3748 return (error); 3749} 3750 3751 3752#ifdef _SYSCALL32_IMPL 3753void --- 78 unchanged lines hidden --- |