ncdf4a13/libsrc/posixio.c File Reference

#include <config.h>
#include <assert.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include "ncio.h"
#include "fbits.h"
#include "rnd.h"

Include dependency graph for posixio.c:

Go to the source code of this file.

Classes

struct  ncio_px
struct  ncio_spx

Defines

#define ENOERR   0
#define SEEK_SET   0
#define SEEK_CUR   1
#define SEEK_END   2
#define MIN(mm, nn)   (((mm) < (nn)) ? (mm) : (nn))
#define X_INT_MAX   2147483647
#define POSIXIO_DEFAULT_PAGESIZE   4096
#define NCIO_MINBLOCKSIZE   256
#define NCIO_MAXBLOCKSIZE   268435456
#define NC_DEFAULT_CREAT_MODE   0666

Typedefs

typedef ncio_px ncio_px
typedef ncio_spx ncio_spx

Functions

static size_t pagesize (void)
static size_t blksize (int fd)
static int fgrow (const int fd, const off_t len)
static int fgrow2 (const int fd, const off_t len)
static int px_pgout (ncio *const nciop, off_t const offset, const size_t extent, void *const vp, off_t *posp)
static int px_pgin (ncio *const nciop, off_t const offset, const size_t extent, void *const vp, size_t *nreadp, off_t *posp)
static int px_rel (ncio_px *const pxp, off_t offset, int rflags)
static int ncio_px_rel (ncio *const nciop, off_t offset, int rflags)
static int px_get (ncio *const nciop, ncio_px *const pxp, off_t offset, size_t extent, int rflags, void **const vpp)
static int ncio_px_get (ncio *const nciop, off_t offset, size_t extent, int rflags, void **const vpp)
static int px_double_buffer (ncio *const nciop, off_t to, off_t from, size_t nbytes, int rflags)
static int ncio_px_move (ncio *const nciop, off_t to, off_t from, size_t nbytes, int rflags)
static int ncio_px_sync (ncio *const nciop)
static void ncio_px_free (void *const pvt)
static int ncio_px_init2 (ncio *const nciop, size_t *sizehintp, int isNew)
static void ncio_px_init (ncio *const nciop)
static int ncio_spx_rel (ncio *const nciop, off_t offset, int rflags)
static int ncio_spx_get (ncio *const nciop, off_t offset, size_t extent, int rflags, void **const vpp)
static int ncio_spx_move (ncio *const nciop, off_t to, off_t from, size_t nbytes, int rflags)
static int ncio_spx_sync (ncio *const nciop)
static void ncio_spx_free (void *const pvt)
static int ncio_spx_init2 (ncio *const nciop, const size_t *const sizehintp)
static void ncio_spx_init (ncio *const nciop)
static void ncio_free (ncio *nciop)
static ncioncio_new (const char *path, int ioflags)
int ncio_create (const char *path, int ioflags, size_t initialsz, off_t igeto, size_t igetsz, size_t *sizehintp, ncio **nciopp, void **const igetvpp)
int ncio_open (const char *path, int ioflags, off_t igeto, size_t igetsz, size_t *sizehintp, ncio **nciopp, void **const igetvpp)
int ncio_filesize (ncio *nciop, off_t *filesizep)
int ncio_pad_length (ncio *nciop, off_t length)
int ncio_close (ncio *nciop, int doUnlink)


Define Documentation

#define ENOERR   0
 

Definition at line 12 of file posixio.c.

#define MIN mm,
nn   )     (((mm) < (nn)) ? (mm) : (nn))
 

Definition at line 42 of file posixio.c.

Referenced by fill_NC_var(), getNCvx_char_char(), getNCvx_double_double(), getNCvx_double_float(), getNCvx_double_int(), getNCvx_double_long(), getNCvx_double_schar(), getNCvx_double_short(), getNCvx_double_uchar(), getNCvx_float_double(), getNCvx_float_float(), getNCvx_float_int(), getNCvx_float_long(), getNCvx_float_schar(), getNCvx_float_short(), getNCvx_float_uchar(), getNCvx_int_double(), getNCvx_int_float(), getNCvx_int_int(), getNCvx_int_long(), getNCvx_int_schar(), getNCvx_int_short(), getNCvx_int_uchar(), getNCvx_schar_double(), getNCvx_schar_float(), getNCvx_schar_int(), getNCvx_schar_long(), getNCvx_schar_schar(), getNCvx_schar_short(), getNCvx_schar_uchar(), getNCvx_short_double(), getNCvx_short_float(), getNCvx_short_int(), getNCvx_short_long(), getNCvx_short_schar(), getNCvx_short_short(), getNCvx_short_uchar(), hash_double(), hash_float(), hash_int(), hash_long(), hash_schar(), hash_short(), hash_text(), hash_uchar(), ncio_px_move(), NCxvarcpy(), putNCvx_char_char(), putNCvx_double_double(), putNCvx_double_float(), putNCvx_double_int(), putNCvx_double_long(), putNCvx_double_schar(), putNCvx_double_short(), putNCvx_double_uchar(), putNCvx_float_double(), putNCvx_float_float(), putNCvx_float_int(), putNCvx_float_long(), putNCvx_float_schar(), putNCvx_float_short(), putNCvx_float_uchar(), putNCvx_int_double(), putNCvx_int_float(), putNCvx_int_int(), putNCvx_int_long(), putNCvx_int_schar(), putNCvx_int_short(), putNCvx_int_uchar(), putNCvx_schar_double(), putNCvx_schar_float(), putNCvx_schar_int(), putNCvx_schar_long(), putNCvx_schar_schar(), putNCvx_schar_short(), putNCvx_schar_uchar(), putNCvx_short_double(), putNCvx_short_float(), putNCvx_short_int(), putNCvx_short_long(), putNCvx_short_schar(), putNCvx_short_short(), putNCvx_short_uchar(), v1h_get_NC_attrV(), and v1h_put_NC_attrV().

#define NC_DEFAULT_CREAT_MODE   0666
 

Definition at line 1398 of file posixio.c.

Referenced by ncio_create().

#define NCIO_MAXBLOCKSIZE   268435456
 

Definition at line 1391 of file posixio.c.

Referenced by ncio_create(), and ncio_open().

#define NCIO_MINBLOCKSIZE   256
 

Definition at line 1390 of file posixio.c.

#define POSIXIO_DEFAULT_PAGESIZE   4096
 

Definition at line 62 of file posixio.c.

Referenced by pagesize().

#define SEEK_CUR   1
 

Definition at line 26 of file posixio.c.

Referenced by fgrow(), fgrow2(), px_pgin(), and px_pgout().

#define SEEK_END   2
 

Definition at line 27 of file posixio.c.

#define SEEK_SET   0
 

Definition at line 25 of file posixio.c.

Referenced by fgrow(), fgrow2(), px_pgin(), and px_pgout().

#define X_INT_MAX   2147483647
 

Definition at line 45 of file posixio.c.


Typedef Documentation

typedef struct ncio_px ncio_px
 

typedef struct ncio_spx ncio_spx
 


Function Documentation

