From ad317226eacbf5b0a770e458290236ba91861fdc Mon Sep 17 00:00:00 2001 From: Vailin Choi Date: Fri, 20 Jul 2018 11:21:50 -0500 Subject: Fix for HDFFV-9277: update the ainfo message after removing an attribute. --- release_docs/RELEASE.txt | 10 ++++++ src/H5Oattribute.c | 9 +++-- test/tattr.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++ 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 { -- cgit v0.12