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
49 #include <sys/types.h>
51 #include <sys/queue.h>
58 #include <catamount/do_iostats.h>
63 * Asynchronous IO context support.
67 * List of all outstanding (in-flight) asynch IO requests tracked
70 static LIST_HEAD( ,ioctx) aioq;
73 * Free callback entry.
75 #define cb_free(cb) free(cb)
78 * Initialization. Must be called before using any other routine in this
90 * Enter an IO context onto the async IO events queue.
93 _sysio_ioctx_enter(struct ioctx *ioctx)
96 LIST_INSERT_HEAD(&aioq, ioctx, ioctx_link);
100 * Allocate and initialize a new IO context.
103 _sysio_ioctx_new(struct inode *ino,
105 const struct iovec *iov,
107 const struct intnl_xtvec *xtv,
112 ioctx = malloc(sizeof(struct ioctx));
126 * Link request onto the outstanding requests queue.
128 _sysio_ioctx_enter(ioctx);
134 * Add an IO completion call-back to the end of the context call-back queue.
135 * These are called in iowait() as the last thing, right before the context
138 * They are called in order. Beware.
141 _sysio_ioctx_cb(struct ioctx *ioctx,
142 void (*f)(struct ioctx *, void *),
145 struct ioctx_callback *entry;
147 entry = malloc(sizeof(struct ioctx_callback));
152 entry->iocb_data = data;
154 TAILQ_INSERT_TAIL(&ioctx->ioctx_cbq, entry, iocb_next);
160 * Find an IO context given it's identifier.
162 * NB: This is dog-slow. If there are alot of these, we will need to change
163 * this implementation.
166 _sysio_ioctx_find(void *id)
170 for (ioctx = aioq.lh_first; ioctx; ioctx = ioctx->ioctx_link.le_next)
178 * Wait for asynchronous IO operation to complete, return status
179 * and dispose of the context.
182 * The context is no longer valid after return.
185 _sysio_ioctx_wait(struct ioctx *ioctx)
190 * Wait for async operation to complete.
192 while (!(ioctx->ioctx_done ||
193 (*ioctx->ioctx_ino->i_ops.inop_iodone)(ioctx)))
199 cc = ioctx->ioctx_cc;
201 cc = -ioctx->ioctx_errno;
206 _sysio_ioctx_complete(ioctx);
212 * Free callback entry.
215 _sysio_ioctx_cb_free(struct ioctx_callback *cb)
222 * Complete an asynchronous IO request.
225 _sysio_ioctx_complete(struct ioctx *ioctx)
227 struct ioctx_callback *entry;
230 /* update IO stats */
231 _SYSIO_UPDACCT(ioctx->ioctx_write, ioctx);
234 * Run the call-back queue.
236 while ((entry = ioctx->ioctx_cbq.tqh_first)) {
237 TAILQ_REMOVE(&ioctx->ioctx_cbq, entry, iocb_next);
238 (*entry->iocb_f)(ioctx, entry->iocb_data);
243 * Unlink from the file record's outstanding request queue.
245 LIST_REMOVE(ioctx, ioctx_link);
247 if (ioctx->ioctx_fast)
250 I_RELE(ioctx->ioctx_ino);