summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--release_docs/RELEASE.txt10
-rw-r--r--src/H5Oattribute.c9
-rw-r--r--test/tattr.c94
3 files changed, 110 insertions, 3 deletions
diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt
index 34d90ff..1976ed6 100644
--- a/release_docs/RELEASE.txt
+++ b/release_docs/RELEASE.txt
@@ -110,6 +110,16 @@ Bug Fixes since HDF5-1.10.2 release
Library
-------
+ - H5Adelete
+
+ H5Adelete failed when deleting the last "large" attribute that
+ is stored densely via fractal heap/v2 b-tree.
+
+ After removing the attribute, update the ainfo message. If the
+ number of attributes goes to zero, remove the message.
+
+ (VC - 2018/07/20, HDFFV-9277)
+
- Error checks in h5stat and when decoding messages
h5stat exited with seg fault/core dumped when
diff --git a/src/H5Oattribute.c b/src/H5Oattribute.c
index e8a8433..640d1c7 100644
--- a/src/H5Oattribute.c
+++ b/src/H5Oattribute.c
@@ -1448,6 +1448,12 @@ H5O_attr_remove_update(const H5O_loc_t *loc, H5O_t *oh, H5O_ainfo_t *ainfo)
} /* end if */
} /* end if */
+ /* Update the message after removing the attribute */
+ /* This is particularly needed when removing the last attribute that is
+ accessed via fractal heap/v2 B-tree (HDFFV-9277) */
+ if(H5O__msg_write_real(loc->file, oh, H5O_MSG_AINFO, H5O_MSG_FLAG_DONTSHARE, 0, ainfo) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTUPDATE, FAIL, "unable to update attribute info message")
+
/* Check if we have deleted all the attributes and the attribute info
* message should be deleted itself.
*/
@@ -1455,9 +1461,6 @@ H5O_attr_remove_update(const H5O_loc_t *loc, H5O_t *oh, H5O_ainfo_t *ainfo)
if(H5O__msg_remove_real(loc->file, oh, H5O_MSG_AINFO, H5O_ALL, NULL, NULL, TRUE) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute info")
} /* end if */
- else
- if(H5O__msg_write_real(loc->file, oh, H5O_MSG_AINFO, H5O_MSG_FLAG_DONTSHARE, 0, ainfo) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTUPDATE, FAIL, "unable to update attribute info message")
done:
/* Release resources */
diff --git a/test/tattr.c b/test/tattr.c
index bf9ce96..4358d4c 100644
--- a/test/tattr.c
+++ b/test/tattr.c
@@ -136,6 +136,13 @@ float attr_data5=-5.123F; /* Test data for 5th attribute */
#define BUG3_DT_NAME "dt"
#define BUG3_ATTR_NAME "attr"
+/* Used by test_attr_delete_last_dense() */
+#define GRPNAME "grp"
+#define ATTRNAME "attr"
+#define DIM0 100
+#define DIM1 100
+#define RANK 2
+
/* Attribute iteration struct */
typedef struct {
H5_iter_order_t order; /* Direction of iteration */
@@ -10672,6 +10679,92 @@ test_attr_bug9(hid_t fcpl, hid_t fapl)
/****************************************************************
**
+** test_attr_delete_dense():
+** This is to verify the error as described in HDFFV-9277
+** is fixed when deleting the last "large" attribute that
+** is stored densely.
+**
+****************************************************************/
+static void
+test_attr_delete_last_dense(hid_t fcpl, hid_t fapl)
+{
+ hid_t fid; /* File ID */
+ hid_t gid; /* Group ID */
+ hid_t aid; /* Attribute ID */
+ hid_t sid; /* Dataspace ID */
+ hsize_t dim2[2] = {DIM0, DIM1}; /* Dimension sizes */
+ int i, j; /* Local index variables */
+ double *data = NULL; /* Pointer to the data buffer */
+ herr_t ret; /* Generic return status */
+
+ /* Output message about test being performed */
+ MESSAGE(5, ("Testing Deleting the last large attribute stored densely\n"));
+
+ /* Create the file */
+ fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl, fapl);
+ CHECK(fid, FAIL, "H5Fcreate");
+
+ /* Create the group */
+ gid = H5Gcreate2(fid, GRPNAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+ CHECK(gid, FAIL, "H5Gcreate");
+
+ /* Create the dataspace */
+ sid = H5Screate_simple(RANK, dim2, NULL);
+ CHECK(sid, FAIL, "H5Screate_simple");
+
+ /* Attach the attribute to the group */
+ aid = H5Acreate2(gid, ATTRNAME, H5T_IEEE_F64LE, sid, H5P_DEFAULT, H5P_DEFAULT);
+ CHECK(aid, FAIL, "H5Acreate2");
+
+ /* Allocate the data buffer */
+ data = (double *)HDmalloc((size_t)(DIM0 * DIM1) * sizeof(double));
+ CHECK_PTR(data, "HDmalloc");
+
+ /* Initialize the data */
+ for(i = 0; i < DIM0; i++)
+ for(j = 0; j < DIM1; j++)
+ *(data + i * DIM1 + j) = i + j;
+
+ /* Write to the attribute */
+ ret = H5Awrite(aid, H5T_NATIVE_DOUBLE, data);
+ CHECK(ret, FAIL, "H5Awrite");
+
+ /* Closing */
+ ret = H5Aclose(aid);
+ CHECK(ret, FAIL, "H5Aclose");
+ ret = H5Sclose(sid);
+ CHECK(ret, FAIL, "H5Sclose");
+ ret = H5Gclose(gid);
+ CHECK(ret, FAIL, "H5Gclose");
+ ret = H5Fclose(fid);
+ CHECK(ret, FAIL, "H5Fclose");
+
+ /* Re-open the file */
+ fid = H5Fopen(FILENAME, H5F_ACC_RDWR, fapl);
+ CHECK(fid, FAIL, "H5Fopen");
+
+ /* Open the group */
+ gid = H5Gopen2(fid, GRPNAME, H5P_DEFAULT);
+ CHECK(gid, FAIL, "H5Gopen");
+
+ /* Delete the attribute */
+ ret = H5Adelete(gid, ATTRNAME);
+ CHECK(ret, FAIL, "H5Adelete");
+
+ /* Closing */
+ ret = H5Gclose(gid);
+ CHECK(ret, FAIL, "H5Gclose");
+ ret = H5Fclose(fid);
+ CHECK(ret, FAIL, "H5Fclose");
+
+ /* Free the data buffer */
+ if(data)
+ HDfree(data);
+
+} /* test_attr_delete_last_dense() */
+
+/****************************************************************
+**
** test_attr(): Main H5A (attribute) testing routine.
**
****************************************************************/
@@ -10819,6 +10912,7 @@ test_attr(void)
test_attr_bug7(my_fcpl, my_fapl); /* Test creating and deleting large attributes in ohdr chunk 0 */
test_attr_bug8(my_fcpl, my_fapl); /* Test attribute expanding object header with undecoded messages */
test_attr_bug9(my_fcpl, my_fapl); /* Test large attributes converting to dense storage */
+ test_attr_delete_last_dense(my_fcpl, my_fapl); /* Test */
} /* end for */
} /* end if */
else {