summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2004-07-14 19:08:34 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2004-07-14 19:08:34 (GMT)
commit769ee96c1fd7cdcc4de2f2b1f36e943ebf9fff8b (patch)
treed17a58cc98b8789145de837650aaba38dd7af262
parentbc6ab7c0a6ff27d3d52707419385ccd0771ffa0c (diff)
downloadhdf5-769ee96c1fd7cdcc4de2f2b1f36e943ebf9fff8b.zip
hdf5-769ee96c1fd7cdcc4de2f2b1f36e943ebf9fff8b.tar.gz
hdf5-769ee96c1fd7cdcc4de2f2b1f36e943ebf9fff8b.tar.bz2
[svn-r8874] Purpose:
Bug fix Description: Correct problems with "resurrecting" a dataset in a file. (This occurs when a dataset which is open gets unlinked from the group hierarchy (making it "dead" and marked for deletion in the file) and then is re-linked to the group hierarchy). Note that the current solution applies only to datasets, further work will fix this for groups and named datatypes also. Also, fix the "debug" routines to be a little more helpful in certain situations. Additionally, fix a locking bug in the symbol table node splitting routine which could be [one of] the cause[s] of the file corruption in flexible parallel operation. Platforms tested: FreeBSD 4.10 (sleipnir) w/parallel h5committested
-rw-r--r--release_docs/RELEASE.txt2
-rw-r--r--src/H5FO.c52
-rw-r--r--src/H5FOprivate.h3
-rw-r--r--src/H5Gent.c4
-rw-r--r--src/H5Gnode.c14
-rw-r--r--src/H5O.c16
-rw-r--r--test/unlink.c86
7 files changed, 151 insertions, 26 deletions
diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt
index 1cd9edc..a0bbcd8 100644
--- a/release_docs/RELEASE.txt
+++ b/release_docs/RELEASE.txt
@@ -142,6 +142,8 @@ Bug Fixes since HDF5-1.6.0 release
Library
-------
+ - Fixed bug where "resurrecting" a dataset was failing.
+ QAK - 2004/07/14
- Fixed bug where incorrect data could be read from a chunked dataset
after it was extended. QAK - 2004/07/12
- Fixed failure to read data back from file of compound type with
diff --git a/src/H5FO.c b/src/H5FO.c
index 7cb5508..32b3706 100644
--- a/src/H5FO.c
+++ b/src/H5FO.c
@@ -259,13 +259,11 @@ done:
Mark an opened object for deletion from the file when it is closed.
GLOBAL VARIABLES
COMMENTS, BUGS, ASSUMPTIONS
- There is currently no way to "undelete" an opened object that is marked
- for deletion.
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
-H5FO_mark(const H5F_t *f, haddr_t addr)
+H5FO_mark(const H5F_t *f, haddr_t addr, hbool_t deleted)
{
H5TB_NODE *obj_node; /* TBBT node holding open object */
H5FO_open_obj_t *open_obj; /* Information about open object */
@@ -283,7 +281,7 @@ H5FO_mark(const H5F_t *f, haddr_t addr)
if((obj_node=H5TB_dfind(f->shared->open_objs,&addr,NULL))!=NULL) {
open_obj=H5TB_NODE_DATA(obj_node);
assert(open_obj);
- open_obj->deleted=1;
+ open_obj->deleted=deleted;
} /* end if */
else
ret_value=FAIL;
@@ -294,6 +292,52 @@ H5FO_mark(const H5F_t *f, haddr_t addr)
/*--------------------------------------------------------------------------
NAME
+ H5FO_marked
+ PURPOSE
+ Check if an object is marked to be deleted when it is closed
+ USAGE
+ htri_t H5FO_mark(f,addr)
+ const H5F_t *f; IN: File opened object is in
+ haddr_t addr; IN: Address of object to delete
+
+ RETURNS
+ Returns a TRUE/FALSE on success, negative on failure
+ DESCRIPTION
+ Checks if the object is currently in the "opened objects" tree and
+ whether its marks for deletion from the file when it is closed.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+htri_t
+H5FO_marked(const H5F_t *f, haddr_t addr)
+{
+ H5TB_NODE *obj_node; /* TBBT node holding open object */
+ H5FO_open_obj_t *open_obj; /* Information about open object */
+ htri_t ret_value=FAIL; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOFUNC(H5FO_marked)
+
+ /* Sanity check */
+ assert(f);
+ assert(f->shared);
+ assert(f->shared->open_objs);
+ assert(H5F_addr_defined(addr));
+
+ /* Get the object node from the TBBT */
+ if((obj_node=H5TB_dfind(f->shared->open_objs,&addr,NULL))!=NULL) {
+ open_obj=H5TB_NODE_DATA(obj_node);
+ assert(open_obj);
+ ret_value=open_obj->deleted;
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FO_marked() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
H5FO_dest
PURPOSE
Destroy an open object info set
diff --git a/src/H5FOprivate.h b/src/H5FOprivate.h
index 389f7ad..7220b75 100644
--- a/src/H5FOprivate.h
+++ b/src/H5FOprivate.h
@@ -38,7 +38,8 @@ H5_DLL herr_t H5FO_create(const H5F_t *f);
H5_DLL hid_t H5FO_opened(const H5F_t *f, haddr_t addr);
H5_DLL herr_t H5FO_insert(const H5F_t *f, haddr_t addr, hid_t id);
H5_DLL herr_t H5FO_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr);
-H5_DLL herr_t H5FO_mark(const H5F_t *f, haddr_t addr);
+H5_DLL herr_t H5FO_mark(const H5F_t *f, haddr_t addr, hbool_t deleted);
+H5_DLL htri_t H5FO_marked(const H5F_t *f, haddr_t addr);
H5_DLL herr_t H5FO_dest(const H5F_t *f);
#endif /* _H5FOprivate_H */
diff --git a/src/H5Gent.c b/src/H5Gent.c
index 6f206dd..4aaaf70 100644
--- a/src/H5Gent.c
+++ b/src/H5Gent.c
@@ -490,7 +490,7 @@ H5G_ent_debug(H5F_t UNUSED *f, hid_t dxpl_id, const H5G_entry_t *ent, FILE * str
HDfprintf (stream, "%*s%-*s %lu\n", nested_indent, "", nested_fwidth,
"Link value offset:",
(unsigned long)(ent->cache.slink.lval_offset));
- if (H5F_addr_defined(heap)) {
+ if (heap>0 && H5F_addr_defined(heap)) {
const H5HL_t *heap_ptr;
heap_ptr = H5HL_protect(ent->file, dxpl_id, heap);
@@ -500,6 +500,8 @@ H5G_ent_debug(H5F_t UNUSED *f, hid_t dxpl_id, const H5G_entry_t *ent, FILE * str
lval);
H5HL_unprotect(ent->file, dxpl_id, heap_ptr, heap);
}
+ else
+ HDfprintf(stream, "%*s%-*s\n", nested_indent, "", nested_fwidth, "Warning: Invalid heap address given, name not displayed!");
break;
default:
diff --git a/src/H5Gnode.c b/src/H5Gnode.c
index 279d9da..6743c7e 100644
--- a/src/H5Gnode.c
+++ b/src/H5Gnode.c
@@ -1163,13 +1163,6 @@ H5G_node_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, void UNUSED *_lt_key,
*rt_key_changed = TRUE;
}
}
-
- if (H5AC_unprotect(f, dxpl_id, H5AC_SNODE, *new_node_p, snrt, FALSE) != SUCCEED) {
- snrt = NULL;
- HGOTO_ERROR(H5E_SYM, H5E_PROTECT, H5B_INS_ERROR, "unable to release symbol table node");
- }
-
- snrt=NULL; /* Make certain future references will be caught */
} else {
/* Where to insert the new entry? */
ret_value = H5B_INS_NOOP;
@@ -1190,6 +1183,8 @@ H5G_node_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, void UNUSED *_lt_key,
insert_into->nsyms += 1;
done:
+ if (snrt && H5AC_unprotect(f, dxpl_id, H5AC_SNODE, *new_node_p, snrt, FALSE) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_PROTECT, H5B_INS_ERROR, "unable to release symbol table node");
if (sn && H5AC_unprotect(f, dxpl_id, H5AC_SNODE, addr, sn, FALSE) < 0)
HDONE_ERROR(H5E_SYM, H5E_PROTECT, H5B_INS_ERROR, "unable to release symbol table node");
@@ -1903,8 +1898,7 @@ H5G_node_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int indent,
for (i = 0; i < sn->nsyms; i++) {
fprintf(stream, "%*sSymbol %d:\n", indent - 3, "", i);
-
- if (H5F_addr_defined(heap)) {
+ if (heap>0 && H5F_addr_defined(heap)) {
if (NULL == (heap_ptr = H5HL_protect(f, dxpl_id, heap)))
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to protect symbol name");
@@ -1917,6 +1911,8 @@ H5G_node_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int indent,
HGOTO_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol name");
heap_ptr=NULL; s=NULL;
}
+ else
+ fprintf(stream, "%*s%-*s\n", indent, "", fwidth, "Warning: Invalid heap address given, name not displayed!");
H5G_ent_debug(f, dxpl_id, sn->entry + i, stream, indent, fwidth, heap);
}
diff --git a/src/H5O.c b/src/H5O.c
index 2b1eb15..f1b4a23 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -1243,7 +1243,7 @@ H5O_link(const H5G_entry_t *ent, int adjust, hid_t dxpl_id)
/* Check if the object is still open by the user */
if(H5FO_opened(ent->file,ent->header)>=0) {
/* Flag the object to be deleted when it's closed */
- if(H5FO_mark(ent->file,ent->header)<0)
+ if(H5FO_mark(ent->file,ent->header,TRUE)<0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "can't mark object for deletion");
} /* end if */
else {
@@ -1256,6 +1256,16 @@ H5O_link(const H5G_entry_t *ent, int adjust, hid_t dxpl_id)
} /* end else */
} /* end if */
} else if (adjust>0) {
+ /* A new object, or one that will be deleted */
+ if(oh->nlink==0) {
+ /* Check if the object is current open, but marked for deletion */
+ if(H5FO_marked(ent->file,ent->header)>0) {
+ /* Remove "delete me" flag on the object */
+ if(H5FO_mark(ent->file,ent->header,FALSE)<0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "can't mark object for deletion");
+ } /* end if */
+ } /* end if */
+
oh->nlink += adjust;
oh->cache_info.is_dirty = TRUE;
}
@@ -1974,8 +1984,6 @@ H5O_unprotect(H5G_entry_t *ent, H5O_t *oh, hid_t dxpl_id)
if (H5AC_unprotect(ent->file, dxpl_id, H5AC_OHDR, ent->header, oh, FALSE) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header");
- oh = NULL;
-
done:
FUNC_LEAVE_NOAPI(ret_value);
} /* end H5O_unprotect() */
@@ -2624,7 +2632,7 @@ H5O_alloc_extend_chunk(H5O_t *oh, unsigned chunkno, size_t size)
/* try to extend a null message */
for (idx=0; idx<oh->nmesgs; idx++) {
if (oh->mesg[idx].chunkno==chunkno) {
- if ( H5O_NULL_ID == oh->mesg[idx].type->id &&
+ if (H5O_NULL_ID == oh->mesg[idx].type->id &&
(oh->mesg[idx].raw + oh->mesg[idx].raw_size ==
oh->chunk[chunkno].image + oh->chunk[chunkno].size)) {
diff --git a/test/unlink.c b/test/unlink.c
index 80ccd59..9f8e5b2 100644
--- a/test/unlink.c
+++ b/test/unlink.c
@@ -29,6 +29,7 @@ const char *FILENAME[] = {
"lunlink",
"filespace",
"slashes",
+ "resurrect",
NULL
};
@@ -1298,7 +1299,7 @@ static int test_create_unlink(const char *msg, hid_t fapl)
return 0;
error:
- return -1;
+ return 1;
} /* end test_create_unlink() */
@@ -1368,7 +1369,7 @@ test_link_slashes(void)
return 0;
error:
- return -1;
+ return 1;
} /* end test_link_slashes() */
@@ -1438,7 +1439,7 @@ test_unlink_slashes(void)
return 0;
error:
- return -1;
+ return 1;
} /* end test_unlink_slashes() */
/*
@@ -1527,7 +1528,7 @@ test_unlink_rightleaf(hid_t fid)
return 0;
error:
- return -1;
+ return 1;
} /* end test_unlink_rightleaf() */
@@ -1588,7 +1589,7 @@ test_unlink_rightnode(hid_t fid)
return 0;
error:
- return -1;
+ return 1;
} /* end test_unlink_rightnode() */
@@ -1792,11 +1793,80 @@ test_unlink_middlenode(hid_t fid)
return 0;
error:
- return -1;
+ return 1;
} /* end test_unlink_middlenode() */
/*-------------------------------------------------------------------------
+ * Function: test_resurrect_dataset
+ *
+ * Purpose: Tests deleting a dataset while its still open and then
+ * "resurrecting" it by creating a link to it again.
+ *
+ * Return: Success: 0
+ * Failure: number of errors
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, July 14, 2004
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_resurrect_dataset(void)
+{
+ hid_t f, s, d, fapl;
+ char filename[1024];
+
+ TESTING("Resurrecting dataset after deletion");
+
+ /* Create file */
+ fapl = h5_fileaccess();
+ h5_fixname(FILENAME[6], fapl, filename, sizeof filename);
+
+ /* Create the file */
+ if((f = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Create a dataset in the file */
+ if((s = H5Screate(H5S_SCALAR))<0) TEST_ERROR;
+ if((d = H5Dcreate(f, DATASETNAME, H5T_NATIVE_INT, s, H5P_DEFAULT))<0) TEST_ERROR;
+ if(H5Sclose(s)<0) TEST_ERROR;
+
+ /* Unlink the dataset while it's open (will mark it for deletion when closed) */
+ if(H5Gunlink(f, DATASETNAME)<0) TEST_ERROR;
+
+ /* Re-link the dataset to the group hierarchy (shouldn't get deleted now) */
+ if(H5Glink2(d, ".", H5G_LINK_HARD, f, DATASET2NAME)<0) TEST_ERROR;
+
+ /* Close things */
+ if(H5Dclose(d)<0) TEST_ERROR;
+ if(H5Fclose(f)<0) TEST_ERROR;
+
+ /* Re-open the file */
+ if((f=H5Fopen(filename, H5F_ACC_RDONLY, fapl))<0) TEST_ERROR;
+
+ /* Attempt to open the dataset under the new name */
+ if((d=H5Dopen(f,DATASET2NAME))<0) TEST_ERROR;
+
+ /* Close things */
+ if(H5Dclose(d)<0) TEST_ERROR;
+ if(H5Fclose(f)<0) TEST_ERROR;
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Sclose(s);
+ H5Dclose(d);
+ H5Fclose(f);
+ } H5E_END_TRY;
+ return 1;
+} /* end test_resurrect_dataset() */
+
+
+/*-------------------------------------------------------------------------
* Function: main
*
* Purpose: Test H5Gunlink()
@@ -1868,6 +1938,9 @@ main(void)
nerrors += test_unlink_rightleaf(file);
nerrors += test_unlink_rightnode(file);
nerrors += test_unlink_middlenode(file);
+
+ /* Test "resurrecting" objects */
+ nerrors += test_resurrect_dataset();
/* Close */
if (H5Fclose(file)<0) TEST_ERROR;
@@ -1881,4 +1954,3 @@ main(void)
error:
return 1;
}
-