static size_t blksize int  fd  )  [static]
 

Definition at line 92 of file posixio.c.

References pagesize().

Referenced by ncio_create(), and ncio_open().

00093 {
00094 #if defined(HAVE_ST_BLKSIZE)
00095         struct stat sb;
00096         if (fstat(fd, &sb) > -1)
00097         {
00098                 if(sb.st_blksize >= 8192)
00099                         return (size_t) sb.st_blksize;
00100                 return 8192;
00101         }
00102         /* else, silent in the face of error */
00103 #endif
00104         return (size_t) 2 * pagesize();
00105 }

static int fgrow const int  fd,
const off_t  len
[static]
 

Definition at line 113 of file posixio.c.

References ENOERR, SEEK_CUR, and SEEK_SET.

Referenced by ncio_create().

00114 {
00115         struct stat sb;
00116         if (fstat(fd, &sb) < 0)
00117                 return errno;
00118         if (len < sb.st_size)
00119                 return ENOERR;
00120         {
00121             const long dumb = 0;
00122             /* we don't use ftruncate() due to problem with FAT32 file systems */
00123             /* cache current position */
00124             const off_t pos = lseek(fd, 0, SEEK_CUR);
00125             if(pos < 0)
00126                 return errno;
00127             if (lseek(fd, len-sizeof(dumb), SEEK_SET) < 0)
00128                 return errno;
00129             if(write(fd, &dumb, sizeof(dumb)) < 0)
00130                 return errno;
00131             if (lseek(fd, pos, SEEK_SET) < 0)
00132                 return errno;
00133         }
00134         return ENOERR;
00135 }

static int fgrow2 const int  fd,
const off_t  len
[static]
 

Definition at line 144 of file posixio.c.

References ENOERR, SEEK_CUR, and SEEK_SET.

Referenced by ncio_pad_length().

00145 {
00146         struct stat sb;
00147         if (fstat(fd, &sb) < 0)
00148                 return errno;
00149         if (len <= sb.st_size)
00150                 return ENOERR;
00151         {
00152             const char dumb = 0;
00153             /* we don't use ftruncate() due to problem with FAT32 file systems */
00154             /* cache current position */
00155             const off_t pos = lseek(fd, 0, SEEK_CUR);
00156             if(pos < 0)
00157                 return errno;
00158             if (lseek(fd, len-1, SEEK_SET) < 0)
00159                 return errno;
00160             if(write(fd, &dumb, sizeof(dumb)) < 0)
00161                 return errno;
00162             if (lseek(fd, pos, SEEK_SET) < 0)
00163                 return errno;
00164         }
00165         return ENOERR;
00166 }

int ncio_close ncio nciop,
int  doUnlink
 

Definition at line 1681 of file posixio.c.

References ENOERR, ncio::fd, ncio_free(), ncio::path, and ncio::sync.

Referenced by nc__create_mp(), nc__open_mp(), nc_abort(), nc_close(), and nc_delete_mp().

01682 {
01683         int status = ENOERR;
01684 
01685         if(nciop == NULL)
01686                 return EINVAL;
01687 
01688         status = nciop->sync(nciop);
01689 
01690         (void) close(nciop->fd);
01691         
01692         if(doUnlink)
01693                 (void) unlink(nciop->path);
01694 
01695         ncio_free(nciop);
01696 
01697         return status;
01698 }

int ncio_create const char *  path,
int  ioflags,
size_t  initialsz,
off_t  igeto,
size_t  igetsz,
size_t *  sizehintp,
ncio **  nciopp,
void **const   igetvpp
 

Definition at line 1417 of file posixio.c.

References blksize(), ENOERR, ncio::fd, fgrow(), fIsSet, fSet, ncio::get, ncio::ioflags, M_RNDUP, NC_DEFAULT_CREAT_MODE, NC_NOCLOBBER, NC_SHARE, NC_WRITE, ncio_free(), NCIO_MAXBLOCKSIZE, ncio_new(), ncio_px_init2(), ncio_spx_init2(), and RGN_WRITE.

Referenced by nc__create_mp().

01421 {
01422         ncio *nciop;
01423         int oflags = (O_RDWR|O_CREAT);
01424         int fd;
01425         int status;
01426 
01427         if(initialsz < (size_t)igeto + igetsz)
01428                 initialsz = (size_t)igeto + igetsz;
01429 
01430         fSet(ioflags, NC_WRITE);
01431 
01432         if(path == NULL || *path == 0)
01433                 return EINVAL;
01434 
01435         nciop = ncio_new(path, ioflags);
01436         if(nciop == NULL)
01437                 return ENOMEM;
01438 
01439         if(fIsSet(ioflags, NC_NOCLOBBER))
01440                 fSet(oflags, O_EXCL);
01441         else
01442                 fSet(oflags, O_TRUNC);
01443 #ifdef O_BINARY
01444         fSet(oflags, O_BINARY);
01445 #endif
01446 #ifdef vms
01447         fd = open(path, oflags, NC_DEFAULT_CREAT_MODE, "ctx=stm");
01448 #else
01449         /* Should we mess with the mode based on NC_SHARE ?? */
01450         fd = open(path, oflags, NC_DEFAULT_CREAT_MODE);
01451 #endif
01452 #if 0
01453         (void) fprintf(stderr, "ncio_create(): path=\"%s\"\n", path);
01454         (void) fprintf(stderr, "ncio_create(): oflags=0x%x\n", oflags);
01455 #endif
01456         if(fd < 0)
01457         {
01458                 status = errno;
01459                 goto unwind_new;
01460         }
01461         *((int *)&nciop->fd) = fd; /* cast away const */
01462 
01463         if(*sizehintp < NCIO_MINBLOCKSIZE || *sizehintp > NCIO_MAXBLOCKSIZE)
01464         {
01465                 /* Use default */
01466                 *sizehintp = blksize(fd);
01467         }
01468         else
01469         {
01470                 *sizehintp = M_RNDUP(*sizehintp);
01471         }
01472 
01473         if(fIsSet(nciop->ioflags, NC_SHARE))
01474                 status = ncio_spx_init2(nciop, sizehintp);
01475         else
01476                 status = ncio_px_init2(nciop, sizehintp, 1);
01477 
01478         if(status != ENOERR)
01479                 goto unwind_open;
01480 
01481         if(initialsz != 0)
01482         {
01483                 status = fgrow(fd, (off_t)initialsz);
01484                 if(status != ENOERR)
01485                         goto unwind_open;
01486         }
01487 
01488         if(igetsz != 0)
01489         {
01490                 status = nciop->get(nciop,
01491                                 igeto, igetsz,
01492                                 RGN_WRITE,
01493                                 igetvpp);
01494                 if(status != ENOERR)
01495                         goto unwind_open;
01496         }
01497 
01498         *nciopp = nciop;
01499         return ENOERR;
01500 
01501 unwind_open:
01502         (void) close(fd);
01503         /* ?? unlink */
01504         /*FALLTHRU*/
01505 unwind_new:
01506         ncio_free(nciop);
01507         return status;
01508 }

int ncio_filesize ncio nciop,
off_t *  filesizep
 

