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 ---