1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Copyright by The HDF Group. *
3 * All rights reserved. *
4 * *
5 * This file is part of HDF5. The full HDF5 copyright notice, including *
6 * terms governing use, modification, and redistribution, is contained in *
7 * the COPYING file, which can be found at the root of the source code *
8 * distribution tree, or in https://www.hdfgroup.org/licenses. *
9 * If you do not have access to either file, you may request a copy from *
10 * help@hdfgroup.org. *
11 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
12
13 /*
14 * Purpose: Link callbacks for the native VOL connector
15 *
16 */
17
18 #define H5L_FRIEND /* Suppress error about including H5Lpkg */
19
20 #include "H5private.h" /* Generic Functions */
21 #include "H5Eprivate.h" /* Error handling */
22 #include "H5Gprivate.h" /* Groups */
23 #include "H5Iprivate.h" /* IDs */
24 #include "H5Lpkg.h" /* Links */
25 #include "H5Pprivate.h" /* Property lists */
26 #include "H5VLprivate.h" /* Virtual Object Layer */
27
28 #include "H5VLnative_private.h" /* Native VOL connector */
29
30 /*-------------------------------------------------------------------------
31 * Function: H5VL__native_link_create
32 *
33 * Purpose: Handles the link create callback
34 *
35 * Return: SUCCEED/FAIL
36 *
37 *-------------------------------------------------------------------------
38 */
39 herr_t
H5VL__native_link_create(H5VL_link_create_type_t create_type,void * obj,const H5VL_loc_params_t * loc_params,hid_t lcpl_id,hid_t H5_ATTR_UNUSED lapl_id,hid_t H5_ATTR_UNUSED dxpl_id,void H5_ATTR_UNUSED ** req,va_list arguments)40 H5VL__native_link_create(H5VL_link_create_type_t create_type, void *obj, const H5VL_loc_params_t *loc_params,
41 hid_t lcpl_id, hid_t H5_ATTR_UNUSED lapl_id, hid_t H5_ATTR_UNUSED dxpl_id,
42 void H5_ATTR_UNUSED **req, va_list arguments)
43 {
44 herr_t ret_value = SUCCEED; /* Return value */
45
46 FUNC_ENTER_PACKAGE
47
48 switch (create_type) {
49 case H5VL_LINK_CREATE_HARD: {
50 H5G_loc_t cur_loc;
51 H5G_loc_t link_loc;
52 void * cur_obj = HDva_arg(arguments, void *);
53 H5VL_loc_params_t *cur_params = HDva_arg(arguments, H5VL_loc_params_t *);
54
55 if (NULL != cur_obj && H5G_loc_real(cur_obj, cur_params->obj_type, &cur_loc) < 0)
56 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object")
57 if (NULL != obj && H5G_loc_real(obj, loc_params->obj_type, &link_loc) < 0)
58 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object")
59
60 /* H5Lcreate_hard */
61 if (H5VL_OBJECT_BY_NAME == cur_params->type) {
62 H5G_loc_t *cur_loc_p, *link_loc_p;
63
64 /* Set up current & new location pointers */
65 cur_loc_p = &cur_loc;
66 link_loc_p = &link_loc;
67 if (NULL == cur_obj)
68 cur_loc_p = link_loc_p;
69 else if (NULL == obj)
70 link_loc_p = cur_loc_p;
71 else if (cur_loc_p->oloc->file != link_loc_p->oloc->file)
72 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL,
73 "source and destination should be in the same file.")
74
75 /* Create the link */
76 if ((ret_value =
77 H5L__create_hard(cur_loc_p, cur_params->loc_data.loc_by_name.name, link_loc_p,
78 loc_params->loc_data.loc_by_name.name, lcpl_id)) < 0)
79 HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link")
80 } /* end if */
81 else { /* H5Olink */
82 /* Link to the object */
83 if (H5L_link(&link_loc, loc_params->loc_data.loc_by_name.name, &cur_loc, lcpl_id) < 0)
84 HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to create link")
85 } /* end else */
86 break;
87 }
88
89 case H5VL_LINK_CREATE_SOFT: {
90 char * target_name = HDva_arg(arguments, char *);
91 H5G_loc_t link_loc; /* Group location for new link */
92
93 if (H5G_loc_real(obj, loc_params->obj_type, &link_loc) < 0)
94 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object")
95
96 /* Create the link */
97 if ((ret_value = H5L__create_soft(target_name, &link_loc, loc_params->loc_data.loc_by_name.name,
98 lcpl_id)) < 0)
99 HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link")
100 break;
101 }
102
103 case H5VL_LINK_CREATE_UD: {
104 H5G_loc_t link_loc; /* Group location for new link */
105 H5L_type_t link_type = (H5L_type_t)HDva_arg(arguments, int);
106 void * udata = HDva_arg(arguments, void *);
107 size_t udata_size = HDva_arg(arguments, size_t);
108
109 if (H5G_loc_real(obj, loc_params->obj_type, &link_loc) < 0)
110 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object")
111
112 /* Create link */
113 if (H5L__create_ud(&link_loc, loc_params->loc_data.loc_by_name.name, udata, udata_size, link_type,
114 lcpl_id) < 0)
115 HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link")
116 break;
117 }
118
119 default:
120 HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "invalid link creation call")
121 } /* end switch */
122
123 done:
124 FUNC_LEAVE_NOAPI(ret_value)
125 } /* end H5VL__native_link_create() */
126
127 /*-------------------------------------------------------------------------
128 * Function: H5VL__native_link_copy
129 *
130 * Purpose: Handles the link copy callback
131 *
132 * Return: SUCCEED/FAIL
133 *
134 *-------------------------------------------------------------------------
135 */
136 herr_t
H5VL__native_link_copy(void * src_obj,const H5VL_loc_params_t * loc_params1,void * dst_obj,const H5VL_loc_params_t * loc_params2,hid_t lcpl_id,hid_t H5_ATTR_UNUSED lapl_id,hid_t H5_ATTR_UNUSED dxpl_id,void H5_ATTR_UNUSED ** req)137 H5VL__native_link_copy(void *src_obj, const H5VL_loc_params_t *loc_params1, void *dst_obj,
138 const H5VL_loc_params_t *loc_params2, hid_t lcpl_id, hid_t H5_ATTR_UNUSED lapl_id,
139 hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req)
140 {
141 H5G_loc_t src_loc, *src_loc_p;
142 H5G_loc_t dst_loc, *dst_loc_p;
143 herr_t ret_value = SUCCEED; /* Return value */
144
145 FUNC_ENTER_PACKAGE
146
147 if (NULL != src_obj && H5G_loc_real(src_obj, loc_params1->obj_type, &src_loc) < 0)
148 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object")
149 if (NULL != dst_obj && H5G_loc_real(dst_obj, loc_params2->obj_type, &dst_loc) < 0)
150 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object")
151
152 /* Set up src & dst location pointers */
153 src_loc_p = &src_loc;
154 dst_loc_p = &dst_loc;
155 if (NULL == src_obj)
156 src_loc_p = dst_loc_p;
157 else if (NULL == dst_obj)
158 dst_loc_p = src_loc_p;
159
160 /* Copy the link */
161 if (H5L__move(src_loc_p, loc_params1->loc_data.loc_by_name.name, dst_loc_p,
162 loc_params2->loc_data.loc_by_name.name, TRUE, lcpl_id) < 0)
163 HGOTO_ERROR(H5E_LINK, H5E_CANTCOPY, FAIL, "unable to copy link")
164
165 done:
166 FUNC_LEAVE_NOAPI(ret_value)
167 } /* end H5VL__native_link_copy() */
168
169 /*-------------------------------------------------------------------------
170 * Function: H5VL__native_link_move
171 *
172 * Purpose: Handles the link move callback
173 *
174 * Return: SUCCEED/FAIL
175 *
176 *-------------------------------------------------------------------------
177 */
178 herr_t
H5VL__native_link_move(void * src_obj,const H5VL_loc_params_t * loc_params1,void * dst_obj,const H5VL_loc_params_t * loc_params2,hid_t lcpl_id,hid_t H5_ATTR_UNUSED lapl_id,hid_t H5_ATTR_UNUSED dxpl_id,void H5_ATTR_UNUSED ** req)179 H5VL__native_link_move(void *src_obj, const H5VL_loc_params_t *loc_params1, void *dst_obj,
180 const H5VL_loc_params_t *loc_params2, hid_t lcpl_id, hid_t H5_ATTR_UNUSED lapl_id,
181 hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req)
182 {
183 H5G_loc_t src_loc, *src_loc_p;
184 H5G_loc_t dst_loc, *dst_loc_p;
185 herr_t ret_value = SUCCEED; /* Return value */
186
187 FUNC_ENTER_PACKAGE
188
189 if (NULL != src_obj && H5G_loc_real(src_obj, loc_params1->obj_type, &src_loc) < 0)
190 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object")
191 if (NULL != dst_obj && H5G_loc_real(dst_obj, loc_params2->obj_type, &dst_loc) < 0)
192 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object")
193
194 /* Set up src & dst location pointers */
195 src_loc_p = &src_loc;
196 dst_loc_p = &dst_loc;
197 if (NULL == src_obj)
198 src_loc_p = dst_loc_p;
199 else if (NULL == dst_obj)
200 dst_loc_p = src_loc_p;
201
202 /* Move the link */
203 if (H5L__move(src_loc_p, loc_params1->loc_data.loc_by_name.name, dst_loc_p,
204 loc_params2->loc_data.loc_by_name.name, FALSE, lcpl_id) < 0)
205 HGOTO_ERROR(H5E_LINK, H5E_CANTMOVE, FAIL, "unable to move link")
206
207 done:
208 FUNC_LEAVE_NOAPI(ret_value)
209 } /* end H5VL__native_link_move() */
210
211 /*-------------------------------------------------------------------------
212 * Function: H5VL__native_link_get
213 *
214 * Purpose: Handles the link get callback
215 *
216 * Return: SUCCEED/FAIL
217 *
218 *-------------------------------------------------------------------------
219 */
220 herr_t
H5VL__native_link_get(void * obj,const H5VL_loc_params_t * loc_params,H5VL_link_get_t get_type,hid_t H5_ATTR_UNUSED dxpl_id,void H5_ATTR_UNUSED ** req,va_list arguments)221 H5VL__native_link_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_get_t get_type,
222 hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req, va_list arguments)
223 {
224 H5G_loc_t loc;
225 herr_t ret_value = SUCCEED; /* Return value */
226
227 FUNC_ENTER_PACKAGE
228
229 if (H5G_loc_real(obj, loc_params->obj_type, &loc) < 0)
230 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object")
231
232 switch (get_type) {
233 /* H5Lget_info/H5Lget_info_by_idx */
234 case H5VL_LINK_GET_INFO: {
235 H5L_info2_t *linfo2 = HDva_arg(arguments, H5L_info2_t *);
236
237 /* Get the link information */
238 if (loc_params->type == H5VL_OBJECT_BY_NAME) { /* H5Lget_info */
239 if (H5L_get_info(&loc, loc_params->loc_data.loc_by_name.name, linfo2) < 0)
240 HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "unable to get link info")
241 } /* end if */
242 else if (loc_params->type == H5VL_OBJECT_BY_IDX) { /* H5Lget_info_by_idx */
243 if (H5L__get_info_by_idx(
244 &loc, loc_params->loc_data.loc_by_idx.name, loc_params->loc_data.loc_by_idx.idx_type,
245 loc_params->loc_data.loc_by_idx.order, loc_params->loc_data.loc_by_idx.n, linfo2) < 0)
246 HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "unable to get link info")
247 } /* end else-if */
248 else
249 HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "unable to get link info")
250
251 break;
252 }
253
254 /* H5Lget_name_by_idx */
255 case H5VL_LINK_GET_NAME: {
256 char * name = HDva_arg(arguments, char *);
257 size_t size = HDva_arg(arguments, size_t);
258 ssize_t *ret = HDva_arg(arguments, ssize_t *);
259
260 /* Get the link name */
261 if ((*ret = H5L__get_name_by_idx(&loc, loc_params->loc_data.loc_by_idx.name,
262 loc_params->loc_data.loc_by_idx.idx_type,
263 loc_params->loc_data.loc_by_idx.order,
264 loc_params->loc_data.loc_by_idx.n, name, size)) < 0)
265 HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "unable to get link info")
266
267 break;
268 }
269
270 /* H5Lget_val/H5Lget_val_by_idx */
271 case H5VL_LINK_GET_VAL: {
272 void * buf = HDva_arg(arguments, void *);
273 size_t size = HDva_arg(arguments, size_t);
274
275 /* Get the link information */
276 if (loc_params->type == H5VL_OBJECT_BY_NAME) { /* H5Lget_val */
277 if (H5L__get_val(&loc, loc_params->loc_data.loc_by_name.name, buf, size) < 0)
278 HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "unable to get link value")
279 }
280 else if (loc_params->type == H5VL_OBJECT_BY_IDX) { /* H5Lget_val_by_idx */
281
282 if (H5L__get_val_by_idx(&loc, loc_params->loc_data.loc_by_idx.name,
283 loc_params->loc_data.loc_by_idx.idx_type,
284 loc_params->loc_data.loc_by_idx.order,
285 loc_params->loc_data.loc_by_idx.n, buf, size) < 0)
286 HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "unable to get link val")
287 }
288 else
289 HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "unable to get link val")
290
291 break;
292 }
293
294 default:
295 HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get this type of information from link")
296 } /* end switch */
297
298 done:
299 FUNC_LEAVE_NOAPI(ret_value)
300 } /* end H5VL__native_link_get() */
301
302 /*-------------------------------------------------------------------------
303 * Function: H5VL__native_link_specific
304 *
305 * Purpose: Handles the link specific callback
306 *
307 * Return: SUCCEED/FAIL
308 *
309 *-------------------------------------------------------------------------
310 */
311 herr_t
H5VL__native_link_specific(void * obj,const H5VL_loc_params_t * loc_params,H5VL_link_specific_t specific_type,hid_t H5_ATTR_UNUSED dxpl_id,void H5_ATTR_UNUSED ** req,va_list arguments)312 H5VL__native_link_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_specific_t specific_type,
313 hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req, va_list arguments)
314 {
315 herr_t ret_value = SUCCEED; /* Return value */
316
317 FUNC_ENTER_PACKAGE
318
319 switch (specific_type) {
320 case H5VL_LINK_EXISTS: {
321 htri_t * ret = HDva_arg(arguments, htri_t *);
322 H5G_loc_t loc;
323
324 if (H5G_loc_real(obj, loc_params->obj_type, &loc) < 0)
325 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object")
326
327 /* Check for the existence of the link */
328 if ((*ret = H5L__exists(&loc, loc_params->loc_data.loc_by_name.name)) < 0)
329 HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "unable to specific link info")
330 break;
331 }
332
333 case H5VL_LINK_ITER: {
334 H5G_loc_t loc;
335 hbool_t recursive = (hbool_t)HDva_arg(arguments, unsigned);
336 H5_index_t idx_type = (H5_index_t)HDva_arg(arguments, int); /* enum work-around */
337 H5_iter_order_t order = (H5_iter_order_t)HDva_arg(arguments, int); /* enum work-around */
338 hsize_t * idx_p = HDva_arg(arguments, hsize_t *);
339 H5L_iterate2_t op = HDva_arg(arguments, H5L_iterate2_t);
340 void * op_data = HDva_arg(arguments, void *);
341
342 /* Get the location */
343 if (H5G_loc_real(obj, loc_params->obj_type, &loc) < 0)
344 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
345
346 /* Visit or iterate over the links */
347 if (loc_params->type == H5VL_OBJECT_BY_SELF) {
348 if (recursive) {
349 /* H5Lvisit */
350 if ((ret_value = H5G_visit(&loc, ".", idx_type, order, op, op_data)) < 0)
351 HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "link visitation failed")
352 } /* end if */
353 else {
354 /* H5Literate */
355 if ((ret_value = H5L_iterate(&loc, ".", idx_type, order, idx_p, op, op_data)) < 0)
356 HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "error iterating over links")
357 } /* end else */
358 } /* end if */
359 else if (loc_params->type == H5VL_OBJECT_BY_NAME) {
360 if (recursive) {
361 /* H5Lvisit_by_name */
362 if ((ret_value = H5G_visit(&loc, loc_params->loc_data.loc_by_name.name, idx_type, order,
363 op, op_data)) < 0)
364 HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "link visitation failed")
365 } /* end if */
366 else {
367 /* H5Literate_by_name */
368 if ((ret_value = H5L_iterate(&loc, loc_params->loc_data.loc_by_name.name, idx_type, order,
369 idx_p, op, op_data)) < 0)
370 HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "error iterating over links")
371 } /* end else */
372 } /* end else-if */
373 else
374 HGOTO_ERROR(H5E_LINK, H5E_UNSUPPORTED, FAIL, "unknown link iterate params")
375
376 break;
377 }
378
379 case H5VL_LINK_DELETE: {
380 H5G_loc_t loc;
381
382 if (H5G_loc_real(obj, loc_params->obj_type, &loc) < 0)
383 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object")
384
385 /* Unlink */
386 if (loc_params->type == H5VL_OBJECT_BY_NAME) { /* H5Ldelete */
387 if (H5L__delete(&loc, loc_params->loc_data.loc_by_name.name) < 0)
388 HGOTO_ERROR(H5E_LINK, H5E_CANTDELETE, FAIL, "unable to delete link")
389 } /* end if */
390 else if (loc_params->type == H5VL_OBJECT_BY_IDX) { /* H5Ldelete_by_idx */
391 if (H5L__delete_by_idx(
392 &loc, loc_params->loc_data.loc_by_idx.name, loc_params->loc_data.loc_by_idx.idx_type,
393 loc_params->loc_data.loc_by_idx.order, loc_params->loc_data.loc_by_idx.n) < 0)
394 HGOTO_ERROR(H5E_LINK, H5E_CANTDELETE, FAIL, "unable to delete link")
395 } /* end else-if */
396 else
397 HGOTO_ERROR(H5E_LINK, H5E_CANTDELETE, FAIL, "unable to delete link")
398 break;
399 }
400
401 default:
402 HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "invalid specific operation")
403 } /* end switch */
404
405 done:
406 FUNC_LEAVE_NOAPI(ret_value)
407 } /* end H5VL__native_link_specific() */
408