Definition at line 1630 of file posixio.c.

References ENOERR, and ncio::fd.

Referenced by nc_close(), and nc_get_NC().

01631 {
01632     struct stat sb;
01633 
01634     assert(nciop != NULL);
01635     if (fstat(nciop->fd, &sb) < 0)
01636         return errno;
01637     *filesizep = sb.st_size;
01638     return ENOERR;
01639 }

static void ncio_free ncio nciop  )  [static]
 

Definition at line 1333 of file posixio.c.

References ncio::free, and ncio::pvt.

Referenced by ncio_close(), ncio_create(), and ncio_open().

01334 {
01335         if(nciop == NULL)
01336                 return;
01337 
01338         if(nciop->free != NULL)
01339                 nciop->free(nciop->pvt);
01340         
01341         free(nciop);
01342 }

static ncio* ncio_new const char *  path,
int  ioflags
[static]
 

Definition at line 1350 of file posixio.c.

References ncio::fd, fIsSet, fSet, ncio::ioflags, M_RNDUP, NC_SHARE, ncio_px_init(), ncio_spx_init(), ncio::path, and ncio::pvt.

Referenced by ncio_create(), and ncio_open().

01351 {
01352         size_t sz_ncio = M_RNDUP(sizeof(ncio));
01353         size_t sz_path = M_RNDUP(strlen(path) +1);
01354         size_t sz_ncio_pvt;
01355         ncio *nciop;
01356  
01357 #if ALWAYS_NC_SHARE /* DEBUG */
01358         fSet(ioflags, NC_SHARE);
01359 #endif
01360 
01361         if(fIsSet(ioflags, NC_SHARE))
01362                 sz_ncio_pvt = sizeof(ncio_spx);
01363         else
01364                 sz_ncio_pvt = sizeof(ncio_px);
01365 
01366         nciop = (ncio *) malloc(sz_ncio + sz_path + sz_ncio_pvt);
01367         if(nciop == NULL)
01368                 return NULL;
01369         
01370         nciop->ioflags = ioflags;
01371         *((int *)&nciop->fd) = -1; /* cast away const */
01372 
01373         nciop->path = (char *) ((char *)nciop + sz_ncio);
01374         (void) strcpy((char *)nciop->path, path); /* cast away const */
01375 
01376                                 /* cast away const */
01377         *((void **)&nciop->pvt) = (void *)(nciop->path + sz_path);
01378 
01379         if(fIsSet(ioflags, NC_SHARE))
01380                 ncio_spx_init(nciop);
01381         else
01382                 ncio_px_init(nciop);
01383 
01384         return nciop;
01385 }

int ncio_open const char *  path,
int  ioflags,
off_t  igeto,
size_t  igetsz,
size_t *  sizehintp,
ncio **  nciopp,
void **const   igetvpp
 

Definition at line 1555 of file posixio.c.

References blksize(), ENOERR, ncio::fd, fIsSet, fSet, ncio::get, ncio::ioflags, M_RNDUP, NC_SHARE, NC_WRITE, ncio_free(), NCIO_MAXBLOCKSIZE, ncio_new(), ncio_px_init2(), and ncio_spx_init2().

Referenced by nc__open_mp(), and nc_delete_mp().

01559 {
01560         ncio *nciop;
01561         int oflags = fIsSet(ioflags, NC_WRITE) ? O_RDWR : O_RDONLY;
01562         int fd;
01563         int status;
01564 
01565         if(path == NULL || *path == 0)
01566                 return EINVAL;
01567 
01568         nciop = ncio_new(path, ioflags);
01569         if(nciop == NULL)
01570                 return ENOMEM;
01571 
01572 #ifdef O_BINARY
01573         fSet(oflags, O_BINARY);
01574 #endif
01575 #ifdef vms
01576         fd = open(path, oflags, 0, "ctx=stm");
01577 #else
01578         fd = open(path, oflags, 0);
01579 #endif
01580         if(fd < 0)
01581         {
01582                 status = errno;
01583                 goto unwind_new;
01584         }
01585         *((int *)&nciop->fd) = fd; /* cast away const */
01586 
01587         if(*sizehintp < NCIO_MINBLOCKSIZE || *sizehintp > NCIO_MAXBLOCKSIZE)
01588         {
01589                 /* Use default */
01590                 *sizehintp = blksize(fd);
01591         }
01592         else
01593         {
01594                 *sizehintp = M_RNDUP(*sizehintp);
01595         }
01596 
01597         if(fIsSet(nciop->ioflags, NC_SHARE))
01598                 status = ncio_spx_init2(nciop, sizehintp);
01599         else
01600                 status = ncio_px_init2(nciop, sizehintp, 0);
01601 
01602         if(status != ENOERR)
01603                 goto unwind_open;
01604 
01605         if(igetsz != 0)
01606         {
01607                 status = nciop->get(nciop,
01608                                 igeto, igetsz,
01609                                 0,
01610                                 igetvpp);
01611                 if(status != ENOERR)
01612                         goto unwind_open;
01613         }
01614 
01615         *nciopp = nciop;
01616         return ENOERR;
01617 
01618 unwind_open:
01619         (void) close(fd);
01620         /*FALLTHRU*/
01621 unwind_new:
01622         ncio_free(nciop);
01623         return status;
01624 }

int ncio_pad_length ncio nciop,
off_t  length
 

Definition at line 1649 of file posixio.c.

References ENOERR, ncio::fd, fgrow2(), fIsSet, ncio::ioflags, NC_NOERR, NC_WRITE, and ncio::sync.

Referenced by nc_close().

01650 {
01651         int status = ENOERR;
01652 
01653         if(nciop == NULL)
01654                 return EINVAL;
01655 
01656         if(!fIsSet(nciop->ioflags, NC_WRITE))
01657                 return EPERM; /* attempt to write readonly file */
01658 
01659         status = nciop->sync(nciop);
01660         if(status != ENOERR)
01661                 return status;
01662 
01663         status = fgrow2(nciop->fd, length);
01664         if(status != NC_NOERR)
01665                 return status;
01666         return ENOERR;
01667 }

static void ncio_px_free void *const   pvt  )  [static]
 

Definition at line 850 of file posixio.c.

References ncio_px::bf_base, ncio_px::bf_extent, ncio_px::bf_offset, OFF_NONE, and ncio_px::slave.

Referenced by ncio_px_init().

00851 {
00852         ncio_px *const pxp = (ncio_px *)pvt;
00853         if(pxp == NULL)
00854                 return;
00855 
00856         if(pxp->slave != NULL)
00857         {
00858                 if(pxp->slave->bf_base != NULL)
00859                 {
00860                         free(pxp->slave->bf_base);
00861                         pxp->slave->bf_base = NULL;
00862                         pxp->slave->bf_extent = 0;
00863                         pxp->slave->bf_offset = OFF_NONE;
00864                 }
00865                 free(pxp->slave);
00866                 pxp->slave = NULL;
00867         }
00868                 
00869         if(pxp->bf_base != NULL)
00870         {
00871                 free(pxp->bf_base);
00872                 pxp->bf_base = NULL;
00873                 pxp->bf_extent = 0;
00874                 pxp->bf_offset = OFF_NONE;
00875         }
00876 }

