Exemplo n.º 1
0
/*\ Delete File
\*/
int elio_delete(const char* filename)
{
    int rc;

    if (access(filename, F_OK) != 0) /* Succeed if the file does not exist */
      return ELIO_OK;

#ifdef PABLO
    int pablo_code = PABLO_elio_delete;
    PABLO_start( pablo_code );
#endif

    rc = unlink(filename);

    /* Remeber the first rc ... now delete possible extents until
       one fails */

    {
      int extent;
      for (extent=1; extent<MAX_EXTENT; extent++) {
    char fname[ELIO_FILENAME_MAX];
    sprintf(fname,"%sx%3.3d",filename,extent);
    /*printf("Deleting extent %d with name '%s'\n",extent,fname);*/
    if (unlink(fname)) break;
      }
    }
    
    if(rc ==-1) ELIO_ERROR(DELFAIL,0);

#ifdef PABLO
    PABLO_end(pablo_code);
#endif
    return(ELIO_OK);
}
Exemplo n.º 2
0
/*\ Close File
\*/
int elio_fsync(Fd_t fd)
{
    int status = ELIO_OK;

#ifdef ELIO_FSYNC
    if (fd->next)
      status = elio_fsync((Fd_t) fd->next);

    printf("syncing extent %d name %s\n", fd->extent, fd->name);
    /*   if(ELIO_FSYNC(fd->fd)==-1 || (status != ELIO_OK)) */
#ifndef WIN32
#if !defined(__INTERIX) 
#ifdef CATAMOUNT
      status = fsync((Fd_t) fd->next);
#else
    sync();
#endif
#endif
#endif
    if(ELIO_FSYNC(fd->fd)==-1 )
      ELIO_ERROR(FSYNCFAIL, 0);
#endif

    return ELIO_OK;
}
Exemplo n.º 3
0
/*\ Check if asynchronous I/O operation completed. If yes, invalidate id.
\*/
int elio_probe(io_request_t *req_id, int* status)
{
  int    errval=-1;
  int    aio_i = 0;
     
#ifdef PABLO
  int pablo_code = PABLO_elio_probe;
  PABLO_start( pablo_code );
#endif

  if(*req_id == ELIO_DONE){
      *status = ELIO_DONE;
  } else {
      
#ifdef AIO
#    if defined(CRAY)

#     if defined(FFIO)
      {
         struct ffsw dumstat, *prdstat=&(cb_fout[*req_id].stat);
         fffcntl(cb_fout[*req_id].filedes, FC_ASPOLL, prdstat, &dumstat);
         errval = (FFSTAT(*prdstat) == 0) ? INPROGRESS: 0;
      }
#     else

         errval = ( IO_DONE(cb_fout[*req_id].stat) == 0)? INPROGRESS: 0;

#     endif

#   elif defined(AIX)
      errval = aio_error(cb_fout[(int)*req_id].aio_handle);
#   else
      errval = aio_error(cb_fout+(int)*req_id);
#   endif
#endif
      switch (errval) {
      case 0: 
          while(aio_req[aio_i] != *req_id && aio_i < MAX_AIO_REQ) aio_i++;
          if(aio_i >= MAX_AIO_REQ) ELIO_ERROR(HANDFAIL, aio_i);

      *req_id = ELIO_DONE; 
      *status = ELIO_DONE;
      aio_req[aio_i] = NULL_AIO;
      break;
      case INPROGRESS:
      *status = ELIO_PENDING; 
      break;
      default:
          return PROBFAIL;
      }
  }

#ifdef PABLO
  PABLO_end(pablo_code);
#endif

  return ELIO_OK;
}
Exemplo n.º 4
0
/**
 * determines directory path for a given file
 */
