summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRaymond Lu <songyulu@hdfgroup.org>2013-04-29 19:23:04 (GMT)
committerRaymond Lu <songyulu@hdfgroup.org>2013-04-29 19:23:04 (GMT)
commitbada3f7a86cb30b24fad3a24f88114861527ed58 (patch)
tree3f351f78649e966c2521c606082ad63e860e81c1 /src
parent029e143471397de6ddc204be0c21f0c04ee5f2e2 (diff)
downloadhdf5-bada3f7a86cb30b24fad3a24f88114861527ed58.zip
hdf5-bada3f7a86cb30b24fad3a24f88114861527ed58.tar.gz
hdf5-bada3f7a86cb30b24fad3a24f88114861527ed58.tar.bz2
[svn-r23656] Issue 8380 H5Zunregister caused seg fault: I added some protection measures:
1. If any opened object uses the filter, let it fail. 2. Flush all opened files to push any cached data to files. Tested with h5committest.
Diffstat (limited to 'src')
-rw-r--r--src/H5D.c47
-rw-r--r--src/H5Dprivate.h1
-rw-r--r--src/H5G.c46
-rw-r--r--src/H5Gprivate.h1
-rw-r--r--src/H5I.c42
-rw-r--r--src/H5Iprivate.h1
-rw-r--r--src/H5Pocpl.c37
-rw-r--r--src/H5Pprivate.h1
-rw-r--r--src/H5Z.c163
-rw-r--r--src/H5Zprivate.h1
10 files changed, 319 insertions, 21 deletions
diff --git a/src/H5D.c b/src/H5D.c
index d204712..d81d4c7 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -572,19 +572,56 @@ done:
hid_t
H5Dget_create_plist(hid_t dset_id)
{
- H5D_t *dset; /* Dataset structure */
+ H5D_t *dataset; /* Dataset structure */
H5P_genplist_t *dcpl_plist; /* Dataset's DCPL */
H5P_genplist_t *new_plist; /* Copy of dataset's DCPL */
H5O_fill_t copied_fill; /* Fill value to tweak */
hid_t new_dcpl_id = FAIL;
- hid_t ret_value; /* Return value */
+ hid_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(FAIL)
H5TRACE1("i", "i", dset_id);
/* Check args */
- if(NULL == (dset = (H5D_t *)H5I_object_verify(dset_id, H5I_DATASET)))
+ if(NULL == (dataset = (H5D_t *)H5I_object_verify(dset_id, H5I_DATASET)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset")
+
+ if((ret_value = H5D_get_create_plist(dataset)) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Dget_create_plist() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_get_create_plist
+ *
+ * Purpose: Private function for H5Dget_create_plist
+ *
+ * Return: Success: ID for a copy of the dataset creation
+ * property list. The template should be
+ * released by calling H5P_close().
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Tuesday, February 3, 1998
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5D_get_create_plist(H5D_t *dset)
+{
+ H5P_genplist_t *dcpl_plist; /* Dataset's DCPL */
+ H5P_genplist_t *new_plist; /* Copy of dataset's DCPL */
+ H5O_fill_t copied_fill; /* Fill value to tweak */
+ hid_t new_dcpl_id = FAIL;
+ hid_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Check args */
if(NULL == (dcpl_plist = (H5P_genplist_t *)H5I_object(dset->shared->dcpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get property list")
@@ -670,8 +707,8 @@ done:
if(H5I_dec_app_ref(new_dcpl_id) < 0)
HDONE_ERROR(H5E_DATASET, H5E_CANTDEC, FAIL, "unable to close temporary object")
- FUNC_LEAVE_API(ret_value)
-} /* end H5Dget_create_plist() */
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D_get_create_plist() */
/*-------------------------------------------------------------------------
diff --git a/src/H5Dprivate.h b/src/H5Dprivate.h
index 1e2b91d..7adc231 100644
--- a/src/H5Dprivate.h
+++ b/src/H5Dprivate.h
@@ -162,6 +162,7 @@ H5_DLL H5O_loc_t *H5D_oloc(H5D_t *dataset);
H5_DLL H5G_name_t *H5D_nameof(H5D_t *dataset);
H5_DLL H5T_t *H5D_typeof(const H5D_t *dset);
H5_DLL herr_t H5D_flush(const H5F_t *f, hid_t dxpl_id);
+H5_DLL hid_t H5D_get_create_plist(H5D_t *dset);
/* Functions that operate on vlen data */
H5_DLL herr_t H5D_vlen_reclaim(hid_t type_id, H5S_t *space, hid_t plist_id,
diff --git a/src/H5G.c b/src/H5G.c
index a0e7767..bd4ad9b 100644
--- a/src/H5G.c
+++ b/src/H5G.c
@@ -499,7 +499,7 @@ H5Gget_create_plist(hid_t group_id)
htri_t ginfo_exists;
htri_t linfo_exists;
htri_t pline_exists;
- H5G_t *grp = NULL;
+ H5G_t *group = NULL;
H5P_genplist_t *gcpl_plist;
H5P_genplist_t *new_plist;
hid_t new_gcpl_id = FAIL;
@@ -509,9 +509,47 @@ H5Gget_create_plist(hid_t group_id)
H5TRACE1("i", "i", group_id);
/* Check args */
- if(NULL == (grp = (H5G_t *)H5I_object_verify(group_id, H5I_GROUP)))
+ if(NULL == (group = (H5G_t *)H5I_object_verify(group_id, H5I_GROUP)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group")
+ if((ret_value = H5G_get_create_plist(group)) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Gget_create_plist() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_get_create_plist
+ *
+ * Purpose: Private function for H5Gget_create_plist
+ *
+ * Return: Success: ID for a copy of the group creation
+ * property list. The property list ID should be
+ * released by calling H5Pclose().
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, October 25, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5G_get_create_plist(H5G_t *grp)
+{
+ H5O_linfo_t linfo; /* Link info message */
+ htri_t ginfo_exists;
+ htri_t linfo_exists;
+ htri_t pline_exists;
+ H5P_genplist_t *gcpl_plist;
+ H5P_genplist_t *new_plist;
+ hid_t new_gcpl_id = FAIL;
+ hid_t ret_value = FAIL;
+
+ FUNC_ENTER_NOAPI(FAIL)
+
/* Copy the default group creation property list */
if(NULL == (gcpl_plist = (H5P_genplist_t *)H5I_object(H5P_LST_GROUP_CREATE_g)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get default group creation property list")
@@ -573,8 +611,8 @@ done:
HDONE_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "can't free")
} /* end if */
- FUNC_LEAVE_API(ret_value)
-} /* end H5Gget_create_plist() */
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_get_create_plist() */
/*-------------------------------------------------------------------------
diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h
index f765b52..50f8bda 100644
--- a/src/H5Gprivate.h
+++ b/src/H5Gprivate.h
@@ -243,6 +243,7 @@ H5_DLL herr_t H5G_obj_remove_by_idx(const struct H5O_loc_t *grp_oloc, H5RS_str_t
H5_index_t idx_type, H5_iter_order_t order, hsize_t n, hid_t dxpl_id);
H5_DLL herr_t H5G_obj_lookup_by_idx(const struct H5O_loc_t *grp_oloc, H5_index_t idx_type,
H5_iter_order_t order, hsize_t n, struct H5O_link_t *lnk, hid_t dxpl_id);
+H5_DLL hid_t H5G_get_create_plist(H5G_t *grp);
/*
* These functions operate on symbol table nodes.
diff --git a/src/H5I.c b/src/H5I.c
index 581356e..6a8c269 100644
--- a/src/H5I.c
+++ b/src/H5I.c
@@ -2002,21 +2002,55 @@ H5Isearch(H5I_type_t type, H5I_search_func_t func, void *key)
if(H5I_IS_LIB_TYPE(type))
HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "cannot call public function on library type")
+ if((ret_value = H5I_search(type, func, key)) == NULL)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "cannot call public function on library type")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Isearch() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5I_search
+ *
+ * Purpose: Private function for H5Isearch
+ *
+ * Return: Success: The first object in the type for which FUNC
+ * returns non-zero. NULL if FUNC returned zero
+ * for every object in the type.
+ *
+ * Failure: NULL
+ *
+ * Programmer: James Laird
+ * Nathaniel Furrer
+ * Friday, April 23, 2004
+ *
+ *-------------------------------------------------------------------------
+ */
+void *
+H5I_search(H5I_type_t _type, H5I_search_func_t _func, void *_key)
+{
+ H5I_search_ud_t udata; /* Context for iteration */
+ void *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(NULL)
+
/* Set up udata struct */
- udata.app_cb = func;
- udata.app_key = key;
+ udata.app_cb = _func;
+ udata.app_key = _key;
udata.ret_obj = NULL;
/* Note that H5I_iterate returns an error code. We ignore it
* here, as we can't do anything with it without revising the API.
*/
- H5I_iterate(type, H5I_search_cb, &udata, TRUE);
+ if(H5I_iterate(_type, H5I_search_cb, &udata, TRUE) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "cannot call public function on library type")
/* Set return value */
ret_value = udata.ret_obj;
done:
- FUNC_LEAVE_API(ret_value)
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5Isearch() */
diff --git a/src/H5Iprivate.h b/src/H5Iprivate.h
index ff1463d..28b6327 100644
--- a/src/H5Iprivate.h
+++ b/src/H5Iprivate.h
@@ -78,6 +78,7 @@ H5_DLL H5I_type_t H5I_get_type(hid_t id);
H5_DLL hid_t H5I_get_file_id(hid_t obj_id, hbool_t app_ref);
H5_DLL void *H5I_remove(hid_t id);
H5_DLL void *H5I_remove_verify(hid_t id, H5I_type_t id_type);
+H5_DLL void *H5I_search(H5I_type_t _type, H5I_search_func_t _func, void *_key);
H5_DLL herr_t H5I_iterate(H5I_type_t type, H5I_search_func_t func, void *udata, hbool_t app_ref);
H5_DLL int H5I_get_ref(hid_t id, hbool_t app_ref);
H5_DLL int H5I_inc_ref(hid_t id, hbool_t app_ref);
diff --git a/src/H5Pocpl.c b/src/H5Pocpl.c
index 880b46a..f80e4e7 100644
--- a/src/H5Pocpl.c
+++ b/src/H5Pocpl.c
@@ -1177,6 +1177,43 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5P_filter_in_pline
+ *
+ * Purpose: Check whether the filter is in the pipeline of the object
+ * creation property list.
+ *
+ * Return: TRUE: found
+ * FALSE: not found
+ * FAIL: error
+ *
+ * Programmer: Raymond Lu
+ * 26 April 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+htri_t
+H5P_filter_in_pline(H5P_genplist_t *plist, H5Z_filter_t id)
+{
+ H5O_pline_t pline; /* Filter pipeline */
+ H5Z_filter_info_t *filter; /* Pointer to filter information */
+ htri_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Get pipeline info */
+ if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline")
+
+ /* Check if the file is in the pipeline */
+ if((ret_value = H5Z_filter_in_pline(&pline, id)) < 0)
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTCOMPARE, FAIL, "can't find filter")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P_get_filter_by_id() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5Premove_filter
*
* Purpose: Deletes a filter from the dataset creation property list;
diff --git a/src/H5Pprivate.h b/src/H5Pprivate.h
index 6560064..083619b 100644
--- a/src/H5Pprivate.h
+++ b/src/H5Pprivate.h
@@ -108,6 +108,7 @@ H5_DLL herr_t H5P_modify_filter(H5P_genplist_t *plist, H5Z_filter_t filter,
H5_DLL herr_t H5P_get_filter_by_id(H5P_genplist_t *plist, H5Z_filter_t id,
unsigned int *flags, size_t *cd_nelmts, unsigned cd_values[],
size_t namelen, char name[], unsigned *filter_config);
+H5_DLL htri_t H5P_filter_in_pline(H5P_genplist_t *plist, H5Z_filter_t id);
/* *SPECIAL* Don't make more of these! -QAK */
H5_DLL htri_t H5P_isa_class(hid_t plist_id, hid_t pclass_id);
diff --git a/src/H5Z.c b/src/H5Z.c
index 9f8b59d..5d68c25 100644
--- a/src/H5Z.c
+++ b/src/H5Z.c
@@ -22,6 +22,7 @@
#include "H5private.h" /* Generic Functions */
#include "H5Dprivate.h" /* Dataset functions */
#include "H5Eprivate.h" /* Error handling */
+#include "H5Fprivate.h" /* File */
#include "H5Iprivate.h" /* IDs */
#include "H5MMprivate.h" /* Memory management */
#include "H5Oprivate.h" /* Object headers */
@@ -51,6 +52,9 @@ typedef enum {
H5Z_PRELUDE_SET_LOCAL /* Call "set local" callback */
} H5Z_prelude_type_t;
+/* Maximal number of the list of opened objects (2^16) */
+#define NUM_OBJS 65536
+
/* Local variables */
static size_t H5Z_table_alloc_g = 0;
static size_t H5Z_table_used_g = 0;
@@ -403,33 +407,133 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5Z_unregister (H5Z_filter_t id)
+H5Z_unregister (H5Z_filter_t filter_id)
{
- size_t i; /* Local index variable */
+ hid_t *file_list = NULL;
+ hid_t *obj_id_list = NULL;
+ size_t num_obj_id = 0;
+ size_t num_file_id = 0;
+ H5F_t *f = NULL; /* File to query */
+ H5I_type_t id_type;
+ hid_t ocpl_id;
+ H5P_genplist_t *plist; /* Property list */
+ size_t filter_index; /* Local index variable for filter */
+ int i;
+ htri_t filter_in_pline = FALSE;
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
- assert (id>=0 && id<=H5Z_FILTER_MAX);
+ assert (filter_id>=0 && filter_id<=H5Z_FILTER_MAX);
/* Is the filter already registered? */
- for (i=0; i<H5Z_table_used_g; i++)
- if (H5Z_table_g[i].id==id)
+ for (filter_index=0; filter_index<H5Z_table_used_g; filter_index++)
+ if (H5Z_table_g[filter_index].id==filter_id)
break;
/* Fail if filter not found */
- if (i>=H5Z_table_used_g)
+ if (filter_index>=H5Z_table_used_g)
HGOTO_ERROR(H5E_PLINE, H5E_NOTFOUND, FAIL, "filter is not registered")
+ /* Count the number of opened datasets and groups among all opened files */
+ if(H5F_get_obj_count(NULL, H5F_OBJ_DATASET | H5F_OBJ_GROUP, FALSE, &num_obj_id) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get object number")
+
+ if(num_obj_id) {
+ if(NULL == (obj_id_list = (hid_t *)H5MM_malloc(num_obj_id*sizeof(hid_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "failed to allocate space")
+
+ /* Find all opened objects that may use the filter (datasets and groups). Passing NULL as a pointer to
+ * file structure indicates searching among all opened files */
+ if(H5F_get_obj_ids(NULL, H5F_OBJ_DATASET | H5F_OBJ_GROUP, num_obj_id, obj_id_list, FALSE, &num_obj_id) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get object IDs")
+ }
+
+ /* Check if any opened object (dataset or group) uses the filter. If so, fail with a message */
+ for(i=0; i<num_obj_id; i++) {
+ if((id_type = H5I_get_type(obj_id_list[i])) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "bad object id");
+
+ switch(id_type) {
+ case H5I_GROUP:
+ {
+ H5G_t *group = NULL;
+
+ if(NULL == (group = (H5G_t *)H5I_object_verify(obj_id_list[i], H5I_GROUP)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group")
+
+ if((ocpl_id = H5G_get_create_plist(group)) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get group creation property list")
+
+ }
+ break;
+
+ case H5I_DATASET:
+ {
+ H5D_t *dataset = NULL;
+
+ if(NULL == (dataset = (H5D_t *)H5I_object_verify(obj_id_list[i], H5I_DATASET)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset")
+
+ if((ocpl_id = H5D_get_create_plist(dataset)) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get dataset creation property list")
+ }
+ break;
+
+ default:
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a valid object")
+ } /* end switch */
+
+ /* Get the plist structure of object creation */
+ if(NULL == (plist = H5P_object_verify(ocpl_id, H5P_OBJECT_CREATE)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Check if the object creation property list uses the filter */
+ if((filter_in_pline = H5P_filter_in_pline(plist, filter_id)) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't check filter in pipeline")
+
+ if(filter_in_pline)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't unregister filter because some object is still using it")
+ }
+
+ /* Count the number of opened files */
+ if(H5F_get_obj_count(NULL, H5F_OBJ_FILE, FALSE, &num_file_id) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get file number")
+
+ /* Get the list of IDs for all opened files */
+ if(num_file_id) {
+ if(NULL == (file_list = (hid_t *)H5MM_malloc(num_file_id*sizeof(hid_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "failed to allocate space")
+
+ if(H5F_get_obj_ids(NULL, H5F_OBJ_FILE, num_file_id, file_list, FALSE, &num_file_id) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get file IDs")
+ }
+
+ /* Flush all opened files in case any file uses the filter */
+ for(i=0; i<num_file_id; i++) {
+ if(NULL == (f = (H5F_t *)H5I_object_verify(file_list[i], H5I_FILE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file")
+
+ /* Call the flush routine for mounted file hierarchies. Do a global flush
+ * if the file is opened for write */
+ if(H5F_ACC_RDWR & H5F_INTENT(f)) {
+ if(H5F_flush_mounts(f, H5AC_dxpl_id) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush file hierarchy")
+ } /* end if */
+ }
+
/* Remove filter from table */
/* Don't worry about shrinking table size (for now) */
- HDmemmove(&H5Z_table_g[i],&H5Z_table_g[i+1],sizeof(H5Z_class2_t)*((H5Z_table_used_g-1)-i));
+ HDmemmove(&H5Z_table_g[filter_index],&H5Z_table_g[filter_index+1],sizeof(H5Z_class2_t)*((H5Z_table_used_g-1)-filter_index));
#ifdef H5Z_DEBUG
- HDmemmove(&H5Z_stat_table_g[i],&H5Z_stat_table_g[i+1],sizeof(H5Z_stats_t)*((H5Z_table_used_g-1)-i));
+ HDmemmove(&H5Z_stat_table_g[filter_index],&H5Z_stat_table_g[filter_index+1],sizeof(H5Z_stats_t)*((H5Z_table_used_g-1)-filter_index));
#endif /* H5Z_DEBUG */
H5Z_table_used_g--;
done:
+ if(file_list) H5MM_free(file_list);
+ if(obj_id_list) H5MM_free(obj_id_list);
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5Z_unregister() */
@@ -1275,6 +1379,49 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5Z_filter_in_pline
+ *
+ * Purpose: Check wheter a filter is in the filter pipeline using the
+ * filter ID. This function is very similar to H5Z_filter_info
+ *
+ * Return: TRUE - found filter
+ * FALSE - not found
+ * FAIL - error
+ *
+ * Programmer: Raymond Lu
+ * 26 April 2013
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+htri_t
+H5Z_filter_in_pline(const H5O_pline_t *pline, H5Z_filter_t filter)
+{
+ size_t idx; /* Index of filter in pipeline */
+ htri_t ret_value = TRUE; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ assert(pline);
+ assert(filter>=0 && filter<=H5Z_FILTER_MAX);
+
+ /* Locate the filter in the pipeline */
+ for(idx=0; idx<pline->nused; idx++)
+ if(pline->filter[idx].id==filter)
+ break;
+
+ /* Check if the filter was not already in the pipeline */
+ if(idx>=pline->nused)
+ ret_value = FALSE;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5Z_filter_in_pline() */
+
+
+
+/*-------------------------------------------------------------------------
* Function: H5Z_all_filters_avail
*
* Purpose: Verify that all the filters in a pipeline are currently
diff --git a/src/H5Zprivate.h b/src/H5Zprivate.h
index f53b50c..6c0a46f 100644
--- a/src/H5Zprivate.h
+++ b/src/H5Zprivate.h
@@ -91,6 +91,7 @@ H5_DLL herr_t H5Z_can_apply_direct(const struct H5O_pline_t *pline);
H5_DLL herr_t H5Z_set_local_direct(const struct H5O_pline_t *pline);
H5_DLL H5Z_filter_info_t *H5Z_filter_info(const struct H5O_pline_t *pline,
H5Z_filter_t filter);
+H5_DLL htri_t H5Z_filter_in_pline(const struct H5O_pline_t *pline, H5Z_filter_t filter);
H5_DLL htri_t H5Z_all_filters_avail(const struct H5O_pline_t *pline);
H5_DLL htri_t H5Z_filter_avail(H5Z_filter_t id);
H5_DLL herr_t H5Z_delete(struct H5O_pline_t *pline, H5Z_filter_t filter);