static int ncio_px_get ncio *const   nciop,
off_t  offset,
size_t  extent,
int  rflags,
void **const   vpp
[static]
 

Definition at line 612 of file posixio.c.

References ncio_px::bf_base, ncio_px::bf_extent, ncio_px::bf_offset, fIsSet, ncio::ioflags, NC_WRITE, OFF_NONE, ncio::pvt, px_get(), RGN_WRITE, and ncio_px::slave.

Referenced by ncio_px_init().

00616 {
00617         ncio_px *const pxp = (ncio_px *)nciop->pvt;
00618         
00619         if(fIsSet(rflags, RGN_WRITE) && !fIsSet(nciop->ioflags, NC_WRITE))
00620                 return EPERM; /* attempt to write readonly file */
00621 
00622         /* reclaim space used in move */
00623         if(pxp->slave != NULL)
00624         {
00625                 if(pxp->slave->bf_base != NULL)
00626                 {
00627                         free(pxp->slave->bf_base);
00628                         pxp->slave->bf_base = NULL;
00629                         pxp->slave->bf_extent = 0;
00630                         pxp->slave->bf_offset = OFF_NONE;
00631                 }
00632                 free(pxp->slave);
00633                 pxp->slave = NULL;
00634         }
00635         return px_get(nciop, pxp, offset, extent, rflags, vpp);
00636 }

static void ncio_px_init ncio *const   nciop  )  [static]
 

Definition at line 935 of file posixio.c.

References ncio_px::bf_base, ncio_px::bf_extent, ncio_px::bf_offset, ncio_px::bf_refcount, ncio_px::bf_rflags, ncio_px::blksz, ncio::free, ncio::get, ncio::move, ncio_px_free(), ncio_px_get(), ncio_px_move(), ncio_px_rel(), ncio_px_sync(), OFF_NONE, ncio_px::pos, ncio::pvt, ncio::rel, ncio_px::slave, and ncio::sync.

Referenced by ncio_new().

00936 {
00937         ncio_px *const pxp = (ncio_px *)nciop->pvt;
00938 
00939         *((ncio_relfunc **)&nciop->rel) = ncio_px_rel; /* cast away const */
00940         *((ncio_getfunc **)&nciop->get) = ncio_px_get; /* cast away const */
00941         *((ncio_movefunc **)&nciop->move) = ncio_px_move; /* cast away const */
00942         *((ncio_syncfunc **)&nciop->sync) = ncio_px_sync; /* cast away const */
00943         *((ncio_freefunc **)&nciop->free) = ncio_px_free; /* cast away const */
00944 
00945         pxp->blksz = 0;
00946         pxp->pos = -1;
00947         pxp->bf_offset = OFF_NONE;
00948         pxp->bf_extent = 0;
00949         pxp->bf_rflags = 0;
00950         pxp->bf_refcount = 0;
00951         pxp->bf_base = NULL;
00952         pxp->slave = NULL;
00953 
00954 }

static int ncio_px_init2 ncio *const   nciop,
size_t *  sizehintp,
int  isNew
[static]
 

Definition at line 899 of file posixio.c.

References ncio_px::bf_base, ncio_px::bf_cnt, ncio_px::bf_extent, ncio_px::bf_offset, ncio_px::blksz, ENOERR, ncio::fd, ncio_px::pos, and ncio::pvt.

Referenced by ncio_create(), and ncio_open().

00900 {
00901         ncio_px *const pxp = (ncio_px *)nciop->pvt;
00902         const size_t bufsz = 2 * *sizehintp;
00903 
00904         assert(nciop->fd >= 0);
00905 
00906         pxp->blksz = *sizehintp;
00907 
00908         assert(pxp->bf_base == NULL);
00909 
00910         /* this is separate allocation because it may grow */
00911         pxp->bf_base = malloc(bufsz);
00912         if(pxp->bf_base == NULL)
00913                 return ENOMEM;
00914         /* else */
00915         pxp->bf_cnt = 0;
00916         if(isNew)
00917         {
00918                 /* save a read */
00919                 pxp->pos = 0;
00920                 pxp->bf_offset = 0;
00921                 pxp->bf_extent = bufsz;
00922                 (void) memset(pxp->bf_base, 0, pxp->bf_extent);
00923         }
00924         return ENOERR;
00925 }

static int ncio_px_move ncio *const   nciop,
off_t  to,
off_t  from,
size_t  nbytes,
int  rflags
[static]
 

Definition at line 713 of file posixio.c.

References ncio_px::blksz, ENOERR, fIsSet, ncio::ioflags, MIN, NC_WRITE, ncio::pvt, px_double_buffer(), px_get(), px_rel(), RGN_MODIFIED, RGN_NOLOCK, and RGN_WRITE.

Referenced by ncio_px_init().

00715 {
00716         ncio_px *const pxp = (ncio_px *)nciop->pvt;
00717         int status = ENOERR;
00718         off_t lower;    
00719         off_t upper;
00720         char *base;
00721         size_t diff;
00722         size_t extent;
00723 
00724         if(to == from)
00725                 return ENOERR; /* NOOP */
00726         
00727         if(fIsSet(rflags, RGN_WRITE) && !fIsSet(nciop->ioflags, NC_WRITE))
00728                 return EPERM; /* attempt to write readonly file */
00729 
00730         rflags &= RGN_NOLOCK; /* filter unwanted flags */
00731 
00732         if(to > from)
00733         {
00734                 /* growing */
00735                 lower = from;   
00736                 upper = to;
00737         }
00738         else
00739         {
00740                 /* shrinking */
00741                 lower = to;
00742                 upper = from;
00743         }
00744         diff = (size_t)(upper - lower);
00745         extent = diff + nbytes;
00746 
00747 #if INSTRUMENT
00748 fprintf(stderr, "ncio_px_move %ld %ld %ld %ld %ld\n",
00749                  (long)to, (long)from, (long)nbytes, (long)lower, (long)extent);
00750 #endif
00751         if(extent > pxp->blksz)
00752         {
00753                 size_t remaining = nbytes;
00754 
00755 if(to > from)
00756 {
00757                 off_t frm = from + nbytes;
00758                 off_t toh = to + nbytes;
00759                 for(;;)
00760                 {
00761                         size_t loopextent = MIN(remaining, pxp->blksz);
00762                         frm -= loopextent;
00763                         toh -= loopextent;
00764 
00765                         status = px_double_buffer(nciop, toh, frm,
00766                                         loopextent, rflags) ;
00767                         if(status != ENOERR)
00768                                 return status;
00769                         remaining -= loopextent;
00770 
00771                         if(remaining == 0)
00772                                 break; /* normal loop exit */
00773                 }
00774 }
00775 else
00776 {
00777                 for(;;)
00778                 {
00779                         size_t loopextent = MIN(remaining, pxp->blksz);
00780 
00781                         status = px_double_buffer(nciop, to, from,
00782                                         loopextent, rflags) ;
00783                         if(status != ENOERR)
00784                                 return status;
00785                         remaining -= loopextent;
00786 
00787                         if(remaining == 0)
00788                                 break; /* normal loop exit */
00789                         to += loopextent;
00790                         from += loopextent;
00791                 }
00792 }
00793                 return ENOERR;
00794         }
00795         
00796 #if INSTRUMENT
00797 fprintf(stderr, "\tncio_px_move small\n");
00798 #endif
00799         status = px_get(nciop, pxp, lower, extent, RGN_WRITE|rflags,
00800                         (void **)&base);
00801 
00802         if(status != ENOERR)
00803                 return status;
00804 
00805         if(to > from)
00806                 (void) memmove(base + diff, base, nbytes); 
00807         else
00808                 (void) memmove(base, base + diff, nbytes); 
00809                 
00810         (void) px_rel(pxp, lower, RGN_MODIFIED);
00811 
00812         return status;
00813 }

