Whamcloud - gitweb
LU-4788 lfsck: replace cfs_list_t with list_head
[fs/lustre-release.git] / lustre / contrib / mpich2-1.0.3.patch
1 Date: Fri, 08 Jun 2007 14:04:34 -0400
2 From: Weikuan Yu <weikuan.yu@gmail.com>
3 To: Weikuan Yu <weikuan.yu@gmail.com>
4 Subject: Re: [Lustre-discuss] MPI-IO for Lustre
5 Cc: lustre-discuss@clusterfs.com
6
7
8 This is the MPICH2 patch I originally started as a base for some ROMIO
9 optimizations over Lustre. It should work fine for MPICH2-1.0.3 on
10 experimental systems. However, use it as your risk :)
11
12 Given time, I will try to push out my optimizations after some cleanup. I
13 would very happy to hear feedbacks on what features people would need most
14 at the time.
15
16 --
17 Weikuan
18
19
20 diff -ruN romio-orig/adio/ad_lustre/ad_lustre.c romio/adio/ad_lustre/ad_lustre.c
21 --- romio-orig/adio/ad_lustre/ad_lustre.c       1969-12-31 19:00:00.000000000 -0500
22 +++ romio/adio/ad_lustre/ad_lustre.c    2006-09-06 18:40:56.000844619 -0400
23 @@ -0,0 +1,37 @@
24 +/* -*- Mode: C; c-basic-offset:4 ; -*- */
25 +/*
26 + *   $Id: ad_lustre.c,v 1.1.1.1 2004/11/04 11:03:38 liam Exp $
27 + *
28 + *   Copyright (C) 2001 University of Chicago.
29 + *   See COPYRIGHT notice in top-level directory.
30 + */
31 +
32 +#include "ad_lustre.h"
33 +
34 +/* adioi.h has the ADIOI_Fns_struct define */
35 +#include "adioi.h"
36 +
37 +struct ADIOI_Fns_struct ADIO_LUSTRE_operations = {
38 +    ADIOI_LUSTRE_Open, /* Open */
39 +    ADIOI_LUSTRE_ReadContig, /* ReadContig */
40 +    ADIOI_LUSTRE_WriteContig, /* WriteContig */
41 +    ADIOI_GEN_ReadStridedColl, /* ReadStridedColl */
42 +    ADIOI_GEN_WriteStridedColl, /* WriteStridedColl */
43 +    ADIOI_GEN_SeekIndividual, /* SeekIndividual */
44 +    ADIOI_LUSTRE_Fcntl, /* Fcntl */
45 +    ADIOI_LUSTRE_SetInfo, /* SetInfo */
46 +    ADIOI_GEN_ReadStrided, /* ReadStrided */
47 +    ADIOI_GEN_WriteStrided, /* WriteStrided */
48 +    ADIOI_LUSTRE_Close, /* Close */
49 +    ADIOI_LUSTRE_IreadContig, /* IreadContig */
50 +    ADIOI_LUSTRE_IwriteContig, /* IwriteContig */
51 +    ADIOI_LUSTRE_ReadDone, /* ReadDone */
52 +    ADIOI_LUSTRE_WriteDone, /* WriteDone */
53 +    ADIOI_LUSTRE_ReadComplete, /* ReadComplete */
54 +    ADIOI_LUSTRE_WriteComplete, /* WriteComplete */
55 +    ADIOI_LUSTRE_IreadStrided, /* IreadStrided */
56 +    ADIOI_LUSTRE_IwriteStrided, /* IwriteStrided */
57 +    ADIOI_GEN_Flush, /* Flush */
58 +    ADIOI_LUSTRE_Resize, /* Resize */
59 +    ADIOI_GEN_Delete, /* Delete */
60 +};
61 diff -ruN romio-orig/adio/ad_lustre/ad_lustre_close.c romio/adio/ad_lustre/ad_lustre_close.c
62 --- romio-orig/adio/ad_lustre/ad_lustre_close.c 1969-12-31 19:00:00.000000000 -0500
63 +++ romio/adio/ad_lustre/ad_lustre_close.c      2006-09-06 17:10:35.000683211 -0400
64 @@ -0,0 +1,32 @@
65 +/* -*- Mode: C; c-basic-offset:4 ; -*- */
66 +/*
67 + *   $Id: ad_lustre_close.c,v 1.1.1.1 2004/11/04 11:03:38 liam Exp $
68 + *
69 + *   Copyright (C) 1997 University of Chicago.
70 + *   See COPYRIGHT notice in top-level directory.
71 + */
72 +
73 +#include "ad_lustre.h"
74 +
75 +void ADIOI_LUSTRE_Close(ADIO_File fd, int *error_code)
76 +{
77 +    int err;
78 +#if defined(MPICH2) || !defined(PRINT_ERR_MSG)
79 +    static char myname[] = "ADIOI_LUSTRE_CLOSE";
80 +#endif
81 +
82 +    err = close(fd->fd_sys);
83 +    if (err == -1) {
84 +#ifdef MPICH2
85 +       *error_code = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io",
86 +           "**io %s", strerror(errno));
87 +#elif defined(PRINT_ERR_MSG)
88 +                       *error_code = MPI_ERR_UNKNOWN;
89 +#else
90 +       *error_code = MPIR_Err_setmsg(MPI_ERR_IO, MPIR_ADIO_ERROR,
91 +                             myname, "I/O Error", "%s", strerror(errno));
92 +       ADIOI_Error(fd, *error_code, myname);
93 +#endif
94 +    }
95 +    else *error_code = MPI_SUCCESS;
96 +}
97 diff -ruN romio-orig/adio/ad_lustre/ad_lustre_done.c romio/adio/ad_lustre/ad_lustre_done.c
98 --- romio-orig/adio/ad_lustre/ad_lustre_done.c  1969-12-31 19:00:00.000000000 -0500
99 +++ romio/adio/ad_lustre/ad_lustre_done.c       2006-09-06 17:10:35.000692922 -0400
100 @@ -0,0 +1,188 @@
101 +/* -*- Mode: C; c-basic-offset:4 ; -*- */
102 +/*
103 + *   $Id: ad_lustre_done.c,v 1.1.1.1 2004/11/04 11:03:38 liam Exp $
104 + *
105 + *   Copyright (C) 1997 University of Chicago.
106 + *   See COPYRIGHT notice in top-level directory.
107 + */
108 +
109 +#include "ad_lustre.h"
110 +
111 +int ADIOI_LUSTRE_ReadDone(ADIO_Request *request, ADIO_Status *status, int *error_code)
112 +{
113 +#ifndef NO_AIO
114 +    int done=0;
115 +#if defined(MPICH2) || !defined(PRINT_ERR_MSG)
116 +    static char myname[] = "ADIOI_LUSTRE_READDONE";
117 +#endif
118 +#ifdef AIO_SUN
119 +    aio_result_t *result=0, *tmp;
120 +#else
121 +    int err;
122 +#endif
123 +#ifdef AIO_HANDLE_IN_AIOCB
124 +    struct aiocb *tmp1;
125 +#endif
126 +#endif
127 +
128 +    if (*request == ADIO_REQUEST_NULL) {
129 +       *error_code = MPI_SUCCESS;
130 +       return 1;
131 +    }
132 +
133 +#ifdef NO_AIO
134 +/* HP, FreeBSD, Linux */
135 +#ifdef HAVE_STATUS_SET_BYTES
136 +    MPIR_Status_set_bytes(status, (*request)->datatype, (*request)->nbytes);
137 +#endif
138 +    (*request)->fd->async_count--;
139 +    ADIOI_Free_request((ADIOI_Req_node *) (*request));
140 +    *request = ADIO_REQUEST_NULL;
141 +    *error_code = MPI_SUCCESS;
142 +    return 1;
143 +#endif
144 +
145 +#ifdef AIO_SUN
146 +    if ((*request)->queued) {
147 +       tmp = (aio_result_t *) (*request)->handle;
148 +       if (tmp->aio_return == AIO_INPROGRESS) {
149 +           done = 0;
150 +           *error_code = MPI_SUCCESS;
151 +       }
152 +       else if (tmp->aio_return != -1) {
153 +           result = (aio_result_t *) aiowait(0); /* dequeue any one request */
154 +           done = 1;
155 +           (*request)->nbytes = tmp->aio_return;
156 +           *error_code = MPI_SUCCESS;
157 +       }
158 +       else {
159 +#ifdef MPICH2
160 +           *error_code = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io",
161 +               "**io %s", strerror(tmp->aio_errno));
162 +           return;
163 +#elif defined(PRINT_ERR_MSG)
164 +           *error_code = MPI_ERR_UNKNOWN;
165 +#else
166 +           *error_code = MPIR_Err_setmsg(MPI_ERR_IO, MPIR_ADIO_ERROR,
167 +                        myname, "I/O Error", "%s", strerror(tmp->aio_errno));
168 +           ADIOI_Error((*request)->fd, *error_code, myname);
169 +#endif
170 +       }
171 +    } /* if ((*request)->queued) ... */
172 +    else {
173 +       /* ADIOI_Complete_Async completed this request, but request object
174 +           was not freed. */
175 +       done = 1;
176 +       *error_code = MPI_SUCCESS;
177 +    }
178 +#ifdef HAVE_STATUS_SET_BYTES
179 +    if (done && ((*request)->nbytes != -1))
180 +       MPIR_Status_set_bytes(status, (*request)->datatype, (*request)->nbytes);
181 +#endif
182 +
183 +#endif
184 +
185 +#ifdef AIO_HANDLE_IN_AIOCB
186 +/* IBM */
187 +    if ((*request)->queued) {
188 +       tmp1 = (struct aiocb *) (*request)->handle;
189 +       errno = aio_error(tmp1->aio_handle);
190 +       if (errno == EINPROG) {
191 +           done = 0;
192 +           *error_code = MPI_SUCCESS;
193 +       }
194 +       else {
195 +           err = aio_return(tmp1->aio_handle);
196 +           (*request)->nbytes = err;
197 +           errno = aio_error(tmp1->aio_handle);
198 +
199 +           done = 1;
200 +
201 +           if (err == -1) {
202 +#ifdef MPICH2
203 +               *error_code = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io",
204 +                   "**io %s", strerror(errno));
205 +               return;
206 +#elif defined(PRINT_ERR_MSG)
207 +                               *error_code = MPI_ERR_UNKNOWN;
208 +#else
209 +               *error_code = MPIR_Err_setmsg(MPI_ERR_IO, MPIR_ADIO_ERROR,
210 +                             myname, "I/O Error", "%s", strerror(errno));
211 +               ADIOI_Error((*request)->fd, *error_code, myname);
212 +#endif
213 +           }
214 +           else *error_code = MPI_SUCCESS;
215 +       }
216 +    } /* if ((*request)->queued) */
217 +    else {
218 +       done = 1;
219 +       *error_code = MPI_SUCCESS;
220 +    }
221 +#ifdef HAVE_STATUS_SET_BYTES
222 +    if (done && ((*request)->nbytes != -1))
223 +       MPIR_Status_set_bytes(status, (*request)->datatype, (*request)->nbytes);
224 +#endif
225 +
226 +#elif (!defined(NO_AIO) && !defined(AIO_SUN))
227 +/* DEC, SGI IRIX 5 and 6 */
228 +    if ((*request)->queued) {
229 +       errno = aio_error((const struct aiocb *) (*request)->handle);
230 +       if (errno == EINPROGRESS) {
231 +           done = 0;
232 +           *error_code = MPI_SUCCESS;
233 +       }
234 +       else {
235 +           err = aio_return((struct aiocb *) (*request)->handle);
236 +           (*request)->nbytes = err;
237 +           errno = aio_error((struct aiocb *) (*request)->handle);
238 +
239 +           done = 1;
240 +
241 +           if (err == -1) {
242 +#ifdef MPICH2
243 +               *error_code = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io",
244 +                   "**io %s", strerror(errno));
245 +               return;
246 +#elif defined(PRINT_ERR_MSG)
247 +                               *error_code = MPI_ERR_UNKNOWN;
248 +#else /* MPICH-1 */
249 +               *error_code = MPIR_Err_setmsg(MPI_ERR_IO, MPIR_ADIO_ERROR,
250 +                             myname, "I/O Error", "%s", strerror(errno));
251 +               ADIOI_Error((*request)->fd, *error_code, myname);
252 +#endif
253 +           }
254 +           else *error_code = MPI_SUCCESS;
255 +       }
256 +    } /* if ((*request)->queued) */
257 +    else {
258 +       done = 1;
259 +       *error_code = MPI_SUCCESS;
260 +    }
261 +#ifdef HAVE_STATUS_SET_BYTES
262 +    if (done && ((*request)->nbytes != -1))
263 +       MPIR_Status_set_bytes(status, (*request)->datatype, (*request)->nbytes);
264 +#endif
265 +
266 +#endif
267 +
268 +#ifndef NO_AIO
269 +    if (done) {
270 +       /* if request is still queued in the system, it is also there
271 +           on ADIOI_Async_list. Delete it from there. */
272 +       if ((*request)->queued) ADIOI_Del_req_from_list(request);
273 +
274 +       (*request)->fd->async_count--;
275 +       if ((*request)->handle) ADIOI_Free((*request)->handle);
276 +       ADIOI_Free_request((ADIOI_Req_node *) (*request));
277 +       *request = ADIO_REQUEST_NULL;
278 +    }
279 +    return done;
280 +#endif
281 +
282 +}
283 +
284 +
285 +int ADIOI_LUSTRE_WriteDone(ADIO_Request *request, ADIO_Status *status, int *error_code)
286 +{
287 +    return ADIOI_LUSTRE_ReadDone(request, status, error_code);
288 +}
289 diff -ruN romio-orig/adio/ad_lustre/ad_lustre_fcntl.c romio/adio/ad_lustre/ad_lustre_fcntl.c
290 --- romio-orig/adio/ad_lustre/ad_lustre_fcntl.c 1969-12-31 19:00:00.000000000 -0500
291 +++ romio/adio/ad_lustre/ad_lustre_fcntl.c      2006-09-06 18:43:11.000365177 -0400
292 @@ -0,0 +1,127 @@
293 +/* -*- Mode: C; c-basic-offset:4 ; -*- */
294 +/*
295 + *   $Id: ad_lustre_fcntl.c,v 1.1.1.1 2004/11/04 11:03:38 liam Exp $
296 + *
297 + *   Copyright (C) 1997 University of Chicago.
298 + *   See COPYRIGHT notice in top-level directory.
299 + */
300 +
301 +#include "ad_lustre.h"
302 +#include "adio_extern.h"
303 +/* #ifdef MPISGI
304 +#include "mpisgi2.h"
305 +#endif */
306 +
307 +void ADIOI_LUSTRE_Fcntl(ADIO_File fd, int flag, ADIO_Fcntl_t *fcntl_struct, int *error_code)
308 +{
309 +    int i, ntimes;
310 +    ADIO_Offset curr_fsize, alloc_size, size, len, done;
311 +    ADIO_Status status;
312 +    char *buf;
313 +#if defined(MPICH2) || !defined(PRINT_ERR_MSG)
314 +    static char myname[] = "ADIOI_LUSTRE_FCNTL";
315 +#endif
316 +
317 +    switch(flag) {
318 +    case ADIO_FCNTL_GET_FSIZE:
319 +       fcntl_struct->fsize = lseek(fd->fd_sys, 0, SEEK_END);
320 +       if (fd->fp_sys_posn != -1)
321 +            lseek(fd->fd_sys, fd->fp_sys_posn, SEEK_SET);
322 +       if (fcntl_struct->fsize == -1) {
323 +#ifdef MPICH2
324 +           *error_code = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io",
325 +               "**io %s", strerror(errno));
326 +#elif defined(PRINT_ERR_MSG)
327 +                       *error_code = MPI_ERR_UNKNOWN;
328 +#else /* MPICH-1 */
329 +           *error_code = MPIR_Err_setmsg(MPI_ERR_IO, MPIR_ADIO_ERROR,
330 +                             myname, "I/O Error", "%s", strerror(errno));
331 +           ADIOI_Error(fd, *error_code, myname);
332 +#endif
333 +       }
334 +       else *error_code = MPI_SUCCESS;
335 +       break;
336 +
337 +    case ADIO_FCNTL_SET_DISKSPACE:
338 +       /* will be called by one process only */
339 +       /* On file systems with no preallocation function, I have to
340 +           explicitly write
341 +           to allocate space. Since there could be holes in the file,
342 +           I need to read up to the current file size, write it back,
343 +           and then write beyond that depending on how much
344 +           preallocation is needed.
345 +           read/write in sizes of no more than ADIOI_PREALLOC_BUFSZ */
346 +
347 +       curr_fsize = lseek(fd->fd_sys, 0, SEEK_END);
348 +       alloc_size = fcntl_struct->diskspace;
349 +
350 +       size = ADIOI_MIN(curr_fsize, alloc_size);
351 +
352 +       ntimes = (size + ADIOI_PREALLOC_BUFSZ - 1)/ADIOI_PREALLOC_BUFSZ;
353 +       buf = (char *) ADIOI_Malloc(ADIOI_PREALLOC_BUFSZ);
354 +       done = 0;
355 +
356 +       for (i=0; i<ntimes; i++) {
357 +           len = ADIOI_MIN(size-done, ADIOI_PREALLOC_BUFSZ);
358 +           ADIO_ReadContig(fd, buf, len, MPI_BYTE, ADIO_EXPLICIT_OFFSET, done,
359 +                           &status, error_code);
360 +           if (*error_code != MPI_SUCCESS) {
361 +#ifdef MPICH2
362 +               *error_code = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io",
363 +                   "**io %s", strerror(errno));
364 +#elif defined(PRINT_ERR_MSG)
365 +               FPRINTF(stderr, "ADIOI_LUSTRE_Fcntl: To preallocate disk space, ROMIO needs to read the file and write it back, but is unable to read the file. Please give the file read permission and open it with MPI_MODE_RDWR.\n");
366 +               MPI_Abort(MPI_COMM_WORLD, 1);
367 +#else /* MPICH-1 */
368 +               *error_code = MPIR_Err_setmsg(MPI_ERR_IO, MPIR_PREALLOC_PERM,
369 +                             myname, (char *) 0, (char *) 0);
370 +               ADIOI_Error(fd, *error_code, myname);
371 +#endif
372 +                return;
373 +           }
374 +           ADIO_WriteContig(fd, buf, len, MPI_BYTE, ADIO_EXPLICIT_OFFSET,
375 +                             done, &status, error_code);
376 +           if (*error_code != MPI_SUCCESS) return;
377 +           done += len;
378 +       }
379 +
380 +       if (alloc_size > curr_fsize) {
381 +           memset(buf, 0, ADIOI_PREALLOC_BUFSZ);
382 +           size = alloc_size - curr_fsize;
383 +           ntimes = (size + ADIOI_PREALLOC_BUFSZ - 1)/ADIOI_PREALLOC_BUFSZ;
384 +           for (i=0; i<ntimes; i++) {
385 +               len = ADIOI_MIN(alloc_size-done, ADIOI_PREALLOC_BUFSZ);
386 +               ADIO_WriteContig(fd, buf, len, MPI_BYTE, ADIO_EXPLICIT_OFFSET,
387 +                                done, &status, error_code);
388 +               if (*error_code != MPI_SUCCESS) return;
389 +               done += len;
390 +           }
391 +       }
392 +       ADIOI_Free(buf);
393 +       if (fd->fp_sys_posn != -1)
394 +           lseek(fd->fd_sys, fd->fp_sys_posn, SEEK_SET);
395 +       *error_code = MPI_SUCCESS;
396 +       break;
397 +
398 +#if 0
399 +    case ADIO_FCNTL_SET_IOMODE:
400 +        /* for implementing PFS I/O modes. will not occur in MPI-IO
401 +           implementation.*/
402 +       if (fd->iomode != fcntl_struct->iomode) {
403 +           fd->iomode = fcntl_struct->iomode;
404 +           MPI_Barrier(MPI_COMM_WORLD);
405 +       }
406 +       *error_code = MPI_SUCCESS;
407 +       break;
408 +#endif
409 +
410 +    case ADIO_FCNTL_SET_ATOMICITY:
411 +       fd->atomicity = (fcntl_struct->atomicity == 0) ? 0 : 1;
412 +       *error_code = MPI_SUCCESS;
413 +       break;
414 +
415 +    default:
416 +       FPRINTF(stderr, "Unknown flag passed to ADIOI_LUSTRE_Fcntl\n");
417 +       MPI_Abort(MPI_COMM_WORLD, 1);
418 +    }
419 +}
420 diff -ruN romio-orig/adio/ad_lustre/ad_lustre_flush.c romio/adio/ad_lustre/ad_lustre_flush.c
421 --- romio-orig/adio/ad_lustre/ad_lustre_flush.c 1969-12-31 19:00:00.000000000 -0500
422 +++ romio/adio/ad_lustre/ad_lustre_flush.c      2006-09-06 17:10:35.000711888 -0400
423 @@ -0,0 +1,14 @@
424 +/* -*- Mode: C; c-basic-offset:4 ; -*- */
425 +/*
426 + *   $Id: ad_lustre_flush.c,v 1.1.1.1 2004/11/04 11:03:38 liam Exp $
427 + *
428 + *   Copyright (C) 1997 University of Chicago.
429 + *   See COPYRIGHT notice in top-level directory.
430 + */
431 +
432 +#include "ad_lustre.h"
433 +
434 +void ADIOI_LUSTRE_Flush(ADIO_File fd, int *error_code)
435 +{
436 +    ADIOI_GEN_Flush(fd, error_code);
437 +}
438 diff -ruN romio-orig/adio/ad_lustre/ad_lustre.h romio/adio/ad_lustre/ad_lustre.h
439 --- romio-orig/adio/ad_lustre/ad_lustre.h       1969-12-31 19:00:00.000000000 -0500
440 +++ romio/adio/ad_lustre/ad_lustre.h    2006-09-06 17:10:35.000722616 -0400
441 @@ -0,0 +1,36 @@
442 +/* -*- Mode: C; c-basic-offset:4 ; -*- */
443 +/*
444 + *   $Id: ad_lustre.h,v 1.2 2005/07/07 14:38:17 liam Exp $
445 + *
446 + *   Copyright (C) 1997 University of Chicago.
447 + *   See COPYRIGHT notice in top-level directory.
448 + */
449 +
450 +#ifndef AD_UNIX_INCLUDE
451 +#define AD_UNIX_INCLUDE
452 +
453 +/* temp*/
454 +#define HAVE_ASM_TYPES_H 1
455 +
456 +#include <unistd.h>
457 +#include <linux/types.h>
458 +#include <fcntl.h>
459 +#include <sys/ioctl.h>
460 +#include "lustre/lustre_user.h"
461 +#include "adio.h"
462 +
463 +#ifndef NO_AIO
464 +#ifdef AIO_SUN
465 +#include <sys/asynch.h>
466 +#else
467 +#include <aio.h>
468 +#ifdef NEEDS_ADIOCB_T
469 +typedef struct adiocb adiocb_t;
470 +#endif
471 +#endif
472 +#endif
473 +
474 +int ADIOI_LUSTRE_aio(ADIO_File fd, void *buf, int len, ADIO_Offset offset,
475 +                 int wr, void *handle);
476 +
477 +#endif
478 diff -ruN romio-orig/adio/ad_lustre/ad_lustre_hints.c romio/adio/ad_lustre/ad_lustre_hints.c
479 --- romio-orig/adio/ad_lustre/ad_lustre_hints.c 1969-12-31 19:00:00.000000000 -0500
480 +++ romio/adio/ad_lustre/ad_lustre_hints.c      2006-09-06 17:10:35.000741994 -0400
481 @@ -0,0 +1,130 @@
482 +/* -*- Mode: C; c-basic-offset:4 ; -*- */
483 +/*
484 + *   $Id: ad_lustre_hints.c,v 1.2 2005/07/07 14:38:17 liam Exp $
485 + *
486 + *   Copyright (C) 1997 University of Chicago.
487 + *   See COPYRIGHT notice in top-level directory.
488 + */
489 +
490 +#include "ad_lustre.h"
491 +
492 +void ADIOI_LUSTRE_SetInfo(ADIO_File fd, MPI_Info users_info, int *error_code)
493 +{
494 +    char *value, *value_in_fd;
495 +    int flag, tmp_val, str_factor=-1, str_unit=0, start_iodev=-1;
496 +    struct lov_user_md lum = { 0 };
497 +    int err, myrank, fd_sys, perm, amode, old_mask;
498 +
499 +    if ( (fd->info) == MPI_INFO_NULL) {
500 +       /* This must be part of the open call. can set striping parameters
501 +           if necessary. */
502 +       MPI_Info_create(&(fd->info));
503 +
504 +       /* has user specified striping or server buffering parameters
505 +           and do they have the same value on all processes? */
506 +       if (users_info != MPI_INFO_NULL) {
507 +           value = (char *) ADIOI_Malloc((MPI_MAX_INFO_VAL+1)*sizeof(char));
508 +
509 +           MPI_Info_get(users_info, "striping_factor", MPI_MAX_INFO_VAL,
510 +                        value, &flag);
511 +           if (flag) {
512 +               str_factor=atoi(value);
513 +               tmp_val = str_factor;
514 +               MPI_Bcast(&tmp_val, 1, MPI_INT, 0, fd->comm);
515 +               if (tmp_val != str_factor) {
516 +                   FPRINTF(stderr, "ADIOI_LUSTRE_SetInfo: the value for key \"striping_factor\" must be the same on all processes\n");
517 +                   MPI_Abort(MPI_COMM_WORLD, 1);
518 +               }
519 +           }
520 +
521 +           MPI_Info_get(users_info, "striping_unit", MPI_MAX_INFO_VAL,
522 +                        value, &flag);
523 +           if (flag) {
524 +               str_unit=atoi(value);
525 +               tmp_val = str_unit;
526 +               MPI_Bcast(&tmp_val, 1, MPI_INT, 0, fd->comm);
527 +               if (tmp_val != str_unit) {
528 +                   FPRINTF(stderr, "ADIOI_LUSTRE_SetInfo: the value for key \"striping_unit\" must be the same on all processes\n");
529 +                   MPI_Abort(MPI_COMM_WORLD, 1);
530 +               }
531 +           }
532 +
533 +           MPI_Info_get(users_info, "start_iodevice", MPI_MAX_INFO_VAL,
534 +                        value, &flag);
535 +           if (flag) {
536 +               start_iodev=atoi(value);
537 +               tmp_val = start_iodev;
538 +               MPI_Bcast(&tmp_val, 1, MPI_INT, 0, fd->comm);
539 +               if (tmp_val != start_iodev) {
540 +                   FPRINTF(stderr, "ADIOI_LUSTRE_SetInfo: the value for key \"start_iodevice\" must be the same on all processes\n");
541 +                   MPI_Abort(MPI_COMM_WORLD, 1);
542 +               }
543 +           }
544 +
545 +         /* if user has specified striping info, process 0 tries to set it */
546 +           if ((str_factor > 0) || (str_unit > 0) || (start_iodev >= 0)) {
547 +               MPI_Comm_rank(fd->comm, &myrank);
548 +               if (!myrank) {
549 +                   if (fd->perm == ADIO_PERM_NULL) {
550 +                       old_mask = umask(022);
551 +                       umask(old_mask);
552 +                       perm = old_mask ^ 0666;
553 +                   }
554 +                   else perm = fd->perm;
555 +
556 +                   amode = 0;
557 +                   if (fd->access_mode & ADIO_CREATE)
558 +                       amode = amode | O_CREAT;
559 +                   if (fd->access_mode & ADIO_RDONLY)
560 +                       amode = amode | O_RDONLY;
561 +                   if (fd->access_mode & ADIO_WRONLY)
562 +                       amode = amode | O_WRONLY;
563 +                   if (fd->access_mode & ADIO_RDWR)
564 +                       amode = amode | O_RDWR;
565 +                   if (fd->access_mode & ADIO_EXCL)
566 +                       amode = amode | O_EXCL;
567 +
568 +                   /* we need to create file so ensure this is set */
569 +                    amode = amode | O_LOV_DELAY_CREATE | O_CREAT;
570 +
571 +                    fd_sys = open(fd->filename, amode, perm);
572 +                    if (fd_sys == -1) {
573 +                       if (errno != EEXIST)
574 +                           printf("Failure to open file %s %d %d\n",strerror(errno), amode, perm);
575 +                    } else {
576 +                        lum.lmm_magic = LOV_USER_MAGIC;
577 +                        lum.lmm_pattern = 0;
578 +                        lum.lmm_stripe_size = str_unit;
579 +                        lum.lmm_stripe_count = str_factor;
580 +                        lum.lmm_stripe_offset = start_iodev;
581 +
582 +                        err = ioctl(fd_sys, LL_IOC_LOV_SETSTRIPE, &lum);
583 +                        if (err == -1 && errno != EEXIST) {
584 +                           printf("Failure to set stripe info %s \n",strerror(errno));
585 +                        }
586 +
587 +                        close(fd_sys);
588 +                   }
589 +
590 +               }
591 +               MPI_Barrier(fd->comm);
592 +           }
593 +
594 +           ADIOI_Free(value);
595 +       }
596 +
597 +       /* set the values for collective I/O and data sieving parameters */
598 +       ADIOI_GEN_SetInfo(fd, users_info, error_code);
599 +    }
600 +
601 +    else {
602 +       /* The file has been opened previously and fd->fd_sys is a valid
603 +           file descriptor. cannot set striping parameters now. */
604 +
605 +       /* set the values for collective I/O and data sieving parameters */
606 +       ADIOI_GEN_SetInfo(fd, users_info, error_code);
607 +
608 +    }
609 +
610 +    *error_code = MPI_SUCCESS;
611 +}
612 diff -ruN romio-orig/adio/ad_lustre/ad_lustre_iread.c romio/adio/ad_lustre/ad_lustre_iread.c
613 --- romio-orig/adio/ad_lustre/ad_lustre_iread.c 1969-12-31 19:00:00.000000000 -0500
614 +++ romio/adio/ad_lustre/ad_lustre_iread.c      2006-09-06 17:10:35.000751765 -0400
615 @@ -0,0 +1,106 @@
616 +/* -*- Mode: C; c-basic-offset:4 ; -*- */
617 +/*
618 + *   $Id: ad_lustre_iread.c,v 1.1.1.1 2004/11/04 11:03:38 liam Exp $
619 + *
620 + *   Copyright (C) 1997 University of Chicago.
621 + *   See COPYRIGHT notice in top-level directory.
622 + */
623 +
624 +#include "ad_lustre.h"
625 +
626 +void ADIOI_LUSTRE_IreadContig(ADIO_File fd, void *buf, int count,
627 +                MPI_Datatype datatype, int file_ptr_type,
628 +                ADIO_Offset offset, ADIO_Request *request, int *error_code)
629 +{
630 +    int len, typesize;
631 +#ifdef NO_AIO
632 +    ADIO_Status status;
633 +#else
634 +    int err=-1;
635 +#if defined(MPICH2) || !defined(PRINT_ERR_MSG)
636 +    static char myname[] = "ADIOI_LUSTRE_IREADCONTIG";
637 +#endif
638 +#endif
639 +
640 +    (*request) = ADIOI_Malloc_request();
641 +    (*request)->optype = ADIOI_READ;
642 +    (*request)->fd = fd;
643 +    (*request)->datatype = datatype;
644 +
645 +    MPI_Type_size(datatype, &typesize);
646 +    len = count * typesize;
647 +
648 +#ifdef NO_AIO
649 +    /* HP, FreeBSD, Linux */
650 +    /* no support for nonblocking I/O. Use blocking I/O. */
651 +
652 +    ADIOI_LUSTRE_ReadContig(fd, buf, len, MPI_BYTE, file_ptr_type, offset,
653 +                        &status, error_code);
654 +    (*request)->queued = 0;
655 +#ifdef HAVE_STATUS_SET_BYTES
656 +    if (*error_code == MPI_SUCCESS) {
657 +       MPI_Get_elements(&status, MPI_BYTE, &len);
658 +       (*request)->nbytes = len;
659 +    }
660 +#endif
661 +
662 +#else
663 +    if (file_ptr_type == ADIO_INDIVIDUAL) offset = fd->fp_ind;
664 +    err = ADIOI_LUSTRE_aio(fd, buf, len, offset, 0, &((*request)->handle));
665 +    if (file_ptr_type == ADIO_INDIVIDUAL) fd->fp_ind += len;
666 +
667 +    (*request)->queued = 1;
668 +    ADIOI_Add_req_to_list(request);
669 +
670 +    if (err == -1) {
671 +#ifdef MPICH2
672 +       *error_code = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io",
673 +           "**io %s", strerror(errno));
674 +       return;
675 +#elif defined(PRINT_ERR_MSG)
676 +                       *error_code = MPI_ERR_UNKNOWN;
677 +#else /* MPICH-1 */
678 +       *error_code = MPIR_Err_setmsg(MPI_ERR_IO, MPIR_ADIO_ERROR,
679 +                             myname, "I/O Error", "%s", strerror(errno));
680 +       ADIOI_Error(fd, *error_code, myname);
681 +#endif
682 +    }
683 +    else *error_code = MPI_SUCCESS;
684 +#endif  /* NO_AIO */
685 +
686 +    fd->fp_sys_posn = -1;   /* set it to null. */
687 +    fd->async_count++;
688 +}
689 +
690 +
691 +
692 +void ADIOI_LUSTRE_IreadStrided(ADIO_File fd, void *buf, int count,
693 +                      MPI_Datatype datatype, int file_ptr_type,
694 +                       ADIO_Offset offset, ADIO_Request *request, int
695 +                       *error_code)
696 +{
697 +    ADIO_Status status;
698 +#ifdef HAVE_STATUS_SET_BYTES
699 +    int typesize;
700 +#endif
701 +
702 +    *request = ADIOI_Malloc_request();
703 +    (*request)->optype = ADIOI_READ;
704 +    (*request)->fd = fd;
705 +    (*request)->datatype = datatype;
706 +    (*request)->queued = 0;
707 +    (*request)->handle = 0;
708 +
709 +/* call the blocking version. It is faster because it does data sieving. */
710 +    ADIOI_LUSTRE_ReadStrided(fd, buf, count, datatype, file_ptr_type,
711 +                            offset, &status, error_code);
712 +
713 +    fd->async_count++;
714 +
715 +#ifdef HAVE_STATUS_SET_BYTES
716 +    if (*error_code == MPI_SUCCESS) {
717 +       MPI_Type_size(datatype, &typesize);
718 +       (*request)->nbytes = count * typesize;
719 +    }
720 +#endif
721 +}
722 diff -ruN romio-orig/adio/ad_lustre/ad_lustre_iwrite.c romio/adio/ad_lustre/ad_lustre_iwrite.c
723 --- romio-orig/adio/ad_lustre/ad_lustre_iwrite.c        1969-12-31 19:00:00.000000000 -0500
724 +++ romio/adio/ad_lustre/ad_lustre_iwrite.c     2006-09-06 17:10:35.000761678 -0400
725 @@ -0,0 +1,268 @@
726 +/* -*- Mode: C; c-basic-offset:4 ; -*- */
727 +/*
728 + *   $Id: ad_lustre_iwrite.c,v 1.1.1.1 2004/11/04 11:03:38 liam Exp $
729 + *
730 + *   Copyright (C) 1997 University of Chicago.
731 + *   See COPYRIGHT notice in top-level directory.
732 + */
733 +
734 +#include "ad_lustre.h"
735 +
736 +void ADIOI_LUSTRE_IwriteContig(ADIO_File fd, void *buf, int count,
737 +                MPI_Datatype datatype, int file_ptr_type,
738 +                ADIO_Offset offset, ADIO_Request *request, int *error_code)
739 +{
740 +    int len, typesize;
741 +#ifdef NO_AIO
742 +    ADIO_Status status;
743 +#else
744 +    int err=-1;
745 +#if defined(MPICH2) || !defined(PRINT_ERR_MSG)
746 +    static char myname[] = "ADIOI_LUSTRE_IWRITECONTIG";
747 +#endif
748 +#endif
749 +
750 +    *request = ADIOI_Malloc_request();
751 +    (*request)->optype = ADIOI_WRITE;
752 +    (*request)->fd = fd;
753 +    (*request)->datatype = datatype;
754 +
755 +    MPI_Type_size(datatype, &typesize);
756 +    len = count * typesize;
757 +
758 +#ifdef NO_AIO
759 +    /* HP, FreeBSD, Linux */
760 +    /* no support for nonblocking I/O. Use blocking I/O. */
761 +
762 +    ADIOI_LUSTRE_WriteContig(fd, buf, len, MPI_BYTE, file_ptr_type, offset,
763 +                         &status, error_code);
764 +    (*request)->queued = 0;
765 +#ifdef HAVE_STATUS_SET_BYTES
766 +    if (*error_code == MPI_SUCCESS) {
767 +       MPI_Get_elements(&status, MPI_BYTE, &len);
768 +       (*request)->nbytes = len;
769 +    }
770 +#endif
771 +
772 +#else
773 +    if (file_ptr_type == ADIO_INDIVIDUAL) offset = fd->fp_ind;
774 +    err = ADIOI_LUSTRE_aio(fd, buf, len, offset, 1, &((*request)->handle));
775 +    if (file_ptr_type == ADIO_INDIVIDUAL) fd->fp_ind += len;
776 +
777 +    (*request)->queued = 1;
778 +    ADIOI_Add_req_to_list(request);
779 +
780 +    if (err == -1) {
781 +#ifdef MPICH2
782 +       *error_code = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io",
783 +           "**io %s", strerror(errno));
784 +       return;
785 +#elif defined(PRINT_ERR_MSG)
786 +                       *error_code = MPI_ERR_UNKNOWN;
787 +#else /* MPICH-1 */
788 +       *error_code = MPIR_Err_setmsg(MPI_ERR_IO, MPIR_ADIO_ERROR,
789 +                             myname, "I/O Error", "%s", strerror(errno));
790 +       ADIOI_Error(fd, *error_code, myname);
791 +#endif
792 +    }
793 +    else *error_code = MPI_SUCCESS;
794 +#endif /* NO_AIO */
795 +
796 +    fd->fp_sys_posn = -1;   /* set it to null. */
797 +    fd->async_count++;
798 +}
799 +
800 +
801 +
802 +
803 +void ADIOI_LUSTRE_IwriteStrided(ADIO_File fd, void *buf, int count,
804 +                      MPI_Datatype datatype, int file_ptr_type,
805 +                       ADIO_Offset offset, ADIO_Request *request, int
806 +                       *error_code)
807 +{
808 +    ADIO_Status status;
809 +#ifdef HAVE_STATUS_SET_BYTES
810 +    int typesize;
811 +#endif
812 +
813 +    *request = ADIOI_Malloc_request();
814 +    (*request)->optype = ADIOI_WRITE;
815 +    (*request)->fd = fd;
816 +    (*request)->datatype = datatype;
817 +    (*request)->queued = 0;
818 +    (*request)->handle = 0;
819 +
820 +/* call the blocking version. It is faster because it does data sieving. */
821 +    ADIOI_LUSTRE_WriteStrided(fd, buf, count, datatype, file_ptr_type,
822 +                            offset, &status, error_code);
823 +
824 +    fd->async_count++;
825 +
826 +#ifdef HAVE_STATUS_SET_BYTES
827 +    if (*error_code == MPI_SUCCESS) {
828 +       MPI_Type_size(datatype, &typesize);
829 +       (*request)->nbytes = count * typesize;
830 +    }
831 +#endif
832 +}
833 +
834 +
835 +/* This function is for implementation convenience. It is not user-visible.
836 +   It takes care of the differences in the interface for nonblocking I/O
837 +   on various Unix machines! If wr==1 write, wr==0 read. */
838 +
839 +int ADIOI_LUSTRE_aio(ADIO_File fd, void *buf, int len, ADIO_Offset offset,
840 +                 int wr, void *handle)
841 +{
842 +    int err=-1, fd_sys;
843 +
844 +#ifndef NO_AIO
845 +    int error_code;
846 +#ifdef AIO_SUN
847 +    aio_result_t *result;
848 +#else
849 +    struct aiocb *aiocbp;
850 +#endif
851 +#endif
852 +
853 +    fd_sys = fd->fd_sys;
854 +
855 +#ifdef AIO_SUN
856 +    result = (aio_result_t *) ADIOI_Malloc(sizeof(aio_result_t));
857 +    result->aio_return = AIO_INPROGRESS;
858 +    if (wr) err = aiowrite(fd_sys, buf, len, offset, SEEK_SET, result);
859 +    else err = aioread(fd_sys, buf, len, offset, SEEK_SET, result);
860 +
861 +    if (err == -1) {
862 +       if (errno == EAGAIN) {
863 +       /* the man pages say EPROCLIM, but in reality errno is set to EAGAIN! */
864 +
865 +        /* exceeded the max. no. of outstanding requests.
866 +           complete all previous async. requests and try again.*/
867 +
868 +           ADIOI_Complete_async(&error_code);
869 +           if (wr) err = aiowrite(fd_sys, buf, len, offset, SEEK_SET, result);
870 +           else err = aioread(fd_sys, buf, len, offset, SEEK_SET, result);
871 +
872 +           while (err == -1) {
873 +               if (errno == EAGAIN) {
874 +                    /* sleep and try again */
875 +                    sleep(1);
876 +                   if (wr) err = aiowrite(fd_sys, buf, len, offset, SEEK_SET, result);
877 +                   else err = aioread(fd_sys, buf, len, offset, SEEK_SET, result);
878 +               }
879 +                else {
880 +                    FPRINTF(stderr, "Unknown errno %d in ADIOI_LUSTRE_aio\n", errno);
881 +                    MPI_Abort(MPI_COMM_WORLD, 1);
882 +                }
883 +           }
884 +       }
885 +        else {
886 +            FPRINTF(stderr, "Unknown errno %d in ADIOI_LUSTRE_aio\n", errno);
887 +            MPI_Abort(MPI_COMM_WORLD, 1);
888 +        }
889 +    }
890 +
891 +    *((aio_result_t **) handle) = result;
892 +#endif
893 +
894 +#ifdef NO_FD_IN_AIOCB
895 +/* IBM */
896 +    aiocbp = (struct aiocb *) ADIOI_Malloc(sizeof(struct aiocb));
897 +    aiocbp->aio_whence = SEEK_SET;
898 +    aiocbp->aio_offset = offset;
899 +    aiocbp->aio_buf = buf;
900 +    aiocbp->aio_nbytes = len;
901 +    if (wr) err = aio_write(fd_sys, aiocbp);
902 +    else err = aio_read(fd_sys, aiocbp);
903 +
904 +    if (err == -1) {
905 +       if (errno == EAGAIN) {
906 +        /* exceeded the max. no. of outstanding requests.
907 +          complete all previous async. requests and try again. */
908 +
909 +           ADIOI_Complete_async(&error_code);
910 +           if (wr) err = aio_write(fd_sys, aiocbp);
911 +           else err = aio_read(fd_sys, aiocbp);
912 +
913 +            while (err == -1) {
914 +                if (errno == EAGAIN) {
915 +                    /* sleep and try again */
916 +                    sleep(1);
917 +                   if (wr) err = aio_write(fd_sys, aiocbp);
918 +                   else err = aio_read(fd_sys, aiocbp);
919 +               }
920 +                else {
921 +                    FPRINTF(stderr, "Unknown errno %d in ADIOI_LUSTRE_aio\n", errno);
922 +                    MPI_Abort(MPI_COMM_WORLD, 1);
923 +                }
924 +            }
925 +       }
926 +        else {
927 +            FPRINTF(stderr, "Unknown errno %d in ADIOI_LUSTRE_aio\n", errno);
928 +            MPI_Abort(MPI_COMM_WORLD, 1);
929 +        }
930 +    }
931 +
932 +    *((struct aiocb **) handle) = aiocbp;
933 +
934 +#elif (!defined(NO_AIO) && !defined(AIO_SUN))
935 +/* DEC, SGI IRIX 5 and 6 */
936 +
937 +    aiocbp = (struct aiocb *) ADIOI_Calloc(sizeof(struct aiocb), 1);
938 +    aiocbp->aio_fildes = fd_sys;
939 +    aiocbp->aio_offset = offset;
940 +    aiocbp->aio_buf = buf;
941 +    aiocbp->aio_nbytes = len;
942 +
943 +#ifdef AIO_PRIORITY_DEFAULT
944 +/* DEC */
945 +    aiocbp->aio_reqprio = AIO_PRIO_DFL;   /* not needed in DEC Unix 4.0 */
946 +    aiocbp->aio_sigevent.sigev_signo = 0;
947 +#else
948 +    aiocbp->aio_reqprio = 0;
949 +#endif
950 +
951 +#ifdef AIO_SIGNOTIFY_NONE
952 +/* SGI IRIX 6 */
953 +    aiocbp->aio_sigevent.sigev_notify = SIGEV_NONE;
954 +#else
955 +    aiocbp->aio_sigevent.sigev_signo = 0;
956 +#endif
957 +
958 +    if (wr) err = aio_write(aiocbp);
959 +    else err = aio_read(aiocbp);
960 +
961 +    if (err == -1) {
962 +       if (errno == EAGAIN) {
963 +        /* exceeded the max. no. of outstanding requests.
964 +           complete all previous async. requests and try again. */
965 +
966 +           ADIOI_Complete_async(&error_code);
967 +           if (wr) err = aio_write(aiocbp);
968 +           else err = aio_read(aiocbp);
969 +
970 +           while (err == -1) {
971 +               if (errno == EAGAIN) {
972 +                   /* sleep and try again */
973 +                   sleep(1);
974 +                   if (wr) err = aio_write(aiocbp);
975 +                   else err = aio_read(aiocbp);
976 +               }
977 +               else {
978 +                   FPRINTF(stderr, "Unknown errno %d in ADIOI_LUSTRE_aio\n", errno);
979 +                   MPI_Abort(MPI_COMM_WORLD, 1);
980 +               }
981 +           }
982 +        }
983 +       else {
984 +           FPRINTF(stderr, "Unknown errno %d in ADIOI_LUSTRE_aio\n", errno);
985 +           MPI_Abort(MPI_COMM_WORLD, 1);
986 +       }
987 +    }
988 +
989 +    *((struct aiocb **) handle) = aiocbp;
990 +#endif
991 +
992 +    return err;
993 +}
994 diff -ruN romio-orig/adio/ad_lustre/ad_lustre_open.c romio/adio/ad_lustre/ad_lustre_open.c
995 --- romio-orig/adio/ad_lustre/ad_lustre_open.c  1969-12-31 19:00:00.000000000 -0500
996 +++ romio/adio/ad_lustre/ad_lustre_open.c       2006-09-06 17:10:35.000771351 -0400
997 @@ -0,0 +1,100 @@
998 +/* -*- Mode: C; c-basic-offset:4 ; -*- */
999 +/*
1000 + *   $Id: ad_lustre_open.c,v 1.1.1.1 2004/11/04 11:03:38 liam Exp $
1001 + *
1002 + *   Copyright (C) 1997 University of Chicago.
1003 + *   See COPYRIGHT notice in top-level directory.
1004 + */
1005 +
1006 +#include "ad_lustre.h"
1007 +
1008 +void ADIOI_LUSTRE_Open(ADIO_File fd, int *error_code)
1009 +{
1010 +    int perm, old_mask, amode;
1011 +    struct lov_user_md lum = { 0 };
1012 +    char *value;
1013 +
1014 +#if defined(MPICH2) || !defined(PRINT_ERR_MSG)
1015 +    static char myname[] = "ADIOI_LUSTRE_OPEN";
1016 +#endif
1017 +
1018 +    if (fd->perm == ADIO_PERM_NULL) {
1019 +       old_mask = umask(022);
1020 +       umask(old_mask);
1021 +       perm = old_mask ^ 0666;
1022 +    }
1023 +    else perm = fd->perm;
1024 +
1025 +    amode = 0;
1026 +    if (fd->access_mode & ADIO_CREATE)
1027 +       amode = amode | O_CREAT;
1028 +    if (fd->access_mode & ADIO_RDONLY)
1029 +       amode = amode | O_RDONLY;
1030 +    if (fd->access_mode & ADIO_WRONLY)
1031 +       amode = amode | O_WRONLY;
1032 +    if (fd->access_mode & ADIO_RDWR)
1033 +       amode = amode | O_RDWR;
1034 +    if (fd->access_mode & ADIO_EXCL)
1035 +       amode = amode | O_EXCL;
1036 +
1037 +    fd->fd_sys = open(fd->filename, amode, perm);
1038 +
1039 +    if (fd->fd_sys != -1) {
1040 +        int err;
1041 +
1042 +        value = (char *) ADIOI_Malloc((MPI_MAX_INFO_VAL+1)*sizeof(char));
1043 +
1044 +        /* get file striping information and set it in info */
1045 +        lum.lmm_magic = LOV_USER_MAGIC;
1046 +        err = ioctl(fd->fd_sys, LL_IOC_LOV_GETSTRIPE, (void *) &lum);
1047 +
1048 +        if (!err) {
1049 +            sprintf(value, "%d", lum.lmm_stripe_size);
1050 +            MPI_Info_set(fd->info, "striping_unit", value);
1051 +
1052 +            sprintf(value, "%d", lum.lmm_stripe_count);
1053 +            MPI_Info_set(fd->info, "striping_factor", value);
1054 +
1055 +            sprintf(value, "%d", lum.lmm_stripe_offset);
1056 +            MPI_Info_set(fd->info, "start_iodevice", value);
1057 +        }
1058 +        ADIOI_Free(value);
1059 +
1060 +        if (fd->access_mode & ADIO_APPEND)
1061 +            fd->fp_ind = fd->fp_sys_posn = lseek(fd->fd_sys, 0, SEEK_END);
1062 +    }
1063 +
1064 +
1065 +    if ((fd->fd_sys != -1) && (fd->access_mode & ADIO_APPEND))
1066 +       fd->fp_ind = fd->fp_sys_posn = lseek(fd->fd_sys, 0, SEEK_END);
1067 +
1068 +    if (fd->fd_sys == -1) {
1069 +#ifdef MPICH2
1070 +       if (errno == ENAMETOOLONG)
1071 +           *error_code = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_BAD_FILE, "**filenamelong", "**filenamelong %s %d", fd->filename, strlen(fd->filename));
1072 +       else if (errno == ENOENT)
1073 +           *error_code = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_NO_SUCH_FILE, "**filenoexist", "**filenoexist %s", fd->filename);
1074 +       else if (errno == ENOTDIR || errno == ELOOP)
1075 +           *error_code = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_BAD_FILE, "**filenamedir", "**filenamedir %s", fd->filename);
1076 +       else if (errno == EACCES) {
1077 +           *error_code = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ACCESS, "**fileaccess", "**fileaccess %s",
1078 +                                              fd->filename);
1079 +       }
1080 +       else if (errno == EROFS) {
1081 +           /* Read only file or file system and write access requested */
1082 +           *error_code = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_READ_ONLY, "**ioneedrd", 0);
1083 +       }
1084 +       else {
1085 +           *error_code = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io",
1086 +           "**io %s", strerror(errno));
1087 +       }
1088 +#elif defined(PRINT_ERR_MSG)
1089 +                       *error_code = MPI_ERR_UNKNOWN;
1090 +#else /* MPICH-1 */
1091 +       *error_code = MPIR_Err_setmsg(MPI_ERR_IO, MPIR_ADIO_ERROR,
1092 +                             myname, "I/O Error", "%s", strerror(errno));
1093 +       ADIOI_Error(ADIO_FILE_NULL, *error_code, myname);
1094 +#endif
1095 +    }
1096 +    else *error_code = MPI_SUCCESS;
1097 +}
1098 diff -ruN romio-orig/adio/ad_lustre/ad_lustre_rdcoll.c romio/adio/ad_lustre/ad_lustre_rdcoll.c
1099 --- romio-orig/adio/ad_lustre/ad_lustre_rdcoll.c        1969-12-31 19:00:00.000000000 -0500
1100 +++ romio/adio/ad_lustre/ad_lustre_rdcoll.c     2006-09-06 17:10:35.000780880 -0400
1101 @@ -0,0 +1,18 @@
1102 +/* -*- Mode: C; c-basic-offset:4 ; -*- */
1103 +/*
1104 + *   $Id: ad_lustre_rdcoll.c,v 1.1.1.1 2004/11/04 11:03:38 liam Exp $
1105 + *
1106 + *   Copyright (C) 1997 University of Chicago.
1107 + *   See COPYRIGHT notice in top-level directory.
1108 + */
1109 +
1110 +#include "ad_lustre.h"
1111 +
1112 +void ADIOI_LUSTRE_ReadStridedColl(ADIO_File fd, void *buf, int count,
1113 +                       MPI_Datatype datatype, int file_ptr_type,
1114 +                       ADIO_Offset offset, ADIO_Status *status, int
1115 +                       *error_code)
1116 +{
1117 +    ADIOI_GEN_ReadStridedColl(fd, buf, count, datatype, file_ptr_type,
1118 +                             offset, status, error_code);
1119 +}
1120 diff -ruN romio-orig/adio/ad_lustre/ad_lustre_read.c romio/adio/ad_lustre/ad_lustre_read.c
1121 --- romio-orig/adio/ad_lustre/ad_lustre_read.c  1969-12-31 19:00:00.000000000 -0500
1122 +++ romio/adio/ad_lustre/ad_lustre_read.c       2006-09-06 17:10:35.000790846 -0400
1123 @@ -0,0 +1,67 @@
1124 +/* -*- Mode: C; c-basic-offset:4 ; -*- */
1125 +/*
1126 + *   $Id: ad_lustre_read.c,v 1.1.1.1 2004/11/04 11:03:38 liam Exp $
1127 + *
1128 + *   Copyright (C) 1997 University of Chicago.
1129 + *   See COPYRIGHT notice in top-level directory.
1130 + */
1131 +
1132 +#include "ad_lustre.h"
1133 +
1134 +void ADIOI_LUSTRE_ReadContig(ADIO_File fd, void *buf, int count,
1135 +                     MPI_Datatype datatype, int file_ptr_type,
1136 +                    ADIO_Offset offset, ADIO_Status *status, int *error_code)
1137 +{
1138 +    int err=-1, datatype_size, len;
1139 +#if defined(MPICH2) || !defined(PRINT_ERR_MSG)
1140 +    static char myname[] = "ADIOI_LUSTRE_READCONTIG";
1141 +#endif
1142 +
1143 +    MPI_Type_size(datatype, &datatype_size);
1144 +    len = datatype_size * count;
1145 +
1146 +    if (file_ptr_type == ADIO_EXPLICIT_OFFSET) {
1147 +       if (fd->fp_sys_posn != offset)
1148 +           lseek(fd->fd_sys, offset, SEEK_SET);
1149 +       err = read(fd->fd_sys, buf, len);
1150 +       fd->fp_sys_posn = offset + len;
1151 +       /* individual file pointer not updated */
1152 +    }
1153 +    else {  /* read from curr. location of ind. file pointer */
1154 +       if (fd->fp_sys_posn != fd->fp_ind)
1155 +           lseek(fd->fd_sys, fd->fp_ind, SEEK_SET);
1156 +       err = read(fd->fd_sys, buf, len);
1157 +       fd->fp_ind += err;
1158 +       fd->fp_sys_posn = fd->fp_ind;
1159 +    }
1160 +
1161 +#ifdef HAVE_STATUS_SET_BYTES
1162 +    if (err != -1) MPIR_Status_set_bytes(status, datatype, err);
1163 +#endif
1164 +
1165 +    if (err == -1) {
1166 +#ifdef MPICH2
1167 +       *error_code = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io",
1168 +           "**io %s", strerror(errno));
1169 +#elif defined(PRINT_ERR_MSG)
1170 +                       *error_code = MPI_ERR_UNKNOWN;
1171 +#else /* MPICH-1 */
1172 +       *error_code = MPIR_Err_setmsg(MPI_ERR_IO, MPIR_ADIO_ERROR,
1173 +                             myname, "I/O Error", "%s", strerror(errno));
1174 +       ADIOI_Error(fd, *error_code, myname);
1175 +#endif
1176 +    }
1177 +    else *error_code = MPI_SUCCESS;
1178 +}
1179 +
1180 +
1181 +
1182 +
1183 +void ADIOI_LUSTRE_ReadStrided(ADIO_File fd, void *buf, int count,
1184 +                       MPI_Datatype datatype, int file_ptr_type,
1185 +                       ADIO_Offset offset, ADIO_Status *status, int
1186 +                       *error_code)
1187 +{
1188 +    ADIOI_GEN_ReadStrided(fd, buf, count, datatype, file_ptr_type,
1189 +                        offset, status, error_code);
1190 +}
1191 diff -ruN romio-orig/adio/ad_lustre/ad_lustre_resize.c romio/adio/ad_lustre/ad_lustre_resize.c
1192 --- romio-orig/adio/ad_lustre/ad_lustre_resize.c        1969-12-31 19:00:00.000000000 -0500
1193 +++ romio/adio/ad_lustre/ad_lustre_resize.c     2006-09-06 17:10:35.000807397 -0400
1194 @@ -0,0 +1,32 @@
1195 +/* -*- Mode: C; c-basic-offset:4 ; -*- */
1196 +/*
1197 + *   $Id: ad_lustre_resize.c,v 1.1.1.1 2004/11/04 11:03:38 liam Exp $
1198 + *
1199 + *   Copyright (C) 1997 University of Chicago.
1200 + *   See COPYRIGHT notice in top-level directory.
1201 + */
1202 +
1203 +#include "ad_lustre.h"
1204 +
1205 +void ADIOI_LUSTRE_Resize(ADIO_File fd, ADIO_Offset size, int *error_code)
1206 +{
1207 +    int err;
1208 +#if defined(MPICH2) || !defined(PRINT_ERR_MSG)
1209 +    static char myname[] = "ADIOI_LUSTRE_RESIZE";
1210 +#endif
1211 +
1212 +    err = ftruncate(fd->fd_sys, size);
1213 +    if (err == -1) {
1214 +#ifdef MPICH2
1215 +       *error_code = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io",
1216 +           "**io %s", strerror(errno));
1217 +#elif defined(PRINT_ERR_MSG)
1218 +                       *error_code = MPI_ERR_UNKNOWN;
1219 +#else /* MPICH-1 */
1220 +       *error_code = MPIR_Err_setmsg(MPI_ERR_IO, MPIR_ADIO_ERROR,
1221 +                             myname, "I/O Error", "%s", strerror(errno));
1222 +       ADIOI_Error(fd, *error_code, myname);
1223 +#endif
1224 +    }
1225 +    else *error_code = MPI_SUCCESS;
1226 +}
1227 diff -ruN romio-orig/adio/ad_lustre/ad_lustre_seek.c romio/adio/ad_lustre/ad_lustre_seek.c
1228 --- romio-orig/adio/ad_lustre/ad_lustre_seek.c  1969-12-31 19:00:00.000000000 -0500
1229 +++ romio/adio/ad_lustre/ad_lustre_seek.c       2006-09-06 17:10:35.000816583 -0400
1230 @@ -0,0 +1,15 @@
1231 +/* -*- Mode: C; c-basic-offset:4 ; -*- */
1232 +/*
1233 + *   $Id: ad_lustre_seek.c,v 1.1.1.1 2004/11/04 11:03:38 liam Exp $
1234 + *
1235 + *   Copyright (C) 1997 University of Chicago.
1236 + *   See COPYRIGHT notice in top-level directory.
1237 + */
1238 +
1239 +#include "ad_lustre.h"
1240 +
1241 +ADIO_Offset ADIOI_LUSTRE_SeekIndividual(ADIO_File fd, ADIO_Offset offset,
1242 +                     int whence, int *error_code)
1243 +{
1244 +    return ADIOI_GEN_SeekIndividual(fd, offset, whence, error_code);
1245 +}
1246 diff -ruN romio-orig/adio/ad_lustre/ad_lustre_wait.c romio/adio/ad_lustre/ad_lustre_wait.c
1247 --- romio-orig/adio/ad_lustre/ad_lustre_wait.c  1969-12-31 19:00:00.000000000 -0500
1248 +++ romio/adio/ad_lustre/ad_lustre_wait.c       2006-09-06 18:45:39.000190529 -0400
1249 @@ -0,0 +1,188 @@
1250 +/* -*- Mode: C; c-basic-offset:4 ; -*- */
1251 +/*
1252 + *   $Id: ad_lustre_wait.c,v 1.1.1.1 2004/11/04 11:03:38 liam Exp $
1253 + *
1254 + *   Copyright (C) 1997 University of Chicago.
1255 + *   See COPYRIGHT notice in top-level directory.
1256 + */
1257 +
1258 +#include "ad_lustre.h"
1259 +
1260 +void ADIOI_LUSTRE_ReadComplete(ADIO_Request *request, ADIO_Status *status, int *error_code)
1261 +{
1262 +#ifndef NO_AIO
1263 +#if defined(MPICH2) || !defined(PRINT_ERR_MSG)
1264 +    static char myname[] = "ADIOI_LUSTRE_READCOMPLETE";
1265 +#endif
1266 +#ifdef AIO_SUN
1267 +    aio_result_t *result=0, *tmp;
1268 +#else
1269 +    int err;
1270 +#endif
1271 +#ifdef AIO_HANDLE_IN_AIOCB
1272 +    struct aiocb *tmp1;
1273 +#endif
1274 +#endif
1275 +
1276 +    if (*request == ADIO_REQUEST_NULL) {
1277 +       *error_code = MPI_SUCCESS;
1278 +       return;
1279 +    }
1280 +
1281 +#ifdef AIO_SUN
1282 +    if ((*request)->queued) {  /* dequeue it */
1283 +       tmp = (aio_result_t *) (*request)->handle;
1284 +       while (tmp->aio_return == AIO_INPROGRESS) usleep(1000);
1285 +       /* sleep for 1 ms., until done. Is 1 ms. a good number? */
1286 +       /* when done, dequeue any one request */
1287 +       result = (aio_result_t *) aiowait(0);
1288 +
1289 +        (*request)->nbytes = tmp->aio_return;
1290 +
1291 +       if (tmp->aio_return == -1) {
1292 +#ifdef MPICH2
1293 +           *error_code = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io",
1294 +               "**io %s", strerror(tmp->aio_errno));
1295 +           return;
1296 +#elif defined(PRINT_ERR_MSG)
1297 +                       *error_code = MPI_ERR_UNKNOWN;
1298 +#else /* MPICH-1 */
1299 +           *error_code = MPIR_Err_setmsg(MPI_ERR_IO, MPIR_ADIO_ERROR,
1300 +                         myname, "I/O Error", "%s", strerror(tmp->aio_errno));
1301 +           ADIOI_Error((*request)->fd, *error_code, myname);
1302 +#endif
1303 +       }
1304 +       else *error_code = MPI_SUCCESS;
1305 +
1306 +/* aiowait only dequeues a request. The completion of a request can be
1307 +   checked by just checking the aio_return flag in the handle passed
1308 +   to the original aioread()/aiowrite(). Therefore, I need to ensure
1309 +   that aiowait() is called exactly once for each previous
1310 +   aioread()/aiowrite(). This is also taken care of in ADIOI_xxxDone */
1311 +    }
1312 +    else *error_code = MPI_SUCCESS;
1313 +
1314 +#ifdef HAVE_STATUS_SET_BYTES
1315 +    if ((*request)->nbytes != -1)
1316 +       MPIR_Status_set_bytes(status, (*request)->datatype, (*request)->nbytes);
1317 +#endif
1318 +
1319 +#endif
1320 +
1321 +#ifdef AIO_HANDLE_IN_AIOCB
1322 +/* IBM */
1323 +    if ((*request)->queued) {
1324 +       do {
1325 +           err = aio_suspend(1, (struct aiocb **) &((*request)->handle));
1326 +       } while ((err == -1) && (errno == EINTR));
1327 +
1328 +       tmp1 = (struct aiocb *) (*request)->handle;
1329 +       if (err != -1) {
1330 +           err = aio_return(tmp1->aio_handle);
1331 +           (*request)->nbytes = err;
1332 +           errno = aio_error(tmp1->aio_handle);
1333 +       }
1334 +       else (*request)->nbytes = -1;
1335 +
1336 +/* on DEC, it is required to call aio_return to dequeue the request.
1337 +   IBM man pages don't indicate what function to use for dequeue.
1338 +   I'm assuming it is aio_return! POSIX says aio_return may be called
1339 +   only once on a given handle. */
1340 +
1341 +       if (err == -1) {
1342 +#ifdef MPICH2
1343 +           *error_code = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io",
1344 +               "**io %s", strerror(errno));
1345 +           return;
1346 +#elif defined(PRINT_ERR_MSG)
1347 +                       *error_code = MPI_ERR_UNKNOWN;
1348 +#else /* MPICH-1 */
1349 +           *error_code = MPIR_Err_setmsg(MPI_ERR_IO, MPIR_ADIO_ERROR,
1350 +             myname, "I/O Error", "%s", strerror(errno));
1351 +           ADIOI_Error((*request)->fd, *error_code, myname);
1352 +#endif
1353 +       }
1354 +       else *error_code = MPI_SUCCESS;
1355 +    } /* if ((*request)->queued)  */
1356 +    else *error_code = MPI_SUCCESS;
1357 +
1358 +#ifdef HAVE_STATUS_SET_BYTES
1359 +    if ((*request)->nbytes != -1)
1360 +       MPIR_Status_set_bytes(status, (*request)->datatype, (*request)->nbytes);
1361 +#endif
1362 +
1363 +#elif (!defined(NO_AIO) && !defined(AIO_SUN))
1364 +/* DEC, SGI IRIX 5 and 6 */
1365 +    if ((*request)->queued) {
1366 +       do {
1367 +           err = aio_suspend((const struct aiocb_t **) &((*request)->handle), 1, 0);
1368 +       } while ((err == -1) && (errno == EINTR));
1369 +
1370 +       if (err != -1) {
1371 +           err = aio_return((struct aiocb *) (*request)->handle);
1372 +           (*request)->nbytes = err;
1373 +           errno = aio_error((struct aiocb *) (*request)->handle);
1374 +       }
1375 +       else (*request)->nbytes = -1;
1376 +
1377 +       if (err == -1) {
1378 +#ifdef MPICH2
1379 +           *error_code = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io",
1380 +               "**io %s", strerror(errno));
1381 +           return;
1382 +#elif defined(PRINT_ERR_MSG)
1383 +                       *error_code = MPI_ERR_UNKNOWN;
1384 +#else /* MPICH-1 */
1385 +           *error_code = MPIR_Err_setmsg(MPI_ERR_IO, MPIR_ADIO_ERROR,
1386 +                           myname, "I/O Error", "%s", strerror(errno));
1387 +           ADIOI_Error((*request)->fd, *error_code, myname);
1388 +#endif
1389 +       }
1390 +       else *error_code = MPI_SUCCESS;
1391 +    } /* if ((*request)->queued) */
1392 +    else *error_code = MPI_SUCCESS;
1393 +#ifdef HAVE_STATUS_SET_BYTES
1394 +    if ((*request)->nbytes != -1)
1395 +       MPIR_Status_set_bytes(status, (*request)->datatype, (*request)->nbytes);
1396 +#endif
1397 +#endif
1398 +
1399 +#ifndef NO_AIO
1400 +    if ((*request)->queued != -1) {
1401 +
1402 +       /* queued = -1 is an internal hack used when the request must
1403 +          be completed, but the request object should not be
1404 +          freed. This is used in ADIOI_Complete_async, because the user
1405 +          will call MPI_Wait later, which would require status to
1406 +          be filled. Ugly but works. queued = -1 should be used only
1407 +          in ADIOI_Complete_async.
1408 +           This should not affect the user in any way. */
1409 +
1410 +       /* if request is still queued in the system, it is also there
1411 +           on ADIOI_Async_list. Delete it from there. */
1412 +       if ((*request)->queued) ADIOI_Del_req_from_list(request);
1413 +
1414 +       (*request)->fd->async_count--;
1415 +       if ((*request)->handle) ADIOI_Free((*request)->handle);
1416 +       ADIOI_Free_request((ADIOI_Req_node *) (*request));
1417 +       *request = ADIO_REQUEST_NULL;
1418 +    }
1419 +
1420 +#else
1421 +/* HP, FreeBSD, Linux */
1422 +
1423 +#ifdef HAVE_STATUS_SET_BYTES
1424 +    MPIR_Status_set_bytes(status, (*request)->datatype, (*request)->nbytes);
1425 +#endif
1426 +    (*request)->fd->async_count--;
1427 +    ADIOI_Free_request((ADIOI_Req_node *) (*request));
1428 +    *request = ADIO_REQUEST_NULL;
1429 +    *error_code = MPI_SUCCESS;
1430 +#endif
1431 +}
1432 +
1433 +
1434 +void ADIOI_LUSTRE_WriteComplete(ADIO_Request *request, ADIO_Status *status, int *error_code)
1435 +{
1436 +    ADIOI_LUSTRE_ReadComplete(request, status, error_code);
1437 +}
1438 diff -ruN romio-orig/adio/ad_lustre/ad_lustre_wrcoll.c romio/adio/ad_lustre/ad_lustre_wrcoll.c
1439 --- romio-orig/adio/ad_lustre/ad_lustre_wrcoll.c        1969-12-31 19:00:00.000000000 -0500
1440 +++ romio/adio/ad_lustre/ad_lustre_wrcoll.c     2006-09-06 17:10:35.000835460 -0400
1441 @@ -0,0 +1,18 @@
1442 +/* -*- Mode: C; c-basic-offset:4 ; -*- */
1443 +/*
1444 + *   $Id: ad_lustre_wrcoll.c,v 1.1.1.1 2004/11/04 11:03:38 liam Exp $
1445 + *
1446 + *   Copyright (C) 1997 University of Chicago.
1447 + *   See COPYRIGHT notice in top-level directory.
1448 + */
1449 +
1450 +#include "ad_lustre.h"
1451 +
1452 +void ADIOI_LUSTRE_WriteStridedColl(ADIO_File fd, void *buf, int count,
1453 +                       MPI_Datatype datatype, int file_ptr_type,
1454 +                       ADIO_Offset offset, ADIO_Status *status, int
1455 +                       *error_code)
1456 +{
1457 +    ADIOI_GEN_WriteStridedColl(fd, buf, count, datatype, file_ptr_type,
1458 +                             offset, status, error_code);
1459 +}
1460 diff -ruN romio-orig/adio/ad_lustre/ad_lustre_write.c romio/adio/ad_lustre/ad_lustre_write.c
1461 --- romio-orig/adio/ad_lustre/ad_lustre_write.c 1969-12-31 19:00:00.000000000 -0500
1462 +++ romio/adio/ad_lustre/ad_lustre_write.c      2006-09-06 17:10:35.000844658 -0400
1463 @@ -0,0 +1,66 @@
1464 +/* -*- Mode: C; c-basic-offset:4 ; -*- */
1465 +/*
1466 + *   $Id: ad_lustre_write.c,v 1.1.1.1 2004/11/04 11:03:38 liam Exp $
1467 + *
1468 + *   Copyright (C) 1997 University of Chicago.
1469 + *   See COPYRIGHT notice in top-level directory.
1470 + */
1471 +
1472 +#include "ad_lustre.h"
1473 +
1474 +void ADIOI_LUSTRE_WriteContig(ADIO_File fd, void *buf, int count,
1475 +                   MPI_Datatype datatype, int file_ptr_type,
1476 +                  ADIO_Offset offset, ADIO_Status *status, int *error_code)
1477 +{
1478 +    int err=-1, datatype_size, len;
1479 +#if defined(MPICH2) || !defined(PRINT_ERR_MSG)
1480 +    static char myname[] = "ADIOI_LUSTRE_WRITECONTIG";
1481 +#endif
1482 +
1483 +    MPI_Type_size(datatype, &datatype_size);
1484 +    len = datatype_size * count;
1485 +
1486 +    if (file_ptr_type == ADIO_EXPLICIT_OFFSET) {
1487 +       if (fd->fp_sys_posn != offset)
1488 +           lseek(fd->fd_sys, offset, SEEK_SET);
1489 +       err = write(fd->fd_sys, buf, len);
1490 +       fd->fp_sys_posn = offset + err;
1491 +       /* individual file pointer not updated */
1492 +    }
1493 +    else { /* write from curr. location of ind. file pointer */
1494 +       if (fd->fp_sys_posn != fd->fp_ind)
1495 +           lseek(fd->fd_sys, fd->fp_ind, SEEK_SET);
1496 +       err = write(fd->fd_sys, buf, len);
1497 +       fd->fp_ind += err;
1498 +       fd->fp_sys_posn = fd->fp_ind;
1499 +    }
1500 +
1501 +#ifdef HAVE_STATUS_SET_BYTES
1502 +    if (err != -1 && status) MPIR_Status_set_bytes(status, datatype, err);
1503 +#endif
1504 +
1505 +    if (err == -1) {
1506 +#ifdef MPICH2
1507 +       *error_code = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io",
1508 +           "**io %s", strerror(errno));
1509 +#elif defined(PRINT_ERR_MSG)
1510 +                       *error_code = MPI_ERR_UNKNOWN;
1511 +#else
1512 +       *error_code = MPIR_Err_setmsg(MPI_ERR_IO, MPIR_ADIO_ERROR,
1513 +                             myname, "I/O Error", "%s", strerror(errno));
1514 +       ADIOI_Error(fd, *error_code, myname);
1515 +#endif
1516 +    }
1517 +    else *error_code = MPI_SUCCESS;
1518 +}
1519 +
1520 +
1521 +
1522 +void ADIOI_LUSTRE_WriteStrided(ADIO_File fd, void *buf, int count,
1523 +                       MPI_Datatype datatype, int file_ptr_type,
1524 +                       ADIO_Offset offset, ADIO_Status *status, int
1525 +                       *error_code)
1526 +{
1527 +    ADIOI_GEN_WriteStrided(fd, buf, count, datatype, file_ptr_type,
1528 +                        offset, status, error_code);
1529 +}
1530 diff -ruN romio-orig/adio/ad_lustre/Makefile.in romio/adio/ad_lustre/Makefile.in
1531 --- romio-orig/adio/ad_lustre/Makefile.in       1969-12-31 19:00:00.000000000 -0500
1532 +++ romio/adio/ad_lustre/Makefile.in    2006-09-06 18:48:56.000800829 -0400
1533 @@ -0,0 +1,51 @@
1534 +CC          = @CC@
1535 +AR          = @AR@
1536 +RANLIB      = @RANLIB@
1537 +LIBNAME     = @LIBNAME@
1538 +srcdir      = @srcdir@
1539 +CC_SHL      = @CC_SHL@
1540 +SHLIBNAME   = @SHLIBNAME@
1541 +
1542 +INCLUDE_DIR = -I@MPI_INCLUDE_DIR@ -I${srcdir}/../include -I../include -I../../include -I${srcdir}/../../../../include -I../../../../include
1543 +CFLAGS      = @CPPFLAGS@ @CFLAGS@ $(INCLUDE_DIR)
1544 +
1545 +top_builddir  = @master_topbuild_dir@
1546 +LIBTOOL       = @LIBTOOL@
1547 +C_COMPILE_SHL = $(CC_SHL) @CFLAGS@ $(INCLUDE_DIR)
1548 +
1549 +@VPATH@
1550 +
1551 +AD_LUSTRE_OBJECTS = ad_lustre.o ad_lustre_close.o ad_lustre_read.o \
1552 +      ad_lustre_open.o ad_lustre_write.o ad_lustre_done.o \
1553 +      ad_lustre_fcntl.o ad_lustre_iread.o ad_lustre_iwrite.o ad_lustre_wait.o \
1554 +      ad_lustre_resize.o ad_lustre_hints.o
1555 +
1556 +default: $(LIBNAME)
1557 +       @if [ "@ENABLE_SHLIB@" != "none" ] ; then \
1558 +           $(MAKE) $(SHLIBNAME).la ;\
1559 +       fi
1560 +
1561 +.SUFFIXES: $(SUFFIXES) .p .lo
1562 +
1563 +.c.o:
1564 +       $(CC) $(CFLAGS) -c $<
1565 +.c.lo:
1566 +       $(C_COMPILE_SHL) -c $< -o _s$*.o
1567 +       @mv -f _s$*.o $*.lo
1568 +#      $(C_COMPILE_SHL) -c $<
1569 +#      @mv -f $*.o $*.lo
1570 +
1571 +$(LIBNAME): $(AD_LUSTRE_OBJECTS)
1572 +       $(AR) $(LIBNAME) $(AD_LUSTRE_OBJECTS)
1573 +       $(RANLIB) $(LIBNAME)
1574 +
1575 +AD_LUSTRE_LOOBJECTS=$(AD_LUSTRE_OBJECTS:.o=.lo)
1576 +$(SHLIBNAME).la: $(AD_LUSTRE_LOOBJECTS)
1577 +       $(AR) $(SHLIBNAME).la $(AD_LUSTRE_LOOBJECTS)
1578 +
1579 +coverage:
1580 +       -@for file in  ${AD_LUSTRE_OBJECTS:.o=.c} ; do \
1581 +               gcov -b -f $$file ; done
1582 +
1583 +clean:
1584 +       @rm -f *.o *.lo
1585 diff -ruN romio-orig/adio/common/ad_fstype.c romio/adio/common/ad_fstype.c
1586 --- romio-orig/adio/common/ad_fstype.c  2005-08-11 19:33:46.000000000 -0400
1587 +++ romio/adio/common/ad_fstype.c       2006-09-06 17:41:20.000830936 -0400
1588 @@ -265,6 +265,9 @@
1589      /* if UFS support is enabled, default to that */
1590      *fstype = ADIO_UFS;
1591      return;
1592 +# elif defined(LINUX) && defined(ROMIO_LUSTRE)
1593 +# warning use correct include
1594 +# define LL_SUPER_MAGIC 0x0BD00BD0
1595  # endif
1596  
1597      /* --BEGIN ERROR HANDLING-- */
1598 @@ -308,6 +311,13 @@
1599      }
1600  # endif
1601  
1602 +# ifdef LL_SUPER_MAGIC
1603 +    if (fsbuf.f_type == LL_SUPER_MAGIC) {
1604 +       *fstype = ADIO_LUSTRE;
1605 +       return;
1606 +    }
1607 +# endif
1608 +
1609  # ifdef PAN_KERNEL_FS_CLIENT_SUPER_MAGIC
1610      if (fsbuf.f_type == PAN_KERNEL_FS_CLIENT_SUPER_MAGIC) {
1611         *fstype = ADIO_PANFS;
1612 @@ -458,6 +468,11 @@
1613      {
1614         *fstype = ADIO_GRIDFTP;
1615      }
1616 +    else if (!strncmp(filename, "lustre:", 7)
1617 +            || !strncmp(filename, "LUSTRE:", 7))
1618 +    {
1619 +       *fstype = ADIO_LUSTRE;
1620 +    }
1621      else {
1622  #ifdef ROMIO_NTFS
1623         *fstype = ADIO_NTFS;
1624 @@ -657,6 +672,14 @@
1625         *ops = &ADIO_GRIDFTP_operations;
1626  #endif
1627      }
1628 +    if (file_system == ADIO_LUSTRE) {
1629 +#ifndef ROMIO_LUSTRE
1630 +       *error_code = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**iofstypeunsupported", 0);
1631 +       return;
1632 +#else
1633 +       *ops = &ADIO_LUSTRE_operations;
1634 +#endif
1635 +    }
1636      *error_code = MPI_SUCCESS;
1637      *fstype = file_system;
1638      return;
1639 diff -ruN romio-orig/adio/include/adio.h romio/adio/include/adio.h
1640 --- romio-orig/adio/include/adio.h      2006-06-09 17:45:04.000000000 -0400
1641 +++ romio/adio/include/adio.h   2006-09-06 17:44:16.000614058 -0400
1642 @@ -302,6 +302,7 @@
1643  #define ADIO_PVFS2               160   /* PVFS2: 2nd generation PVFS */
1644  #define ADIO_PANFS               161   /* Panasas FS */
1645  #define ADIO_GRIDFTP             162   /* Globus GridFTP */
1646 +#define ADIO_LUSTRE              163   /* Lustre */
1647  
1648  #define ADIO_SEEK_SET            SEEK_SET
1649  #define ADIO_SEEK_CUR            SEEK_CUR
1650 diff -ruN romio-orig/adio/include/adioi_fs_proto.h romio/adio/include/adioi_fs_proto.h
1651 --- romio-orig/adio/include/adioi_fs_proto.h    2005-06-08 17:16:39.000000000 -0400
1652 +++ romio/adio/include/adioi_fs_proto.h 2006-09-06 17:48:11.000523566 -0400
1653 @@ -49,6 +49,68 @@
1654  /* prototypes are in adio/ad_sfs/ad_sfs.h */
1655  #endif
1656  
1657 +#ifdef ROMIO_LUSTRE
1658 +extern struct ADIOI_Fns_struct ADIO_LUSTRE_operations;
1659 +
1660 +void ADIOI_LUSTRE_Open(ADIO_File fd, int *error_code);
1661 +void ADIOI_LUSTRE_Close(ADIO_File fd, int *error_code);
1662 +void ADIOI_LUSTRE_ReadContig(ADIO_File fd, void *buf, int count,
1663 +                      MPI_Datatype datatype, int file_ptr_type,
1664 +                     ADIO_Offset offset, ADIO_Status *status, int
1665 +                    *error_code);
1666 +void ADIOI_LUSTRE_WriteContig(ADIO_File fd, void *buf, int count,
1667 +                      MPI_Datatype datatype, int file_ptr_type,
1668 +                      ADIO_Offset offset, ADIO_Status *status, int
1669 +                     *error_code);
1670 +void ADIOI_LUSTRE_IwriteContig(ADIO_File fd, void *buf, int count,
1671 +                      MPI_Datatype datatype, int file_ptr_type,
1672 +                      ADIO_Offset offset, ADIO_Request *request, int
1673 +                     *error_code);
1674 +void ADIOI_LUSTRE_IreadContig(ADIO_File fd, void *buf, int count,
1675 +                      MPI_Datatype datatype, int file_ptr_type,
1676 +                      ADIO_Offset offset, ADIO_Request *request, int
1677 +                     *error_code);
1678 +int ADIOI_LUSTRE_ReadDone(ADIO_Request *request, ADIO_Status *status, int
1679 +                      *error_code);
1680 +int ADIOI_LUSTRE_WriteDone(ADIO_Request *request, ADIO_Status *status, int
1681 +                      *error_code);
1682 +void ADIOI_LUSTRE_ReadComplete(ADIO_Request *request, ADIO_Status *status, int
1683 +                      *error_code);
1684 +void ADIOI_LUSTRE_WriteComplete(ADIO_Request *request, ADIO_Status *status,
1685 +                       int *error_code);
1686 +void ADIOI_LUSTRE_Fcntl(ADIO_File fd, int flag, ADIO_Fcntl_t *fcntl_struct, int
1687 +               *error_code);
1688 +void ADIOI_LUSTRE_WriteStrided(ADIO_File fd, void *buf, int count,
1689 +                      MPI_Datatype datatype, int file_ptr_type,
1690 +                      ADIO_Offset offset, ADIO_Status *status, int
1691 +                      *error_code);
1692 +void ADIOI_LUSTRE_ReadStrided(ADIO_File fd, void *buf, int count,
1693 +                      MPI_Datatype datatype, int file_ptr_type,
1694 +                      ADIO_Offset offset, ADIO_Status *status, int
1695 +                      *error_code);
1696 +void ADIOI_LUSTRE_WriteStridedColl(ADIO_File fd, void *buf, int count,
1697 +                      MPI_Datatype datatype, int file_ptr_type,
1698 +                      ADIO_Offset offset, ADIO_Status *status, int
1699 +                      *error_code);
1700 +void ADIOI_LUSTRE_ReadStridedColl(ADIO_File fd, void *buf, int count,
1701 +                      MPI_Datatype datatype, int file_ptr_type,
1702 +                      ADIO_Offset offset, ADIO_Status *status, int
1703 +                      *error_code);
1704 +void ADIOI_LUSTRE_IreadStrided(ADIO_File fd, void *buf, int count,
1705 +                      MPI_Datatype datatype, int file_ptr_type,
1706 +                      ADIO_Offset offset, ADIO_Request *request, int
1707 +                      *error_code);
1708 +void ADIOI_LUSTRE_IwriteStrided(ADIO_File fd, void *buf, int count,
1709 +                      MPI_Datatype datatype, int file_ptr_type,
1710 +                      ADIO_Offset offset, ADIO_Request *request, int
1711 +                      *error_code);
1712 +void ADIOI_LUSTRE_Flush(ADIO_File fd, int *error_code);
1713 +void ADIOI_LUSTRE_Resize(ADIO_File fd, ADIO_Offset size, int *error_code);
1714 +ADIO_Offset ADIOI_LUSTRE_SeekIndividual(ADIO_File fd, ADIO_Offset offset,
1715 +                       int whence, int *error_code);
1716 +void ADIOI_LUSTRE_SetInfo(ADIO_File fd, MPI_Info users_info, int *error_code);
1717 +#endif
1718 +
1719  #ifdef ROMIO_NTFS
1720  extern struct ADIOI_Fns_struct ADIO_NTFS_operations;
1721  /* prototypes are in adio/ad_ntfs/ad_ntfs.h */
1722 diff -ruN romio-orig/adio/include/mpio_error.h romio/adio/include/mpio_error.h
1723 --- romio-orig/adio/include/mpio_error.h        2005-05-23 19:27:50.000000000 -0400
1724 +++ romio/adio/include/mpio_error.h     2006-09-06 17:10:35.000984078 -0400
1725 @@ -63,6 +63,7 @@
1726  #define MPIR_ERR_FILETYPE 33 
1727  #define MPIR_ERR_NO_NTFS 35
1728  #define MPIR_ERR_NO_TESTFS 36
1729 +#define MPIR_ERR_NO_LUSTRE 37
1730  
1731  /* MPI_ERR_COMM */
1732  #ifndef MPIR_ERR_COMM_NULL
1733 diff -ruN romio-orig/adio/include/romioconf.h.in romio/adio/include/romioconf.h.in
1734 --- romio-orig/adio/include/romioconf.h.in      2006-08-11 09:48:44.000000000 -0400
1735 +++ romio/adio/include/romioconf.h.in   2006-09-06 17:43:08.000599274 -0400
1736 @@ -276,6 +276,9 @@
1737  /* Define for ROMIO with PVFS2 */
1738  #undef ROMIO_PVFS2
1739  
1740 +/* Define for ROMIO with LUSTRE */
1741 +#undef ROMIO_LUSTRE
1742 +
1743  /* Define if int64_t must be defined for PVFS */
1744  #undef ROMIO_PVFS_NEEDS_INT64_DEFINITION
1745  
1746 diff -ruN romio-orig/configure romio/configure
1747 --- romio-orig/configure        2006-08-11 09:48:45.000000000 -0400
1748 +++ romio/configure     2006-09-06 17:20:57.000555513 -0400
1749 @@ -1400,7 +1400,7 @@
1750  #
1751  have_aio=no
1752  #
1753 -known_filesystems="nfs ufs pfs pvfs pvfs2 testfs xfs panfs gridftp"
1754 +known_filesystems="nfs ufs pfs pvfs pvfs2 testfs xfs panfs gridftp lustre"
1755  known_mpi_impls="mpich2_mpi mpich_mpi sgi_mpi hp_mpi cray_mpi lam_mpi"
1756  #
1757  # Defaults
1758 @@ -7490,6 +7490,14 @@
1759  
1760  fi
1761  
1762 +if test -n "$file_system_lustre"; then
1763 +
1764 +cat >>confdefs.h <<\_ACEOF
1765 +#define ROMIO_LUSTRE 1
1766 +_ACEOF
1767 +
1768 +fi
1769 +
1770  #
1771  # Check for presence and characteristics of async. I/O calls if
1772  # not disabled.
1773 @@ -11977,7 +11985,7 @@
1774  # are active will be called by the top level ROMIO make
1775            ac_config_commands="$ac_config_commands default-1"
1776  
1777 -                                                                                                                                                                                                                                                                                                                                          ac_config_files="$ac_config_files Makefile localdefs mpi-io/Makefile mpi2-other/info/Makefile mpi2-other/array/Makefile adio/common/Makefile test/Makefile test/misc.c test/large_file.c test/runtests util/romioinstall include/mpio.h include/mpiof.h adio/ad_nfs/Makefile adio/ad_ufs/Makefile adio/ad_panfs/Makefile adio/ad_xfs/Makefile adio/ad_sfs/Makefile adio/ad_pfs/Makefile adio/ad_testfs/Makefile adio/ad_pvfs/Makefile adio/ad_pvfs2/Makefile adio/ad_gridftp/Makefile mpi-io/fortran/Makefile mpi2-other/info/fortran/Makefile mpi2-other/array/fortran/Makefile test/fmisc.f test/fcoll_test.f test/pfcoll_test.f test/fperf.f mpi-io/glue/mpich2/Makefile mpi-io/glue/mpich1/Makefile mpi-io/glue/default/Makefile"
1778 +                                                                                                                                                                                                                                                                                                                                          ac_config_files="$ac_config_files Makefile localdefs mpi-io/Makefile mpi2-other/info/Makefile mpi2-other/array/Makefile adio/common/Makefile test/Makefile test/misc.c test/large_file.c test/runtests util/romioinstall include/mpio.h include/mpiof.h adio/ad_nfs/Makefile adio/ad_ufs/Makefile adio/ad_panfs/Makefile adio/ad_xfs/Makefile adio/ad_sfs/Makefile adio/ad_pfs/Makefile adio/ad_testfs/Makefile adio/ad_pvfs/Makefile adio/ad_pvfs2/Makefile adio/ad_gridftp/Makefile adio/ad_lustre/Makefile mpi-io/fortran/Makefile mpi2-other/info/fortran/Makefile mpi2-other/array/fortran/Makefile test/fmisc.f test/fcoll_test.f test/pfcoll_test.f test/fperf.f mpi-io/glue/mpich2/Makefile mpi-io/glue/mpich1/Makefile mpi-io/glue/default/Makefile"
1779  cat >confcache <<\_ACEOF
1780  # This file is a shell script that caches the results of configure
1781  # tests run on this system so they can be shared between configure
1782 @@ -12535,6 +12543,7 @@
1783    "adio/ad_pvfs/Makefile" ) CONFIG_FILES="$CONFIG_FILES adio/ad_pvfs/Makefile" ;;
1784    "adio/ad_pvfs2/Makefile" ) CONFIG_FILES="$CONFIG_FILES adio/ad_pvfs2/Makefile" ;;
1785    "adio/ad_gridftp/Makefile" ) CONFIG_FILES="$CONFIG_FILES adio/ad_gridftp/Makefile" ;;
1786 +  "adio/ad_lustre/Makefile" ) CONFIG_FILES="$CONFIG_FILES adio/ad_lustre/Makefile" ;;
1787    "mpi-io/fortran/Makefile" ) CONFIG_FILES="$CONFIG_FILES mpi-io/fortran/Makefile" ;;
1788    "mpi2-other/info/fortran/Makefile" ) CONFIG_FILES="$CONFIG_FILES mpi2-other/info/fortran/Makefile" ;;
1789    "mpi2-other/array/fortran/Makefile" ) CONFIG_FILES="$CONFIG_FILES mpi2-other/array/fortran/Makefile" ;;
1790 diff -ruN romio-orig/configure.in romio/configure.in
1791 --- romio-orig/configure.in     2006-07-24 17:55:57.000000000 -0400
1792 +++ romio/configure.in  2006-09-06 17:16:13.000525117 -0400
1793 @@ -93,7 +93,7 @@
1794  #
1795  have_aio=no
1796  #
1797 -known_filesystems="nfs ufs pfs pvfs pvfs2 testfs xfs panfs gridftp"
1798 +known_filesystems="nfs ufs pfs pvfs pvfs2 testfs xfs panfs gridftp lustre"
1799  known_mpi_impls="mpich2_mpi mpich_mpi sgi_mpi hp_mpi cray_mpi lam_mpi"
1800  #
1801  # Defaults
1802 @@ -1062,6 +1062,9 @@
1803  if test -n "$file_system_testfs"; then
1804      AC_DEFINE(ROMIO_TESTFS,1,[Define for ROMIO with TESTFS])
1805  fi
1806 +if test -n "$file_system_lustre"; then
1807 +    AC_DEFINE(ROMIO_LUSTRE,1,[Define for ROMIO with LUSTRE])
1808 +fi
1809  
1810  if test -n "$file_system_xfs"; then
1811      AC_DEFINE(ROMIO_XFS,1,[Define for ROMIO with XFS])
1812 @@ -2024,6 +2027,7 @@
1813                    adio/ad_testfs/Makefile adio/ad_pvfs/Makefile \
1814                    adio/ad_pvfs2/Makefile \
1815                    adio/ad_gridftp/Makefile \
1816 +                  adio/ad_lustre/Makefile \
1817                     mpi-io/fortran/Makefile mpi2-other/info/fortran/Makefile \
1818                     mpi2-other/array/fortran/Makefile test/fmisc.f \
1819                     test/fcoll_test.f test/pfcoll_test.f test/fperf.f \
1820 diff -ruN romio-orig/Makefile.in romio/Makefile.in
1821 --- romio-orig/Makefile.in      2005-05-24 18:53:11.000000000 -0400
1822 +++ romio/Makefile.in   2006-09-06 17:13:25.000393429 -0400
1823 @@ -14,7 +14,7 @@
1824  MPIO_DIRS   = mpi-io
1825  EXTRA_SRC_DIRS = @EXTRA_SRC_DIRS@
1826  FILE_SYS_DIRS = @FILE_SYS_DIRS@
1827 -ALL_DIRS    = mpi-io mpi-io/fortran mpi2-other/info mpi2-other/info/fortran mpi2-other/array mpi2-other/array/fortran adio/common adio/ad_pfs adio/ad_piofs adio/ad_nfs adio/ad_ufs adio/ad_xfs adio/ad_hfs adio/ad_sfs adio/ad_testfs adio/ad_pvfs adio/ad_pvfs2 adio/ad_panfs adio/ad_gridftp test
1828 +ALL_DIRS    = mpi-io mpi-io/fortran mpi2-other/info mpi2-other/info/fortran mpi2-other/array mpi2-other/array/fortran adio/common adio/ad_pfs adio/ad_piofs adio/ad_nfs adio/ad_ufs adio/ad_xfs adio/ad_hfs adio/ad_sfs adio/ad_testfs adio/ad_pvfs adio/ad_pvfs2 adio/ad_panfs adio/ad_gridftp adio/ad_lustre test
1829  SHELL       = /bin/sh
1830  
1831  @VPATH@