6
**********************************************************************\
7
ELementary I/O (ELIO) disk operations for parallel I/O libraries
8
Authors: Jarek Nieplocha (PNNL) and Jace Mogill (ANL)
12
* This material was prepared as an account of work sponsored by an
13
* agency of the United States Government. Neither the United States
14
* Government nor the United States Department of Energy, nor Battelle,
15
* nor any of their employees, MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
16
* ASSUMES ANY LEGAL LIABILITY OR RESPONSIBILITY FOR THE ACCURACY,
17
* COMPLETENESS, OR USEFULNESS OF ANY INFORMATION, APPARATUS, PRODUCT,
18
* SOFTWARE, OR PROCESS DISCLOSED, OR REPRESENTS THAT ITS USE WOULD NOT
19
* INFRINGE PRIVATELY OWNED RIGHTS.
23
* This software and its documentation were produced with United States
24
* Government support under Contract Number DE-AC06-76RLO-1830 awarded by
25
* the United States Department of Energy. The United States Government
26
* retains a paid-up non-exclusive, irrevocable worldwide license to
27
* reproduce, prepare derivative works, perform publicly and display
28
* publicly by or for the US Government, including the right to
29
* distribute to other US Government contractors.
32
#include <lustre/lustre_user.h> /* for O_LOV_DELAY_CREATE, LL_IOC_LOV_SETSTRIPE */
33
#include <linux/lustre_idl.h> /* for struct lov_mds_md, LOV_MAGIC */
34
#include <sys/ioctl.h> /* for ioctl */
39
#include "../sf/coms.h"
41
#if defined(CRAY) && defined(__crayx1)
45
#if defined(AIX) || defined(DECOSF) || defined(SGITFP) || defined(SGI64) || defined(SGI_N32) || defined(CRAY) || defined(LINUXAIO)
46
/* systems with Asynchronous I/O */
53
/****************** Internal Constants and Parameters **********************/
56
#define NULL_AIO -123456
57
#define FOPEN_MODE 0644
58
#define MAX_ATTEMPTS 10
67
# define WRITE ffwrite
68
# define WRITEA ffwritea
70
# define READA ffreada
71
# define CLOSE ffclose
77
# define WRITEA writea
88
#define ELIO_FSYNC _commit
91
#define ELIO_FSYNC fsync
94
/* structure to emulate control block in Posix AIO */
97
typedef struct { struct ffsw stat; int filedes; }io_status_t;
99
# include <sys/iosw.h>
100
typedef struct { struct iosw stat; int filedes; }io_status_t;
102
io_status_t cb_fout[MAX_AIO_REQ];
103
io_status_t *cb_fout_arr[MAX_AIO_REQ];
108
# define INPROGRESS EINPROG
110
# define INPROGRESS EINPROGRESS
112
struct aiocb cb_fout[MAX_AIO_REQ];
116
struct aiocb *cb_fout_arr[MAX_AIO_REQ];
120
# define INPROGRESS 1
123
static long aio_req[MAX_AIO_REQ]; /* array for AIO requests */
124
static int first_elio_init = 1; /* intialization status */
125
int _elio_Errors_Fatal=0; /* sets mode of handling errors */
128
/****************************** Internal Macros *****************************/
130
# define AIO_LOOKUP(aio_i) {\
132
while(aio_req[aio_i] != NULL_AIO && aio_i < MAX_AIO_REQ) aio_i++;\
135
# define AIO_LOOKUP(aio_i) aio_i = MAX_AIO_REQ
138
#define SYNC_EMULATE(op) *req_id = ELIO_DONE; \
139
if((stat= elio_ ## op (fd, offset, buf, bytes)) != bytes ){ \
140
ELIO_ERROR(stat,0); \
145
#define PARIO_MIN(a,b) (((a) <= (b)) ? (a) : (b))
149
* Offsets bigger than ABSURDLY_LARGE generate a SEEKFAIL.
150
* The maximum no. of extents permitted for a file is MAX_EXTENT.
153
#if defined(_LARGE_FILES) || defined(_LARGEFILE_SOURCE) || defined(_LARGEFILE64_SOURCE) || _FILE_OFFSET_BITS+0 == 64 || SIZEOF_VOIDP == 8
157
#define MAX_EXTENT 127
159
#define ABSURDLY_LARGE 1e14
161
#define ABSURDLY_LARGE (MAX_EXTENT*2147483648.0)
164
/*****************************************************************************/
166
static Off_t elio_max_file_size(Fd_t fd)
168
* Return the maximum size permitted for this PHYSICAL file.
169
* Presently not file dependent.
173
return ABSURDLY_LARGE;
175
return (2047.0*1024.0*1024.0); /* 2 GB - 1 MB */
179
static Fd_t elio_get_next_extent(Fd_t fd)
181
* Return a pointer to the file descriptor that forms
182
* the next extent of this file. If the extension file
183
* does not exist then it is opened. If the open fails
184
* then the usual error condition of elio_open is returned.
187
Fd_t next_fd = (Fd_t) fd->next;
189
/* Eventually need to replace this with user controllable naming
190
* and combine with similar logic in delete routine.
192
char fname[ELIO_FILENAME_MAX];
194
if (fd->extent >= MAX_EXTENT)
196
strcpy(fname, fd->name);
198
if (fd->extent) len -= 4;
199
sprintf(fname+len,"x%3.3d",fd->extent+1);
200
/*printf("Opening extent %d with name '%s'\n",fd->extent+1,fname);*/
201
if ((next_fd = elio_open(fname, fd->type, fd->mode))) {
202
next_fd->extent = fd->extent + 1;
203
fd->next = (struct fd_struct *) next_fd;
209
void elio_errors_fatal(int onoff)
211
_elio_Errors_Fatal = onoff;
216
* - returns number of bytes written or error code (<0) if failed
218
Size_t elio_write(Fd_t fd, Off_t doffset, const void* buf, Size_t bytes)
221
Size_t stat, bytes_to_write = bytes;
224
if (doffset >= ABSURDLY_LARGE)
225
ELIO_ERROR(SEEKFAIL,0);
227
/* Follow the linked list of extents down until we hit the file
228
that contains the offset */
229
if (doffset >= elio_max_file_size(fd)) {
230
Fd_t next_fd = elio_get_next_extent(fd);
231
if (!next_fd) ELIO_ERROR(OPENFAIL,0);
232
doffset -= elio_max_file_size(fd);
233
return elio_write(next_fd, doffset, buf, bytes);
236
/* Figure out if the write continues onto the next extent */
237
offset = (off_t) doffset;
239
if ((doffset+bytes_to_write) >= elio_max_file_size(fd)) {
240
nextbytes = bytes_to_write;
241
bytes_to_write = (Size_t) (elio_max_file_size(fd)-doffset);
242
nextbytes -= bytes_to_write;
244
/*printf("TRYING TO WRITE AT doffset=%f offset=%lu bw=%lu nb=%lu\n", doffset, offset,
245
bytes_to_write, nextbytes);*/
247
/* Write to this extent */
250
int pablo_code = PABLO_elio_write;
251
PABLO_start( pablo_code );
254
if(offset != SEEK(fd->fd,offset,SEEK_SET)) ELIO_ERROR(SEEKFAIL,0);
256
while (bytes_to_write) {
257
stat = WRITE(fd->fd, buf, bytes_to_write);
258
if ((stat == -1) && ((errno == EINTR) || (errno == EAGAIN))) {
259
; /* interrupted write should be restarted */
260
} else if (stat > 0) {
261
bytes_to_write -= stat;
262
buf = stat + (char*)buf; /*advance pointer by # bytes written*/
264
ELIO_ERROR(WRITFAIL, stat);
268
/* Only get here if all has gone OK */
271
PABLO_end(pablo_code);
274
/* Write to next extent(s) ... relies on incrementing of buf */
276
Fd_t next_fd = elio_get_next_extent(fd);
277
if (!next_fd) ELIO_ERROR(OPENFAIL,0);
278
stat = elio_write(next_fd, (Off_t) 0, buf, nextbytes);
279
if (stat != nextbytes)
280
ELIO_ERROR(WRITFAIL, stat);
286
int elio_set_cb(Fd_t fd, Off_t doffset, int reqn, void *buf, Size_t bytes)
289
off_t offset = (off_t) doffset;
291
if(offset != SEEK(fd->fd, offset, SEEK_SET))return (SEEKFAIL);
292
cb_fout_arr[reqn] = cb_fout+reqn;
293
cb_fout[reqn].filedes = fd->fd;
295
cb_fout[reqn].aio_offset = offset;
296
cb_fout_arr[reqn] = cb_fout+reqn;
297
cb_fout[reqn].aio_buf = buf;
298
cb_fout[reqn].aio_nbytes = bytes;
300
cb_fout[reqn].aio_whence = SEEK_SET;
302
cb_fout[reqn].aio_sigevent.sigev_notify = SIGEV_NONE;
303
cb_fout[reqn].aio_fildes = fd->fd;
311
/*\ Asynchronous Write: returns 0 if succeded or err code if failed
313
int elio_awrite(Fd_t fd, Off_t doffset, const void* buf, Size_t bytes, io_request_t * req_id)
321
if (doffset >= ABSURDLY_LARGE)
322
ELIO_ERROR(SEEKFAIL,0);
324
/* Follow the linked list of extents down until we hit the file
325
that contains the offset */
326
if (doffset >= elio_max_file_size(fd)) {
327
Fd_t next_fd = elio_get_next_extent(fd);
328
if (!next_fd) ELIO_ERROR(OPENFAIL,0);
329
doffset -= elio_max_file_size(fd);
330
return elio_awrite(next_fd, doffset, buf, bytes, req_id);
333
/* Figure out if the write continues onto the next extent
334
* ... if so then force the entire request to be done synchronously
335
* so that we don't have to manage multiple async requests */
337
if ((doffset+((Off_t) bytes)) >= elio_max_file_size(fd)) {
339
if (elio_write(fd, doffset, buf, bytes) != bytes)
345
offset = (off_t) doffset;
348
int pablo_code = PABLO_elio_awrite;
349
PABLO_start( pablo_code );
357
/* blocking io when request table is full */
358
if(aio_i >= MAX_AIO_REQ){
359
# if defined(DEBUG) && defined(ASYNC)
360
fprintf(stderr, "elio_awrite: Warning- asynch overflow\n");
365
*req_id = (io_request_t) aio_i;
366
if((rc=elio_set_cb(fd, offset, aio_i, (void*) buf, bytes)))
370
rc = WRITEA(fd->fd, (char*)buf, bytes, &cb_fout[aio_i].stat, DEFARG);
371
stat = (rc < 0)? -1 : 0;
373
# if !defined(AIX52) && !defined(_AIO_AIX_SOURCE)
374
stat = aio_write(fd->fd, cb_fout + aio_i);
377
stat = aio_write(cb_fout+aio_i);
379
aio_req[aio_i] = *req_id;
383
/* call blocking write when AIO not available */
387
if(stat ==-1) ELIO_ERROR(AWRITFAIL, 0);
390
PABLO_end(pablo_code);
397
/*\ Truncate the file at the specified length.
399
int elio_truncate(Fd_t fd, Off_t dlength)
401
off_t length = (off_t) dlength;
403
# define ftruncate _chsize
407
int pablo_code = PABLO_elio_truncate;
408
PABLO_start( pablo_code );
410
if(dlength >= elio_max_file_size(fd)){
411
Fd_t next_fd = elio_get_next_extent(fd);
412
dlength -= elio_max_file_size(fd);
414
printf(stderr," calling ftruncate with length = %f \n", dlength);
416
return elio_truncate(next_fd, dlength);
418
(void) SEEK(fd->fd, 0L, SEEK_SET);
419
if (ftruncate(fd->fd, length))
425
PABLO_end(pablo_code);
430
/*\ Return in length the length of the file
432
int elio_length(Fd_t fd, Off_t *dlength)
437
/* Add up the lengths of any extents */
439
status = elio_length((Fd_t) fd->next, dlength);
440
*dlength += elio_max_file_size(fd);
445
int pablo_code = PABLO_elio_length;
446
PABLO_start( pablo_code );
449
if ((length = SEEK(fd->fd, (off_t) 0, SEEK_END)) != -1)
455
PABLO_end(pablo_code);
458
*dlength = (Off_t) length;
465
* - returns number of bytes read or error code (<0) if failed
467
Size_t elio_read(Fd_t fd, Off_t doffset, void* buf, Size_t bytes)
470
Size_t stat, bytes_to_read = bytes;
474
if (doffset >= ABSURDLY_LARGE)
475
ELIO_ERROR(SEEKFAIL,0);
477
/* Follow the linked list of extents down until we hit the file
478
that contains the offset */
479
if (doffset >= elio_max_file_size(fd)) {
480
Fd_t next_fd = elio_get_next_extent(fd);
481
if (!next_fd) ELIO_ERROR(OPENFAIL,0);
482
doffset -= elio_max_file_size(fd);
483
return elio_read(next_fd, doffset, buf, bytes);
486
/* Figure out if the read continues onto the next extent */
487
offset = (off_t) doffset;
489
if ((doffset+bytes_to_read) >= elio_max_file_size(fd)) {
490
nextbytes = bytes_to_read;
491
bytes_to_read = (Size_t) (elio_max_file_size(fd)-doffset);
492
nextbytes -= bytes_to_read;
496
/* Read from this physical file */
499
int pablo_code = PABLO_elio_read;
500
PABLO_start( pablo_code );
503
if(offset != SEEK(fd->fd,offset,SEEK_SET)) ELIO_ERROR(SEEKFAIL,0);
505
while (bytes_to_read) {
506
stat = READ(fd->fd, buf, bytes_to_read);
508
ELIO_ERROR(EOFFAIL, stat);
509
} else if ((stat == -1) && ((errno == EINTR) || (errno == EAGAIN))) {
510
; /* interrupted read should be restarted */
511
} else if (stat > 0) {
512
bytes_to_read -= stat;
513
buf = stat + (char*)buf; /*advance pointer by # bytes read*/
515
ELIO_ERROR(READFAIL, stat);
520
/* Only get here if all went OK */
523
PABLO_end(pablo_code);
526
/* Read from next extent(s) ... relies on incrementing of buf */
528
Fd_t next_fd = elio_get_next_extent(fd);
529
if (!next_fd) ELIO_ERROR(OPENFAIL,0);
530
stat = elio_read(next_fd, (Off_t) 0, buf, nextbytes);
531
if (stat != nextbytes)
532
ELIO_ERROR(READFAIL, stat);
541
/*\ Asynchronous Read: returns 0 if succeded or -1 if failed
543
int elio_aread(Fd_t fd, Off_t doffset, void* buf, Size_t bytes, io_request_t * req_id)
545
off_t offset = (off_t) doffset;
554
if (doffset >= ABSURDLY_LARGE)
555
ELIO_ERROR(SEEKFAIL,0);
557
/* Follow the linked list of extents down until we hit the file
558
that contains the offset */
559
if (doffset >= elio_max_file_size(fd)) {
560
Fd_t next_fd = elio_get_next_extent(fd);
561
if (!next_fd) ELIO_ERROR(OPENFAIL,0);
562
doffset -= elio_max_file_size(fd);
563
return elio_aread(next_fd, doffset, buf, bytes, req_id);
566
/* Figure out if the read continues onto the next extent
567
* ... if so then force the entire request to be done synchronously
568
* so that we don't have to manage multiple async requests */
570
if ((doffset+((Off_t) bytes)) >= elio_max_file_size(fd)) {
572
if (elio_read(fd, doffset, buf, bytes) != bytes)
578
offset = (off_t) doffset;
581
int pablo_code = PABLO_elio_aread;
582
PABLO_start( pablo_code );
590
/* blocking io when request table is full */
591
if(aio_i >= MAX_AIO_REQ){
593
fprintf(stderr, "elio_read: Warning- asynch overflow\n");
599
*req_id = (io_request_t) aio_i;
600
if((stat=elio_set_cb(fd, offset, aio_i, (void*) buf, bytes)))
601
ELIO_ERROR((int)stat,0);
603
rc = READA(fd->fd, buf, bytes, &cb_fout[aio_i].stat, DEFARG);
604
stat = (rc < 0)? -1 : 0;
606
#if !defined(AIX52) && !defined(_AIO_AIX_SOURCE)
607
stat = aio_read(fd->fd, cb_fout+aio_i);
610
stat = aio_read(cb_fout+aio_i);
612
aio_req[aio_i] = *req_id;
616
/* call blocking write when AIO not available */
621
if(stat ==-1) ELIO_ERROR(AWRITFAIL, 0);
624
PABLO_end(pablo_code);
631
/*\ Wait for asynchronous I/O operation to complete. Invalidate id.
633
int elio_wait(io_request_t *req_id)
638
rc=0; /* just to remove the compiler warning */
640
int pablo_code = PABLO_elio_wait;
641
PABLO_start( pablo_code );
644
if(*req_id != ELIO_DONE ) {
651
struct ffsw dumstat, *prdstat=&(cb_fout[*req_id].stat);
652
fffcntl(cb_fout[*req_id].filedes, FC_RECALL, prdstat, &dumstat);
653
if (FFSTAT(*prdstat) == FFERR) ELIO_ERROR(SUSPFAIL,0);
657
struct iosw *statlist[1];
658
statlist[0] = &(cb_fout[*req_id].stat);
659
recall(cb_fout[*req_id].filedes, 1, statlist);
664
# if !defined(AIX52) && !defined(_AIO_AIX_SOURCE)
665
do { /* I/O can be interrupted on SP through rcvncall ! */
666
rc =(int)aio_suspend(1, cb_fout_arr+(int)*req_id);
667
} while(rc == -1 && errno == EINTR);
671
if((int)aio_suspend((const struct aiocb *const*)(cb_fout_arr+(int)*req_id), 1, NULL) != 0) rc =-1;
673
if(rc ==-1) ELIO_ERROR(SUSPFAIL,0);
676
/* on DEC aio_return is required to clean internal data structures */
677
if(aio_return(cb_fout+(int)*req_id) == -1) ELIO_ERROR(RETUFAIL,0);
681
while(aio_req[aio_i] != *req_id && aio_i < MAX_AIO_REQ) aio_i++;
682
if(aio_i >= MAX_AIO_REQ) ELIO_ERROR(HANDFAIL, aio_i);
684
aio_req[aio_i] = NULL_AIO;
689
PABLO_end(pablo_code);
697
/*\ Check if asynchronous I/O operation completed. If yes, invalidate id.
699
int elio_probe(io_request_t *req_id, int* status)
705
int pablo_code = PABLO_elio_probe;
706
PABLO_start( pablo_code );
709
if(*req_id == ELIO_DONE){
718
struct ffsw dumstat, *prdstat=&(cb_fout[*req_id].stat);
719
fffcntl(cb_fout[*req_id].filedes, FC_ASPOLL, prdstat, &dumstat);
720
errval = (FFSTAT(*prdstat) == 0) ? INPROGRESS: 0;
724
errval = ( IO_DONE(cb_fout[*req_id].stat) == 0)? INPROGRESS: 0;
729
errval = aio_error(cb_fout[(int)*req_id].aio_handle);
731
errval = aio_error(cb_fout+(int)*req_id);
736
while(aio_req[aio_i] != *req_id && aio_i < MAX_AIO_REQ) aio_i++;
737
if(aio_i >= MAX_AIO_REQ) ELIO_ERROR(HANDFAIL, aio_i);
741
aio_req[aio_i] = NULL_AIO;
744
*status = ELIO_PENDING;
752
PABLO_end(pablo_code);
759
#if defined(CRAY) && defined(FFIO)
760
static int cray_part_info(char *dirname,long *pparts,long *sparts)
765
if(statfs(dirname, &stats, sizeof(struct statfs), 0) == -1) return -1;
767
temp = stats.f_priparts;
774
if(stats.f_secparts != 0){
776
temp = (stats.f_secparts << count);
791
/*\ Noncollective File Open
793
Fd_t elio_open(const char* fname, int type, int mode)
798
char dirname[ELIO_FILENAME_MAX];
801
Create a file for writing to in lustre with
802
a specified pagesize and stripe.
804
lustre_stripe_count = 32;
808
struct lov_mds_md stripecfg;
810
int lustre_stripe_count;
813
lustre_stripe_count = 32;
817
int pablo_code = PABLO_elio_open;
818
PABLO_start( pablo_code );
821
if(first_elio_init) elio_init();
824
case ELIO_W: ptype = O_CREAT | O_TRUNC | O_WRONLY;
826
case ELIO_R: ptype = O_RDONLY;
828
case ELIO_RW: ptype = O_CREAT | O_RDWR;
831
ELIO_ERROR_NULL(MODEFAIL, type);
834
#if defined(WIN32) || defined(CYGNUS)
838
if((fd = (Fd_t ) malloc(sizeof(fd_struct)) ) == NULL)
839
ELIO_ERROR_NULL(ALOCFAIL, 0);
841
if( (rc = elio_dirname(fname, dirname, ELIO_FILENAME_MAX)) != ELIO_OK) {
843
ELIO_ERROR_NULL(rc, 0);
846
if( (rc = elio_stat(dirname, &statinfo)) != ELIO_OK) {
848
ELIO_ERROR_NULL(rc, 0);
851
fd->fs = statinfo.fs;
858
lustre_file = (strncmp(fname,"/dtemp",6) == 0) && (access(fname, F_OK) != 0) && (ME() == 0);
860
ptype = ptype | O_LOV_DELAY_CREATE ;
864
#if defined(CRAY) && defined(FFIO)
867
long pparts, sparts, cbits, cblocks;
868
extern long _MPP_MY_PE;
869
char *ffio_str="cache:256"; /* intern I/O buffer/cache 256*4096 bytes */
870
/* JN: we do not want read-ahead write-behind*/
872
if(cray_part_info(dirname,&pparts,&sparts) != ELIO_OK){
874
ELIO_ERROR_NULL(STATFAIL, 0);
877
ptype |= ( O_BIG | O_PLACE | O_RAW );
878
cbits = (sparts != 0) ? 1 : 0;
882
/* stripe is set so we only select secondary partitions with cbits */
883
if(mode == ELIO_SHARED){
884
cbits = ~((~0L)<<PARIO_MIN(32,sparts)); /* use all secondary partitions */
887
cbits = 1 << (_MPP_MY_PE%sparts); /* round robin over s part */
890
cbits <<= pparts; /* move us out of the primary partitions */
895
/* printf ("parts=%d cbits = %X\n",sparts,cbits);*/
897
if(mode == ELIO_SHARED)
898
fd->fd = OPEN(fname, ptype, FOPEN_MODE, cbits, cblocks, &ffstat, NULL);
900
fd->fd = OPEN(fname, ptype, FOPEN_MODE, 0L , 0 , &ffstat, ffio_str);
904
fd->fd = OPEN(fname, ptype, FOPEN_MODE );
907
if( (int)fd->fd == -1) {
909
ELIO_ERROR_NULL(OPENFAIL, 0);
912
fd->name = strdup(fname);
916
stripecfg.lmm_magic = LOV_MAGIC;
917
stripecfg.lmm_pattern = 0; /* Only available option for now. */
918
stripecfg.lmm_stripe_size = pagesize; /* Stripe size in bytes. */
919
stripecfg.lmm_stripe_count = lustre_stripe_count;
920
if (ioctl((int)fd->fd, LL_IOC_LOV_SETSTRIPE, &stripecfg) < 0) {
922
"fp_create_out_filefp: Error: unable to stripe %s file.\n"
924
fname,strerror(errno));
927
ELIO_ERROR_NULL(OPENFAIL, 0);
929
} /* end if (luster_file) (is in /dtemp) */
933
PABLO_end(pablo_code);
941
int elio_close(Fd_t fd)
943
int status = ELIO_OK;
945
pablo_code = PABLO_elio_close;
946
PABLO_start( pablo_code );
950
status = elio_close((Fd_t) fd->next);
952
/*printf("Closing extent %d name %s\n", fd->extent, fd->name);*/
953
if(CLOSE(fd->fd)==-1 || (status != ELIO_OK))
954
ELIO_ERROR(CLOSFAIL, 0);
960
PABLO_end(pablo_code);
969
int elio_fsync(Fd_t fd)
971
int status = ELIO_OK;
975
status = elio_fsync((Fd_t) fd->next);
977
/* printf("syncing extent %d name %s\n", fd->extent, fd->name); */
978
/* if(ELIO_FSYNC(fd->fd)==-1 || (status != ELIO_OK)) */
980
#if !defined(__INTERIX)
982
status = fsync((Fd_t) fd->next);
988
if(ELIO_FSYNC(fd->fd)==-1 )
989
ELIO_ERROR(FSYNCFAIL, 0);
998
int elio_delete(const char* filename)
1002
if (access(filename, F_OK) != 0) /* Succeed if the file does not exist */
1006
int pablo_code = PABLO_elio_delete;
1007
PABLO_start( pablo_code );
1010
rc = unlink(filename);
1012
/* Remeber the first rc ... now delete possible extents until
1017
for (extent=1; extent<MAX_EXTENT; extent++) {
1018
char fname[ELIO_FILENAME_MAX];
1019
sprintf(fname,"%sx%3.3d",filename,extent);
1020
/*printf("Deleting extent %d with name '%s'\n",extent,fname);*/
1021
if (unlink(fname)) break;
1025
if(rc ==-1) ELIO_ERROR(DELFAIL,0);
1028
PABLO_end(pablo_code);
1037
void elio_init(void)
1039
if(first_elio_init) {
1042
for(i=0; i < MAX_AIO_REQ; i++)
1043
aio_req[i] = NULL_AIO;
1045
first_elio_init = 0;
1050
/*\ Return Error String Associated with Given Error Code
1052
void elio_errmsg(int code, char *msg)
1055
(void) strcpy(msg, ">OK");
1058
else if(code == ELIO_PENDING_ERR) code = elio_pending_error;
1060
if(code<OFFSET || code >OFFSET+ERRLEN) *msg=(char)0;
1061
else (void) strcpy(msg, errtable[-OFFSET + code]);
1065
int elio_pending_error=UNKNFAIL;
1067
char *errtable[ERRLEN] ={
1070
">Asynchronous Write Failed",
1072
">Asynchronous Read Failed",
1074
">I/O Request Handle not in Table",
1075
">Incorrect File Mode",
1076
">Unable to Determine Directory",
1077
">Stat For Specified File or Directory Failed",
1079
">Unable To Allocate Internal Data Structure",
1080
">Unsupported Feature",
1083
">Operation Interrupted Too Many Times",
1084
">AIO Return Failed",
1085
">Name String too Long",
1086
">Unable to Determine Filesystem Type",
1087
">Numeric Conversion Error",
1088
">Incorrect Filesystem/Device Type",
1090
">Unable to Truncate",