static int ncio_px_rel ncio *const   nciop,
off_t  offset,
int  rflags
[static]
 

Definition at line 339 of file posixio.c.

References fIsSet, ncio::ioflags, NC_WRITE, ncio::pvt, px_rel(), and RGN_MODIFIED.

Referenced by ncio_px_init().

00340 {
00341         ncio_px *const pxp = (ncio_px *)nciop->pvt;
00342 
00343         if(fIsSet(rflags, RGN_MODIFIED) && !fIsSet(nciop->ioflags, NC_WRITE))
00344                 return EPERM; /* attempt to write readonly file */
00345 
00346         return px_rel(pxp, offset, rflags);
00347 }

static int ncio_px_sync ncio *const   nciop  )  [static]
 

Definition at line 820 of file posixio.c.

References ncio_px::bf_base, ncio_px::bf_cnt, ncio_px::bf_offset, ncio_px::bf_refcount, ncio_px::bf_rflags, ENOERR, fIsSet, OFF_NONE, ncio_px::pos, ncio::pvt, px_pgout(), RGN_MODIFIED, and RGN_WRITE.

Referenced by ncio_px_init().

00821 {
00822         ncio_px *const pxp = (ncio_px *)nciop->pvt;
00823         int status = ENOERR;
00824         if(fIsSet(pxp->bf_rflags, RGN_MODIFIED))
00825         {
00826                 assert(pxp->bf_refcount <= 0);
00827                 status = px_pgout(nciop, pxp->bf_offset,
00828                         pxp->bf_cnt,
00829                         pxp->bf_base, &pxp->pos);
00830                 if(status != ENOERR)
00831                         return status;
00832                 pxp->bf_rflags = 0;
00833         }
00834         else if (!fIsSet(pxp->bf_rflags, RGN_WRITE))
00835         {
00836             /*
00837              * The dataset is readonly.  Invalidate the buffers so
00838              * that the next ncio_px_get() will actually read data.
00839              */
00840             pxp->bf_offset = OFF_NONE;
00841             pxp->bf_cnt = 0;
00842         }
00843         return status;
00844 }

static void ncio_spx_free void *const   pvt  )  [static]
 

Definition at line 1254 of file posixio.c.

References ncio_spx::bf_base, ncio_spx::bf_cnt, ncio_spx::bf_extent, ncio_spx::bf_offset, and OFF_NONE.

Referenced by ncio_spx_init().

01255 {
01256         ncio_spx *const pxp = (ncio_spx *)pvt;
01257         if(pxp == NULL)
01258                 return;
01259 
01260         if(pxp->bf_base != NULL)
01261         {
01262                 free(pxp->bf_base);
01263                 pxp->bf_base = NULL;
01264                 pxp->bf_offset = OFF_NONE;
01265                 pxp->bf_extent = 0;
01266                 pxp->bf_cnt = 0;
01267         }
01268 }

static int ncio_spx_get ncio *const   nciop,
off_t  offset,
size_t  extent,
int  rflags,
void **const   vpp
[static]
 

Definition at line 1035 of file posixio.c.

References ncio_spx::bf_base, ncio_spx::bf_cnt, ncio_spx::bf_extent, ncio_spx::bf_offset, ENOERR, fIsSet, ncio::ioflags, NC_WRITE, ncio_spx::pos, ncio::pvt, px_pgin(), RGN_WRITE, X_ALIGN, and X_INT_MAX.

Referenced by ncio_spx_init(), and ncio_spx_move().

01039 {
01040         ncio_spx *const pxp = (ncio_spx *)nciop->pvt;
01041         int status = ENOERR;
01042 #ifdef X_ALIGN
01043         size_t rem;
01044 #endif
01045         
01046         if(fIsSet(rflags, RGN_WRITE) && !fIsSet(nciop->ioflags, NC_WRITE))
01047                 return EPERM; /* attempt to write readonly file */
01048 
01049         assert(extent != 0);
01050         assert(extent < X_INT_MAX); /* sanity check */
01051 
01052         assert(pxp->bf_cnt == 0);
01053 
01054 #ifdef X_ALIGN
01055         rem = (size_t)(offset % X_ALIGN);
01056         if(rem != 0)
01057         {
01058                 offset -= rem;
01059                 extent += rem;
01060         }
01061 
01062         {
01063                 const size_t rndup = extent % X_ALIGN;
01064                 if(rndup != 0)
01065                         extent += X_ALIGN - rndup;
01066         }
01067 
01068         assert(offset % X_ALIGN == 0);
01069         assert(extent % X_ALIGN == 0);
01070 #endif
01071 
01072         if(pxp->bf_extent < extent)
01073         {
01074                 if(pxp->bf_base != NULL)
01075                 {
01076                         free(pxp->bf_base);
01077                         pxp->bf_base = NULL;
01078                         pxp->bf_extent = 0;
01079                 }
01080                 assert(pxp->bf_extent == 0);
01081                 pxp->bf_base = malloc(extent);
01082                 if(pxp->bf_base == NULL)
01083                         return ENOMEM;
01084                 pxp->bf_extent = extent;
01085         }
01086 
01087         status = px_pgin(nciop, offset,
01088                  extent,
01089                  pxp->bf_base,
01090                  &pxp->bf_cnt, &pxp->pos);
01091         if(status != ENOERR)
01092                 return status;
01093 
01094         pxp->bf_offset = offset;
01095 
01096         if(pxp->bf_cnt < extent)
01097                 pxp->bf_cnt = extent;
01098 
01099 #ifdef X_ALIGN
01100         *vpp = (char *)pxp->bf_base + rem;
01101 #else
01102         *vpp = pxp->bf_base;
01103 #endif
01104         return ENOERR;
01105 }

static void ncio_spx_init ncio *const   nciop  )  [static]
 

Definition at line 1307 of file posixio.c.

References ncio_spx::bf_base, ncio_spx::bf_cnt, ncio_spx::bf_extent, ncio_spx::bf_offset, ncio::free, ncio::get, ncio::move, ncio_spx_free(), ncio_spx_get(), ncio_spx_move(), ncio_spx_rel(), ncio_spx_sync(), OFF_NONE, ncio_spx::pos, ncio::pvt, ncio::rel, and ncio::sync.

