Moved lseek call out of assert statement into an explicit check. JIRA NCF-312.

This commit is contained in:
Ward Fisher 2014-08-27 14:26:54 -06:00
parent 51e3cc4b06
commit 4286822b91

View File

@ -223,7 +223,7 @@ fgrow2(const int fd, const off_t len)
posp - pointer to current position in file, updated after write.
*/
static int
px_pgout(ncio *const nciop,
px_pgout(ncio *const nciop,
off_t const offset, const size_t extent,
void *const vp, off_t *posp)
{
@ -254,7 +254,7 @@ px_pgout(ncio *const nciop,
while((partial = write(nciop->fd, nvp, nextent)) != -1) {
if(partial == nextent)
break;
nvp += partial;
nvp += partial;
nextent -= partial;
}
if(partial == -1)
@ -264,14 +264,16 @@ px_pgout(ncio *const nciop,
return ENOERR;
}
/* Read in a page of data.
/*! Read in a page of data.
nciop - a pointer to the ncio struct for this file.
offset - byte offset in file where read starts.
extent - the size of the page that will be read.
vp - a pointer to where the data will end up.
nreadp - returned number of bytes actually read (may be less than extent).
posp - pointer to current position in file, updated after read.
@param[in] nciop A pointer to the ncio struct for this file.
@param[in] offset The byte offset in file where read starts.
@param[in] extent The size of the page that will be read.
@param[in] vp A pointer to where the data will end up.
@param[in,out] nreadp Returned number of bytes actually read (may be less than extent).
@param[in,out] posp The pointer to current position in file, updated after read.
@return Return 0 on success, otherwise an error code.
*/
static int
px_pgin(ncio *const nciop,
@ -285,8 +287,18 @@ px_pgin(ncio *const nciop,
assert(offset % X_ALIGN == 0);
assert(extent % X_ALIGN == 0);
#endif
/*
assert(*posp == OFF_NONE || *posp == lseek(nciop->fd, 0, SEEK_CUR));
*/
/* *posp == OFF_NONE (-1) on first call. This
is problematic because lseek also returns -1
on error. Use errno instead. */
if(*posp != OFF_NONE || *posp == lseek(nciop->fd, 0, SEEK_CUR)) {
if(errno) {
status = errno;
return status;
}
}
if(*posp != offset)
{
@ -333,7 +345,7 @@ typedef struct ncio_px {
size_t blksz;
off_t pos;
/* buffer */
off_t bf_offset;
off_t bf_offset;
size_t bf_extent;
size_t bf_cnt;
void *bf_base;
@ -406,7 +418,7 @@ ncio_px_rel(ncio *const nciop, off_t offset, int rflags)
/* POSIX get. This will "make a region available." Since we're using
buffered IO, this means that if needed, we'll fetch a new page from
the file, otherwise, just return a pointer to what's in memory
already.
already.
nciop - pointer to ncio struct, containing file info.
pxp - pointer to ncio_px struct, which contains special metadate
@ -416,7 +428,7 @@ ncio_px_rel(ncio *const nciop, off_t offset, int rflags)
rflags - One of the RGN_* flags defined in ncio.h.
vpp - pointer to pointer that will recieve data.
NOTES:
NOTES:
* For blkoffset round offset down to the nearest pxp->blksz. This
provides the offset (in bytes) to the beginning of the block that
@ -436,7 +448,7 @@ ncio_px_rel(ncio *const nciop, off_t offset, int rflags)
* If this is called on a newly opened file, pxp->bf_offset will be
OFF_NONE and we'll jump to label pgin to immediately read in a
page.
page.
*/
static int
px_get(ncio *const nciop, ncio_px *const pxp,
@ -449,7 +461,7 @@ px_get(ncio *const nciop, ncio_px *const pxp,
const off_t blkoffset = _RNDDOWN(offset, (off_t)pxp->blksz);
off_t diff = (size_t)(offset - blkoffset);
off_t blkextent = _RNDUP(diff + extent, pxp->blksz);
assert(extent != 0);
assert(extent < X_INT_MAX); /* sanity check */
assert(offset >= 0); /* sanity check */
@ -475,7 +487,7 @@ px_get(ncio *const nciop, ncio_px *const pxp,
if(blkoffset == pxp->bf_offset)
{
/* hit */
if(blkextent > pxp->bf_extent)
if(blkextent > pxp->bf_extent)
{
/* page in upper */
void *const middle =
@ -669,7 +681,7 @@ done:
corresponding call to rel().
For POSIX systems, without NC_SHARE. This function gets a page of
size extent?
size extent?
This is a wrapper for the function px_get, which does all the heavy
lifting.
@ -682,13 +694,13 @@ done:
vpp - handle to point at data when it's been read.
*/
static int
ncio_px_get(ncio *const nciop,
ncio_px_get(ncio *const nciop,
off_t offset, size_t extent,
int rflags,
void **const vpp)
{
ncio_px *const pxp = (ncio_px *)nciop->pvt;
if(fIsSet(rflags, RGN_WRITE) && !fIsSet(nciop->ioflags, NC_WRITE))
return EPERM; /* attempt to write readonly file */
@ -718,7 +730,7 @@ px_double_buffer(ncio *const nciop, off_t to, off_t from,
int status = ENOERR;
void *src;
void *dest;
#if INSTRUMENT
fprintf(stderr, "\tdouble_buffr %ld %ld %ld\n",
(long)to, (long)from, (long)nbytes);
@ -736,7 +748,7 @@ fprintf(stderr, "\tdouble_buffr %ld %ld %ld\n",
pxp->slave->blksz = pxp->blksz;
/* pos done below */
pxp->slave->bf_offset = pxp->bf_offset;
pxp->slave->bf_offset = pxp->bf_offset;
pxp->slave->bf_extent = pxp->bf_extent;
pxp->slave->bf_cnt = pxp->bf_cnt;
pxp->slave->bf_base = malloc(2 * pxp->blksz);
@ -748,7 +760,7 @@ fprintf(stderr, "\tdouble_buffr %ld %ld %ld\n",
pxp->slave->bf_refcount = 0;
pxp->slave->slave = NULL;
}
pxp->slave->pos = pxp->pos;
status = px_get(nciop, pxp->slave, from, nbytes, 0,
&src);
@ -764,7 +776,7 @@ fprintf(stderr, "\tdouble_buffr %ld %ld %ld\n",
(void)px_rel(pxp->slave, from, 0);
(void)px_rel(pxp, to, RGN_MODIFIED);
return status;
}
@ -788,7 +800,7 @@ ncio_px_move(ncio *const nciop, off_t to, off_t from,
{
ncio_px *const pxp = (ncio_px *)nciop->pvt;
int status = ENOERR;
off_t lower;
off_t lower;
off_t upper;
char *base;
size_t diff;
@ -796,7 +808,7 @@ ncio_px_move(ncio *const nciop, off_t to, off_t from,
if(to == from)
return ENOERR; /* NOOP */
if(fIsSet(rflags, RGN_WRITE) && !fIsSet(nciop->ioflags, NC_WRITE))
return EPERM; /* attempt to write readonly file */
@ -805,7 +817,7 @@ ncio_px_move(ncio *const nciop, off_t to, off_t from,
if(to > from)
{
/* growing */
lower = from;
lower = from;
upper = to;
}
else
@ -865,7 +877,7 @@ else
}
return ENOERR;
}
#if INSTRUMENT
fprintf(stderr, "\tncio_px_move small\n");
#endif
@ -876,10 +888,10 @@ fprintf(stderr, "\tncio_px_move small\n");
return status;
if(to > from)
(void) memmove(base + diff, base, nbytes);
(void) memmove(base + diff, base, nbytes);
else
(void) memmove(base, base + diff, nbytes);
(void) memmove(base, base + diff, nbytes);
(void) px_rel(pxp, lower, RGN_MODIFIED);
return status;
@ -938,7 +950,7 @@ ncio_px_freepvt(void *const pvt)
free(pxp->slave);
pxp->slave = NULL;
}
if(pxp->bf_base != NULL)
{
free(pxp->bf_base);
@ -1036,7 +1048,7 @@ ncio_px_init(ncio *const nciop)
typedef struct ncio_spx {
off_t pos;
/* buffer */
off_t bf_offset;
off_t bf_offset;
size_t bf_extent;
size_t bf_cnt;
void *bf_base;
@ -1117,7 +1129,7 @@ ncio_spx_get(ncio *const nciop,
#ifdef X_ALIGN
size_t rem;
#endif
if(fIsSet(rflags, RGN_WRITE) && !fIsSet(nciop->ioflags, NC_WRITE))
return EPERM; /* attempt to write readonly file */
@ -1191,7 +1203,7 @@ strategy(ncio *const nciop, off_t to, off_t offset,
#ifdef X_ALIGN
size_t rem;
#endif
assert(extent != 0);
assert(extent < X_INT_MAX); /* sanity check */
#if INSTRUMENT
@ -1241,7 +1253,7 @@ fprintf(stderr, "strategy %ld at %ld to %ld\n",
return status;
pxp->bf_offset = to; /* TODO: XALIGN */
if(pxp->bf_cnt < extent)
pxp->bf_cnt = extent;
@ -1271,7 +1283,7 @@ ncio_spx_move(ncio *const nciop, off_t to, off_t from,
size_t nbytes, int rflags)
{
int status = ENOERR;
off_t lower = from;
off_t lower = from;
off_t upper = to;
char *base;
size_t diff;
@ -1281,11 +1293,11 @@ ncio_spx_move(ncio *const nciop, off_t to, off_t from,
if(to == from)
return ENOERR; /* NOOP */
if(to > from)
{
/* growing */
lower = from;
lower = from;
upper = to;
}
else
@ -1305,10 +1317,10 @@ ncio_spx_move(ncio *const nciop, off_t to, off_t from,
return status;
if(to > from)
(void) memmove(base + diff, base, nbytes);
(void) memmove(base + diff, base, nbytes);
else
(void) memmove(base, base + diff, nbytes);
(void) memmove(base, base + diff, nbytes);
(void) ncio_spx_rel(nciop, lower, RGN_MODIFIED);
return status;
@ -1344,12 +1356,12 @@ ncio_spx_freepvt(void *const pvt)
/* This does the second half of the ncio_spx struct initialization for
POSIX systems, with NC_SHARE on.
POSIX systems, with NC_SHARE on.
nciop - pointer to ncio struct for this file. File has been opened.
sizehintp - pointer to a size which will be rounded up to the
nearest 8-byt boundary and then used as the max size "chunk" (or
page) to read from the file.
page) to read from the file.
*/
static int
ncio_spx_init2(ncio *const nciop, const size_t *const sizehintp)
@ -1439,7 +1451,7 @@ ncio_px_new(const char *path, int ioflags)
size_t sz_path = M_RNDUP(strlen(path) +1);
size_t sz_ncio_pvt;
ncio *nciop;
#if ALWAYS_NC_SHARE /* DEBUG */
fSet(ioflags, NC_SHARE);
#endif
@ -1452,7 +1464,7 @@ ncio_px_new(const char *path, int ioflags)
nciop = (ncio *) malloc(sz_ncio + sz_path + sz_ncio_pvt);
if(nciop == NULL)
return NULL;
nciop->ioflags = ioflags;
*((int *)&nciop->fd) = -1; /* cast away const */
@ -1494,8 +1506,8 @@ ncio_px_new(const char *path, int ioflags)
ioflags - flags from nc_create
initialsz - From the netcdf man page: "The argument
Iinitialsize sets the initial size of the file at creation time."
igeto -
igetsz -
igeto -
igetsz -
sizehintp - this eventually goes into pxp->blksz and is the size of
a page of data for buffered reads and writes.
nciopp - pointer to a pointer that will get location of newly
@ -1608,17 +1620,17 @@ unwind_new:
path - path of data file.
ioflags - flags passed into nc_open.
igeto - looks like this function can do an initial page get, and
igeto is going to be the offset for that. But it appears to be
unused
unused
igetsz - the size in bytes of initial page get (a.k.a. extent). Not
ever used in the library.
sizehintp - pointer to sizehint parameter from nc__open or
nc__create. This is used to set pxp->blksz.
nc__create. This is used to set pxp->blksz.
Here's what the man page has to say:
"The argument referenced by chunksize controls a space versus time
@ -1724,7 +1736,7 @@ unwind_new:
return status;
}
/*
/*
* Get file size in bytes.
*/
static int
@ -1733,7 +1745,7 @@ ncio_px_filesize(ncio *nciop, off_t *filesizep)
/* There is a problem with fstat on Windows based systems
which manifests (so far) when Config RELEASE is built.
which manifests (so far) when Config RELEASE is built.
Use _filelengthi64 isntead. */
#ifdef HAVE_FILE_LENGTH_I64
@ -1766,7 +1778,7 @@ ncio_px_pad_length(ncio *nciop, off_t length)
{
int status = ENOERR;
if(nciop == NULL)
return EINVAL;
@ -1789,12 +1801,12 @@ ncio_px_pad_length(ncio *nciop, off_t length)
Sync any changes, then close the open file associated with the ncio
struct, and free its memory.
nciop - pointer to ncio to close.
doUnlink - if true, unlink file
*/
static int
static int
ncio_px_close(ncio *nciop, int doUnlink)
{
int status = ENOERR;
@ -1803,14 +1815,14 @@ ncio_px_close(ncio *nciop, int doUnlink)
if(nciop->fd > 0) {
status = nciop->sync(nciop);
(void) close(nciop->fd);
}
}
if(doUnlink)
(void) unlink(nciop->path);
ncio_px_free(nciop);
return status;
}
static int
static int
ncio_spx_close(ncio *nciop, int doUnlink)
{
int status = ENOERR;