int elio_dirname(const char *fname, char *dirname, int len)
{
    size_t flen = strlen(fname);
    
    if(len<=((int)flen)) 
    ELIO_ERROR(LONGFAIL,flen);
    
#ifdef WIN32
    while(fname[flen] != '/' && fname[flen] != '\\' && flen >0 ) flen--;
#else
    while(fname[flen] != '/' && flen >0 ) flen--;
#endif

    if(flen==0)strcpy(dirname,".");
    else {strncpy(dirname, fname, flen); dirname[flen]=(char)0;}
    
    return(ELIO_OK);
}
Exemplo n.º 5
0
/*\ Close File
\*/
int elio_close(Fd_t fd)
{
    int status = ELIO_OK;
#ifdef PABLO
    pablo_code = PABLO_elio_close;
    PABLO_start( pablo_code );
#endif

    if (fd->next)
      status = elio_close((Fd_t) fd->next);

    /*printf("Closing extent %d name %s\n", fd->extent, fd->name);*/
    if(CLOSE(fd->fd)==-1 || (status != ELIO_OK)) 
      ELIO_ERROR(CLOSFAIL, 0);

    free(fd->name);
    free(fd);

#ifdef PABLO
    PABLO_end(pablo_code);
#endif
    return ELIO_OK;
}
Exemplo n.º 6
0
/*\ Wait for asynchronous I/O operation to complete. Invalidate id.
\*/
int elio_wait(io_request_t *req_id)
{
  int  aio_i=0;
  int  rc;

  rc=0; /* just to remove the compiler warning */
#ifdef PABLO
  int pablo_code = PABLO_elio_wait;
  PABLO_start( pablo_code );
#endif

  if(*req_id != ELIO_DONE ) { 

#    ifdef AIO
#      if defined(CRAY)

#        if defined(FFIO)
         {
            struct ffsw dumstat, *prdstat=&(cb_fout[*req_id].stat);
            fffcntl(cb_fout[*req_id].filedes, FC_RECALL, prdstat, &dumstat);
            if (FFSTAT(*prdstat) == FFERR) ELIO_ERROR(SUSPFAIL,0);
         }
#        else
         {
            struct iosw *statlist[1];
            statlist[0] = &(cb_fout[*req_id].stat);
            recall(cb_fout[*req_id].filedes, 1, statlist); 
         }
#        endif

#      elif defined(AIX) 
#         if    !defined(AIX52) && !defined(_AIO_AIX_SOURCE)
              do {    /* I/O can be interrupted on SP through rcvncall ! */
                   rc =(int)aio_suspend(1, cb_fout_arr+(int)*req_id);
              } while(rc == -1 && errno == EINTR); 
#         endif

#  else
      if((int)aio_suspend((const struct aiocb *const*)(cb_fout_arr+(int)*req_id), 1, NULL) != 0) rc =-1;
#  endif
      if(rc ==-1) ELIO_ERROR(SUSPFAIL,0);

#  if defined(DECOSF)
      /* on DEC aio_return is required to clean internal data structures */
      if(aio_return(cb_fout+(int)*req_id) == -1) ELIO_ERROR(RETUFAIL,0);
#  endif
#endif

      while(aio_req[aio_i] != *req_id && aio_i < MAX_AIO_REQ) aio_i++;
      if(aio_i >= MAX_AIO_REQ) ELIO_ERROR(HANDFAIL, aio_i);

      aio_req[aio_i] = NULL_AIO;
      *req_id = ELIO_DONE;
   }

#ifdef PABLO
   PABLO_end(pablo_code);
#endif

   return ELIO_OK;
}
Exemplo n.º 7
0
/*\ Asynchronous Read: returns 0 if succeded or -1 if failed
\*/
int elio_aread(Fd_t fd, Off_t doffset, void* buf, Size_t bytes, io_request_t * req_id)
{
  off_t offset = (off_t) doffset;
  Size_t stat;
#ifdef AIO
  int    aio_i;
#endif
#ifdef CRAY
  int rc;
#endif

  if (doffset >= ABSURDLY_LARGE) 
    ELIO_ERROR(SEEKFAIL,0);

  /* Follow the linked list of extents down until we hit the file
     that contains the offset */
  if (doffset >= elio_max_file_size(fd)) {
    Fd_t next_fd = elio_get_next_extent(fd);
    if (!next_fd) ELIO_ERROR(OPENFAIL,0);
    doffset -= elio_max_file_size(fd);
    return elio_aread(next_fd, doffset, buf, bytes, req_id);
  }

  /* Figure out if the read continues onto the next extent 
   * ... if so then force the entire request to be done synchronously
   * so that we don't have to manage multiple async requests */

  if ((doffset+((Off_t) bytes)) >= elio_max_file_size(fd)) {
    *req_id = ELIO_DONE;
    if (elio_read(fd, doffset, buf, bytes) != bytes)
      return -1;
    else
      return 0;
  }

  offset = (off_t) doffset;

#ifdef PABLO
  int pablo_code = PABLO_elio_aread;
  PABLO_start( pablo_code );
#endif

  *req_id = ELIO_DONE;

#ifdef AIO
    AIO_LOOKUP(aio_i);

    /* blocking io when request table is full */
    if(aio_i >= MAX_AIO_REQ){
#       if defined(DEBUG)
           fprintf(stderr, "elio_read: Warning- asynch overflow\n");
#       endif
        SYNC_EMULATE(read);

    } else {

       *req_id = (io_request_t) aio_i;
        if((stat=elio_set_cb(fd, offset, aio_i, (void*) buf, bytes)))
                                                 ELIO_ERROR((int)stat,0);
#       if defined(CRAY)
          rc = READA(fd->fd, buf, bytes, &cb_fout[aio_i].stat, DEFARG);
          stat = (rc < 0)? -1 : 0;
#       elif defined(AIX)
#if    !defined(AIX52) && !defined(_AIO_AIX_SOURCE)
          stat = aio_read(fd->fd, cb_fout+aio_i);
#endif
#       else
          stat = aio_read(cb_fout+aio_i);
#       endif
        aio_req[aio_i] = *req_id;
    }
#else

    /* call blocking write when AIO not available */
    SYNC_EMULATE(read);

#endif

    if(stat ==-1) ELIO_ERROR(AWRITFAIL, 0);

#ifdef PABLO
    PABLO_end(pablo_code);
#endif

    return((int)stat);
}
Exemplo n.º 8
0
/*\ Blocking Read 
 *      - returns number of bytes read or error code (<0) if failed
\*/
Size_t elio_read(Fd_t fd, Off_t doffset, void* buf, Size_t bytes)
{
off_t offset;
Size_t stat, bytes_to_read = bytes;
Size_t nextbytes;
int    attempt=0;

 if (doffset >= ABSURDLY_LARGE) 
    ELIO_ERROR(SEEKFAIL,0);

  /* Follow the linked list of extents down until we hit the file
     that contains the offset */
  if (doffset >= elio_max_file_size(fd)) {
    Fd_t next_fd = elio_get_next_extent(fd);
    if (!next_fd) ELIO_ERROR(OPENFAIL,0);
    doffset -= elio_max_file_size(fd);
    return elio_read(next_fd, doffset, buf, bytes);
  }

  /* Figure out if the read continues onto the next extent */
  offset = (off_t) doffset;
  nextbytes = 0;
  if ((doffset+bytes_to_read) >= elio_max_file_size(fd)) {
    nextbytes = bytes_to_read;
    bytes_to_read = (Size_t) (elio_max_file_size(fd)-doffset);
    nextbytes -= bytes_to_read;
  }


  /* Read from this physical file */

#ifdef PABLO
  int pablo_code = PABLO_elio_read;
  PABLO_start( pablo_code );
#endif

  if(offset != SEEK(fd->fd,offset,SEEK_SET)) ELIO_ERROR(SEEKFAIL,0);
  
  while (bytes_to_read) {
    stat = READ(fd->fd, buf, bytes_to_read);
    if(stat==0){
      ELIO_ERROR(EOFFAIL, stat);
    } else if ((stat == -1) && ((errno == EINTR) || (errno == EAGAIN))) {
      ; /* interrupted read should be restarted */
    } else if (stat > 0) {
      bytes_to_read -= stat;
      buf = stat + (char*)buf; /*advance pointer by # bytes read*/
    } else {
      ELIO_ERROR(READFAIL, stat);
    }
    attempt++;
  }
  
  /* Only get here if all went OK */
  
#ifdef PABLO
  PABLO_end(pablo_code);
#endif
  
  /* Read from next extent(s) ... relies on incrementing of buf */
  if (nextbytes) {
    Fd_t next_fd = elio_get_next_extent(fd);
    if (!next_fd) ELIO_ERROR(OPENFAIL,0);
    stat = elio_read(next_fd, (Off_t) 0, buf, nextbytes);
    if (stat != nextbytes)
      ELIO_ERROR(READFAIL, stat);
  }


  return bytes;
}
Exemplo n.º 9
0
/*\ Blocking Write 
 *    - returns number of bytes written or error code (<0) if failed
\*/
Size_t elio_write(Fd_t fd, Off_t  doffset, const void* buf, Size_t bytes)
{
  off_t offset;
  Size_t stat, bytes_to_write = bytes;
  Size_t nextbytes;

  if (doffset >= ABSURDLY_LARGE) 
    ELIO_ERROR(SEEKFAIL,0);

  /* Follow the linked list of extents down until we hit the file
     that contains the offset */
  if (doffset >= elio_max_file_size(fd)) {
    Fd_t next_fd = elio_get_next_extent(fd);
    if (!next_fd) ELIO_ERROR(OPENFAIL,0);
    doffset -= elio_max_file_size(fd);
    return elio_write(next_fd, doffset, buf, bytes);
  }

  /* Figure out if the write continues onto the next extent */
  offset = (off_t) doffset;
  nextbytes = 0;
  if ((doffset+bytes_to_write) >= elio_max_file_size(fd)) {
    nextbytes = bytes_to_write;
    bytes_to_write = (Size_t) (elio_max_file_size(fd)-doffset);
    nextbytes -= bytes_to_write;
  }
  /*printf("TRYING TO WRITE AT doffset=%f offset=%lu bw=%lu nb=%lu\n", doffset, offset,
    bytes_to_write, nextbytes);*/

  /* Write to this extent */

#ifdef PABLO
  int pablo_code = PABLO_elio_write;
  PABLO_start( pablo_code );
#endif
  
  if(offset != SEEK(fd->fd,offset,SEEK_SET)) ELIO_ERROR(SEEKFAIL,0);
  
  while (bytes_to_write) {
    stat = WRITE(fd->fd, buf, bytes_to_write);
    if ((stat == -1) && ((errno == EINTR) || (errno == EAGAIN))) {
      ; /* interrupted write should be restarted */
    } else if (stat > 0) {
      bytes_to_write -= stat;
      buf = stat + (char*)buf; /*advance pointer by # bytes written*/
    } else {
      ELIO_ERROR(WRITFAIL, stat);
    }
  }

  /* Only get here if all has gone OK */
  
#ifdef PABLO
  PABLO_end(pablo_code);
#endif

  /* Write to next extent(s) ... relies on incrementing of buf */
  if (nextbytes) {
    Fd_t next_fd = elio_get_next_extent(fd);
    if (!next_fd) ELIO_ERROR(OPENFAIL,0);
    stat = elio_write(next_fd, (Off_t) 0, buf, nextbytes);
    if (stat != nextbytes)
      ELIO_ERROR(WRITFAIL, stat);
  }
  
  return bytes;
}
Exemplo n.º 10
0
/**
 * Stat a file (or path) to determine it's filesystem info
 */