Referenced by ncio_new().

01308 {
01309         ncio_spx *const pxp = (ncio_spx *)nciop->pvt;
01310 
01311         *((ncio_relfunc **)&nciop->rel) = ncio_spx_rel; /* cast away const */
01312         *((ncio_getfunc **)&nciop->get) = ncio_spx_get; /* cast away const */
01313         *((ncio_movefunc **)&nciop->move) = ncio_spx_move; /* cast away const */
01314         *((ncio_syncfunc **)&nciop->sync) = ncio_spx_sync; /* cast away const */
01315         *((ncio_freefunc **)&nciop->free) = ncio_spx_free; /* cast away const */
01316 
01317         pxp->pos = -1;
01318         pxp->bf_offset = OFF_NONE;
01319         pxp->bf_extent = 0;
01320         pxp->bf_cnt = 0;
01321         pxp->bf_base = NULL;
01322 }

static int ncio_spx_init2 ncio *const   nciop,
const size_t *const   sizehintp
[static]
 

Definition at line 1280 of file posixio.c.

References ncio_spx::bf_base, ncio_spx::bf_extent, ENOERR, ncio::fd, and ncio::pvt.

Referenced by ncio_create(), and ncio_open().

01281 {
01282         ncio_spx *const pxp = (ncio_spx *)nciop->pvt;
01283 
01284         assert(nciop->fd >= 0);
01285 
01286         pxp->bf_extent = *sizehintp;
01287 
01288         assert(pxp->bf_base == NULL);
01289 
01290         /* this is separate allocation because it may grow */
01291         pxp->bf_base = malloc(pxp->bf_extent);
01292         if(pxp->bf_base == NULL)
01293         {
01294                 pxp->bf_extent = 0;
01295                 return ENOMEM;
01296         }
01297         /* else */
01298         return ENOERR;
01299 }

static int ncio_spx_move ncio *const   nciop,
off_t  to,
off_t  from,
size_t  nbytes,
int  rflags
[static]
 

Definition at line 1195 of file posixio.c.

References ENOERR, ncio_spx_get(), ncio_spx_rel(), RGN_MODIFIED, RGN_NOLOCK, and RGN_WRITE.

Referenced by ncio_spx_init().

01197 {
01198         int status = ENOERR;
01199         off_t lower = from;     
01200         off_t upper = to;
01201         char *base;
01202         size_t diff = (size_t)(upper - lower);
01203         size_t extent = diff + nbytes;
01204 
01205         rflags &= RGN_NOLOCK; /* filter unwanted flags */
01206 
01207         if(to == from)
01208                 return ENOERR; /* NOOP */
01209         
01210         if(to > from)
01211         {
01212                 /* growing */
01213                 lower = from;   
01214                 upper = to;
01215         }
01216         else
01217         {
01218                 /* shrinking */
01219                 lower = to;
01220                 upper = from;
01221         }
01222 
01223         diff = (size_t)(upper - lower);
01224         extent = diff + nbytes;
01225 
01226         status = ncio_spx_get(nciop, lower, extent, RGN_WRITE|rflags,
01227                         (void **)&base);
01228 
01229         if(status != ENOERR)
01230                 return status;
01231 
01232         if(to > from)
01233                 (void) memmove(base + diff, base, nbytes); 
01234         else
01235                 (void) memmove(base, base + diff, nbytes); 
01236                 
01237         (void) ncio_spx_rel(nciop, lower, RGN_MODIFIED);
01238 
01239         return status;
01240 }

static int ncio_spx_rel ncio *const   nciop,
off_t  offset,
int  rflags
[static]
 

Definition at line 989 of file posixio.c.

References ncio_spx::bf_base, ncio_spx::bf_cnt, ncio_spx::bf_extent, ncio_spx::bf_offset, ENOERR, fIsSet, ncio::ioflags, NC_WRITE, OFF_NONE, ncio_spx::pos, ncio::pvt, px_pgout(), RGN_MODIFIED, and X_ALIGN.

Referenced by ncio_spx_init(), and ncio_spx_move().

00990 {
00991         ncio_spx *const pxp = (ncio_spx *)nciop->pvt;
00992         int status = ENOERR;
00993 
00994         assert(pxp->bf_offset <= offset);
00995         assert(pxp->bf_cnt != 0);
00996         assert(pxp->bf_cnt <= pxp->bf_extent);
00997 #ifdef X_ALIGN
00998         assert(offset < pxp->bf_offset + X_ALIGN);
00999         assert(pxp->bf_cnt % X_ALIGN == 0 );
01000 #endif
01001 
01002         if(fIsSet(rflags, RGN_MODIFIED))
01003         {
01004                 if(!fIsSet(nciop->ioflags, NC_WRITE))
01005                         return EPERM; /* attempt to write readonly file */
01006 
01007                 status = px_pgout(nciop, pxp->bf_offset,
01008                         pxp->bf_cnt,
01009                         pxp->bf_base, &pxp->pos);
01010                 /* if error, invalidate buffer anyway */
01011         }
01012         pxp->bf_offset = OFF_NONE;
01013         pxp->bf_cnt = 0;
01014         return status;
01015 }

static int ncio_spx_sync ncio *const   nciop  )  [static]
 

Definition at line 1247 of file posixio.c.

References ENOERR.

Referenced by ncio_spx_init().

01248 {
01249         /* NOOP */
01250         return ENOERR;
01251 }

static size_t pagesize void   )  [static]
 

Definition at line 68 of file posixio.c.

References POSIXIO_DEFAULT_PAGESIZE.

Referenced by blksize().

00069 {
00070 /* Hmm, aren't standards great? */
00071 #if defined(_SC_PAGE_SIZE) && !defined(_SC_PAGESIZE)
00072 #define _SC_PAGESIZE _SC_PAGE_SIZE
00073 #endif
00074 
00075 #ifdef _SC_PAGESIZE
00076         {
00077                 const long pgsz = sysconf(_SC_PAGESIZE);
00078                 if(pgsz > 0)
00079                         return (size_t) pgsz;
00080                 /* else, silent in the face of error */
00081         }
00082 #elif defined(HAVE_GETPAGESIZE)
00083         return (size_t) getpagesize();
00084 #endif
00085         return (size_t) POSIXIO_DEFAULT_PAGESIZE;
00086 }

static int px_double_buffer ncio *const   nciop,
off_t  to,
off_t  from,
size_t  nbytes,
int  rflags
[static]
 

Definition at line 641 of file posixio.c.

References ncio_px::bf_base, ncio_px::bf_cnt, ncio_px::bf_extent, ncio_px::bf_offset, ncio_px::bf_refcount, ncio_px::bf_rflags, ncio_px::blksz, ENOERR, ncio_px::pos, ncio::pvt, px_get(), px_rel(), RGN_MODIFIED, RGN_WRITE, and ncio_px::slave.

Referenced by ncio_px_move().

