diff options
-rw-r--r-- | src/H5F.c | 5 | ||||
-rw-r--r-- | src/H5Fsuper.c | 77 | ||||
-rw-r--r-- | src/H5MF.c | 41 | ||||
-rw-r--r-- | src/H5MFprivate.h | 3 |
4 files changed, 98 insertions, 28 deletions
@@ -2520,6 +2520,7 @@ hssize_t H5Fget_freespace(hid_t file_id) { H5F_t *file; /* File object for file ID */ + hsize_t tot_space; /* Amount of free space in the file */ hssize_t ret_value; /* Return value */ FUNC_ENTER_API(H5Fget_freespace, FAIL) @@ -2530,9 +2531,11 @@ H5Fget_freespace(hid_t file_id) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID") /* Go get the actual amount of free space in the file */ - if((ret_value = H5MF_get_freespace(file, H5AC_ind_dxpl_id)) < 0) + if(H5MF_get_freespace(file, H5AC_ind_dxpl_id, &tot_space, NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to check free space for file") + ret_value = (hssize_t)tot_space; + done: FUNC_LEAVE_API(ret_value) } /* end H5Fget_freespace() */ diff --git a/src/H5Fsuper.c b/src/H5Fsuper.c index 6a72b57..72d1965 100644 --- a/src/H5Fsuper.c +++ b/src/H5Fsuper.c @@ -112,6 +112,7 @@ /********************/ static herr_t H5F_super_ext_create(H5F_t *f, hid_t dxpl_id, H5O_loc_t *ext_ptr); static herr_t H5F_super_ext_open(H5F_t *f, H5O_loc_t *ext_ptr); +static herr_t H5F_super_ext_write_msg(H5F_t *f, hid_t dxpl_id, void *mesg, unsigned id, hbool_t may_create); static herr_t H5F_super_ext_close(H5F_t *f, H5O_loc_t *ext_ptr); @@ -1109,7 +1110,6 @@ H5F_super_write(H5F_t *f, hid_t dxpl_id) /* Check for driver info message */ H5_ASSIGN_OVERFLOW(driver_size, H5FD_sb_size(f->shared->lf), hsize_t, size_t); if(driver_size > 0) { - H5O_loc_t ext_loc; /* "Object location" for superblock extension */ H5O_drvinfo_t drvinfo; /* Driver info */ uint8_t dbuf[H5F_MAX_DRVINFOBLOCK_SIZE]; /* Driver info block encoding buffer */ @@ -1120,19 +1120,11 @@ H5F_super_write(H5F_t *f, hid_t dxpl_id) if(H5FD_sb_encode(f->shared->lf, drvinfo.name, dbuf) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to encode driver information") - /* Open the superblock extension */ - if(H5F_super_ext_open(f, &ext_loc) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENOBJ, FAIL, "unable to start file's superblock extension") - /* Write driver info information to the superblock extension */ drvinfo.len = driver_size; drvinfo.buf = dbuf; - if(H5O_msg_write(&ext_loc, H5O_DRVINFO_ID, H5O_MSG_FLAG_DONTSHARE, H5O_UPDATE_TIME, &drvinfo, dxpl_id) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "unable to update driver info header message") - - /* Close superblock extension */ - if(H5F_super_ext_close(f, &ext_loc) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "unable to close file's superblock extension") + if(H5F_super_ext_write_msg(f, dxpl_id, &drvinfo, H5O_DRVINFO_ID, FALSE) < 0) + HGOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, "unable to update driver info header message") } /* end if */ } /* end if */ @@ -1181,3 +1173,66 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* H5F_super_ext_size() */ + +/*------------------------------------------------------------------------- + * Function: H5F_super_ext_write_msg() + * + * Purpose: Write the message with ID to the superblock extension + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi; Feb 2009 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5F_super_ext_write_msg(H5F_t *f, hid_t dxpl_id, void *mesg, unsigned id, hbool_t may_create) +{ + H5O_loc_t ext_loc; /* "Object location" for superblock extension */ + htri_t status; /* Indicate whether the message exists or not */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5F_super_ext_write_msg) + + /* Open/create the superblock extension object header */ + if(H5F_addr_defined(f->shared->extension_addr)) { + if(H5F_super_ext_open(f, &ext_loc) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENOBJ, FAIL, "unable to open file's superblock extension") + } /* end if */ + else { + HDassert(may_create); + if(H5F_super_ext_create(f, dxpl_id, &ext_loc) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCREATE, FAIL, "unable to create file's superblock extension") + } /* end else */ + HDassert(H5F_addr_defined(ext_loc.addr)); + + /* Check if message with ID does not exist in the object header */ + if((status = H5O_msg_exists(&ext_loc, id, dxpl_id)) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to check object header for message or message exists") + + /* Check for creating vs. writing */ + if(may_create) { + if(status) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "Message should not exist") + + /* Create the message with ID in the superblock extension */ + if(H5O_msg_create(&ext_loc, id, H5O_MSG_FLAG_DONTSHARE, H5O_UPDATE_TIME, mesg, dxpl_id) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to create the message in object header") + } /* end if */ + else { + if(!status) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "Message should exist") + + /* Update the message with ID in the superblock extension */ + if(H5O_msg_write(&ext_loc, id, H5O_MSG_FLAG_DONTSHARE, H5O_UPDATE_TIME, mesg, dxpl_id) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to write the message in object header") + } /* end else */ + + /* Close the superblock extension object header */ + if(H5F_super_ext_close(f, &ext_loc) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "unable to close file's superblock extension") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5F_super_ext_write_msg() */ + @@ -420,7 +420,7 @@ HDfprintf(stderr, "%s: alloc_type = %u, size = %Hu\n", FUNC, (unsigned)alloc_typ /* Check if the free space manager for the file has been initialized */ if(!f->shared->fs_man[fs_type] && H5F_addr_defined(f->shared->fs_addr[fs_type])) if(H5MF_alloc_open(f, dxpl_id, fs_type) < 0) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, HADDR_UNDEF, "can't initialize file free space") + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTOPENOBJ, HADDR_UNDEF, "can't initialize file free space") /* Search for large enough space in the free space manager */ if(f->shared->fs_man[fs_type]) { @@ -768,8 +768,8 @@ H5MF_sects_dump(f, dxpl_id, stderr); * *------------------------------------------------------------------------- */ -hssize_t -H5MF_get_freespace(H5F_t *f, hid_t dxpl_id) +herr_t +H5MF_get_freespace(H5F_t *f, hid_t dxpl_id, hsize_t *tot_space, hsize_t *meta_size) { haddr_t eoa; /* End of allocated space in the file */ haddr_t ma_addr = HADDR_UNDEF; /* Base "metadata aggregator" address */ @@ -777,8 +777,9 @@ H5MF_get_freespace(H5F_t *f, hid_t dxpl_id) haddr_t sda_addr = HADDR_UNDEF; /* Base "small data aggregator" address */ hsize_t sda_size = 0; /* Size of "small data aggregator" */ hsize_t tot_fs_size = 0; /* Amount of all free space managed */ + hsize_t tot_meta_size = 0; /* Amount of metadata for free space managers */ H5FD_mem_t type; /* Memory type for iteration */ - hssize_t ret_value; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5MF_get_freespace, FAIL) @@ -801,7 +802,6 @@ H5MF_get_freespace(H5F_t *f, hid_t dxpl_id) /* Iterate over all the free space types that have managers and get each free list's space */ for(type = H5FD_MEM_DEFAULT; type < H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t, type)) { - hsize_t type_fs_size = 0; /* Amount of free space managed for each type */ hbool_t fs_started = FALSE; /* Check if the free space for the file has been initialized */ @@ -812,13 +812,21 @@ H5MF_get_freespace(H5F_t *f, hid_t dxpl_id) fs_started = TRUE; } /* end if */ - /* Retrieve free space size from free space manager */ - if(f->shared->fs_man[type]) - if((ret_value = H5FS_sect_stats(f->shared->fs_man[type], &type_fs_size, NULL)) < 0) + /* Check if there's free space of this type */ + if(f->shared->fs_man[type]) { + hsize_t type_fs_size = 0; /* Amount of free space managed for each type */ + hsize_t type_meta_size = 0; /* Amount of free space metadata for each type */ + + /* Retrieve free space size from free space manager */ + if(H5FS_sect_stats(f->shared->fs_man[type], &type_fs_size, NULL) < 0) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "can't query free space stats") + if(H5FS_size(f, f->shared->fs_man[type], &type_meta_size) < 0) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "can't query free space metadata stats") - /* Increment total free space for types */ - tot_fs_size += type_fs_size; + /* Increment total free space for types */ + tot_fs_size += type_fs_size; + tot_meta_size += type_meta_size; + } /* end if */ /* Close the free space manager, if we opened it here */ if(fs_started) @@ -826,15 +834,12 @@ H5MF_get_freespace(H5F_t *f, hid_t dxpl_id) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't close file free space") } /* end for */ - /* Start computing value to return */ - ret_value = tot_fs_size; - /* Check for aggregating metadata allocations */ if(ma_size > 0) { /* Add in the reserved space for metadata to the available free space */ /* (if it's not at the tail of the file) */ if(H5F_addr_ne(ma_addr + ma_size, eoa)) - ret_value += ma_size; + tot_fs_size += ma_size; } /* end if */ /* Check for aggregating small data allocations */ @@ -842,9 +847,15 @@ H5MF_get_freespace(H5F_t *f, hid_t dxpl_id) /* Add in the reserved space for metadata to the available free space */ /* (if it's not at the tail of the file) */ if(H5F_addr_ne(sda_addr + sda_size, eoa)) - ret_value += sda_size; + tot_fs_size += sda_size; } /* end if */ + /* Set the value(s) to return */ + if(tot_space) + *tot_space = tot_fs_size; + if(meta_size) + *meta_size = tot_meta_size; + done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5MF_get_freespace() */ diff --git a/src/H5MFprivate.h b/src/H5MFprivate.h index e08381f..515fed8 100644 --- a/src/H5MFprivate.h +++ b/src/H5MFprivate.h @@ -60,7 +60,8 @@ /* File space manager routines */ H5_DLL herr_t H5MF_init_merge_flags(H5F_t *f); -H5_DLL hssize_t H5MF_get_freespace(H5F_t *f, hid_t dxpl_id); +H5_DLL herr_t H5MF_get_freespace(H5F_t *f, hid_t dxpl_id, hsize_t *tot_space, + hsize_t *meta_size); H5_DLL herr_t H5MF_close(H5F_t *f, hid_t dxpl_id); /* File space allocation routines */ |