summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorNeil Fortner <nfortne2@hdfgroup.org>2010-03-09 18:19:42 (GMT)
committerNeil Fortner <nfortne2@hdfgroup.org>2010-03-09 18:19:42 (GMT)
commit2ece0d878a28544a30dbbdce879fc4cc3ef58e6f (patch)
tree0bf248bd535bead2288ee24b4ccebc268f2f3b2d /src
parentf139fe1c2dd6ae09e4d289b4a481f9da9fee1e2f (diff)
downloadhdf5-2ece0d878a28544a30dbbdce879fc4cc3ef58e6f.zip
hdf5-2ece0d878a28544a30dbbdce879fc4cc3ef58e6f.tar.gz
hdf5-2ece0d878a28544a30dbbdce879fc4cc3ef58e6f.tar.bz2
[svn-r18395] Purpose: Fix links.c failure
Description: The core file driver previously matched files only based on the name used to open them, even when a backing store is used. This caused problems in the failing test when it traversed an external link to itself, and did not recognize that it was the same file. Similar tests in links.c were skipped when the core file driver was used. The failure was previously masked by inappropriate file flushes caused by external link traversal. Added code to the core file driver to keep track of low level file information of the backings store to allow for accurate recognition of duplicate files. Also re-enabled all links.c tests for the core file driver. Tested: Fedora (core and sec2 drivers; no time for full commit test, will monitor daily tests)
Diffstat (limited to 'src')
-rw-r--r--src/H5FDcore.c125
1 files changed, 107 insertions, 18 deletions
diff --git a/src/H5FDcore.c b/src/H5FDcore.c
index 1333995..3a56524 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? */
} H5FD_core_t;
@@ -391,6 +416,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;
@@ -415,11 +444,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 */
@@ -439,13 +471,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 */
@@ -529,6 +579,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.
*
*-------------------------------------------------------------------------
*/
@@ -537,28 +592,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() */
/*-------------------------------------------------------------------------