00643 {
00644         ncio_px *const pxp = (ncio_px *)nciop->pvt;
00645         int status = ENOERR;
00646         void *src;
00647         void *dest;
00648         
00649 #if INSTRUMENT
00650 fprintf(stderr, "\tdouble_buffr %ld %ld %ld\n",
00651                  (long)to, (long)from, (long)nbytes);
00652 #endif
00653         status = px_get(nciop, pxp, to, nbytes, RGN_WRITE,
00654                         &dest);
00655         if(status != ENOERR)
00656                 return status;
00657 
00658         if(pxp->slave == NULL)
00659         {
00660                 pxp->slave = (ncio_px *) malloc(sizeof(ncio_px));
00661                 if(pxp->slave == NULL)
00662                         return ENOMEM;
00663 
00664                 pxp->slave->blksz = pxp->blksz;
00665                 /* pos done below */
00666                 pxp->slave->bf_offset = pxp->bf_offset; 
00667                 pxp->slave->bf_extent = pxp->bf_extent;
00668                 pxp->slave->bf_cnt = pxp->bf_cnt;
00669                 pxp->slave->bf_base = malloc(2 * pxp->blksz);
00670                 if(pxp->slave->bf_base == NULL)
00671                         return ENOMEM;
00672                 (void) memcpy(pxp->slave->bf_base, pxp->bf_base,
00673                          pxp->bf_extent);
00674                 pxp->slave->bf_rflags = 0;
00675                 pxp->slave->bf_refcount = 0;
00676                 pxp->slave->slave = NULL;
00677         }
00678         
00679         pxp->slave->pos = pxp->pos;
00680         status = px_get(nciop, pxp->slave, from, nbytes, 0,
00681                         &src);
00682         if(status != ENOERR)
00683                 return status;
00684         if(pxp->pos != pxp->slave->pos)
00685         {
00686                 /* position changed, sync */
00687                 pxp->pos = pxp->slave->pos;
00688         }
00689 
00690         (void) memcpy(dest, src, nbytes);
00691 
00692         (void)px_rel(pxp->slave, from, 0);
00693         (void)px_rel(pxp, to, RGN_MODIFIED);
00694         
00695         return status;
00696 }

static int px_get ncio *const   nciop,
ncio_px *const   pxp,
off_t  offset,
size_t  extent,
int  rflags,
void **const   vpp
[static]
 

Definition at line 385 of file posixio.c.

References _RNDDOWN, _RNDUP, ncio_px::bf_base, ncio_px::bf_cnt, ncio_px::bf_extent, ncio_px::bf_offset, ncio_px::bf_refcount, ncio_px::bf_rflags, ncio_px::blksz, ENOERR, fIsSet, OFF_NONE, ncio_px::pos, px_pgin(), px_pgout(), RGN_MODIFIED, and X_INT_MAX.

Referenced by ncio_px_get(), ncio_px_move(), and px_double_buffer().

00389 {
00390         int status = ENOERR;
00391 
00392         const off_t blkoffset = _RNDDOWN(offset, (off_t)pxp->blksz);
00393         size_t diff = (size_t)(offset - blkoffset);
00394         size_t blkextent = _RNDUP(diff + extent, pxp->blksz);
00395         
00396         assert(extent != 0);
00397         assert(extent < X_INT_MAX); /* sanity check */
00398         assert(offset >= 0); /* sanity check */
00399 
00400         if(2 * pxp->blksz < blkextent)
00401                 return E2BIG; /* TODO: temporary kludge */
00402         if(pxp->bf_offset == OFF_NONE)
00403         {
00404                 /* Uninitialized */
00405                 if(pxp->bf_base == NULL)
00406                 {
00407                         assert(pxp->bf_extent == 0);
00408                         assert(blkextent <= 2 * pxp->blksz);
00409                         pxp->bf_base = malloc(2 * pxp->blksz);
00410                         if(pxp->bf_base == NULL)
00411                                 return ENOMEM;
00412                 }
00413                 goto pgin;
00414         }
00415         /* else */
00416         assert(blkextent <= 2 * pxp->blksz);
00417 
00418         if(blkoffset == pxp->bf_offset)
00419         {
00420                 /* hit */
00421                 if(blkextent > pxp->bf_extent) 
00422                 {
00423                         /* page in upper */
00424                         void *const middle =
00425                                 (void *)((char *)pxp->bf_base + pxp->blksz);
00426                         assert(pxp->bf_extent == pxp->blksz);
00427                         status = px_pgin(nciop,
00428                                  pxp->bf_offset + (off_t)pxp->blksz,
00429                                  pxp->blksz,
00430                                  middle,
00431                                  &pxp->bf_cnt,
00432                                  &pxp->pos);
00433                         if(status != ENOERR)
00434                                 return status;
00435                         pxp->bf_extent = 2 * pxp->blksz;
00436                         pxp->bf_cnt += pxp->blksz;
00437                 }
00438                 goto done;
00439         }
00440         /* else */
00441 
00442         if(pxp->bf_extent > pxp->blksz
00443                  && blkoffset == pxp->bf_offset + (off_t)pxp->blksz)
00444         {
00445                 /* hit in upper half */
00446                 if(blkextent == pxp->blksz)
00447                 {
00448                         /* all in upper half, no fault needed */
00449                         diff += pxp->blksz;
00450                         goto done;
00451                 }
00452                 /* else */
00453                 if(pxp->bf_cnt > pxp->blksz)
00454                 {
00455                         /* data in upper half */
00456                         void *const middle =
00457                                 (void *)((char *)pxp->bf_base + pxp->blksz);
00458                         assert(pxp->bf_extent == 2 * pxp->blksz);
00459                         if(fIsSet(pxp->bf_rflags, RGN_MODIFIED))
00460                         {
00461                                 /* page out lower half */
00462                                 assert(pxp->bf_refcount <= 0);
00463                                 status = px_pgout(nciop,
00464                                         pxp->bf_offset,
00465                                         pxp->blksz,
00466                                         pxp->bf_base,
00467                                         &pxp->pos);
00468                                 if(status != ENOERR)
00469                                         return status;
00470                         }
00471                         pxp->bf_cnt -= pxp->blksz;
00472                         /* copy upper half into lower half */
00473                         (void) memcpy(pxp->bf_base, middle, pxp->bf_cnt);
00474                 }
00475                 pxp->bf_offset = blkoffset;
00476                 /* pxp->bf_extent = pxp->blksz; */
00477 
00478                 assert(blkextent == 2 * pxp->blksz);
00479                 {
00480                         /* page in upper */
00481                         void *const middle =
00482                                 (void *)((char *)pxp->bf_base + pxp->blksz);
00483                         status = px_pgin(nciop,
00484                                  pxp->bf_offset + (off_t)pxp->blksz,
00485                                  pxp->blksz,
00486                                  middle,
00487                                  &pxp->bf_cnt,
00488                                  &pxp->pos);
00489                         if(status != ENOERR)
00490                                 return status;
00491                         pxp->bf_extent = 2 * pxp->blksz;
00492                         pxp->bf_cnt += pxp->blksz;
00493                 }
00494                 goto done;
00495         }
00496         /* else */
00497 
00498         if(blkoffset == pxp->bf_offset - (off_t)pxp->blksz)
00499         {
00500                 /* wants the page below */
00501                 void *const middle =
00502                         (void *)((char *)pxp->bf_base + pxp->blksz);
00503                 size_t upper_cnt = 0;
00504                 if(pxp->bf_cnt > pxp->blksz)
00505                 {
00506                         /* data in upper half */
00507                         assert(pxp->bf_extent == 2 * pxp->blksz);
00508                         if(fIsSet(pxp->bf_rflags, RGN_MODIFIED))
00509                         {
00510                                 /* page out upper half */
00511                                 assert(pxp->bf_refcount <= 0);
00512                                 status = px_pgout(nciop,
00513                                         pxp->bf_offset + (off_t)pxp->blksz,
00514                                         pxp->bf_cnt - pxp->blksz,
00515                                         middle,
00516                                         &pxp->pos);
00517                                 if(status != ENOERR)
00518                                         return status;
00519                         }
00520                         pxp->bf_cnt = pxp->blksz;
00521                         pxp->bf_extent = pxp->blksz;
00522                 }
00523                 if(pxp->bf_cnt > 0)
00524                 {
00525                         /* copy lower half into upper half */
00526                         (void) memcpy(middle, pxp->bf_base, pxp->blksz);
00527                         upper_cnt = pxp->bf_cnt;
00528                 }
00529                 /* read page below into lower half */
00530                 status = px_pgin(nciop,
00531                          blkoffset,
00532                          pxp->blksz,
00533                          pxp->bf_base,
00534                          &pxp->bf_cnt,
00535                          &pxp->pos);
00536                 if(status != ENOERR)
00537                         return status;
00538                 pxp->bf_offset = blkoffset;
00539                 if(upper_cnt != 0)
00540                 {
00541                         pxp->bf_extent = 2 * pxp->blksz;
00542                         pxp->bf_cnt = pxp->blksz + upper_cnt;
00543                 }
00544                 else
00545                 {
00546                         pxp->bf_extent = pxp->blksz;
00547                 }
00548                 goto done;
00549         }
00550         /* else */
00551 
00552         /* no overlap */
00553         if(fIsSet(pxp->bf_rflags, RGN_MODIFIED))
00554         {
00555                 assert(pxp->bf_refcount <= 0);
00556                 status = px_pgout(nciop,
00557                         pxp->bf_offset,
00558                         pxp->bf_cnt,
00559                         pxp->bf_base,
00560                         &pxp->pos);
00561                 if(status != ENOERR)
00562                         return status;
00563                 pxp->bf_rflags = 0;
00564         }
00565 
00566 pgin:
00567         status = px_pgin(nciop,
00568                  blkoffset,
00569                  blkextent,
00570                  pxp->bf_base,
00571                  &pxp->bf_cnt,
00572                  &pxp->pos);
00573         if(status != ENOERR)
00574                 return status;
00575          pxp->bf_offset = blkoffset;
00576          pxp->bf_extent = blkextent;
00577 
00578 done:
00579         extent += diff;
00580         if(pxp->bf_cnt < extent)
00581                 pxp->bf_cnt = extent;
00582         assert(pxp->bf_cnt <= pxp->bf_extent);
00583 
00584         pxp->bf_rflags |= rflags;
00585         pxp->bf_refcount++;
00586 
00587         *vpp = (char *)pxp->bf_base + diff;
00588         return ENOERR;
00589 }

