summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--release_docs/RELEASE.txt2
-rw-r--r--src/H5FO.c103
-rw-r--r--src/H5FOprivate.h9
-rw-r--r--src/H5Gent.c9
-rw-r--r--src/H5Gnode.c18
-rw-r--r--src/H5O.c163
-rw-r--r--test/unlink.c88
7 files changed, 274 insertions, 118 deletions
diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt
index a7f2c81..070007c 100644
--- a/release_docs/RELEASE.txt
+++ b/release_docs/RELEASE.txt
@@ -82,6 +82,8 @@ Bug Fixes since HDF5-1.6.2 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
- After compound datatype with variable-length string in the fields
diff --git a/src/H5FO.c b/src/H5FO.c
index efb5f65..7f34556 100644
--- a/src/H5FO.c
+++ b/src/H5FO.c
@@ -22,14 +22,16 @@
#define H5F_PACKAGE /*suppress error about including H5Fpkg */
+/* Pablo information */
+/* (Put before include files to avoid problems with inline functions) */
+#define PABLO_MASK H5FO_mask
+
#include "H5Eprivate.h" /* Error handling */
#include "H5Fpkg.h" /* File access */
#include "H5FLprivate.h" /* Free lists */
#include "H5FOprivate.h" /* File objects */
#include "H5Oprivate.h" /* Object headers */
-#define PABLO_MASK H5FO_mask
-
/* Interface initialization */
static int interface_initialize_g = 0;
#define INTERFACE_INIT NULL
@@ -67,11 +69,11 @@ H5FL_DEFINE_STATIC(H5FO_open_obj_t);
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
-H5FO_create(H5F_t *f)
+H5FO_create(const H5F_t *f)
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5FO_create,FAIL);
+ FUNC_ENTER_NOAPI(H5FO_create,FAIL)
/* Sanity check */
assert(f);
@@ -79,10 +81,10 @@ H5FO_create(H5F_t *f)
/* Create TBBT used to store open object info */
if((f->shared->open_objs=H5TB_fast_dmake(H5TB_FAST_HADDR_COMPARE))==NULL)
- HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to create open object TBBT");
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to create open object TBBT")
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5FO_create() */
@@ -113,7 +115,7 @@ H5FO_opened(const H5F_t *f, haddr_t addr)
H5FO_open_obj_t *open_obj; /* Information about open object */
hid_t ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5FO_opened,FAIL);
+ FUNC_ENTER_NOAPI(H5FO_opened,FAIL)
/* Sanity check */
assert(f);
@@ -132,7 +134,7 @@ H5FO_opened(const H5F_t *f, haddr_t addr)
ret_value=FAIL;
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5FO_opened() */
@@ -158,12 +160,12 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
-H5FO_insert(H5F_t *f, haddr_t addr, hid_t id)
+H5FO_insert(const H5F_t *f, haddr_t addr, hid_t id)
{
H5FO_open_obj_t *open_obj; /* Information about open object */
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5FO_insert,FAIL);
+ FUNC_ENTER_NOAPI(H5FO_insert,FAIL)
/* Sanity check */
assert(f);
@@ -174,7 +176,7 @@ H5FO_insert(H5F_t *f, haddr_t addr, hid_t id)
/* Allocate new opened object information structure */
if((open_obj=H5FL_MALLOC(H5FO_open_obj_t))==NULL)
- HGOTO_ERROR(H5E_CACHE,H5E_NOSPACE,FAIL,"memory allocation failed");
+ HGOTO_ERROR(H5E_CACHE,H5E_NOSPACE,FAIL,"memory allocation failed")
/* Assign information */
open_obj->addr=addr;
@@ -183,10 +185,10 @@ H5FO_insert(H5F_t *f, haddr_t addr, hid_t id)
/* Insert into TBBT */
if(H5TB_dins(f->shared->open_objs,open_obj,open_obj)==NULL)
- HGOTO_ERROR(H5E_CACHE,H5E_CANTINSERT,FAIL,"can't insert object into TBBT");
+ HGOTO_ERROR(H5E_CACHE,H5E_CANTINSERT,FAIL,"can't insert object into TBBT")
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5FO_insert() */
@@ -216,7 +218,7 @@ H5FO_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr)
H5FO_open_obj_t *open_obj; /* Information about open object */
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5FO_delete,FAIL);
+ FUNC_ENTER_NOAPI(H5FO_delete,FAIL)
/* Sanity check */
assert(f);
@@ -226,23 +228,23 @@ H5FO_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr)
/* Get the object node from the TBBT */
if((obj_node=H5TB_dfind(f->shared->open_objs,&addr,NULL))==NULL)
- HGOTO_ERROR(H5E_CACHE,H5E_NOTFOUND,FAIL,"can't locate object in TBBT");
+ HGOTO_ERROR(H5E_CACHE,H5E_NOTFOUND,FAIL,"can't locate object in TBBT")
/* Remove from TBBT */
if((open_obj=H5TB_rem(&f->shared->open_objs->root,obj_node,NULL))==NULL)
- HGOTO_ERROR(H5E_CACHE,H5E_CANTRELEASE,FAIL,"can't remove object from TBBT");
+ HGOTO_ERROR(H5E_CACHE,H5E_CANTRELEASE,FAIL,"can't remove object from TBBT")
/* Check if the object was deleted from the file */
if(open_obj->deleted) {
if(H5O_delete(f, dxpl_id, addr)<0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "can't delete object from file");
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "can't delete object from file")
} /* end if */
/* Release the object information */
H5FL_FREE(H5FO_open_obj_t,open_obj);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5FO_delete() */
@@ -262,19 +264,17 @@ 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 */
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5FO_mark,FAIL);
+ FUNC_ENTER_NOAPI(H5FO_mark,FAIL)
/* Sanity check */
assert(f);
@@ -286,18 +286,65 @@ 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;
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5FO_mark() */
/*--------------------------------------------------------------------------
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(H5FO_marked,FAIL)
+
+ /* 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 */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FO_marked() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
H5FO_dest
PURPOSE
Destroy an open object info set
@@ -315,11 +362,11 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
-H5FO_dest(H5F_t *f)
+H5FO_dest(const H5F_t *f)
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5FO_dest,FAIL);
+ FUNC_ENTER_NOAPI(H5FO_dest,FAIL)
/* Sanity check */
assert(f);
@@ -328,12 +375,12 @@ H5FO_dest(H5F_t *f)
/* Check if the object info set is empty */
if(H5TB_count(f->shared->open_objs)!=0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTRELEASE, FAIL, "objects still in open object info set");
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTRELEASE, FAIL, "objects still in open object info set")
/* Release the open object info set TBBT */
f->shared->open_objs=H5TB_dfree(f->shared->open_objs,NULL,NULL);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5FO_dest() */
diff --git a/src/H5FOprivate.h b/src/H5FOprivate.h
index f9780ae..7220b75 100644
--- a/src/H5FOprivate.h
+++ b/src/H5FOprivate.h
@@ -34,12 +34,13 @@ typedef H5TB_TREE H5FO_t; /* Currently, all open objects are stored in TBB
/* Macros */
/* Private routines */
-H5_DLL herr_t H5FO_create(H5F_t *f);
+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(H5F_t *f, haddr_t addr, hid_t id);
+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_dest(H5F_t *f);
+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 9596eb0..b050453 100644
--- a/src/H5Gent.c
+++ b/src/H5Gent.c
@@ -19,6 +19,10 @@
#define H5G_PACKAGE
#define H5F_PACKAGE /*suppress error about including H5Fpkg */
+/* Pablo information */
+/* (Put before include files to avoid problems with inline functions) */
+#define PABLO_MASK H5G_ent_mask
+
#include "H5private.h" /* Generic Functions */
#include "H5Eprivate.h" /* Error handling */
#include "H5Fpkg.h" /* File access */
@@ -26,7 +30,6 @@
#include "H5HLprivate.h" /* Local Heaps */
#include "H5MMprivate.h" /* Memory management */
-#define PABLO_MASK H5G_ent_mask
static int interface_initialize_g = 0;
#define INTERFACE_INIT NULL
@@ -497,12 +500,14 @@ 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)) {
lval = H5HL_peek (ent->file, dxpl_id, heap, ent->cache.slink.lval_offset);
HDfprintf (stream, "%*s%-*s %s\n", nested_indent, "", nested_fwidth,
"Link value:",
lval);
}
+ 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 5009b2c..851de13 100644
--- a/src/H5Gnode.c
+++ b/src/H5Gnode.c
@@ -1048,7 +1048,8 @@ H5G_node_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, void UNUSED *_lt_key,
if (H5G_node_create(f, dxpl_id, H5B_INS_FIRST, NULL, NULL, NULL,
new_node_p/*out*/)<0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, H5B_INS_ERROR, "unable to split symbol table node");
- if (NULL==(snrt=H5AC_find(f, dxpl_id, H5AC_SNODE, *new_node_p, NULL, NULL)))
+
+ if (NULL == (snrt = H5AC_protect(f, dxpl_id, H5AC_SNODE, *new_node_p, NULL, NULL)))
HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5B_INS_ERROR, "unable to split symbol table node");
HDmemcpy(snrt->entry, sn->entry + H5F_SYM_LEAF_K(f),
@@ -1078,7 +1079,6 @@ H5G_node_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, void UNUSED *_lt_key,
*rt_key_changed = TRUE;
}
}
-
} else {
/* Where to insert the new entry? */
ret_value = H5B_INS_NOOP;
@@ -1099,7 +1099,9 @@ H5G_node_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, void UNUSED *_lt_key,
insert_into->nsyms += 1;
done:
- if (sn && H5AC_unprotect(f, dxpl_id, H5AC_SNODE, addr, sn, FALSE) < 0 && ret_value!=H5B_INS_ERROR)
+ 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");
FUNC_LEAVE_NOAPI(ret_value);
@@ -1729,17 +1731,21 @@ H5G_node_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int indent,
fwidth = MAX(0, fwidth - 3);
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) &&
(s = H5HL_peek(f, dxpl_id, heap, sn->entry[i].name_off))) {
fprintf(stream, "%*s%-*s `%s'\n", indent, "", fwidth,
"Name:",
s);
}
+ 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);
}
- H5AC_unprotect(f, dxpl_id, H5AC_SNODE, addr, sn, FALSE);
-
done:
+ if (sn && H5AC_unprotect(f, dxpl_id, H5AC_SNODE, addr, sn, FALSE) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to release symbol table node");
+
FUNC_LEAVE_NOAPI(ret_value);
}
diff --git a/src/H5O.c b/src/H5O.c
index 42a97a6..b7ef425 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -28,23 +28,25 @@
#define H5F_PACKAGE /*suppress error about including H5Fpkg */
#define H5O_PACKAGE /*suppress error about including H5Opkg */
-#include "H5private.h"
-#include "H5ACprivate.h"
-#include "H5Eprivate.h"
-#include "H5Fpkg.h"
-#include "H5FLprivate.h" /*Free Lists */
-#include "H5Iprivate.h"
-#include "H5MFprivate.h"
-#include "H5MMprivate.h"
-#include "H5Opkg.h" /* Object header functions */
-#include "H5Pprivate.h"
+/* Pablo information */
+/* (Put before include files to avoid problems with inline functions) */
+#define PABLO_MASK H5O_mask
+
+#include "H5private.h" /* Generic Functions */
+#include "H5ACprivate.h" /* Metadata cache */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Fpkg.h" /* File access */
+#include "H5FLprivate.h" /* Free lists */
+#include "H5Iprivate.h" /* IDs */
+#include "H5MFprivate.h" /* File memory management */
+#include "H5MMprivate.h" /* Memory management */
+#include "H5Opkg.h" /* Object headers */
+#include "H5Pprivate.h" /* Property lists */
#ifdef H5_HAVE_GETTIMEOFDAY
#include <sys/time.h>
#endif /* H5_HAVE_GETTIMEOFDAY */
-#define PABLO_MASK H5O_mask
-
/* PRIVATE PROTOTYPES */
static herr_t H5O_init(H5F_t *f, hid_t dxpl_id, size_t size_hint,
H5G_entry_t *ent/*out*/, haddr_t header);
@@ -60,10 +62,10 @@ static herr_t H5O_share(H5F_t *f, hid_t dxpl_id, const H5O_class_t *type, const
H5HG_t *hobj/*out*/);
#endif /* NOT_YET */
static unsigned H5O_find_in_ohdr(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
- const H5O_class_t **type_p, int sequence);
+ const H5O_class_t **type_p, int sequence);
static int H5O_modify_real(H5G_entry_t *ent, const H5O_class_t *type,
int overwrite, unsigned flags, unsigned update_time, const void *mesg,
-hid_t dxpl_id);
+ hid_t dxpl_id);
static int H5O_append_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
const H5O_class_t *type, unsigned flags, const void *mesg);
static herr_t H5O_remove_real(H5G_entry_t *ent, const H5O_class_t *type,
@@ -140,13 +142,13 @@ static void *(*H5O_fast_g[H5G_NCACHED]) (const H5G_cache_t *,
/* Declare a free list to manage the H5O_t struct */
H5FL_DEFINE_STATIC(H5O_t);
-/* Declare a PQ free list to manage the H5O_mesg_t array information */
+/* Declare a free list to manage the H5O_mesg_t sequence information */
H5FL_SEQ_DEFINE_STATIC(H5O_mesg_t);
-/* Declare a PQ free list to manage the H5O_chunk_t array information */
+/* Declare a free list to manage the H5O_chunk_t sequence information */
H5FL_SEQ_DEFINE_STATIC(H5O_chunk_t);
-/* Declare a PQ free list to manage the chunk image information */
+/* Declare a free list to manage the chunk image information */
H5FL_BLK_DEFINE_STATIC(chunk_image);
/* Declare external the free list for time_t's */
@@ -231,7 +233,7 @@ H5O_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, H5G_entry_t *ent/*out*/)
/* initialize the object header */
if (H5O_init(f, dxpl_id, size_hint, ent, header) != SUCCEED)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to initialize object header");
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to initialize object header");
done:
FUNC_LEAVE_NOAPI(ret_value);
@@ -474,7 +476,6 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1,
unsigned chunkno;
haddr_t chunk_addr;
size_t chunk_size;
- H5O_cont_t *cont = NULL;
uint8_t flags;
FUNC_ENTER_NOAPI(H5O_load, NULL);
@@ -521,7 +522,6 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1,
/* read each chunk from disk */
while (H5F_addr_defined(chunk_addr)) {
-
/* increase chunk array size */
if (oh->nchunks >= oh->alloc_nchunks) {
unsigned na = oh->alloc_nchunks + H5O_NCHUNKS;
@@ -545,9 +545,7 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1,
HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "unable to read object header data");
/* load messages from this chunk */
- for (p = oh->chunk[chunkno].image;
- p < oh->chunk[chunkno].image + chunk_size;
- p += mesg_size) {
+ for (p = oh->chunk[chunkno].image; p < oh->chunk[chunkno].image + chunk_size; p += mesg_size) {
UINT16DECODE(p, id);
UINT16DECODE(p, mesg_size);
assert (mesg_size==H5O_ALIGN (mesg_size));
@@ -583,22 +581,21 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1,
oh->mesg[mesgno].chunkno = chunkno;
}
}
- assert(p == oh->chunk[chunkno].image + chunk_size);
-
- /* decode next object header continuation message */
- for (chunk_addr=HADDR_UNDEF;
- !H5F_addr_defined(chunk_addr) && curmesg < oh->nmesgs;
- curmesg++) {
- if (H5O_CONT_ID == oh->mesg[curmesg].type->id) {
- uint8_t *p2 = oh->mesg[curmesg].raw;
-
- cont = (H5O_CONT->decode) (f, dxpl_id, p2, NULL);
- oh->mesg[curmesg].native = cont;
- chunk_addr = cont->addr;
- chunk_size = cont->size;
- cont->chunkno = oh->nchunks; /*the next chunk to allocate */
- }
- }
+
+ assert(p == oh->chunk[chunkno].image + chunk_size);
+
+ /* decode next object header continuation message */
+ for (chunk_addr = HADDR_UNDEF; !H5F_addr_defined(chunk_addr) && curmesg < oh->nmesgs; ++curmesg) {
+ if (H5O_CONT_ID == oh->mesg[curmesg].type->id) {
+ H5O_cont_t *cont;
+
+ cont = (H5O_CONT->decode) (f, dxpl_id, oh->mesg[curmesg].raw, NULL);
+ oh->mesg[curmesg].native = cont;
+ chunk_addr = cont->addr;
+ chunk_size = cont->size;
+ cont->chunkno = oh->nchunks; /*the next chunk to allocate */
+ }
+ }
}
/* Set return value */
@@ -1190,7 +1187,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 {
@@ -1203,6 +1200,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.dirty = TRUE;
}
@@ -1211,7 +1218,7 @@ H5O_link(const H5G_entry_t *ent, int adjust, hid_t dxpl_id)
ret_value = oh->nlink;
done:
- if (oh && H5AC_unprotect(ent->file, dxpl_id, H5AC_OHDR, ent->header, oh, deleted) < 0 && ret_value>=0)
+ if (oh && H5AC_unprotect(ent->file, dxpl_id, H5AC_OHDR, ent->header, oh, deleted) < 0)
HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header");
FUNC_LEAVE_NOAPI(ret_value);
@@ -1298,18 +1305,21 @@ H5O_count_real (H5G_entry_t *ent, const H5O_class_t *type, hid_t dxpl_id)
assert (type);
/* Load the object header */
- if (NULL==(oh=H5AC_find(ent->file, dxpl_id, H5AC_OHDR, ent->header, NULL, NULL)))
+ if (NULL == (oh = H5AC_protect(ent->file, dxpl_id, H5AC_OHDR, ent->header, NULL, NULL)))
HGOTO_ERROR (H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header");
- for (u=acc=0; u<oh->nmesgs; u++) {
+ /* Loop over all messages, counting the ones of the type looked for */
+ for (u=acc=0; u<oh->nmesgs; u++)
if (oh->mesg[u].type==type)
acc++;
- }
/* Set return value */
ret_value=acc;
done:
+ if (oh && H5AC_unprotect(ent->file, dxpl_id, H5AC_OHDR, ent->header, oh, FALSE) != SUCCEED)
+ HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header");
+
FUNC_LEAVE_NOAPI(ret_value);
} /* end H5O_count_real() */
@@ -1397,7 +1407,7 @@ H5O_exists_real(H5G_entry_t *ent, const H5O_class_t *type, int sequence, hid_t d
assert(sequence>=0);
/* Load the object header */
- if (NULL==(oh=H5AC_find(ent->file, dxpl_id, H5AC_OHDR, ent->header, NULL, NULL)))
+ if (NULL == (oh = H5AC_protect(ent->file, dxpl_id, H5AC_OHDR, ent->header, NULL, NULL)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header");
/* Scan through the messages looking for the right one */
@@ -1412,6 +1422,9 @@ H5O_exists_real(H5G_entry_t *ent, const H5O_class_t *type, int sequence, hid_t d
ret_value=(sequence<0);
done:
+ if (oh && H5AC_unprotect(ent->file, dxpl_id, H5AC_OHDR, ent->header, oh, FALSE) != SUCCEED)
+ HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header");
+
FUNC_LEAVE_NOAPI(ret_value);
} /* end H5O_exists_real() */
@@ -1493,17 +1506,22 @@ done:
* Aug 6 1997
*
* Modifications:
- *
+ * Bill Wendling, 2003-09-30
+ * Protect the object header and pass it into the H5O_find_in_ohdr
+ * function. This is done because the H5O_find_in_ohdr used to
+ * protect the ohdr, find the message, and then unprotect it. This
+ * saves time and also helps the FPHDF5 stuff, where unprotecting
+ * actually destroys the object in the cache.
*-------------------------------------------------------------------------
*/
void *
H5O_read_real(H5G_entry_t *ent, const H5O_class_t *type, int sequence, void *mesg, hid_t dxpl_id)
{
- H5O_t *oh = NULL;
- int idx;
- H5G_cache_t *cache = NULL;
- H5G_type_t cache_type;
- void *ret_value = NULL;
+ H5O_t *oh = NULL;
+ int idx;
+ H5G_cache_t *cache = NULL;
+ H5G_type_t cache_type;
+ void *ret_value = NULL;
FUNC_ENTER_NOAPI_NOINIT(H5O_read_real);
@@ -1516,6 +1534,7 @@ H5O_read_real(H5G_entry_t *ent, const H5O_class_t *type, int sequence, void *mes
/* can we get it from the symbol table entry? */
cache = H5G_ent_cache(ent, &cache_type);
+
if (H5O_fast_g[cache_type]) {
ret_value = (H5O_fast_g[cache_type]) (cache, type, mesg);
if (ret_value)
@@ -1553,7 +1572,7 @@ H5O_read_real(H5G_entry_t *ent, const H5O_class_t *type, int sequence, void *mes
}
done:
- if (oh && H5AC_unprotect(ent->file, dxpl_id, H5AC_OHDR, ent->header, oh, FALSE) < 0 && ret_value!=NULL)
+ if (oh && H5AC_unprotect(ent->file, dxpl_id, H5AC_OHDR, ent->header, oh, FALSE) < 0)
HDONE_ERROR(H5E_OHDR, H5E_PROTECT, NULL, "unable to release object header");
FUNC_LEAVE_NOAPI(ret_value);
@@ -1563,25 +1582,27 @@ done:
/*-------------------------------------------------------------------------
* Function: H5O_find_in_ohdr
*
- * Purpose: Find a message in the object header without consulting
- * a symbol table entry.
+ * Purpose: Find a message in the object header without consulting
+ * a symbol table entry.
*
- * Return: Success: Index number of message.
+ * Return: Success: Index number of message.
+ * Failure: Negative
*
- * Failure: Negative
- *
- * Programmer: Robb Matzke
- * matzke@llnl.gov
- * Aug 6 1997
+ * Programmer: Robb Matzke
+ * matzke@llnl.gov
+ * Aug 6 1997
*
* Modifications:
- * Robb Matzke, 1999-07-28
- * The ADDR argument is passed by value.
+ * Robb Matzke, 1999-07-28
+ * The ADDR argument is passed by value.
+ *
+ * Bill Wendling, 2003-09-30
+ * Modified so that the object header needs to be AC_protected
+ * before calling this function.
*-------------------------------------------------------------------------
*/
static unsigned
-H5O_find_in_ohdr(H5F_t *f, hid_t dxpl_id, H5O_t *oh, const H5O_class_t **type_p,
- int sequence)
+H5O_find_in_ohdr(H5F_t *f, hid_t dxpl_id, H5O_t *oh, const H5O_class_t **type_p, int sequence)
{
unsigned u;
const H5O_class_t *type = NULL;
@@ -1601,6 +1622,7 @@ H5O_find_in_ohdr(H5F_t *f, hid_t dxpl_id, H5O_t *oh, const H5O_class_t **type_p,
if (--sequence < 0)
break;
}
+
if (sequence >= 0)
HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, UFAIL, "unable to find object header message");
@@ -1613,6 +1635,7 @@ H5O_find_in_ohdr(H5F_t *f, hid_t dxpl_id, H5O_t *oh, const H5O_class_t **type_p,
} else {
type = oh->mesg[u].type;
}
+
if (NULL == oh->mesg[u].native) {
assert(type->decode);
oh->mesg[u].native = (type->decode) (f, dxpl_id, oh->mesg[u].raw, NULL);
@@ -1820,7 +1843,7 @@ H5O_modify_real(H5G_entry_t *ent, const H5O_class_t *type, int overwrite,
ret_value = sequence;
done:
- if (oh && H5AC_unprotect(ent->file, dxpl_id, H5AC_OHDR, ent->header, oh, FALSE) < 0 && ret_value!=FAIL)
+ if (oh && H5AC_unprotect(ent->file, dxpl_id, H5AC_OHDR, ent->header, oh, FALSE) < 0)
HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header");
FUNC_LEAVE_NOAPI(ret_value);
@@ -1903,7 +1926,7 @@ H5O_unprotect(H5G_entry_t *ent, H5O_t *oh, hid_t dxpl_id)
assert(oh);
if (H5AC_unprotect(ent->file, dxpl_id, H5AC_OHDR, ent->header, oh, FALSE) < 0)
- HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header");
+ HGOTO_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header");
done:
FUNC_LEAVE_NOAPI(ret_value);
@@ -2243,7 +2266,7 @@ H5O_touch(H5G_entry_t *ent, hbool_t force, hid_t dxpl_id)
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to update object modificaton time");
done:
- if (oh && H5AC_unprotect(ent->file, dxpl_id, H5AC_OHDR, ent->header, oh, FALSE)<0 && ret_value>=0)
+ if (oh && H5AC_unprotect(ent->file, dxpl_id, H5AC_OHDR, ent->header, oh, FALSE)<0)
HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header");
FUNC_LEAVE_NOAPI(ret_value);
@@ -2495,7 +2518,7 @@ H5O_remove_real(H5G_entry_t *ent, const H5O_class_t *type, int sequence, hid_t d
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to remove constant message(s)");
done:
- if (oh && H5AC_unprotect(ent->file, dxpl_id, H5AC_OHDR, ent->header, oh, FALSE) < 0 && ret_value>=0)
+ if (oh && H5AC_unprotect(ent->file, dxpl_id, H5AC_OHDR, ent->header, oh, FALSE) < 0)
HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header");
FUNC_LEAVE_NOAPI(ret_value);
@@ -3135,7 +3158,7 @@ H5O_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr)
HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "can't delete object from file");
done:
- if (oh && H5AC_unprotect(f, dxpl_id, H5AC_OHDR, addr, oh, TRUE)<0 && ret_value>=0)
+ if (oh && H5AC_unprotect(f, dxpl_id, H5AC_OHDR, addr, oh, TRUE)<0)
HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header");
FUNC_LEAVE_NOAPI(ret_value);
@@ -3546,7 +3569,7 @@ H5O_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int f
HDfprintf(stream, "*** TOTAL SIZE DOES NOT MATCH ALLOCATED SIZE!\n");
done:
- if (oh && H5AC_unprotect(f, dxpl_id, H5AC_OHDR, addr, oh, FALSE) < 0 && ret_value>=0)
+ if (oh && H5AC_unprotect(f, dxpl_id, H5AC_OHDR, addr, oh, FALSE) < 0)
HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header");
FUNC_LEAVE_NOAPI(ret_value);
diff --git a/test/unlink.c b/test/unlink.c
index cf9b5c8..123847a 100644
--- a/test/unlink.c
+++ b/test/unlink.c
@@ -29,6 +29,7 @@ const char *FILENAME[] = {
"lunlink",
"filespace",
"slashes",
+ "resurrect",
NULL
};
@@ -1303,7 +1304,7 @@ static int test_create_unlink(const char *msg, hid_t fapl)
return 0;
error:
- return -1;
+ return 1;
} /* end test_create_unlink() */
@@ -1373,7 +1374,7 @@ test_link_slashes(void)
return 0;
error:
- return -1;
+ return 1;
} /* end test_link_slashes() */
@@ -1443,7 +1444,7 @@ test_unlink_slashes(void)
return 0;
error:
- return -1;
+ return 1;
} /* end test_unlink_slashes() */
/*
@@ -1532,7 +1533,7 @@ test_unlink_rightleaf(hid_t fid)
return 0;
error:
- return -1;
+ return 1;
} /* end test_unlink_rightleaf() */
@@ -1593,7 +1594,7 @@ test_unlink_rightnode(hid_t fid)
return 0;
error:
- return -1;
+ return 1;
} /* end test_unlink_rightnode() */
@@ -1797,11 +1798,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()
@@ -1872,11 +1942,14 @@ main(void)
nerrors += test_link_slashes();
nerrors += test_unlink_slashes();
-
+
/* Test specific B-tree removal issues */
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;
@@ -1890,4 +1963,3 @@ main(void)
error:
return 1;
}
-