summaryrefslogtreecommitdiffstats
path: root/src/H5Fsec2.c
diff options
context:
space:
mode:
authorRobb Matzke <matzke@llnl.gov>1998-02-19 18:19:48 (GMT)
committerRobb Matzke <matzke@llnl.gov>1998-02-19 18:19:48 (GMT)
commitb24130dcf051e6f569612c0a9b13d2168c6213c0 (patch)
tree607e5fc4db5da70f6584c9567f28ef9b88faeae1 /src/H5Fsec2.c
parent5b8d25d3c6db32d04213978500dca99dd1794d77 (diff)
downloadhdf5-b24130dcf051e6f569612c0a9b13d2168c6213c0.zip
hdf5-b24130dcf051e6f569612c0a9b13d2168c6213c0.tar.gz
hdf5-b24130dcf051e6f569612c0a9b13d2168c6213c0.tar.bz2
[svn-r290] Changes since 19980206
---------------------- ./configure.in ./src/H5Fprivate.h ./src/H5Fsec2.c We now detect and use lseek64() on systems that have it (e.g., Irix64) and are able to generate >2GB files on Irix XFS file systems (and anything else that supports large files). This change also removed some warning messages from the Irix `-64' compiler. > $ ls -l istore.h5 > -rw-r--r-- 1 matzke meshtv 8605436856 Feb 17 14:03 istore.h5 ./configure.in ./src/H5Fprivate.h ./src/H5Fstdio.h We now detect and use fseek64() on systems that have it (e.g., Irix64) and are able to generate >2GB files on Irix XFS file systems (and anything else that supports large files). This change also removed some warning messages from the Iris `-64' compiler. ./src/H5E.c ./src/H5Epublic.h Added the H5E_OVERFLOW error to signal file address overflow. ./src/H5Fpublic.h ./examples/h5_chunk_read.c ./examples/h5_compound.c ./examples/h5_extend_write.c ./examples/h5_group.c ./examples/h5_read.c ./examples/h5_write.c ./html/Datasets.html ./html/Files.html ./html/H5.api.html ./html/H5.intro.html ./html/H5.sample_code.html ./html/ph5example.c ./html/review1.html ./test/cmpd_dset.c ./test/dsets.c ./test/extend.c ./test/tfile.c ./test/th5p.c ./test/theap.c ./test/tohdr.c ./test/tstab.c ./testpar/phdf5.c Renamed file access constants to follow the naming scheme. Also changed the base names a little to be more accurate as to what they do. The old names H5ACC_WRITE and H5ACC_OVERWRITE will temporarily work. H5ACC_DEFAULT --> H5F_ACC_RDONLY for H5Fopen() H5ACC_DEFAULT --> H5F_ACC_EXCL for H5Fcreate() H5ACC_WRITE --> H5F_ACC_RDWR H5ACC_OVERWRITE --> H5F_ACC_TRUNC Albert or Kim: The H5ACC_INDEPENDENT and H5ACC_COLLECTIVE macros in H5Fpublic.h should be an enum typedef and have names more like H5F_MPIO_INDEPENDENT and H5F_MPIO_COLLECTIVE. Also change the access_mode argument of H5Cset_mpio(). H5Fcreate() and H5Fopen() are more strict now about which flags are acceptable for the operation. ./src/H5Fprivate.h ./src/H5F.c ./src/H5C.c Changed the file access template to make it more general. A union contains a struct for each type of low-level driver and the default template is initialized at run-time. ./src/H5Fpublic.h ./src/H5F.c Added H5Fget_access_template() and cleaned up H5Fget_create_template(). ./src/H5C.c The H5Cset_mpi() no longer trashes the file access template when an error is detected. We check for errors and *then* update the file access template. Added H5C_close() so Albert and Kim have a place to release the MPI communicator and info from the file access property list. Kim or Albert: I notice in H5Cset_mpi() you copy the MPI communicator. Do you need to do something similar in H5C_copy()? ./src/H5F.c Added more error checking for the file creation and access property lists because it used to be possible to make the library dump core by swapping the creation and access property list ID numbers of H5Fcreate(). ./test/istore.c ./test/tfile.c ./test/th5p.c ./test/theap.c ./test/tohdr.c ./test/tstab.c ./testpar/testphdf5.c One must pass H5C_DEFAULT as the file creation or access property list in order to get the default property list. It is no longer possible to pass zero or any other arbitrary bad object ID. ./src/H5Fcore.c ./src/H5Ffamly.c ./src/H5Flow.c ./src/H5Fmpio.c ./src/H5Fsec2.c ./src/H5Fsplit.c ./src/H5Fstdio.c ./src/H5MF.c The file access property list is passed to all H5F_low_...() functions and to the drivers. ./src/H5Fcore.c The block size can be set at run time on a per-file basis instead of at compile time across all files. The "5000 items in a group test" now takes 1.6 seconds. ./src/H5private.h Removed inclusion of mpi.h and mpio.h since they're included from H5public.h. ./src/H5Cpublic.h ./src/H5C.c Added H5Cset_stdio(), H5Cset_sec2(), H5Cset_core(), H5Cset_split(), and H5Cset_family() in addition to the H5Cset_mpio() that Kim and Albert already wrote. We still need the H5Cget_driver() and an H5Cget...() counterpart for each of those functions. The split and family drivers still need a little work but I'm checking this in anyway.
Diffstat (limited to 'src/H5Fsec2.c')
-rw-r--r--src/H5Fsec2.c265
1 files changed, 151 insertions, 114 deletions
diff --git a/src/H5Fsec2.c b/src/H5Fsec2.c
index 5fb3b08..dd0ab0f 100644
--- a/src/H5Fsec2.c
+++ b/src/H5Fsec2.c
@@ -1,18 +1,18 @@
/*
* Copyright (C) 1997 NCSA
- * All rights reserved.
+ * All rights reserved.
*
* Programmer: Robb Matzke <matzke@llnl.gov>
- * Wednesday, October 22, 1997
+ * Wednesday, October 22, 1997
*
* Purpose: This is the Posix section-2 I/O subclass of H5Flow.
*
* Notes: This driver keeps track of its own file position in order to
- * minimize the number of calls to lseek(). We assume that
- * opening a file sets the current file position to the beginning
- * and that read() and write() modify the file position as
- * expected when they return successfully (unsuccessful return
- * leaves the file position undefined).
+ * minimize the number of calls to lseek(). We assume that
+ * opening a file sets the current file position to the beginning
+ * and that read() and write() modify the file position as
+ * expected when they return successfully (unsuccessful return
+ * leaves the file position undefined).
*/
#include <H5private.h>
#include <H5Eprivate.h>
@@ -22,66 +22,70 @@
#include <sys/types.h>
#include <sys/stat.h>
-#define PABLO_MASK H5F_sec2
-static hbool_t interface_initialize_g = FALSE;
-#define INTERFACE_INIT NULL
+#define PABLO_MASK H5F_sec2
+static hbool_t interface_initialize_g = FALSE;
+#define INTERFACE_INIT NULL
-static H5F_low_t *H5F_sec2_open(const char *name, uintn flags, H5F_search_t *);
-static herr_t H5F_sec2_close(H5F_low_t *lf);
-static herr_t H5F_sec2_read(H5F_low_t *lf, const haddr_t *addr, size_t size,
- uint8 *buf);
-static herr_t H5F_sec2_write(H5F_low_t *lf, const haddr_t *addr, size_t size,
- const uint8 *buf);
+static H5F_low_t *H5F_sec2_open(const char *name,
+ const H5F_access_t *access_parms, uintn flags,
+ H5F_search_t *key/*out*/);
+static herr_t H5F_sec2_close(H5F_low_t *lf, const H5F_access_t *access_parms);
+static herr_t H5F_sec2_read(H5F_low_t *lf, const H5F_access_t *access_parms,
+ const haddr_t *addr, size_t size,
+ uint8 *buf/*out*/);
+static herr_t H5F_sec2_write(H5F_low_t *lf, const H5F_access_t *access_parms,
+ const haddr_t *addr, size_t size,
+ const uint8 *buf);
+
+const H5F_low_class_t H5F_LOW_SEC2_g[1] = {{
+ NULL, /* access method */
+ H5F_sec2_open, /* open method */
+ H5F_sec2_close, /* close method */
+ H5F_sec2_read, /* read method */
+ H5F_sec2_write, /* write method */
+ NULL, /* flush method */
+ NULL, /* extend method */
+}};
-const H5F_low_class_t H5F_LOW_SEC2[1] =
-{
- {
- NULL, /* access method */
- H5F_sec2_open, /* open method */
- H5F_sec2_close, /* close method */
- H5F_sec2_read, /* read method */
- H5F_sec2_write, /* write method */
- NULL, /* flush method */
- NULL, /* extend method */
- }};
/*-------------------------------------------------------------------------
- * Function: H5F_sec2_open
+ * Function: H5F_sec2_open
*
- * Purpose: Opens a file with name NAME. The FLAGS are a bit field with
- * the possible values defined in H5F_low_open().
+ * Purpose: Opens a file with name NAME. The FLAGS are a bit field with
+ * the possible values defined in H5F_low_open().
*
* Errors:
- * IO CANTOPENFILE Open failed.
+ * IO CANTOPENFILE Open failed.
*
- * Return: Success: Low-level file pointer
+ * Return: Success: Low-level file pointer
*
- * Failure: NULL
+ * Failure: NULL
*
- * Programmer: Robb Matzke
- * Wednesday, October 22, 1997
+ * Programmer: Robb Matzke
+ * Wednesday, October 22, 1997
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
-static H5F_low_t *
-H5F_sec2_open(const char *name, uintn flags, H5F_search_t *key /*out */ )
+static H5F_low_t *
+H5F_sec2_open(const char *name, const H5F_access_t *access_parms, uintn flags,
+ H5F_search_t *key/*out*/)
{
- uintn oflags;
- H5F_low_t *lf = NULL;
- int fd;
- struct stat sb;
+ uintn oflags;
+ H5F_low_t *lf = NULL;
+ int fd;
+ struct stat sb;
FUNC_ENTER(H5F_sec2_open, NULL);
- oflags = (flags & H5F_ACC_WRITE) ? O_RDWR : O_RDONLY;
+ oflags = (flags & H5F_ACC_RDWR) ? O_RDWR : O_RDONLY;
oflags |= (flags & H5F_ACC_CREAT) ? O_CREAT : 0;
oflags |= (flags & H5F_ACC_EXCL) ? O_EXCL : 0;
oflags |= (flags & H5F_ACC_TRUNC) ? O_TRUNC : 0;
if ((fd = open(name, oflags, 0666)) < 0) {
- HRETURN_ERROR(H5E_IO, H5E_CANTOPENFILE, NULL, "open failed");
+ HRETURN_ERROR(H5E_IO, H5E_CANTOPENFILE, NULL, "open failed");
}
lf = H5MM_xcalloc(1, sizeof(H5F_low_t));
lf->u.sec2.fd = fd;
@@ -91,38 +95,38 @@ H5F_sec2_open(const char *name, uintn flags, H5F_search_t *key /*out */ )
lf->eof.offset = sb.st_size;
if (key) {
- key->dev = sb.st_dev;
- key->ino = sb.st_ino;
+ key->dev = sb.st_dev;
+ key->ino = sb.st_ino;
}
FUNC_LEAVE(lf);
}
/*-------------------------------------------------------------------------
- * Function: H5F_sec2_close
+ * Function: H5F_sec2_close
*
- * Purpose: Closes a file.
+ * Purpose: Closes a file.
*
* Errors:
- * IO CLOSEERROR Close failed.
+ * IO CLOSEERROR Close failed.
*
- * Return: Success: SUCCEED
+ * Return: Success: SUCCEED
*
- * Failure: FAIL
+ * Failure: FAIL
*
- * Programmer: Robb Matzke
- * Wednesday, October 22, 1997
+ * Programmer: Robb Matzke
+ * Wednesday, October 22, 1997
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static herr_t
-H5F_sec2_close(H5F_low_t *lf)
+H5F_sec2_close(H5F_low_t *lf, const H5F_access_t *access_parms)
{
FUNC_ENTER(H5F_sec2_close, FAIL);
if (close(lf->u.sec2.fd) < 0) {
- HRETURN_ERROR(H5E_IO, H5E_CLOSEERROR, FAIL, "close failed");
+ HRETURN_ERROR(H5E_IO, H5E_CLOSEERROR, FAIL, "close failed");
}
lf->u.sec2.fd = -1;
@@ -130,148 +134,181 @@ H5F_sec2_close(H5F_low_t *lf)
}
/*-------------------------------------------------------------------------
- * Function: H5F_sec2_read
+ * Function: H5F_sec2_read
*
- * Purpose: Reads SIZE bytes beginning at address ADDR in file LF and
- * places them in buffer BUF. Reading past the logical or
- * physical end of file returns zeros instead of failing.
+ * Purpose: Reads SIZE bytes beginning at address ADDR in file LF and
+ * places them in buffer BUF. Reading past the logical or
+ * physical end of file returns zeros instead of failing.
*
* Errors:
- * IO READERROR Read failed.
- * IO SEEKERROR Lseek failed.
+ * IO READERROR Read failed.
+ * IO SEEKERROR Lseek failed.
*
- * Return: Success: SUCCEED
+ * Return: Success: SUCCEED
*
- * Failure: FAIL
+ * Failure: FAIL
*
- * Programmer: Robb Matzke
- * Wednesday, October 22, 1997
+ * Programmer: Robb Matzke
+ * Wednesday, October 22, 1997
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static herr_t
-H5F_sec2_read(H5F_low_t *lf, const haddr_t *addr, size_t size, uint8 *buf)
+H5F_sec2_read(H5F_low_t *lf, const H5F_access_t *access_parms,
+ const haddr_t *addr, size_t size, uint8 *buf)
{
- ssize_t n;
- off_t offset;
+ ssize_t n;
+ uint64 mask;
+#ifdef HAVE_LSEEK64
+ off64_t offset;
+#else
+ off_t offset;
+#endif
FUNC_ENTER(H5F_sec2_read, FAIL);
/* Check for overflow */
- offset = addr->offset; /*FIX_ME*/
- assert("address overflowed" && offset == addr->offset);
- assert("overflow" && offset + size >= offset);
+ mask = (uint64)1 << (8*sizeof(offset)-1);
+ if (addr->offset >= mask ||
+ addr->offset+size < addr->offset ||
+ addr->offset+size >= mask) {
+ HRETURN_ERROR (H5E_IO, H5E_OVERFLOW, FAIL, "file address overflowed");
+ }
+#ifdef HAVE_LSEEK64
+ offset = (off64_t)(addr->offset); /*checked for overflow*/
+#else
+ offset = (off_t)(addr->offset); /*checked for overflow*/
+#endif
/* Check easy cases */
- if (0 == size)
- HRETURN(SUCCEED);
+ if (0 == size) HRETURN(SUCCEED);
if (offset >= lf->eof.offset) {
- HDmemset(buf, 0, size);
- HRETURN(SUCCEED);
+ HDmemset(buf, 0, size);
+ HRETURN(SUCCEED);
}
+
/*
* Optimize seeking. If that optimization is disabled then always call
* lseek().
*/
if (!H5F_OPT_SEEK ||
- lf->u.sec2.op == H5F_OP_UNKNOWN ||
- lf->u.sec2.cur != offset) {
- if (lseek(lf->u.sec2.fd, offset, SEEK_SET) < 0) {
- HRETURN_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "lseek failed");
- }
- lf->u.sec2.cur = offset;
+ lf->u.sec2.op == H5F_OP_UNKNOWN ||
+ lf->u.sec2.cur != offset) {
+ if (lseek(lf->u.sec2.fd, offset, SEEK_SET) < 0) {
+ HRETURN_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "lseek failed");
+ }
+ lf->u.sec2.cur = offset;
}
+
/*
* Read zeros past the logical end of file (physical is handled below)
*/
if ((size_t) offset + size > lf->eof.offset) {
- size_t nbytes = (size_t) offset + size - lf->eof.offset;
- HDmemset(buf + size - nbytes, 0, nbytes);
- size -= nbytes;
+ size_t nbytes = (size_t)offset + size - lf->eof.offset;
+ HDmemset(buf + size - nbytes, 0, nbytes);
+ size -= nbytes;
}
+
/*
* Read the data. If a read error occurs then set the last file operation
* to UNKNOWN because the file position isn't guaranteed by Posix.
*/
if ((n = read(lf->u.sec2.fd, buf, size)) < 0) {
- lf->u.sec2.op = H5F_OP_UNKNOWN;
- HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "read failed");
+ lf->u.sec2.op = H5F_OP_UNKNOWN;
+ HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "read failed");
} else if (n < size) {
- HDmemset(buf + n, 0, size - n);
+ HDmemset(buf + n, 0, size - n);
}
+
/*
- * Update the file position with the number of bytes actually read. This
+ * Update the file position with the number of bytes actually read. This
* might be different than the number requested.
*/
lf->u.sec2.op = H5F_OP_READ;
lf->u.sec2.cur = offset + n;
- assert("address overflowed" && lf->u.sec2.cur >= offset);
FUNC_LEAVE(SUCCEED);
}
/*-------------------------------------------------------------------------
- * Function: H5F_sec2_write
+ * Function: H5F_sec2_write
*
- * Purpose: Writes SIZE bytes from the beginning of BUF into file LF at
- * file address ADDR.
+ * Purpose: Writes SIZE bytes from the beginning of BUF into file LF at
+ * file address ADDR.
*
* Errors:
- * IO SEEKERROR Lseek failed.
- * IO WRITEERROR Write failed.
+ * IO SEEKERROR Lseek failed.
+ * IO WRITEERROR Write failed.
*
- * Return: Success: SUCCEED
+ * Return: Success: SUCCEED
*
- * Failure: FAIL
+ * Failure: FAIL
*
- * Programmer: Robb Matzke
- * Wednesday, October 22, 1997
+ * Programmer: Robb Matzke
+ * Wednesday, October 22, 1997
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static herr_t
-H5F_sec2_write(H5F_low_t *lf, const haddr_t *addr, size_t size,
- const uint8 *buf)
+H5F_sec2_write(H5F_low_t *lf, const H5F_access_t *access_parms,
+ const haddr_t *addr, size_t size, const uint8 *buf)
{
- off_t offset;
+ uint64 mask;
+ ssize_t n;
+#ifdef HAVE_LSEEK64
+ off64_t offset;
+#else
+ off_t offset;
+#endif
FUNC_ENTER(H5F_sec2_write, FAIL);
/* Check for overflow */
- offset = addr->offset; /*FIX_ME*/
- assert("address overflowed" && offset == addr->offset);
- assert("overflow" && offset + size >= offset);
+ mask = (uint64)1 << (8*sizeof(offset)-1);
+ if (addr->offset >= mask ||
+ addr->offset+size < addr->offset ||
+ addr->offset+size >= mask) {
+ HRETURN_ERROR (H5E_IO, H5E_OVERFLOW, FAIL, "file address overflowed");
+ }
+#ifdef HAVE_LSEEK64
+ offset = (off64_t)(addr->offset); /*checked for overflow*/
+ n = (off64_t)size; /*checked for overflow*/
+#else
+ offset = (off_t)(addr->offset); /*checked for overflow*/
+ n = (off_t)size; /*checked for overflow*/
+#endif
/*
* Optimize seeking. If that optimization is disabled then always call
* lseek().
*/
if (!H5F_OPT_SEEK ||
- lf->u.sec2.op == H5F_OP_UNKNOWN ||
- lf->u.sec2.cur != offset) {
- if (lseek(lf->u.sec2.fd, offset, SEEK_SET) < 0) {
- HRETURN_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "lseek failed");
- }
- lf->u.sec2.cur = offset;
+ lf->u.sec2.op == H5F_OP_UNKNOWN ||
+ lf->u.sec2.cur != offset) {
+ if (lseek(lf->u.sec2.fd, offset, SEEK_SET) < 0) {
+ HRETURN_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "lseek failed");
+ }
+ lf->u.sec2.cur = offset;
}
+
/*
* Write the data to the file. If the write failed then set the
* operation back to UNKNOWN since Posix doesn't gurantee its value.
*/
- if (size != write(lf->u.sec2.fd, buf, size)) {
- lf->u.sec2.op = H5F_OP_UNKNOWN;
- HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "write failed");
+ if (n != write(lf->u.sec2.fd, buf, size)) {
+ lf->u.sec2.op = H5F_OP_UNKNOWN;
+ HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "write failed");
}
+
/*
* Update the file position.
*/
lf->u.sec2.op = H5F_OP_WRITE;
- lf->u.sec2.cur = offset + size; /*FIX_ME*/
- assert("address overflowed" && lf->u.sec2.cur >= offset);
+ lf->u.sec2.cur = offset + n;
FUNC_LEAVE(SUCCEED);
}