static int px_pgin ncio *const   nciop,
off_t const   offset,
const size_t  extent,
void *const   vp,
size_t *  nreadp,
off_t *  posp
[static]
 

Definition at line 220 of file posixio.c.

References ENOERR, ncio::fd, OFF_NONE, SEEK_CUR, SEEK_SET, and X_ALIGN.

Referenced by ncio_spx_get(), and px_get().

00223 {
00224         int status;
00225         ssize_t nread;
00226 
00227 #ifdef X_ALIGN
00228         assert(offset % X_ALIGN == 0);
00229         assert(extent % X_ALIGN == 0);
00230 #endif
00231 
00232         assert(*posp == OFF_NONE || *posp == lseek(nciop->fd, 0, SEEK_CUR));
00233 
00234         if(*posp != offset)
00235         {
00236                 if(lseek(nciop->fd, offset, SEEK_SET) != offset)
00237                 {
00238                         status = errno;
00239                         return status;
00240                 }
00241                 *posp = offset;
00242         }
00243 
00244         errno = 0;
00245         nread = read(nciop->fd, vp, extent);
00246         if(nread != (ssize_t) extent)
00247         {
00248                 status = errno;
00249                 if(nread == -1 || status != ENOERR)
00250                         return status;
00251                 /* else it's okay we read less than asked for */
00252                 (void) memset((char *)vp + nread, 0, (ssize_t)extent - nread);
00253         }
00254         *nreadp = nread;
00255         *posp += nread;
00256 
00257         return ENOERR;
00258 }

static int px_pgout ncio *const   nciop,
off_t const   offset,
const size_t  extent,
void *const   vp,
off_t *  posp
[static]
 

Definition at line 183 of file posixio.c.

References ENOERR, ncio::fd, OFF_NONE, SEEK_CUR, SEEK_SET, and X_ALIGN.

Referenced by ncio_px_sync(), ncio_spx_rel(), and px_get().

00186 {
00187 #ifdef X_ALIGN
00188         assert(offset % X_ALIGN == 0);
00189 #endif
00190 
00191         assert(*posp == OFF_NONE || *posp == lseek(nciop->fd, 0, SEEK_CUR));
00192 
00193         if(*posp != offset)
00194         {
00195                 if(lseek(nciop->fd, offset, SEEK_SET) != offset)
00196                 {
00197                         return errno;
00198                 }
00199                 *posp = offset;
00200         }
00201         if(write(nciop->fd, vp, extent) != (ssize_t) extent)
00202         {
00203                 return errno;
00204         }
00205         *posp += extent;
00206 
00207         return ENOERR;
00208 }

static int px_rel ncio_px *const   pxp,
off_t  offset,
int  rflags
[static]
 

Definition at line 306 of file posixio.c.

References ncio_px::bf_extent, ncio_px::bf_offset, ncio_px::bf_refcount, ncio_px::bf_rflags, ENOERR, fIsSet, fSet, pIf, RGN_MODIFIED, and RGN_WRITE.

Referenced by ncio_px_move(), ncio_px_rel(), and px_double_buffer().

00307 {
00308         assert(pxp->bf_offset <= offset
00309                  && offset < pxp->bf_offset + (off_t) pxp->bf_extent);
00310         assert(pIf(fIsSet(rflags, RGN_MODIFIED),
00311                 fIsSet(pxp->bf_rflags, RGN_WRITE)));
00312 
00313         if(fIsSet(rflags, RGN_MODIFIED))
00314         {
00315                 fSet(pxp->bf_rflags, RGN_MODIFIED);
00316         }
00317         pxp->bf_refcount--;
00318 
00319         return ENOERR;
00320 }


Generated on Thu Mar 16 18:11:12 2006 for nco by  doxygen 1.4.4