int  elio_stat(char *fname, stat_t *statinfo)
{
    struct  stat      ufs_stat;
    int bsize;
    
    struct  STATVFS   ufs_statfs;
    
    PABLO_start(PABLO_elio_stat); 
    
    if(stat(fname, &ufs_stat) != 0)
        ELIO_ERROR(STATFAIL, 1);

#   if defined(PIOFS)
/*        fprintf(stderr,"filesystem %d\n",ufs_stat.st_vfstype);*/
        /* according to /etc/vfs, "9" means piofs */
        if(ufs_stat.st_vfstype == 9) statinfo->fs = ELIO_PIOFS;
        else
#   endif

    statinfo->fs = ELIO_UFS;
    
    /* only regular or directory files are OK */
    if(!S_ISREG(ufs_stat.st_mode) && !S_ISDIR(ufs_stat.st_mode))
        ELIO_ERROR(TYPEFAIL, 1);
    
#   if defined(CRAY)
    if(statfs(fname, &ufs_statfs, sizeof(ufs_statfs), 0) != 0)
#   else
        if(STATVFS(fname, &ufs_statfs) != 0)
#   endif
           ELIO_ERROR(STATFAIL,1);
    
#   if defined(WIN32)

       get_avail_space(ufs_statfs.st_dev, &(statinfo->avail), &bsize);
      
#   else
      /* get number of available blocks */
#     if defined(CRAY) || defined(NEC)
          /* f_bfree == f_bavail -- naming changes */

#        ifdef CRAY
          if(ufs_statfs.f_secnfree != 0) /* check for secondary partition */
             statinfo->avail = (avail_t) ufs_statfs.f_secnfree;
          else
#        endif
             statinfo->avail = (avail_t) ufs_statfs.f_bfree;
#     else
          statinfo->avail = (avail_t) ufs_statfs.f_bavail;
#     endif

#     ifdef NO_F_FRSIZE
         /*       on some older systems it was f_bsize */
         bsize = (int) ufs_statfs.f_bsize; 
#     else
         /* get block size, fail if bszie is still 0 */
         bsize = (int) ufs_statfs.f_frsize;
         if(bsize==0)bsize =(int) ufs_statfs.f_bsize; 
         if(bsize==0) ELIO_ERROR(STATFAIL, 1);

         if(DEBUG_)
           printf("stat: f_frsize=%d f_bsize=%d bsize=%d free blocks=%ld\n",
            (int) ufs_statfs.f_frsize,(int) ufs_statfs.f_bsize, bsize,
            statinfo->avail );
#     endif
#   endif
    
    /* translate number of available blocks into kilobytes */
    switch (bsize) {
    case 512:  statinfo->avail /=2; break;
    case 1024: break;
    case 2048: statinfo->avail *=2; break;
    case 4096: statinfo->avail *=4; break;
    case 8192: statinfo->avail *=8; break;
    case 16384: statinfo->avail *=16; break;
    case 32768: statinfo->avail *=32; break;
    default:   { 
        double avail;
        double factor = ((double)bsize)/1024.0;
        avail = factor * (double)statinfo->avail;
        statinfo->avail = (avail_t) avail;
               }
    }
    
    PABLO_end(PABLO_elio_stat);
    return(ELIO_OK);
}