summaryrefslogtreecommitdiffstats
path: root/src/H5FDcore.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2010-03-25 03:51:41 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2010-03-25 03:51:41 (GMT)
commit42efc1c2b591e4cd45ec6cb3bdf32044343118d2 (patch)
tree0ab542871c32246199479e8933ff26286aaf629a /src/H5FDcore.c
parent3360c3af0c100ac4d3a2fe2865f34661da862ec5 (diff)
downloadhdf5-42efc1c2b591e4cd45ec6cb3bdf32044343118d2.zip
hdf5-42efc1c2b591e4cd45ec6cb3bdf32044343118d2.tar.gz
hdf5-42efc1c2b591e4cd45ec6cb3bdf32044343118d2.tar.bz2
[svn-r18451] Description:
Bring r18172:18446 from trunk to revise_chunks branch. Tested on: FreeBSD/32 6.3 (duty) in debug mode FreeBSD/64 6.3 (liberty) w/C++ & FORTRAN, in debug mode Linux/32 2.6 (jam) w/PGI compilers, w/default API=1.8.x, w/C++ & FORTRAN, w/threadsafe, in debug mode Linux/64-amd64 2.6 (amani) w/Intel compilers, w/default API=1.6.x, w/C++ & FORTRAN, in production mode Solaris/32 2.10 (linew) w/deprecated symbols disabled, w/C++ & FORTRAN, w/szip filter, in production mode Linux/64-ia64 2.6 (cobalt) w/Intel compilers, w/C++ & FORTRAN, in production mode Linux/64-ia64 2.4 (tg-login3) w/parallel, w/FORTRAN, in debug mode Linux/64-amd64 2.6 (abe) w/parallel, w/FORTRAN, in production mode
Diffstat (limited to 'src/H5FDcore.c')
-rw-r--r--src/H5FDcore.c125
1 files changed, 107 insertions, 18 deletions
diff --git a/src/H5FDcore.c b/src/H5FDcore.c
index 7324afb..f91c6b5 100644
--- a/src/H5FDcore.c
+++ b/src/H5FDcore.c
@@ -52,6 +52,31 @@ typedef struct H5FD_core_t {
size_t increment; /*multiples for mem allocation */
hbool_t backing_store; /*write to file name on flush */
int fd; /*backing store file descriptor */
+ /* Information for determining uniqueness of a file with a backing store */
+#ifndef _WIN32
+ /*
+ * On most systems the combination of device and i-node number uniquely
+ * identify a file.
+ */
+ dev_t device; /*file device number */
+#ifdef H5_VMS
+ ino_t inode[3]; /*file i-node number */
+#else
+ ino_t inode; /*file i-node number */
+#endif /*H5_VMS*/
+#else
+ /*
+ * On _WIN32 the low-order word of a unique identifier associated with the
+ * file and the volume serial number uniquely identify a file. This number
+ * (which, both? -rpm) may change when the system is restarted or when the
+ * file is opened. After a process opens a file, the identifier is
+ * constant until the file is closed. An application can use this
+ * identifier and the volume serial number to determine whether two
+ * handles refer to the same file.
+ */
+ DWORD fileindexlo;
+ DWORD fileindexhi;
+#endif
hbool_t dirty; /*changes not saved? */
/* Information from file open flags, for SWMR access */
@@ -394,6 +419,10 @@ H5FD_core_open(const char *name, unsigned flags, hid_t fapl_id,
H5FD_core_t *file=NULL;
H5FD_core_fapl_t *fa=NULL;
H5P_genplist_t *plist; /* Property list pointer */
+#ifdef _WIN32
+ HFILE filehandle;
+ struct _BY_HANDLE_FILE_INFORMATION fileinfo;
+#endif
h5_stat_t sb;
int fd=-1;
H5FD_t *ret_value;
@@ -418,11 +447,14 @@ H5FD_core_open(const char *name, unsigned flags, hid_t fapl_id,
if(H5F_ACC_CREAT & flags) o_flags |= O_CREAT;
if(H5F_ACC_EXCL & flags) o_flags |= O_EXCL;
- /* Open backing store. The only case that backing store is off is when
- * the backing_store flag is off and H5F_ACC_CREAT is on. */
+ /* Open backing store, and get stat() from file. The only case that backing
+ * store is off is when the backing_store flag is off and H5F_ACC_CREAT is
+ * on. */
if(fa->backing_store || !(H5F_ACC_CREAT & flags)) {
if(fa && (fd = HDopen(name, o_flags, 0666)) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file")
+ if(HDfstat(fd, &sb) < 0)
+ HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, NULL, "unable to fstat file")
} /* end if */
/* Create the new file struct */
@@ -442,13 +474,31 @@ H5FD_core_open(const char *name, unsigned flags, hid_t fapl_id,
/* If save data in backing store. */
file->backing_store = fa->backing_store;
+ if(fd >= 0) {
+ /* Retrieve information for determining uniqueness of file */
+#ifdef _WIN32
+ filehandle = _get_osfhandle(fd);
+ (void)GetFileInformationByHandle((HANDLE)filehandle, &fileinfo);
+ file->fileindexhi = fileinfo.nFileIndexHigh;
+ file->fileindexlo = fileinfo.nFileIndexLow;
+#else /* _WIN32 */
+ file->device = sb.st_dev;
+#ifdef H5_VMS
+ file->inode[0] = sb.st_ino[0];
+ file->inode[1] = sb.st_ino[1];
+ file->inode[2] = sb.st_ino[2];
+#else
+ file->inode = sb.st_ino;
+#endif /* H5_VMS */
+
+#endif /* _WIN32 */
+ } /* end if */
+
/* If an existing file is opened, load the whole file into memory. */
if(!(H5F_ACC_CREAT & flags)) {
size_t size;
- /* stat() file to retrieve its size */
- if(HDfstat(file->fd, &sb) < 0)
- HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, NULL, "unable to fstat file")
+ /* Retrieve file size */
size = (size_t)sb.st_size;
/* Check if we should allocate the memory buffer and read in existing data */
@@ -536,6 +586,11 @@ done:
* Thursday, July 29, 1999
*
* Modifications:
+ * Neil Fortner
+ * Tuesday, March 9, 2010
+ * Modified function to compare low level file information if
+ * a backing store is opened for both files, similar to the
+ * sec2 file driver.
*
*-------------------------------------------------------------------------
*/
@@ -544,28 +599,62 @@ H5FD_core_cmp(const H5FD_t *_f1, const H5FD_t *_f2)
{
const H5FD_core_t *f1 = (const H5FD_core_t*)_f1;
const H5FD_core_t *f2 = (const H5FD_core_t*)_f2;
- int ret_value;
+ int ret_value = 0;
FUNC_ENTER_NOAPI(H5FD_core_cmp, FAIL)
- if (NULL==f1->name && NULL==f2->name) {
- if (f1<f2)
+ if(f1->fd >= 0 && f2->fd >= 0) {
+ /* Compare low level file information for backing store */
+#ifdef _WIN32
+ if (f1->fileindexhi < f2->fileindexhi) HGOTO_DONE(-1)
+ if (f1->fileindexhi > f2->fileindexhi) HGOTO_DONE(1)
+
+ if (f1->fileindexlo < f2->fileindexlo) HGOTO_DONE(-1)
+ if (f1->fileindexlo > f2->fileindexlo) HGOTO_DONE(1)
+
+#else
+#ifdef H5_DEV_T_IS_SCALAR
+ if (f1->device < f2->device) HGOTO_DONE(-1)
+ if (f1->device > f2->device) HGOTO_DONE(1)
+#else /* H5_DEV_T_IS_SCALAR */
+ /* If dev_t isn't a scalar value on this system, just use memcmp to
+ * determine if the values are the same or not. The actual return value
+ * shouldn't really matter...
+ */
+ if(HDmemcmp(&(f1->device),&(f2->device),sizeof(dev_t))<0) HGOTO_DONE(-1)
+ if(HDmemcmp(&(f1->device),&(f2->device),sizeof(dev_t))>0) HGOTO_DONE(1)
+#endif /* H5_DEV_T_IS_SCALAR */
+
+#ifndef H5_VMS
+ if (f1->inode < f2->inode) HGOTO_DONE(-1)
+ if (f1->inode > f2->inode) HGOTO_DONE(1)
+#else
+ if(HDmemcmp(&(f1->inode),&(f2->inode),3*sizeof(ino_t))<0) HGOTO_DONE(-1)
+ if(HDmemcmp(&(f1->inode),&(f2->inode),3*sizeof(ino_t))>0) HGOTO_DONE(1)
+#endif /* H5_VMS */
+
+#endif /*_WIN32*/
+ } /* end if */
+ else {
+ if (NULL==f1->name && NULL==f2->name) {
+ if (f1<f2)
+ HGOTO_DONE(-1)
+ if (f1>f2)
+ HGOTO_DONE(1)
+ HGOTO_DONE(0)
+ } /* end if */
+
+ if (NULL==f1->name)
HGOTO_DONE(-1)
- if (f1>f2)
+ if (NULL==f2->name)
HGOTO_DONE(1)
- HGOTO_DONE(0)
- }
- if (NULL==f1->name)
- HGOTO_DONE(-1)
- if (NULL==f2->name)
- HGOTO_DONE(1)
-
- ret_value = HDstrcmp(f1->name, f2->name);
+ ret_value = HDstrcmp(f1->name, f2->name);
+ } /* end else */
done:
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5FD_core_cmp() */
/*-------------------------------------------------------------------------