2 * This Cplant(TM) source code is the property of Sandia National
5 * This Cplant(TM) source code is copyrighted by Sandia National
8 * The redistribution of this Cplant(TM) source code is subject to the
9 * terms of the GNU Lesser General Public License
10 * (see cit/LGPL or http://www.gnu.org/licenses/lgpl.html)
12 * Cplant(TM) Copyright 1998-2004 Sandia Corporation.
13 * Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive
14 * license for use of this work by or on behalf of the US Government.
15 * Export of this program may require a license from the United States
20 * This library is free software; you can redistribute it and/or
21 * modify it under the terms of the GNU Lesser General Public
22 * License as published by the Free Software Foundation; either
23 * version 2.1 of the License, or (at your option) any later version.
25 * This library is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28 * Lesser General Public License for more details.
30 * You should have received a copy of the GNU Lesser General Public
31 * License along with this library; if not, write to the Free Software
32 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
34 * Questions or comments about this library should be sent to:
37 * Sandia National Laboratories, New Mexico
39 * Albuquerque, NM 87185-1110
50 #include <sys/types.h>
52 #include <sys/queue.h>
59 #include <catamount/do_iostats.h>
64 * Asynchronous IO context support.
68 * List of all outstanding (in-flight) asynch IO requests tracked
71 static LIST_HEAD( ,ioctx) aioq;
74 * Free callback entry.
76 #define cb_free(cb) free(cb)
79 * Initialization. Must be called before using any other routine in this
91 * Enter an IO context onto the async IO events queue.
94 _sysio_ioctx_enter(struct ioctx *ioctx)
97 LIST_INSERT_HEAD(&aioq, ioctx, ioctx_link);
101 * Allocate and initialize a new IO context.
104 _sysio_ioctx_new(struct inode *ino,
106 const struct iovec *iov,
108 const struct intnl_xtvec *xtv,
113 ioctx = malloc(sizeof(struct ioctx));
127 * Link request onto the outstanding requests queue.
129 _sysio_ioctx_enter(ioctx);
135 * Add an IO completion call-back to the end of the context call-back queue.
136 * These are called in iowait() as the last thing, right before the context
139 * They are called in order. Beware.
142 _sysio_ioctx_cb(struct ioctx *ioctx,
143 void (*f)(struct ioctx *, void *),
146 struct ioctx_callback *entry;
148 entry = malloc(sizeof(struct ioctx_callback));
153 entry->iocb_data = data;
155 TAILQ_INSERT_TAIL(&ioctx->ioctx_cbq, entry, iocb_next);
161 * Find an IO context given it's identifier.
163 * NB: This is dog-slow. If there are alot of these, we will need to change
164 * this implementation.
167 _sysio_ioctx_find(void *id)
171 for (ioctx = aioq.lh_first; ioctx; ioctx = ioctx->ioctx_link.le_next)
179 * Check if asynchronous IO operation is complete.
182 _sysio_ioctx_done(struct ioctx *ioctx)
185 if (ioctx->ioctx_done)
187 if (!(*ioctx->ioctx_ino->i_ops.inop_iodone)(ioctx))
189 ioctx->ioctx_done = 1;
194 * Wait for asynchronous IO operation to complete, return status
195 * and dispose of the context.
198 * The context is no longer valid after return.
201 _sysio_ioctx_wait(struct ioctx *ioctx)
206 * Wait for async operation to complete.
208 while (!_sysio_ioctx_done(ioctx)) {
209 #ifdef POSIX_PRIORITY_SCHEDULING
210 (void )sched_yield();
217 cc = ioctx->ioctx_cc;
219 cc = -ioctx->ioctx_errno;
224 _sysio_ioctx_complete(ioctx);
230 * Free callback entry.
233 _sysio_ioctx_cb_free(struct ioctx_callback *cb)
240 * Complete an asynchronous IO request.
243 _sysio_ioctx_complete(struct ioctx *ioctx)
245 struct ioctx_callback *entry;
248 /* update IO stats */
249 _SYSIO_UPDACCT(ioctx->ioctx_write, ioctx->ioctx_cc);
252 * Run the call-back queue.
254 while ((entry = ioctx->ioctx_cbq.tqh_first)) {
255 TAILQ_REMOVE(&ioctx->ioctx_cbq, entry, iocb_next);
256 (*entry->iocb_f)(ioctx, entry->iocb_data);
261 * Unlink from the file record's outstanding request queue.
263 LIST_REMOVE(ioctx, ioctx_link);
265 if (ioctx->ioctx_fast)
268 I_RELE(ioctx->ioctx_ino);