diff options
108 files changed, 3245 insertions, 1447 deletions
@@ -662,6 +662,7 @@ ./src/H5Obogus.c ./src/H5Obtreek.c ./src/H5Ocache.c +./src/H5Ochunk.c ./src/H5Ocont.c ./src/H5Ocopy.c ./src/H5Odbg.c diff --git a/Makefile.in b/Makefile.in index 3f30707..2f426f6 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, @@ -470,7 +470,7 @@ distclean-libtool: # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): - @failcom='exit 1'; \ + @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ @@ -495,7 +495,7 @@ $(RECURSIVE_TARGETS): fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): - @failcom='exit 1'; \ + @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ @@ -659,7 +659,8 @@ distdir: $(DISTFILES) fi; \ done -test -n "$(am__skip_mode_fix)" \ - || find "$(distdir)" -type d ! -perm -777 -exec chmod a+rwx {} \; -o \ + || find "$(distdir)" -type d ! -perm -755 \ + -exec chmod u+rwx,go+rx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ @@ -703,17 +704,17 @@ dist dist-all: distdir distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ - GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ - bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\ + bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lzma*) \ - unlzma -c $(distdir).tar.lzma | $(am__untar) ;;\ + lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ - GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac @@ -1,4 +1,4 @@ -HDF5 version 1.9.66-FA_a4 currently under development +HDF5 version 1.9.67-FA_a4 currently under development Please refer to the release_docs/INSTALL file for installation instructions. ------------------------------------------------------------------------------ @@ -1,4 +1,4 @@ -# generated automatically by aclocal 1.11 -*- Autoconf -*- +# generated automatically by aclocal 1.11.1 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. @@ -13,8 +13,8 @@ m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl -m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.64],, -[m4_warning([this file was generated for autoconf 2.64. +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.65],, +[m4_warning([this file was generated for autoconf 2.65. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically `autoreconf'.])]) @@ -34,7 +34,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.11' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.11], [], +m4_if([$1], [1.11.1], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -50,7 +50,7 @@ m4_define([_AM_AUTOCONF_VERSION], []) # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.11])dnl +[AM_AUTOMAKE_VERSION([1.11.1])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) @@ -6889,7 +6889,7 @@ if test "$_lt_caught_CXX_error" != yes; then pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in - *pgCC\ [[1-5]]* | *pgcpp\ [[1-5]]*) + *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ @@ -6908,7 +6908,7 @@ if test "$_lt_caught_CXX_error" != yes; then $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; - *) # Version 6 will use weak symbols + *) # Version 6 and above use weak symbols _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; @@ -8841,15 +8841,15 @@ m4_define([lt_dict_filter], # Generated from ltversion.in. -# serial 3012 ltversion.m4 +# serial 3017 ltversion.m4 # This file is part of GNU Libtool -m4_define([LT_PACKAGE_VERSION], [2.2.6]) -m4_define([LT_PACKAGE_REVISION], [1.3012]) +m4_define([LT_PACKAGE_VERSION], [2.2.6b]) +m4_define([LT_PACKAGE_REVISION], [1.3017]) AC_DEFUN([LTVERSION_VERSION], -[macro_version='2.2.6' -macro_revision='1.3012' +[macro_version='2.2.6b' +macro_revision='1.3017' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) diff --git a/bin/ltmain.sh b/bin/ltmain.sh index b36c4ad..a72f2fd 100644 --- a/bin/ltmain.sh +++ b/bin/ltmain.sh @@ -1,6 +1,6 @@ # Generated from ltmain.m4sh. -# ltmain.sh (GNU libtool) 2.2.6 +# ltmain.sh (GNU libtool) 2.2.6b # Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007 2008 Free Software Foundation, Inc. @@ -65,7 +65,7 @@ # compiler: $LTCC # compiler flags: $LTCFLAGS # linker: $LD (gnu? $with_gnu_ld) -# $progname: (GNU libtool) 2.2.6 +# $progname: (GNU libtool) 2.2.6b # automake: $automake_version # autoconf: $autoconf_version # @@ -73,9 +73,9 @@ PROGRAM=ltmain.sh PACKAGE=libtool -VERSION=2.2.6 +VERSION=2.2.6b TIMESTAMP="" -package_revision=1.3012 +package_revision=1.3017 # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then @@ -116,15 +116,15 @@ $lt_unset CDPATH : ${CP="cp -f"} : ${ECHO="echo"} -: ${EGREP="/usr/bin/grep -E"} -: ${FGREP="/usr/bin/grep -F"} -: ${GREP="/usr/bin/grep"} +: ${EGREP="/bin/grep -E"} +: ${FGREP="/bin/grep -F"} +: ${GREP="/bin/grep"} : ${LN_S="ln -s"} : ${MAKE="make"} : ${MKDIR="mkdir"} : ${MV="mv -f"} : ${RM="rm -f"} -: ${SED="/opt/local/bin/gsed"} +: ${SED="/bin/sed"} : ${SHELL="${CONFIG_SHELL-/bin/sh}"} : ${Xsed="$SED -e 1s/^X//"} diff --git a/bin/reconfigure b/bin/reconfigure index 65a46bc..50428f4 100755 --- a/bin/reconfigure +++ b/bin/reconfigure @@ -28,32 +28,32 @@ # of versions that can get confused (not even counting the m4 utility)! # HDF5 currently uses the following versions of the autotools: -AUTOCONF_VERSION="autoconf (GNU Autoconf) 2.64" -AUTOMAKE_VERSION="automake (GNU automake) 1.11" -AUTOHEADER_VERSION="autoheader (GNU Autoconf) 2.64" -ACLOCAL_VERSION="aclocal (GNU automake) 1.11" -LIBTOOL_VERSION="(GNU libtool) 2.2.6" +AUTOCONF_VERSION="autoconf (GNU Autoconf) 2.65" +AUTOMAKE_VERSION="automake (GNU automake) 1.11.1" +AUTOHEADER_VERSION="autoheader (GNU Autoconf) 2.65" +ACLOCAL_VERSION="aclocal (GNU automake) 1.11.1" +LIBTOOL_VERSION="(GNU libtool) 2.2.6b-mcg" # # When upgrading automake's version, don't forget to also update its # helper utilities, especially depcomp. # If paths to autotools are not specified by the user, assume tools are -# running on kagiso and set paths accordingly. +# running on jam in /mnt/hdf/packages and set paths accordingly. if test -z ${AUTOCONF}; then - AUTOCONF=/mnt/hdf/packages/autoconf/autoconf-2.64/bin/autoconf + AUTOCONF=/mnt/hdf/packages/autoconf/autoconf-2.65/bin/autoconf fi if test -z ${AUTOMAKE}; then - AUTOMAKE=/mnt/hdf/packages/automake/automake-1.11/bin/automake-1.11 + AUTOMAKE=/mnt/hdf/packages/automake/automake-1.11.1/bin/automake-1.11 fi if test -z ${AUTOHEADER}; then - AUTOHEADER=/mnt/hdf/packages/autoconf/autoconf-2.64/bin/autoheader + AUTOHEADER=/mnt/hdf/packages/autoconf/autoconf-2.65/bin/autoheader fi if test -z ${ACLOCAL}; then - ACLOCAL=/mnt/hdf/packages/automake/automake-1.11/bin/aclocal-1.11 + ACLOCAL=/mnt/hdf/packages/automake/automake-1.11.1/bin/aclocal-1.11 fi if test -z ${LIBTOOL}; then - LIBTOOL=/mnt/hdf/packages/libtool/libtool-2.2.6a/bin/libtool + LIBTOOL=/mnt/hdf/packages/libtool/libtool-2.2.6b-mcg/bin/libtool fi # Check version numbers of all autotools against the "correct" versions diff --git a/c++/Makefile.in b/c++/Makefile.in index 424aa15..2dfb03a 100644 --- a/c++/Makefile.in +++ b/c++/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, @@ -429,7 +429,7 @@ clean-libtool: # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): - @failcom='exit 1'; \ + @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ @@ -454,7 +454,7 @@ $(RECURSIVE_TARGETS): fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): - @failcom='exit 1'; \ + @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ diff --git a/c++/examples/Makefile.in b/c++/examples/Makefile.in index 5acaa12..46a50c5 100644 --- a/c++/examples/Makefile.in +++ b/c++/examples/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, diff --git a/c++/src/Makefile.in b/c++/src/Makefile.in index a76a9ef..e599563 100644 --- a/c++/src/Makefile.in +++ b/c++/src/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, @@ -390,7 +390,7 @@ CHECK_CLEANFILES = *.chkexe *.chklog *.clog # Add libtool shared library version numbers to the HDF5 library # See libtool versioning documentation online. LT_VERS_INTERFACE = 6 -LT_VERS_REVISION = 56 +LT_VERS_REVISION = 57 LT_VERS_AGE = 0 # Include src directory diff --git a/c++/test/Makefile.in b/c++/test/Makefile.in index 03c8ff7..0945169 100644 --- a/c++/test/Makefile.in +++ b/c++/test/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, diff --git a/config/lt_vers.am b/config/lt_vers.am index 5096b76..e08ea85 100644 --- a/config/lt_vers.am +++ b/config/lt_vers.am @@ -17,7 +17,7 @@ # Add libtool shared library version numbers to the HDF5 library # See libtool versioning documentation online. LT_VERS_INTERFACE = 6 -LT_VERS_REVISION = 56 +LT_VERS_REVISION = 57 LT_VERS_AGE = 0 ## If the API changes *at all*, increment LT_VERS_INTERFACE and @@ -1,13 +1,15 @@ #! /bin/sh -# From configure.in Id: configure.in 18451 2010-03-25 03:51:41Z koziol . +# From configure.in Id: configure.in 18534 2010-04-08 15:30:10Z koziol . # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.64 for HDF5 1.9.66-FA_a4. +# Generated by GNU Autoconf 2.65 for HDF5 1.9.67-FA_a4. # # Report bugs to <help@hdfgroup.org>. # +# # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, -# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software -# Foundation, Inc. +# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. @@ -677,7 +679,8 @@ fi -exec 7<&0 </dev/null 6>&1 +test -n "$DJDIR" || exec 7<&0 </dev/null +exec 6>&1 # Name of the host. # hostname on some systems (SVR3.2, Linux) returns a bogus exit status, @@ -699,8 +702,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='HDF5' PACKAGE_TARNAME='hdf5' -PACKAGE_VERSION='1.9.66-FA_a4' -PACKAGE_STRING='HDF5 1.9.66-FA_a4' +PACKAGE_VERSION='1.9.67-FA_a4' +PACKAGE_STRING='HDF5 1.9.67-FA_a4' PACKAGE_BUGREPORT='help@hdfgroup.org' PACKAGE_URL='' @@ -1571,7 +1574,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures HDF5 1.9.66-FA_a4 to adapt to many kinds of systems. +\`configure' configures HDF5 1.9.67-FA_a4 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1641,7 +1644,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of HDF5 1.9.66-FA_a4:";; + short | recursive ) echo "Configuration of HDF5 1.9.67-FA_a4:";; esac cat <<\_ACEOF @@ -1753,7 +1756,7 @@ Some influential environment variables: LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a nonstandard directory <lib dir> LIBS libraries to pass to the linker, e.g. -l<library> - CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I<include dir> if + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if you have headers in a nonstandard directory <include dir> FC Fortran compiler command FCFLAGS Fortran compiler flags @@ -1828,8 +1831,8 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -HDF5 configure 1.9.66-FA_a4 -generated by GNU Autoconf 2.64 +HDF5 configure 1.9.67-FA_a4 +generated by GNU Autoconf 2.65 Copyright (C) 2009 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation @@ -1876,7 +1879,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} - return $ac_retval + as_fn_set_status $ac_retval } # ac_fn_c_try_compile @@ -1914,7 +1917,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} - return $ac_retval + as_fn_set_status $ac_retval } # ac_fn_fc_try_compile @@ -1960,7 +1963,7 @@ fi # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} - return $ac_retval + as_fn_set_status $ac_retval } # ac_fn_c_try_link @@ -2002,7 +2005,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} - return $ac_retval + as_fn_set_status $ac_retval } # ac_fn_fc_try_run @@ -2040,7 +2043,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} - return $ac_retval + as_fn_set_status $ac_retval } # ac_fn_cxx_try_compile @@ -2077,7 +2080,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} - return $ac_retval + as_fn_set_status $ac_retval } # ac_fn_cxx_try_cpp @@ -2119,7 +2122,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} - return $ac_retval + as_fn_set_status $ac_retval } # ac_fn_cxx_try_run @@ -2187,7 +2190,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} - return $ac_retval + as_fn_set_status $ac_retval } # ac_fn_c_try_cpp @@ -2229,7 +2232,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} - return $ac_retval + as_fn_set_status $ac_retval } # ac_fn_c_try_run @@ -2350,7 +2353,7 @@ fi # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} - return $ac_retval + as_fn_set_status $ac_retval } # ac_fn_cxx_try_link @@ -2396,7 +2399,7 @@ fi # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} - return $ac_retval + as_fn_set_status $ac_retval } # ac_fn_fc_try_link @@ -2785,7 +2788,7 @@ rm -f conftest.val fi eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} - return $ac_retval + as_fn_set_status $ac_retval } # ac_fn_c_compute_int @@ -2912,8 +2915,8 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by HDF5 $as_me 1.9.66-FA_a4, which was -generated by GNU Autoconf 2.64. Invocation command line was +It was created by HDF5 $as_me 1.9.67-FA_a4, which was +generated by GNU Autoconf 2.65. Invocation command line was $ $0 $@ @@ -3166,7 +3169,7 @@ fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue - if test -r "$ac_site_file"; then + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 @@ -3175,9 +3178,9 @@ $as_echo "$as_me: loading site script $ac_site_file" >&6;} done if test -r "$cache_file"; then - # Some versions of bash will fail to source /dev/null (special - # files actually), so we avoid doing that. - if test -f "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in @@ -3601,6 +3604,7 @@ IFS=$as_save_IFS fi + test -d ./--version && rmdir ./--version if test "${ac_cv_path_mkdir+set}" = set; then MKDIR_P="$ac_cv_path_mkdir -p" else @@ -3608,7 +3612,6 @@ fi # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. - test -d ./--version && rmdir ./--version MKDIR_P="$ac_install_sh -d" fi fi @@ -3725,7 +3728,7 @@ fi # Define the identity of the package. PACKAGE='hdf5' - VERSION='1.9.66-FA_a4' + VERSION='1.9.67-FA_a4' cat >>confdefs.h <<_ACEOF @@ -4382,32 +4385,30 @@ $as_echo "$ac_try_echo"; } >&5 ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 - rm -f conftest.er1 conftest.err fi + rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include <stdio.h> + int main () { -FILE *f = fopen ("conftest.out", "w"); - return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out conftest.out" +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 -$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: @@ -4469,10 +4470,10 @@ test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 -$as_echo "$ac_file" >&6; } if test -z "$ac_file"; then : - $as_echo "$as_me: failed program was:" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 @@ -4480,51 +4481,18 @@ $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { as_fn_set_status 77 as_fn_error "C compiler cannot create executables See \`config.log' for more details." "$LINENO" 5; }; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext -# Check that the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 -$as_echo_n "checking whether the C compiler works... " >&6; } -# If not cross compiling, check that we can run a simple program. -if test "$cross_compiling" != yes; then - if { ac_try='./$ac_file' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; }; then - cross_compiling=no - else - if test "$cross_compiling" = maybe; then - cross_compiling=yes - else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error "cannot run C compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details." "$LINENO" 5; } - fi - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out conftest.out +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save -# Check that the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 -$as_echo_n "checking whether we are cross compiling... " >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 -$as_echo "$cross_compiling" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" @@ -4557,13 +4525,72 @@ $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." "$LINENO" 5; } fi -rm -f conftest$ac_cv_exeext +rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdio.h> +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if test "${ac_cv_objext+set}" = set; then : @@ -5172,8 +5199,8 @@ $as_echo "$ac_try_echo"; } >&5 ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 - rm -f conftest.er1 conftest.err fi + rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done @@ -5433,8 +5460,8 @@ $as_echo "$ac_try_echo"; } >&5 ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 - rm -f conftest.er1 conftest.err fi + rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done @@ -6494,8 +6521,8 @@ $as_echo "$ac_try_echo"; } >&5 ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 - rm -f conftest.er1 conftest.err fi + rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done @@ -7620,8 +7647,8 @@ esac -macro_version='2.2.6' -macro_revision='1.3012' +macro_version='2.2.6b' +macro_revision='1.3017' @@ -8221,13 +8248,13 @@ if test "${lt_cv_nm_interface+set}" = set; then : else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:8224: $ac_compile\"" >&5) + (eval echo "\"\$as_me:8251: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 - (eval echo "\"\$as_me:8227: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval echo "\"\$as_me:8254: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 - (eval echo "\"\$as_me:8230: output\"" >&5) + (eval echo "\"\$as_me:8257: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" @@ -9432,7 +9459,7 @@ ia64-*-hpux*) ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 9435 "configure"' > conftest.$ac_ext + echo '#line 9462 "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -10616,8 +10643,8 @@ $as_echo "$ac_try_echo"; } >&5 ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 - rm -f conftest.er1 conftest.err fi + rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done @@ -11168,8 +11195,8 @@ $as_echo "$ac_try_echo"; } >&5 ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 - rm -f conftest.er1 conftest.err fi + rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done @@ -11751,11 +11778,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:11754: $lt_compile\"" >&5) + (eval echo "\"\$as_me:11781: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:11758: \$? = $ac_status" >&5 + echo "$as_me:11785: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -12090,11 +12117,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:12093: $lt_compile\"" >&5) + (eval echo "\"\$as_me:12120: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:12097: \$? = $ac_status" >&5 + echo "$as_me:12124: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -12195,11 +12222,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:12198: $lt_compile\"" >&5) + (eval echo "\"\$as_me:12225: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:12202: \$? = $ac_status" >&5 + echo "$as_me:12229: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -12250,11 +12277,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:12253: $lt_compile\"" >&5) + (eval echo "\"\$as_me:12280: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:12257: \$? = $ac_status" >&5 + echo "$as_me:12284: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -14681,7 +14708,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 14684 "configure" +#line 14711 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -14777,7 +14804,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 14780 "configure" +#line 14807 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -15788,7 +15815,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in - *pgCC\ [1-5]* | *pgcpp\ [1-5]*) + *pgCC\ [1-5].* | *pgcpp\ [1-5].*) prelink_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ @@ -15807,7 +15834,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; - *) # Version 6 will use weak symbols + *) # Version 6 and above use weak symbols archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; @@ -16749,11 +16776,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:16752: $lt_compile\"" >&5) + (eval echo "\"\$as_me:16779: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:16756: \$? = $ac_status" >&5 + echo "$as_me:16783: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -16848,11 +16875,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:16851: $lt_compile\"" >&5) + (eval echo "\"\$as_me:16878: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:16855: \$? = $ac_status" >&5 + echo "$as_me:16882: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -16900,11 +16927,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:16903: $lt_compile\"" >&5) + (eval echo "\"\$as_me:16930: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:16907: \$? = $ac_status" >&5 + echo "$as_me:16934: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -18417,11 +18444,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:18420: $lt_compile\"" >&5) + (eval echo "\"\$as_me:18447: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:18424: \$? = $ac_status" >&5 + echo "$as_me:18451: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -18516,11 +18543,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:18519: $lt_compile\"" >&5) + (eval echo "\"\$as_me:18546: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:18523: \$? = $ac_status" >&5 + echo "$as_me:18550: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -18568,11 +18595,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:18571: $lt_compile\"" >&5) + (eval echo "\"\$as_me:18598: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:18575: \$? = $ac_status" >&5 + echo "$as_me:18602: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -28847,8 +28874,8 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by HDF5 $as_me 1.9.66-FA_a4, which was -generated by GNU Autoconf 2.64. Invocation command line was +This file was extended by HDF5 $as_me 1.9.67-FA_a4, which was +generated by GNU Autoconf 2.65. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -28888,6 +28915,7 @@ Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit + --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files @@ -28910,10 +28938,11 @@ Report bugs to <help@hdfgroup.org>." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -HDF5 config.status 1.9.66-FA_a4 -configured by $0, generated by GNU Autoconf 2.64, - with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" +HDF5 config.status 1.9.67-FA_a4 +configured by $0, generated by GNU Autoconf 2.65, + with options \\"\$ac_cs_config\\" Copyright (C) 2009 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation @@ -28951,6 +28980,8 @@ do ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) @@ -29636,7 +29667,7 @@ s/'"$ac_delim"'$// t delim :nl h -s/\(.\{148\}\).*/\1/ +s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p @@ -29650,7 +29681,7 @@ s/.\{148\}// t nl :delim h -s/\(.\{148\}\).*/\1/ +s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p diff --git a/configure.in b/configure.in index d266f5d..2f31df9 100644 --- a/configure.in +++ b/configure.in @@ -26,7 +26,7 @@ dnl dnl NOTE: Don't forget to change the version number here when we do a dnl release!!! dnl -AC_INIT([HDF5], [1.9.66-FA_a4], [help@hdfgroup.org]) +AC_INIT([HDF5], [1.9.67-FA_a4], [help@hdfgroup.org]) AC_CONFIG_SRCDIR([src/H5.c]) AM_CONFIG_HEADER([src/H5config.h]) diff --git a/examples/Makefile.in b/examples/Makefile.in index 5eb9d55..04c5f2d 100644 --- a/examples/Makefile.in +++ b/examples/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, diff --git a/fortran/Makefile.in b/fortran/Makefile.in index 67fce8c..1a1be60 100644 --- a/fortran/Makefile.in +++ b/fortran/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, @@ -438,7 +438,7 @@ clean-libtool: # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): - @failcom='exit 1'; \ + @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ @@ -463,7 +463,7 @@ $(RECURSIVE_TARGETS): fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): - @failcom='exit 1'; \ + @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ diff --git a/fortran/examples/Makefile.in b/fortran/examples/Makefile.in index 151bac5..7a92157 100644 --- a/fortran/examples/Makefile.in +++ b/fortran/examples/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, diff --git a/fortran/src/Makefile.am b/fortran/src/Makefile.am index d2644a1..f38e94f 100644 --- a/fortran/src/Makefile.am +++ b/fortran/src/Makefile.am @@ -90,11 +90,14 @@ clean-local: @if test -n "$(F9XMODEXT)" && test "X$(F9XMODEXT)" != "Xo"; then \ $(RM) *.$(F9XMODEXT); \ fi + $(RM) $(DESTDIR)$(includedir)/H5f90i*.h install-data-local: @if test -n "$(F9XMODEXT)" && test "X$(F9XMODEXT)" != "Xo"; then \ $(CP) $(top_builddir)/$(subdir)/*.$(F9XMODEXT) $(DESTDIR)$(includedir)/. ; \ fi + $(CP) $(top_builddir)/$(subdir)/H5f90i_gen.h $(DESTDIR)$(includedir)/. + $(CP) $(top_srcdir)/fortran/src/H5f90i.h $(DESTDIR)$(includedir)/. uninstall-local: @if test -n "$(F9XMODEXT)" -a "X$(F9XMODEXT)" != "Xo"; then \ @@ -103,6 +106,7 @@ uninstall-local: fi; \ fi; \ $(RM) $(DESTDIR)$(bindir)/$(H5FC_NAME) + $(RM) $(DESTDIR)$(includedir)/H5f90i*.h # Also install and uninstall (uninstall-local above) h5fc script install-exec-local: diff --git a/fortran/src/Makefile.in b/fortran/src/Makefile.in index f3226f5..d608a21 100644 --- a/fortran/src/Makefile.in +++ b/fortran/src/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, @@ -424,7 +424,7 @@ CHECK_CLEANFILES = *.chkexe *.chklog *.clog # Add libtool shared library version numbers to the HDF5 library # See libtool versioning documentation online. LT_VERS_INTERFACE = 6 -LT_VERS_REVISION = 56 +LT_VERS_REVISION = 57 LT_VERS_AGE = 0 # Include src directory in both Fortran and C flags (C compiler is used @@ -916,11 +916,14 @@ clean-local: @if test -n "$(F9XMODEXT)" && test "X$(F9XMODEXT)" != "Xo"; then \ $(RM) *.$(F9XMODEXT); \ fi + $(RM) $(DESTDIR)$(includedir)/H5f90i*.h install-data-local: @if test -n "$(F9XMODEXT)" && test "X$(F9XMODEXT)" != "Xo"; then \ $(CP) $(top_builddir)/$(subdir)/*.$(F9XMODEXT) $(DESTDIR)$(includedir)/. ; \ fi + $(CP) $(top_builddir)/$(subdir)/H5f90i_gen.h $(DESTDIR)$(includedir)/. + $(CP) $(top_srcdir)/fortran/src/H5f90i.h $(DESTDIR)$(includedir)/. uninstall-local: @if test -n "$(F9XMODEXT)" -a "X$(F9XMODEXT)" != "Xo"; then \ @@ -929,6 +932,7 @@ uninstall-local: fi; \ fi; \ $(RM) $(DESTDIR)$(bindir)/$(H5FC_NAME) + $(RM) $(DESTDIR)$(includedir)/H5f90i*.h # Also install and uninstall (uninstall-local above) h5fc script install-exec-local: diff --git a/fortran/test/Makefile.in b/fortran/test/Makefile.in index f586adb..3de711a 100644 --- a/fortran/test/Makefile.in +++ b/fortran/test/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, diff --git a/fortran/testpar/Makefile.in b/fortran/testpar/Makefile.in index 6dcf2bd..613a0ec 100644 --- a/fortran/testpar/Makefile.in +++ b/fortran/testpar/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, diff --git a/hl/Makefile.in b/hl/Makefile.in index 8fd29b4..0d4c6c1 100755 --- a/hl/Makefile.in +++ b/hl/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, @@ -435,7 +435,7 @@ clean-libtool: # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): - @failcom='exit 1'; \ + @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ @@ -460,7 +460,7 @@ $(RECURSIVE_TARGETS): fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): - @failcom='exit 1'; \ + @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ diff --git a/hl/c++/Makefile.in b/hl/c++/Makefile.in index d83f520..0a5d32d 100644 --- a/hl/c++/Makefile.in +++ b/hl/c++/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, @@ -429,7 +429,7 @@ clean-libtool: # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): - @failcom='exit 1'; \ + @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ @@ -454,7 +454,7 @@ $(RECURSIVE_TARGETS): fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): - @failcom='exit 1'; \ + @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ diff --git a/hl/c++/examples/Makefile.in b/hl/c++/examples/Makefile.in index 9fad167..51c04ad 100644 --- a/hl/c++/examples/Makefile.in +++ b/hl/c++/examples/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, diff --git a/hl/c++/src/Makefile.in b/hl/c++/src/Makefile.in index bd90cd2..f58a07b 100644 --- a/hl/c++/src/Makefile.in +++ b/hl/c++/src/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, @@ -380,7 +380,7 @@ CHECK_CLEANFILES = *.chkexe *.chklog *.clog # Add libtool shared library version numbers to the HDF5 library # See libtool versioning documentation online. LT_VERS_INTERFACE = 6 -LT_VERS_REVISION = 56 +LT_VERS_REVISION = 57 LT_VERS_AGE = 0 # Include src directory diff --git a/hl/c++/test/Makefile.in b/hl/c++/test/Makefile.in index 7266306..644966b 100644 --- a/hl/c++/test/Makefile.in +++ b/hl/c++/test/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, diff --git a/hl/examples/Makefile.in b/hl/examples/Makefile.in index 44333b5..31c21f0 100644 --- a/hl/examples/Makefile.in +++ b/hl/examples/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, diff --git a/hl/fortran/Makefile.in b/hl/fortran/Makefile.in index 4a91756..799edee 100644 --- a/hl/fortran/Makefile.in +++ b/hl/fortran/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, @@ -433,7 +433,7 @@ clean-libtool: # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): - @failcom='exit 1'; \ + @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ @@ -458,7 +458,7 @@ $(RECURSIVE_TARGETS): fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): - @failcom='exit 1'; \ + @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ diff --git a/hl/fortran/examples/Makefile.in b/hl/fortran/examples/Makefile.in index ef5d165..3abc2dd 100644 --- a/hl/fortran/examples/Makefile.in +++ b/hl/fortran/examples/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, diff --git a/hl/fortran/src/Makefile.in b/hl/fortran/src/Makefile.in index c92f09f..195acf2 100644 --- a/hl/fortran/src/Makefile.in +++ b/hl/fortran/src/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, @@ -389,7 +389,7 @@ CHECK_CLEANFILES = *.chkexe *.chklog *.clog # Add libtool shared library version numbers to the HDF5 library # See libtool versioning documentation online. LT_VERS_INTERFACE = 6 -LT_VERS_REVISION = 56 +LT_VERS_REVISION = 57 LT_VERS_AGE = 0 INCLUDES = -I$(top_srcdir)/src -I$(top_srcdir)/hl/src -I$(top_builddir)/hl/src \ -I$(top_srcdir)/fortran/src -I$(top_builddir)/fortran/src diff --git a/hl/fortran/test/Makefile.in b/hl/fortran/test/Makefile.in index c6d1c35..6ff5d02 100644 --- a/hl/fortran/test/Makefile.in +++ b/hl/fortran/test/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, diff --git a/hl/src/Makefile.in b/hl/src/Makefile.in index cac49d3..ef8dc41 100644 --- a/hl/src/Makefile.in +++ b/hl/src/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, @@ -380,7 +380,7 @@ CHECK_CLEANFILES = *.chkexe *.chklog *.clog # Add libtool shared library version numbers to the HDF5 library # See libtool versioning documentation online. LT_VERS_INTERFACE = 6 -LT_VERS_REVISION = 56 +LT_VERS_REVISION = 57 LT_VERS_AGE = 0 # This library is our main target. diff --git a/hl/test/Makefile.in b/hl/test/Makefile.in index 4f86240..3d37e3e 100644 --- a/hl/test/Makefile.in +++ b/hl/test/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, diff --git a/hl/tools/Makefile.in b/hl/tools/Makefile.in index cb80338..99d627d 100644 --- a/hl/tools/Makefile.in +++ b/hl/tools/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, @@ -431,7 +431,7 @@ clean-libtool: # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): - @failcom='exit 1'; \ + @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ @@ -456,7 +456,7 @@ $(RECURSIVE_TARGETS): fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): - @failcom='exit 1'; \ + @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ diff --git a/hl/tools/gif2h5/Makefile.in b/hl/tools/gif2h5/Makefile.in index b4cf901..ed61e3c 100644 --- a/hl/tools/gif2h5/Makefile.in +++ b/hl/tools/gif2h5/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, diff --git a/perform/Makefile.in b/perform/Makefile.in index a5a28f5..5d5df32 100644 --- a/perform/Makefile.in +++ b/perform/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, diff --git a/perform/perf_meta.c b/perform/perf_meta.c index b3966d6..8c3b06f 100644 --- a/perform/perf_meta.c +++ b/perform/perf_meta.c @@ -20,9 +20,6 @@ * Purpose: Tests performance of metadata */ -#include <stdlib.h> -#include <string.h> -#include <sys/time.h> #include "h5test.h" #ifdef H5_HAVE_PARALLEL @@ -685,7 +682,7 @@ double retrieve_time(void) if(facc_type == FACC_DEFAULT) { #endif /*H5_HAVE_PARALLEL*/ struct timeval t; - gettimeofday(&t, NULL); + HDgettimeofday(&t, NULL); return ((double)t.tv_sec + (double)t.tv_usec / 1000000); #ifdef H5_HAVE_PARALLEL } else { diff --git a/perform/zip_perf.c b/perform/zip_perf.c index d1d36b4..7d96405 100644 --- a/perform/zip_perf.c +++ b/perform/zip_perf.c @@ -28,14 +28,15 @@ #include <errno.h> #include <fcntl.h> #include <math.h> -#include <sys/time.h> #include <sys/types.h> #include <sys/stat.h> -#include <unistd.h> + +#ifdef H5_HAVE_UNISTD_H +# include <unistd.h> +#endif /* our header files */ -#include "hdf5.h" -#include "H5private.h" +#include "h5test.h" #include "h5tools_utils.h" #ifdef H5_HAVE_FILTER_DEFLATE @@ -86,6 +87,9 @@ #define FALSE (!TRUE) #endif /* FALSE */ +#ifndef S_IRWXU +#define S_IRWXU (_S_IREAD|_S_IWRITE) +#endif /* internal variables */ static const char *prog; @@ -214,9 +218,9 @@ write_file(Bytef *source, uLongf sourceLen) if (!dest) error("out of memory"); - gettimeofday(&timer_start, NULL); + HDgettimeofday(&timer_start, NULL); compress_buffer(dest, &destLen, source, sourceLen); - gettimeofday(&timer_stop, NULL); + HDgettimeofday(&timer_stop, NULL); compression_time += ((double)timer_stop.tv_sec + ((double)timer_stop.tv_usec) / MICROSECOND) - @@ -508,7 +512,7 @@ do_write_test(unsigned long file_size, unsigned long min_buf_size, printf("\n"); /* do uncompressed data write */ - gettimeofday(&timer_start, NULL); + HDgettimeofday(&timer_start, NULL); output = HDopen(filename, O_RDWR | O_CREAT, S_IRWXU); if (output == -1) @@ -534,7 +538,7 @@ do_write_test(unsigned long file_size, unsigned long min_buf_size, } close(output); - gettimeofday(&timer_stop, NULL); + HDgettimeofday(&timer_stop, NULL); total_time = ((double)timer_stop.tv_sec + ((double)timer_stop.tv_usec) / MICROSECOND) - @@ -554,13 +558,13 @@ do_write_test(unsigned long file_size, unsigned long min_buf_size, error(strerror(errno)); report_once_flag = 1; - gettimeofday(&timer_start, NULL); + HDgettimeofday(&timer_start, NULL); for (total_len = 0; total_len < file_size; total_len += src_len) write_file(src, src_len); close(output); - gettimeofday(&timer_stop, NULL); + HDgettimeofday(&timer_stop, NULL); total_time = ((double)timer_stop.tv_sec + ((double)timer_stop.tv_usec) / MICROSECOND) - diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 84af92e..cc51a6b 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -1,4 +1,4 @@ -HDF5 version 1.9.66-FA_a4 currently under development +HDF5 version 1.9.67-FA_a4 currently under development ================================================================================ @@ -39,6 +39,9 @@ New Features Configuration: ------------- + - Upgraded versions of autotools used to generate configuration suite. + We now use Automake 1.11.1, Autoconf 2.65, and Libtool 2.2.6b. + MAM 2010/04/15. - Added the xlc-* and mpcc_r-* BASENAME patterns to be recognized as IBM compilers so that the ibm compiler options can be added properly. This allows non-system-default compiler command names (e.g. xlc-m.n.k.l) be @@ -210,6 +213,8 @@ Bug Fixes since HDF5-1.8.0 release Library ------- + - Fixed a bug when copying objects with NULL references with the + H5O_COPY_EXPAND_REFERENCE_FLAG flag set. (NAF - 2010/04/08 - 1815) - Files can now be concurrently opened more than once using the core file driver, as long as the backing store is used. (NAF - 2010/03/09) - Added support for H5O_COPY_EXPAND_EXT_LINK_FLAG to H5Ocopy. External @@ -154,7 +154,7 @@ static herr_t H5AC_log_deleted_entry(H5AC_t * cache_ptr, haddr_t addr, unsigned int flags); -static herr_t H5AC_log_dirtied_entry(const H5C_cache_entry_t *entry_ptr, +static herr_t H5AC_log_dirtied_entry(const H5AC_info_t * entry_ptr, haddr_t addr, hbool_t size_changed, size_t new_size); @@ -482,6 +482,7 @@ static const char * H5AC_entry_type_names[H5AC_NTYPES] = "local heap data blocks", "global heaps", "object headers", + "object header chunks", "v2 B-tree headers", "v2 B-tree internal nodes", "v2 B-tree leaf nodes", @@ -2822,7 +2823,6 @@ herr_t H5AC_validate_config(H5AC_cache_config_t * config_ptr) { herr_t result; - int name_len; H5C_auto_size_ctl_t internal_config; herr_t ret_value = SUCCEED; /* Return value */ @@ -2861,6 +2861,7 @@ H5AC_validate_config(H5AC_cache_config_t * config_ptr) /* don't bother to test trace_file_name unless open_trace_file is TRUE */ if ( config_ptr->open_trace_file ) { + size_t name_len; /* Can't really test the trace_file_name field without trying to * open the file, so we will content ourselves with a couple of diff --git a/src/H5ACprivate.h b/src/H5ACprivate.h index 04c3577..abfbb96 100644 --- a/src/H5ACprivate.h +++ b/src/H5ACprivate.h @@ -49,6 +49,7 @@ typedef enum { H5AC_LHEAP_DBLK_ID, /*local heap data block */ H5AC_GHEAP_ID, /*global heap */ H5AC_OHDR_ID, /*object header */ + H5AC_OHDR_CHK_ID, /*object header chunk */ H5AC_BT2_HDR_ID, /*v2 B-tree header */ H5AC_BT2_INT_ID, /*v2 B-tree internal node */ H5AC_BT2_LEAF_ID, /*v2 B-tree leaf node */ diff --git a/src/H5Adeprec.c b/src/H5Adeprec.c index 77f5736..2b244fd 100644 --- a/src/H5Adeprec.c +++ b/src/H5Adeprec.c @@ -334,6 +334,19 @@ H5Aget_num_attrs(hid_t loc_id) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get location for object") break; + case H5I_UNINIT: + case H5I_BADID: + case H5I_FILE: + case H5I_DATASPACE: + case H5I_ATTR: + case H5I_REFERENCE: + case H5I_VFL: + case H5I_GENPROP_CLS: + case H5I_GENPROP_LST: + case H5I_ERROR_CLASS: + case H5I_ERROR_MSG: + case H5I_ERROR_STACK: + case H5I_NTYPES: default: HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "inappropriate attribute target") } /*lint !e788 All appropriate cases are covered */ @@ -1511,7 +1511,7 @@ H5B_remove_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type HDmemmove(bt->child + idx, bt->child + idx + 1, - (bt->nchildren - idx) * sizeof(haddr_t)); + (bt->nchildren - 1 - idx) * sizeof(haddr_t)); bt->nchildren -= 1; bt_flags |= H5AC__DIRTIED_FLAG; @@ -654,7 +654,7 @@ H5B2_index(H5B2_t *bt2, hid_t dxpl_id, H5_iter_order_t order, hsize_t idx, } /* end if */ else /* Index that is greater than the number of records in the tree? */ - HDassert("Index off end of tree??" && 0); + HDassert(0 && "Index off end of tree??"); } /* end if */ /* Decrement depth we're at in B-tree */ diff --git a/src/H5B2pkg.h b/src/H5B2pkg.h index 6307187..dd8f67b 100644 --- a/src/H5B2pkg.h +++ b/src/H5B2pkg.h @@ -248,7 +248,7 @@ H5_DLLVAR const H5B2_class_t H5B2_TEST[1]; #endif /* H5B2_TESTING */ /* Array of v2 B-tree client ID -> client class mappings */ -extern const H5B2_class_t *const H5B2_client_class_g[]; +extern const H5B2_class_t *const H5B2_client_class_g[H5B2_NUM_BTREE_ID]; /******************************/ @@ -620,8 +620,7 @@ done: H5SL_close(cache_ptr->slist_ptr); cache_ptr->magic = 0; - (void)H5FL_FREE(H5C_t, cache_ptr); - cache_ptr = NULL; + cache_ptr = H5FL_FREE(H5C_t, cache_ptr); } /* end if */ diff --git a/src/H5Cpkg.h b/src/H5Cpkg.h index 5ffb0ca..727223b 100644 --- a/src/H5Cpkg.h +++ b/src/H5Cpkg.h @@ -96,11 +96,11 @@ * * JRM - 9/26/05 * - * magic: Unsigned 32 bit integer always set to H5C__H5C_T_MAGIC. - * This field is used to validate pointers to instances of + * magic: Unsigned 32 bit integer always set to H5C__H5C_T_MAGIC. + * This field is used to validate pointers to instances of * H5C_t. * - * flush_in_progress: Boolean flag indicating whether a flush is in + * flush_in_progress: Boolean flag indicating whether a flush is in * progress. * * trace_file_ptr: File pointer pointing to the trace file, which is used @@ -109,7 +109,7 @@ * no trace file should be recorded. * * Since much of the code supporting the parallel metadata - * cache is in H5AC, we don't write the trace file from + * cache is in H5AC, we don't write the trace file from * H5C. Instead, H5AC reads the trace_file_ptr as needed. * * When we get to using H5C in other places, we may add @@ -182,7 +182,7 @@ * writes. The following field is used to implement this. * * evictions_enabled: Boolean flag that is initialized to TRUE. When - * this flag is set to FALSE, the metadata cache will not + * this flag is set to FALSE, the metadata cache will not * attempt to evict entries to make space for newly protected * entries, and instead the will grow without limit. * @@ -288,7 +288,7 @@ * following two fields have been added. They are only compiled in when * H5C_DO_SANITY_CHECKS is TRUE. * - * slist_len_increase: Number of entries that have been added to the + * slist_len_increase: Number of entries that have been added to the * slist since the last time this field was set to zero. * * slist_size_increase: Total size of all entries that have been added @@ -625,23 +625,23 @@ * equal to the array index has not been in cache when * requested in the current epoch. * - * write_protects: Array of int64 of length H5C__MAX_NUM_TYPE_IDS + 1. The - * cells are used to record the number of times an entry with - * type id equal to the array index has been write protected + * write_protects: Array of int64 of length H5C__MAX_NUM_TYPE_IDS + 1. The + * cells are used to record the number of times an entry with + * type id equal to the array index has been write protected * in the current epoch. * * Observe that (hits + misses) = (write_protects + read_protects). * - * read_protects: Array of int64 of length H5C__MAX_NUM_TYPE_IDS + 1. The - * cells are used to record the number of times an entry with - * type id equal to the array index has been read protected in + * read_protects: Array of int64 of length H5C__MAX_NUM_TYPE_IDS + 1. The + * cells are used to record the number of times an entry with + * type id equal to the array index has been read protected in * the current epoch. * * Observe that (hits + misses) = (write_protects + read_protects). * - * max_read_protects: Array of int32 of length H5C__MAX_NUM_TYPE_IDS + 1. - * The cells are used to maximum number of simultaneous read - * protects on any entry with type id equal to the array index + * max_read_protects: Array of int32 of length H5C__MAX_NUM_TYPE_IDS + 1. + * The cells are used to maximum number of simultaneous read + * protects on any entry with type id equal to the array index * in the current epoch. * * insertions: Array of int64 of length H5C__MAX_NUM_TYPE_IDS + 1. The cells @@ -649,9 +649,9 @@ * id equal to the array index has been inserted into the * cache in the current epoch. * - * pinned_insertions: Array of int64 of length H5C__MAX_NUM_TYPE_IDS + 1. - * The cells are used to record the number of times an entry - * with type id equal to the array index has been inserted + * pinned_insertions: Array of int64 of length H5C__MAX_NUM_TYPE_IDS + 1. + * The cells are used to record the number of times an entry + * with type id equal to the array index has been inserted * pinned into the cache in the current epoch. * * clears: Array of int64 of length H5C__MAX_NUM_TYPE_IDS + 1. The cells @@ -674,13 +674,13 @@ * id equal to the array index has been renamed in the current * epoch. * - * entry_flush_renames: Array of int64 of length H5C__MAX_NUM_TYPE_IDS + 1. - * The cells are used to record the number of times an entry + * entry_flush_renames: Array of int64 of length H5C__MAX_NUM_TYPE_IDS + 1. + * The cells are used to record the number of times an entry * with type id equal to the array index has been renamed * during its flush callback in the current epoch. * - * cache_flush_renames: Array of int64 of length H5C__MAX_NUM_TYPE_IDS + 1. - * The cells are used to record the number of times an entry + * cache_flush_renames: Array of int64 of length H5C__MAX_NUM_TYPE_IDS + 1. + * The cells are used to record the number of times an entry * with type id equal to the array index has been renamed * during a cache flush in the current epoch. * @@ -719,14 +719,14 @@ * with type id equal to the array index has decreased in * size in the current epoch. * - * entry_flush_size_changes: Array of int64 of length - * H5C__MAX_NUM_TYPE_IDS + 1. The cells are used to record - * the number of times an entry with type id equal to the + * entry_flush_size_changes: Array of int64 of length + * H5C__MAX_NUM_TYPE_IDS + 1. The cells are used to record + * the number of times an entry with type id equal to the * array index has changed size while in its flush callback. * - * cache_flush_size_changes: Array of int64 of length - * H5C__MAX_NUM_TYPE_IDS + 1. The cells are used to record - * the number of times an entry with type id equal to the + * cache_flush_size_changes: Array of int64 of length + * H5C__MAX_NUM_TYPE_IDS + 1. The cells are used to record + * the number of times an entry with type id equal to the * array index has changed size during a cache flush * * total_ht_insertions: Number of times entries have been inserted into the @@ -860,7 +860,7 @@ #define H5C__HASH_TABLE_LEN (64 * 1024) /* must be a power of 2 */ #define H5C__H5C_T_MAGIC 0x005CAC0E -#define H5C__MAX_NUM_TYPE_IDS 27 +#define H5C__MAX_NUM_TYPE_IDS 28 #define H5C__PREFIX_LEN 32 struct H5C_t @@ -1449,7 +1449,7 @@ if ( ( (entry_ptr) == NULL ) || \ * More pinned entry stats related updates. * * JRM -- 3/31/07 - * Updated H5C__UPDATE_STATS_FOR_PROTECT() to keep stats on + * Updated H5C__UPDATE_STATS_FOR_PROTECT() to keep stats on * read and write protects. * * MAM -- 1/15/09 @@ -2877,7 +2877,7 @@ if ( (cache_ptr)->index_size != \ (cache_ptr)->pel_tail_ptr, \ (cache_ptr)->pel_len, \ (cache_ptr)->pel_size, (fail_val)) \ - \ + \ } else { \ \ /* modified LRU specific code */ \ @@ -3122,62 +3122,70 @@ if ( (cache_ptr)->index_size != \ HDassert( ((entry_ptr)->ro_ref_count) == 0 ); \ HDassert( (entry_ptr)->size > 0 ); \ \ - if ( ! ((entry_ptr)->is_pinned) ) { \ - \ + if ( ! ( (entry_ptr)->is_pinned ) ) { \ + \ /* modified LRU specific code */ \ \ /* remove the entry from the LRU list, and re-insert it at the head. \ */ \ \ - H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->LRU_head_ptr, \ - (cache_ptr)->LRU_tail_ptr, \ - (cache_ptr)->LRU_list_len, \ - (cache_ptr)->LRU_list_size, (fail_val)) \ + H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->LRU_head_ptr, \ + (cache_ptr)->LRU_tail_ptr, \ + (cache_ptr)->LRU_list_len, \ + (cache_ptr)->LRU_list_size, (fail_val)) \ \ H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, \ (cache_ptr)->LRU_tail_ptr, \ (cache_ptr)->LRU_list_len, \ (cache_ptr)->LRU_list_size, (fail_val)) \ \ - /* remove the entry from either the clean or dirty LUR list as \ - * indicated by the was_dirty parameter \ - */ \ - if ( was_dirty ) { \ + /* remove the entry from either the clean or dirty LUR list as \ + * indicated by the was_dirty parameter \ + */ \ + if ( was_dirty ) { \ \ - H5C__AUX_DLL_REMOVE((entry_ptr), (cache_ptr)->dLRU_head_ptr, \ - (cache_ptr)->dLRU_tail_ptr, \ - (cache_ptr)->dLRU_list_len, \ - (cache_ptr)->dLRU_list_size, (fail_val)) \ + H5C__AUX_DLL_REMOVE((entry_ptr), \ + (cache_ptr)->dLRU_head_ptr, \ + (cache_ptr)->dLRU_tail_ptr, \ + (cache_ptr)->dLRU_list_len, \ + (cache_ptr)->dLRU_list_size, \ + (fail_val)) \ \ - } else { \ + } else { \ \ - H5C__AUX_DLL_REMOVE((entry_ptr), (cache_ptr)->cLRU_head_ptr, \ - (cache_ptr)->cLRU_tail_ptr, \ - (cache_ptr)->cLRU_list_len, \ - (cache_ptr)->cLRU_list_size, (fail_val)) \ - } \ + H5C__AUX_DLL_REMOVE((entry_ptr), \ + (cache_ptr)->cLRU_head_ptr, \ + (cache_ptr)->cLRU_tail_ptr, \ + (cache_ptr)->cLRU_list_len, \ + (cache_ptr)->cLRU_list_size, \ + (fail_val)) \ + } \ \ - /* insert the entry at the head of either the clean or dirty LRU \ - * list as appropriate. \ - */ \ + /* insert the entry at the head of either the clean or dirty \ + * LRU list as appropriate. \ + */ \ \ - if ( (entry_ptr)->is_dirty ) { \ + if ( (entry_ptr)->is_dirty ) { \ \ - H5C__AUX_DLL_PREPEND((entry_ptr), (cache_ptr)->dLRU_head_ptr, \ - (cache_ptr)->dLRU_tail_ptr, \ - (cache_ptr)->dLRU_list_len, \ - (cache_ptr)->dLRU_list_size, (fail_val)) \ + H5C__AUX_DLL_PREPEND((entry_ptr), \ + (cache_ptr)->dLRU_head_ptr, \ + (cache_ptr)->dLRU_tail_ptr, \ + (cache_ptr)->dLRU_list_len, \ + (cache_ptr)->dLRU_list_size, \ + (fail_val)) \ \ - } else { \ + } else { \ \ - H5C__AUX_DLL_PREPEND((entry_ptr), (cache_ptr)->cLRU_head_ptr, \ - (cache_ptr)->cLRU_tail_ptr, \ - (cache_ptr)->cLRU_list_len, \ - (cache_ptr)->cLRU_list_size, (fail_val)) \ - } \ + H5C__AUX_DLL_PREPEND((entry_ptr), \ + (cache_ptr)->cLRU_head_ptr, \ + (cache_ptr)->cLRU_tail_ptr, \ + (cache_ptr)->cLRU_list_len, \ + (cache_ptr)->cLRU_list_size, \ + (fail_val)) \ + } \ \ - /* End modified LRU specific code. */ \ - } \ + /* End modified LRU specific code. */ \ + } \ } /* H5C__UPDATE_RP_FOR_RENAME */ #else /* H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS */ @@ -3192,25 +3200,25 @@ if ( (cache_ptr)->index_size != \ HDassert( ((entry_ptr)->ro_ref_count) == 0 ); \ HDassert( (entry_ptr)->size > 0 ); \ \ - if ( ! ((entry_ptr)->is_pinned) ) { \ - \ + if ( ! ( (entry_ptr)->is_pinned ) ) { \ + \ /* modified LRU specific code */ \ \ /* remove the entry from the LRU list, and re-insert it at the head. \ */ \ \ - H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->LRU_head_ptr, \ - (cache_ptr)->LRU_tail_ptr, \ - (cache_ptr)->LRU_list_len, \ - (cache_ptr)->LRU_list_size, (fail_val)) \ + H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->LRU_head_ptr, \ + (cache_ptr)->LRU_tail_ptr, \ + (cache_ptr)->LRU_list_len, \ + (cache_ptr)->LRU_list_size, (fail_val)) \ \ - H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, \ - (cache_ptr)->LRU_tail_ptr, \ - (cache_ptr)->LRU_list_len, \ - (cache_ptr)->LRU_list_size, (fail_val)) \ + H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, \ + (cache_ptr)->LRU_tail_ptr, \ + (cache_ptr)->LRU_list_len, \ + (cache_ptr)->LRU_list_size, (fail_val)) \ \ - /* End modified LRU specific code. */ \ - } \ + /* End modified LRU specific code. */ \ + } \ } /* H5C__UPDATE_RP_FOR_RENAME */ #endif /* H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS */ @@ -3267,7 +3275,7 @@ if ( (cache_ptr)->index_size != \ (cache_ptr)->pel_size, \ (entry_ptr)->size, \ (new_size)); \ - \ + \ } else { \ \ /* modified LRU specific code */ \ @@ -3393,35 +3401,39 @@ if ( (cache_ptr)->index_size != \ (cache_ptr)->pel_size, (fail_val)) \ HDassert( (cache_ptr)->pel_len >= 0 ); \ \ - /* modified LRU specific code */ \ + /* modified LRU specific code */ \ \ - /* insert the entry at the head of the LRU list. */ \ + /* insert the entry at the head of the LRU list. */ \ \ - H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, \ - (cache_ptr)->LRU_tail_ptr, \ - (cache_ptr)->LRU_list_len, \ - (cache_ptr)->LRU_list_size, (fail_val)) \ + H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, \ + (cache_ptr)->LRU_tail_ptr, \ + (cache_ptr)->LRU_list_len, \ + (cache_ptr)->LRU_list_size, (fail_val)) \ \ - /* Similarly, insert the entry at the head of either the clean or \ - * dirty LRU list as appropriate. \ - */ \ + /* Similarly, insert the entry at the head of either the clean \ + * or dirty LRU list as appropriate. \ + */ \ \ - if ( (entry_ptr)->is_dirty ) { \ + if ( (entry_ptr)->is_dirty ) { \ \ - H5C__AUX_DLL_PREPEND((entry_ptr), (cache_ptr)->dLRU_head_ptr, \ - (cache_ptr)->dLRU_tail_ptr, \ - (cache_ptr)->dLRU_list_len, \ - (cache_ptr)->dLRU_list_size, (fail_val)) \ + H5C__AUX_DLL_PREPEND((entry_ptr), \ + (cache_ptr)->dLRU_head_ptr, \ + (cache_ptr)->dLRU_tail_ptr, \ + (cache_ptr)->dLRU_list_len, \ + (cache_ptr)->dLRU_list_size, \ + (fail_val)) \ \ - } else { \ + } else { \ \ - H5C__AUX_DLL_PREPEND((entry_ptr), (cache_ptr)->cLRU_head_ptr, \ - (cache_ptr)->cLRU_tail_ptr, \ - (cache_ptr)->cLRU_list_len, \ - (cache_ptr)->cLRU_list_size, (fail_val)) \ - } \ + H5C__AUX_DLL_PREPEND((entry_ptr), \ + (cache_ptr)->cLRU_head_ptr, \ + (cache_ptr)->cLRU_tail_ptr, \ + (cache_ptr)->cLRU_list_len, \ + (cache_ptr)->cLRU_list_size, \ + (fail_val)) \ + } \ \ - /* End modified LRU specific code. */ \ + /* End modified LRU specific code. */ \ \ } /* H5C__UPDATE_RP_FOR_UNPIN */ @@ -3446,16 +3458,16 @@ if ( (cache_ptr)->index_size != \ (cache_ptr)->pel_size, (fail_val)) \ HDassert( (cache_ptr)->pel_len >= 0 ); \ \ - /* modified LRU specific code */ \ + /* modified LRU specific code */ \ \ - /* insert the entry at the head of the LRU list. */ \ + /* insert the entry at the head of the LRU list. */ \ \ - H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, \ - (cache_ptr)->LRU_tail_ptr, \ - (cache_ptr)->LRU_list_len, \ - (cache_ptr)->LRU_list_size, (fail_val)) \ + H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, \ + (cache_ptr)->LRU_tail_ptr, \ + (cache_ptr)->LRU_list_len, \ + (cache_ptr)->LRU_list_size, (fail_val)) \ \ - /* End modified LRU specific code. */ \ + /* End modified LRU specific code. */ \ \ } /* H5C__UPDATE_RP_FOR_UNPIN */ diff --git a/src/H5Dbtree.c b/src/H5Dbtree.c index c11c0e1..c4e9e90 100644 --- a/src/H5Dbtree.c +++ b/src/H5Dbtree.c @@ -121,7 +121,7 @@ static H5B_ins_t H5D_btree_remove( H5F_t *f, hid_t dxpl_id, haddr_t addr, static herr_t H5D_btree_decode_key(const H5B_shared_t *shared, const uint8_t *raw, void *_key); static herr_t H5D_btree_encode_key(const H5B_shared_t *shared, uint8_t *raw, - void *_key); + const void *_key); static herr_t H5D_btree_debug_key(FILE *stream, int indent, int fwidth, const void *key, const void *udata); @@ -708,9 +708,9 @@ H5D_btree_decode_key(const H5B_shared_t *shared, const uint8_t *raw, void *_key) *------------------------------------------------------------------------- */ static herr_t -H5D_btree_encode_key(const H5B_shared_t *shared, uint8_t *raw, void *_key) +H5D_btree_encode_key(const H5B_shared_t *shared, uint8_t *raw, const void *_key) { - H5D_btree_key_t *key = (H5D_btree_key_t *) _key; + const H5D_btree_key_t *key = (const H5D_btree_key_t *)_key; size_t ndims; unsigned u; diff --git a/src/H5Defl.c b/src/H5Defl.c index 8b2da6a..18750c8 100644 --- a/src/H5Defl.c +++ b/src/H5Defl.c @@ -269,16 +269,16 @@ H5D_efl_read(const H5O_efl_t *efl, haddr_t addr, size_t size, uint8_t *buf) } /* Read the data */ - while (size) { + while(size) { HDassert(buf); - if (u>=efl->nused) - HGOTO_ERROR (H5E_EFL, H5E_OVERFLOW, FAIL, "read past logical end of file") - if (H5F_OVERFLOW_HSIZET2OFFT (efl->slot[u].offset+skip)) - HGOTO_ERROR (H5E_EFL, H5E_OVERFLOW, FAIL, "external file address overflowed") - if ((fd=HDopen (efl->slot[u].name, O_RDONLY, 0))<0) - HGOTO_ERROR (H5E_EFL, H5E_CANTOPENFILE, FAIL, "unable to open external raw data file") - if (HDlseek (fd, (off_t)(efl->slot[u].offset+skip), SEEK_SET)<0) - HGOTO_ERROR (H5E_EFL, H5E_SEEKERROR, FAIL, "unable to seek in external raw data file") + if(u>=efl->nused) + HGOTO_ERROR(H5E_EFL, H5E_OVERFLOW, FAIL, "read past logical end of file") + if(H5F_OVERFLOW_HSIZET2OFFT (efl->slot[u].offset + skip)) + HGOTO_ERROR(H5E_EFL, H5E_OVERFLOW, FAIL, "external file address overflowed") + if((fd = HDopen(efl->slot[u].name, O_RDONLY, 0)) < 0) + HGOTO_ERROR(H5E_EFL, H5E_CANTOPENFILE, FAIL, "unable to open external raw data file") + if(HDlseek(fd, (off_t)(efl->slot[u].offset + skip), SEEK_SET) < 0) + HGOTO_ERROR(H5E_EFL, H5E_SEEKERROR, FAIL, "unable to seek in external raw data file") #ifndef NDEBUG tempto_read = MIN(efl->slot[u].size-skip,(hsize_t)size); H5_CHECK_OVERFLOW(tempto_read,hsize_t,size_t); diff --git a/src/H5Dint.c b/src/H5Dint.c index 228fe83..d252a03 100644 --- a/src/H5Dint.c +++ b/src/H5Dint.c @@ -793,7 +793,7 @@ H5D_update_oh_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset, hid_t dapl_id) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create dataset object header") HDassert(file == dset->oloc.file); - /* Get a pointer to the object header itself */ + /* Pin the object header */ if(NULL == (oh = H5O_pin(oloc, dxpl_id))) HGOTO_ERROR(H5E_DATASET, H5E_CANTPIN, FAIL, "unable to pin dataset object header") @@ -2264,7 +2264,7 @@ H5D_flush_real(H5D_t *dataset, hid_t dxpl_id) if(dataset->shared->layout_dirty || dataset->shared->space_dirty) { unsigned update_flags = H5O_UPDATE_TIME; /* Modification time flag */ - /* Get a pointer to the dataset's object header */ + /* Pin the object header */ if(NULL == (oh = H5O_pin(&dataset->oloc, dxpl_id))) HGOTO_ERROR(H5E_DATASET, H5E_CANTPIN, FAIL, "unable to pin dataset object header") diff --git a/src/H5Dmpio.c b/src/H5Dmpio.c index e111404..fb0c1f4 100644 --- a/src/H5Dmpio.c +++ b/src/H5Dmpio.c @@ -1163,7 +1163,7 @@ if(H5DEBUG(D)) * Note: even there is no selection for this process, the process still * needs to contribute MPI NONE TYPE. */ - if(chunk_io_option[u] == 1) { + if(chunk_io_option[u] == H5D_CHUNK_IO_MODE_COL) { #ifdef H5D_DEBUG if(H5DEBUG(D)) HDfprintf(H5DEBUG(D),"inside collective chunk IO mpi_rank = %d, chunk index = %Zu\n", mpi_rank, u); @@ -1206,7 +1206,7 @@ if(H5DEBUG(D)) HDassert(chunk_io_option[u] == 0); #if !defined(H5_MPI_COMPLEX_DERIVED_DATATYPE_WORKS) || !defined(H5_MPI_SPECIAL_COLLECTIVE_IO_WORKS) - /* Check if this process has somethign to do with this chunk */ + /* Check if this process has something to do with this chunk */ if(chunk_info) { H5D_io_info_t *chk_io_info; /* Pointer to I/O info object for this chunk */ H5D_chunk_ud_t udata; /* B-tree pass-through */ @@ -1849,7 +1849,7 @@ H5D_obtain_mpio_mode(H5D_io_info_t* io_info, H5D_chunk_map_t *fm, MPI_Comm comm; int ic, root; int mpi_code; - int mem_cleanup = 0; + hbool_t mem_cleanup = FALSE; #ifdef H5_HAVE_INSTRUMENTED_LIBRARY int new_value; htri_t check_prop; @@ -1890,8 +1890,7 @@ H5D_obtain_mpio_mode(H5D_io_info_t* io_info, H5D_chunk_map_t *fm, tempbuf = mergebuf + total_chunks; if(mpi_rank == root) recv_io_mode_info = (uint8_t *)H5MM_malloc(total_chunks * mpi_size); - - mem_cleanup = 1; + mem_cleanup = TRUE; /* Obtain the regularity and selection information for all chunks in this process. */ chunk_node = H5SL_first(fm->sel_chunks); @@ -1911,7 +1910,7 @@ H5D_obtain_mpio_mode(H5D_io_info_t* io_info, H5D_chunk_map_t *fm, chunk_node = H5SL_next(chunk_node); } /* end while */ - /*Gather all the information */ + /* Gather all the information */ if(MPI_SUCCESS != (mpi_code = MPI_Gather(io_mode_info, total_chunks, MPI_BYTE, recv_io_mode_info, total_chunks, MPI_BYTE, root, comm))) HMPI_GOTO_ERROR(FAIL, "MPI_Gather failed", mpi_code) diff --git a/src/H5Doh.c b/src/H5Doh.c index de4fb17..8236ccd 100644 --- a/src/H5Doh.c +++ b/src/H5Doh.c @@ -163,7 +163,7 @@ H5O_dset_free_copy_file_udata(void *_udata) H5O_msg_free(H5O_LAYOUT_ID, udata->src_layout); /* Release space for 'copy file' user data */ - (void)H5FL_FREE(H5D_copy_file_ud_t, udata); + udata = H5FL_FREE(H5D_copy_file_ud_t, udata); FUNC_LEAVE_NOAPI_VOID } /* end H5O_dset_free_copy_file_udata() */ diff --git a/src/H5EApkg.h b/src/H5EApkg.h index 319ae51..d3fe569 100644 --- a/src/H5EApkg.h +++ b/src/H5EApkg.h @@ -355,7 +355,7 @@ H5_DLLVAR const H5EA_class_t H5EA_CLS_TEST[1]; #endif /* H5EA_TESTING */ /* Array of extensible array client ID -> client class mappings */ -extern const H5EA_class_t *const H5EA_client_class_g[]; +extern const H5EA_class_t *const H5EA_client_class_g[H5EA_NUM_CLS_ID]; /******************************/ diff --git a/src/H5FApkg.h b/src/H5FApkg.h index 04bf6da..9f82a32 100644 --- a/src/H5FApkg.h +++ b/src/H5FApkg.h @@ -227,7 +227,7 @@ H5_DLLVAR const H5FA_class_t H5FA_CLS_FILT_CHUNK[1]; H5_DLLVAR const H5FA_class_t H5FA_CLS_TEST[1]; /* Array of fixed array client ID -> client class mappings */ -extern const H5FA_class_t *const H5FA_client_class_g[]; +extern const H5FA_class_t *const H5FA_client_class_g[H5FA_NUM_CLS_ID]; /******************************/ diff --git a/src/H5FDmpio.c b/src/H5FDmpio.c index 5e5349d..1c246ae 100644 --- a/src/H5FDmpio.c +++ b/src/H5FDmpio.c @@ -637,7 +637,6 @@ done: FUNC_LEAVE_API(ret_value) } - /*------------------------------------------------------------------------- * Function: H5Pset_dxpl_mpio_chunk_opt_num @@ -1407,15 +1406,15 @@ H5FD_mpio_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t dxpl_id, haddr_t add { H5FD_mpio_t *file = (H5FD_mpio_t*)_file; MPI_Offset mpi_off; - MPI_Status mpi_stat; + MPI_Status mpi_stat; /* Status from I/O operation */ int mpi_code; /* mpi return code */ - MPI_Datatype buf_type=MPI_BYTE; /* MPI description of the selection in memory */ + MPI_Datatype buf_type = MPI_BYTE; /* MPI description of the selection in memory */ int size_i; /* Integer copy of 'size' to read */ int bytes_read; /* Number of bytes read in */ int n; int type_size; /* MPI datatype used for I/O's size */ int io_size; /* Actual number of bytes requested */ - H5P_genplist_t *plist; /* Property list pointer */ + H5P_genplist_t *plist = NULL; /* Property list pointer */ hbool_t use_view_this_time = FALSE; herr_t ret_value = SUCCEED; @@ -1498,6 +1497,7 @@ H5FD_mpio_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t dxpl_id, haddr_t add fprintf(stdout, "H5FD_mpio_read: using MPIO collective mode\n"); #endif /* Peek the collective_opt property to check whether the application wants to do IO individually. */ + HDassert(plist); coll_opt_mode = (H5FD_mpio_collective_opt_t)H5P_peek_unsigned(plist, H5D_XFER_MPIO_COLLECTIVE_OPT_NAME); if(coll_opt_mode == H5FD_MPIO_COLLECTIVE_IO) { @@ -1692,15 +1692,15 @@ H5FD_mpio_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, { H5FD_mpio_t *file = (H5FD_mpio_t*)_file; MPI_Offset mpi_off; - MPI_Status mpi_stat; - MPI_Datatype buf_type=MPI_BYTE; /* MPI description of the selection in memory */ + MPI_Status mpi_stat; /* Status from I/O operation */ + MPI_Datatype buf_type = MPI_BYTE; /* MPI description of the selection in memory */ int mpi_code; /* MPI return code */ int size_i, bytes_written; int type_size; /* MPI datatype used for I/O's size */ int io_size; /* Actual number of bytes requested */ hbool_t use_view_this_time = FALSE; - H5P_genplist_t *plist; /* Property list pointer */ - herr_t ret_value=SUCCEED; + H5P_genplist_t *plist = NULL; /* Property list pointer */ + herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI(H5FD_mpio_write, FAIL) @@ -1730,14 +1730,14 @@ H5FD_mpio_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, fprintf(stdout, "in H5FD_mpio_write mpi_off=%ld size_i=%d\n", (long)mpi_off, size_i); #endif - /* Obtain the data transfer properties */ - if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list") - if(type == H5FD_MEM_DRAW) { H5FD_mpio_xfer_t xfer_mode; /* I/O tranfer mode */ /* Obtain the data transfer properties */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list") + + /* Obtain the data transfer properties */ xfer_mode = (H5FD_mpio_xfer_t)H5P_peek_unsigned(plist, H5D_XFER_IO_XFER_MODE_NAME); /* @@ -1790,6 +1790,7 @@ H5FD_mpio_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, fprintf(stdout, "H5FD_mpio_write: using MPIO collective mode\n"); #endif /* Peek the collective_opt property to check whether the application wants to do IO individually. */ + HDassert(plist); coll_opt_mode = (H5FD_mpio_collective_opt_t)H5P_peek_unsigned(plist, H5D_XFER_MPIO_COLLECTIVE_OPT_NAME); /*OKAY: CAST DISCARDS CONST QUALIFIER*/ @@ -2352,7 +2352,7 @@ H5FL_fac_term(H5FL_fac_head_t *factory) } /* end else */ /* Free factory info */ - (void)H5FL_FREE(H5FL_fac_head_t, factory); + factory = H5FL_FREE(H5FL_fac_head_t, factory); done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5Faccum.c b/src/H5Faccum.c index e525a08..426a639 100644 --- a/src/H5Faccum.c +++ b/src/H5Faccum.c @@ -126,68 +126,68 @@ H5F_accum_read(const H5F_t *f, hid_t dxpl_id, H5FD_mem_t type, haddr_t addr, /* Check if this information is in the metadata accumulator */ if((f->shared->feature_flags & H5FD_FEAT_ACCUMULATE_METADATA) && type != H5FD_MEM_DRAW && size < H5F_ACCUM_MAX_SIZE) { - /* Current read overlaps with metadata accumulator */ - if(H5F_addr_overlap(addr, size, f->shared->accum.loc, f->shared->accum.size)) { - unsigned char *read_buf = (unsigned char *)buf; /* Pointer to the buffer being read in */ - size_t amount_read; /* Amount to read at a time */ - hsize_t read_off; /* Offset to read from */ + /* Sanity check */ + HDassert(!f->shared->accum.buf || (f->shared->accum.alloc_size >= f->shared->accum.size)); + + /* Current read adjoins or overlaps with metadata accumulator */ + if(H5F_addr_overlap(addr, size, f->shared->accum.loc, f->shared->accum.size) + || ((addr + size) == f->shared->accum.loc) + || (f->shared->accum.loc + f->shared->accum.size) == addr) { + size_t amount_before; /* Amount to read before current accumulator */ + haddr_t new_addr; /* New address of the accumulator buffer */ + size_t new_size; /* New size of the accumulator buffer */ + + /* Compute new values for accumulator */ + new_addr = MIN(addr, f->shared->accum.loc); + new_size = (size_t)(MAX((addr + size), (f->shared->accum.loc + f->shared->accum.size)) + - new_addr); + + /* Check if we need more buffer space */ + if(new_size > f->shared->accum.size) { + /* Adjust the buffer size, by doubling it */ + f->shared->accum.alloc_size = MAX(f->shared->accum.alloc_size * 2, new_size); + + /* Reallocate the metadata accumulator buffer */ + if(NULL == (f->shared->accum.buf = H5FL_BLK_REALLOC(meta_accum, f->shared->accum.buf, f->shared->accum.alloc_size))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "unable to allocate metadata accumulator buffer") +#ifdef H5_CLEAR_MEMORY +HDmemset(f->shared->accum.buf + f->shared->accum.size, 0, (f->shared->accum.alloc_size - f->shared->accum.size)); +#endif /* H5_CLEAR_MEMORY */ + } /* end if */ /* Read the part before the metadata accumulator */ if(addr < f->shared->accum.loc) { /* Set the amount to read */ - H5_ASSIGN_OVERFLOW(amount_read, (f->shared->accum.loc - addr), hsize_t, size_t); + H5_ASSIGN_OVERFLOW(amount_before, (f->shared->accum.loc - addr), hsize_t, size_t); + + /* Make room for the metadata to read in */ + HDmemmove(f->shared->accum.buf + amount_before, f->shared->accum.buf, f->shared->accum.size); /* Dispatch to driver */ - if(H5FD_read(f->shared->lf, dxpl_id, type, addr, amount_read, read_buf) < 0) + if(H5FD_read(f->shared->lf, dxpl_id, type, addr, amount_before, f->shared->accum.buf) < 0) HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "driver read request failed") - - /* Adjust the buffer, address & size */ - read_buf += amount_read; - addr += amount_read; - size -= amount_read; } /* end if */ + else + amount_before = 0; - /* Copy the part overlapping the metadata accumulator */ - if(size > 0 && (addr >= f->shared->accum.loc && addr < (f->shared->accum.loc + f->shared->accum.size))) { - /* Set the offset to "read" from */ - read_off = addr - f->shared->accum.loc; - - /* Set the amount to "read" */ -#ifndef NDEBUG -{ - hsize_t tempamount_read; /* Amount to read at a time */ - - tempamount_read = f->shared->accum.size - read_off; - H5_CHECK_OVERFLOW(tempamount_read, hsize_t, size_t); - amount_read = MIN(size, (size_t)tempamount_read); -} -#else /* NDEBUG */ - amount_read = MIN(size, (size_t)(f->shared->accum.size - read_off)); -#endif /* NDEBUG */ - - /* Copy the data out of the buffer */ - HDmemcpy(read_buf, f->shared->accum.buf + read_off, amount_read); + /* Read the part after the metadata accumulator */ + if((addr + size) > (f->shared->accum.loc + f->shared->accum.size)) { + size_t amount_after; /* Amount to read at a time */ - /* Adjust the buffer, address & size */ - read_buf += amount_read; - addr += amount_read; - size -= amount_read; - } /* end if */ + /* Set the amount to read */ + H5_ASSIGN_OVERFLOW(amount_after, ((addr + size) - (f->shared->accum.loc + f->shared->accum.size)), hsize_t, size_t); - /* Read the part after the metadata accumulator */ - if(size > 0 && addr >= (f->shared->accum.loc + f->shared->accum.size)) { /* Dispatch to driver */ - if(H5FD_read(f->shared->lf, dxpl_id, type, addr, size, read_buf) < 0) + if(H5FD_read(f->shared->lf, dxpl_id, type, (f->shared->accum.loc + f->shared->accum.size), amount_after, (f->shared->accum.buf + f->shared->accum.size + amount_before)) < 0) HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "driver read request failed") - - /* Adjust the buffer, address & size */ - read_buf += size; - addr += size; - size -= size; } /* end if */ - /* Make certain we've read it all */ - HDassert(size == 0); + /* Copy the data out of the buffer */ + HDmemcpy(buf, f->shared->accum.buf + (addr - new_addr), size); + + /* Adjust the accumulator address & size */ + f->shared->accum.loc = new_addr; + f->shared->accum.size = new_size; } /* end if */ /* Current read doesn't overlap with metadata accumulator, read it from file */ else { @@ -340,6 +340,9 @@ H5F_accum_write(const H5F_t *f, hid_t dxpl_id, H5FD_mem_t type, haddr_t addr, /* Check for accumulating metadata */ if((f->shared->feature_flags & H5FD_FEAT_ACCUMULATE_METADATA) && type != H5FD_MEM_DRAW && size < H5F_ACCUM_MAX_SIZE) { + /* Sanity check */ + HDassert(!f->shared->accum.buf || (f->shared->accum.alloc_size >= f->shared->accum.size)); + /* Check if there is already metadata in the accumulator */ if(f->shared->accum.size > 0) { /* Check if the new metadata adjoins the beginning of the current accumulator */ @@ -433,8 +436,30 @@ H5F_accum_write(const H5F_t *f, hid_t dxpl_id, H5FD_mem_t type, haddr_t addr, /* Mark it as written to */ f->shared->accum.dirty = TRUE; } /* end if */ + /* New metadata overlaps both ends of the current accumulator */ else { - HDassert(0 && "New metadata overlapped both beginning and end of existing metadata accumulator!"); + /* Check if we need more buffer space */ + if(size > f->shared->accum.size) { + /* Adjust the buffer size, by doubling it */ + f->shared->accum.alloc_size = MAX(f->shared->accum.alloc_size * 2, size); + + /* Reallocate the metadata accumulator buffer */ + if(NULL == (f->shared->accum.buf = H5FL_BLK_REALLOC(meta_accum, f->shared->accum.buf, f->shared->accum.alloc_size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer") +#ifdef H5_CLEAR_MEMORY +HDmemset(f->shared->accum.buf + size, 0, (f->shared->accum.alloc_size - size)); +#endif /* H5_CLEAR_MEMORY */ + } /* end if */ + + /* Copy the new metadata to the buffer */ + HDmemcpy(f->shared->accum.buf, buf, size); + + /* Set the new size & location of the metadata accumulator */ + f->shared->accum.loc = addr; + f->shared->accum.size = size; + + /* Mark it as written to */ + f->shared->accum.dirty = TRUE; } /* end else */ } /* end if */ /* New piece of metadata doesn't adjoin or overlap the existing accumulator */ diff --git a/src/H5Ffake.c b/src/H5Ffake.c index e96aedf..f71d373 100644 --- a/src/H5Ffake.c +++ b/src/H5Ffake.c @@ -120,8 +120,8 @@ H5F_fake_free(H5F_t *f) if(f) { /* Destroy shared file struct */ if(f->shared) - f->shared = (H5F_file_t *)H5FL_FREE(H5F_file_t, f->shared); - (void)H5FL_FREE(H5F_t, f); + f->shared = H5FL_FREE(H5F_file_t, f->shared); + f = H5FL_FREE(H5F_t, f); } /* end if */ FUNC_LEAVE_NOAPI(SUCCEED) diff --git a/src/H5Fsfile.c b/src/H5Fsfile.c index 708fbf7..8144986 100644 --- a/src/H5Fsfile.c +++ b/src/H5Fsfile.c @@ -219,7 +219,7 @@ H5F_sfile_remove(H5F_file_t *shared) /* Release the shared file node struct */ /* (the shared file info itself is freed elsewhere) */ - (void)H5FL_FREE(H5F_sfile_node_t, curr); + curr = H5FL_FREE(H5F_sfile_node_t, curr); done: FUNC_LEAVE_NOAPI(ret_value) @@ -1772,8 +1772,7 @@ H5G_visit(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5G_t *grp = NULL; /* Group opened */ H5G_loc_t loc; /* Location of group passed in */ H5G_loc_t start_loc; /* Location of starting group */ - H5O_type_t otype; /* Basic object type (group, dataset, etc.) */ - unsigned rc; /* Reference count of object */ + unsigned rc; /* Reference count of object */ herr_t ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5G_visit, FAIL) @@ -1814,8 +1813,8 @@ H5G_visit(hid_t loc_id, const char *group_name, H5_index_t idx_type, if((udata.visited = H5SL_create(H5SL_TYPE_OBJ)) == NULL) HGOTO_ERROR(H5E_SYM, H5E_CANTCREATE, FAIL, "can't create skip list for visited objects") - /* Get the group's reference count and type */ - if(H5O_get_rc_and_type(&grp->oloc, dxpl_id, &rc, &otype) < 0) + /* Get the group's reference count */ + if(H5O_get_rc_and_type(&grp->oloc, dxpl_id, &rc, NULL) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to get object info") /* If its ref count is > 1, we add it to the list of visited objects */ diff --git a/src/H5Gobj.c b/src/H5Gobj.c index 7766280..daad6ae 100644 --- a/src/H5Gobj.c +++ b/src/H5Gobj.c @@ -901,7 +901,7 @@ H5G_obj_remove_update_linfo(H5O_loc_t *oloc, H5O_linfo_t *linfo, hid_t dxpl_id) if(H5G_dense_build_table(oloc->file, dxpl_id, linfo, H5_INDEX_NAME, H5_ITER_NATIVE, <able) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTNEXT, FAIL, "error iterating over links") - /* Get a pointer to the object header itself */ + /* Pin the object header */ if(NULL == (oh = H5O_pin(oloc, dxpl_id))) HGOTO_ERROR(H5E_SYM, H5E_CANTPIN, FAIL, "unable to pin group object header") @@ -451,9 +451,9 @@ H5MP_close(H5MP_pool_t *mp) /* Free the page appropriately */ if(page->fac_alloc) - page = H5FL_FAC_FREE(mp->page_fac, page); + page = (H5MP_page_t *)H5FL_FAC_FREE(mp->page_fac, page); else - page = H5MM_xfree(page); + page = (H5MP_page_t *)H5MM_xfree(page); page = next_page; } /* end while */ @@ -142,6 +142,9 @@ H5FL_SEQ_DEFINE(H5O_chunk_t); /* Declare a free list to manage the chunk image information */ H5FL_BLK_DEFINE(chunk_image); +/* Declare external the free list for H5O_cont_t sequences */ +H5FL_SEQ_EXTERN(H5O_cont_t); + /*****************************/ /* Library Private Variables */ @@ -1174,7 +1177,7 @@ H5O_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, hid_t ocpl_id, /* Determine correct value for chunk #0 size bits */ /* Avoid compiler warning on 32-bit machines */ #if H5_SIZEOF_SIZE_T > H5_SIZEOF_INT32_T - if(size_hint > 4294967295) + if(size_hint > 4294967295UL) oh->flags |= H5O_HDR_CHUNK0_8; else #endif /* H5_SIZEOF_SIZE_T > H5_SIZEOF_INT32_T */ @@ -1190,7 +1193,7 @@ H5O_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, hid_t ocpl_id, /* Compute total size of initial object header */ /* (i.e. object header prefix and first chunk) */ - oh_size = H5O_SIZEOF_HDR(oh) + size_hint; + oh_size = (size_t)H5O_SIZEOF_HDR(oh) + size_hint; /* Allocate disk space for header and first chunk */ if(HADDR_UNDEF == (oh_addr = H5MF_alloc(f, H5FD_MEM_OHDR, dxpl_id, (hsize_t)oh_size))) @@ -1202,7 +1205,6 @@ H5O_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, hid_t ocpl_id, HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") /* Initialize the first chunk */ - oh->chunk[0].dirty = TRUE; oh->chunk[0].addr = oh_addr; oh->chunk[0].size = oh_size; oh->chunk[0].gap = 0; @@ -1458,13 +1460,18 @@ done: *------------------------------------------------------------------------- */ int -H5O_link_oh(H5F_t *f, int adjust, hid_t dxpl_id, H5O_t *oh, unsigned *oh_flags) +H5O_link_oh(H5F_t *f, int adjust, hid_t dxpl_id, H5O_t *oh, hbool_t *deleted) { haddr_t addr = H5O_OH_GET_ADDR(oh); /* Object header address */ int ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5O_link_oh, FAIL) + /* check args */ + HDassert(f); + HDassert(oh); + HDassert(deleted); + /* Check for adjusting link count */ if(adjust) { if(adjust < 0) { @@ -1476,7 +1483,8 @@ H5O_link_oh(H5F_t *f, int adjust, hid_t dxpl_id, H5O_t *oh, unsigned *oh_flags) oh->nlink += adjust; /* Mark object header as dirty in cache */ - *oh_flags |= H5AC__DIRTIED_FLAG; + if(H5AC_mark_pinned_or_protected_entry_dirty(oh) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTMARKDIRTY, FAIL, "unable to mark object header as dirty") /* Check if the object should be deleted */ if(oh->nlink == 0) { @@ -1487,12 +1495,8 @@ H5O_link_oh(H5F_t *f, int adjust, hid_t dxpl_id, H5O_t *oh, unsigned *oh_flags) HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "can't mark object for deletion") } /* end if */ else { - /* Delete object right now */ - if(H5O_delete_oh(f, dxpl_id, oh) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "can't delete object from file") - /* Mark the object header for deletion */ - *oh_flags = H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG; + *deleted = TRUE; } /* end else */ } /* end if */ } /* end if */ @@ -1511,7 +1515,8 @@ H5O_link_oh(H5F_t *f, int adjust, hid_t dxpl_id, H5O_t *oh, unsigned *oh_flags) oh->nlink += adjust; /* Mark object header as dirty in cache */ - *oh_flags |= H5AC__DIRTIED_FLAG; + if(H5AC_mark_pinned_or_protected_entry_dirty(oh) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTMARKDIRTY, FAIL, "unable to mark object header as dirty") } /* end if */ /* Check for operations on refcount message */ @@ -1521,7 +1526,7 @@ H5O_link_oh(H5F_t *f, int adjust, hid_t dxpl_id, H5O_t *oh, unsigned *oh_flags) /* Check for removing refcount message */ if(oh->nlink <= 1) { if(H5O_msg_remove_real(f, oh, H5O_MSG_REFCOUNT, H5O_ALL, NULL, NULL, TRUE, dxpl_id) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete refcount message") + HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "unable to delete refcount message") oh->has_refcount_msg = FALSE; } /* end if */ /* Update refcount message with new link count */ @@ -1529,7 +1534,7 @@ H5O_link_oh(H5F_t *f, int adjust, hid_t dxpl_id, H5O_t *oh, unsigned *oh_flags) H5O_refcount_t refcount = oh->nlink; if(H5O_msg_write_real(f, dxpl_id, oh, H5O_MSG_REFCOUNT, H5O_MSG_FLAG_DONTSHARE, 0, &refcount) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTUPDATE, FAIL, "unable to update refcount message") + HGOTO_ERROR(H5E_OHDR, H5E_CANTUPDATE, FAIL, "unable to update refcount message") } /* end else */ } /* end if */ else { @@ -1538,7 +1543,7 @@ H5O_link_oh(H5F_t *f, int adjust, hid_t dxpl_id, H5O_t *oh, unsigned *oh_flags) H5O_refcount_t refcount = oh->nlink; if(H5O_msg_append_real(f, dxpl_id, oh, H5O_MSG_REFCOUNT, H5O_MSG_FLAG_DONTSHARE, 0, &refcount) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "unable to create new refcount message") + HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "unable to create new refcount message") oh->has_refcount_msg = TRUE; } /* end if */ } /* end else */ @@ -1549,7 +1554,7 @@ H5O_link_oh(H5F_t *f, int adjust, hid_t dxpl_id, H5O_t *oh, unsigned *oh_flags) ret_value = (int)oh->nlink; done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_link_oh() */ @@ -1573,9 +1578,8 @@ int H5O_link(const H5O_loc_t *loc, int adjust, hid_t dxpl_id) { H5O_t *oh = NULL; - H5AC_protect_t oh_acc; /* Access mode for protecting object header */ - unsigned oh_flags = H5AC__NO_FLAGS_SET; /* Whether the object was deleted */ - int ret_value; /* Return value */ + hbool_t deleted = FALSE; /* Whether the object was deleted */ + int ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5O_link, FAIL) @@ -1584,29 +1588,30 @@ H5O_link(const H5O_loc_t *loc, int adjust, hid_t dxpl_id) HDassert(loc->file); HDassert(H5F_addr_defined(loc->addr)); - /* Get header */ - oh_acc = adjust ? H5AC_WRITE : H5AC_READ; - if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, oh_acc))) - HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header") + /* Pin the object header */ + if(NULL == (oh = H5O_pin(loc, dxpl_id))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTPIN, FAIL, "unable to pin object header") /* Call the "real" link routine */ - if((ret_value = H5O_link_oh(loc->file, adjust, dxpl_id, oh, &oh_flags)) < 0) + if((ret_value = H5O_link_oh(loc->file, adjust, dxpl_id, oh, &deleted)) < 0) HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, "unable to adjust object link count") done: - if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, oh_flags) < 0) - HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header") + if(oh && H5O_unpin(oh) < 0) + HDONE_ERROR(H5E_OHDR, H5E_CANTUNPIN, FAIL, "unable to unpin object header") + if(ret_value >= 0 && deleted && H5O_delete(loc->file, dxpl_id, loc->addr) < 0) + HDONE_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "can't delete object from file") FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_link() */ /*------------------------------------------------------------------------- - * Function: H5O_pin + * Function: H5O_protect * - * Purpose: Pin an object header down for use during a sequence of message - * operations, which prevents the object header from being - * evicted from the cache. + * Purpose: Wrapper around H5AC_protect for use during a H5O_protect-> + * H5O_msg_append->...->H5O_msg_append->H5O_unprotect sequence of calls + * during an object's creation. * * Return: Success: Pointer to the object header structure for the * object. @@ -1619,12 +1624,15 @@ done: *------------------------------------------------------------------------- */ H5O_t * -H5O_pin(H5O_loc_t *loc, hid_t dxpl_id) +H5O_protect(const H5O_loc_t *loc, hid_t dxpl_id, H5AC_protect_t prot) { - H5O_t *oh = NULL; /* Object header */ - H5O_t *ret_value; /* Return value */ + H5O_t *oh = NULL; /* Object header protected */ + H5O_cache_ud_t udata; /* User data for protecting object header */ + H5O_cont_msgs_t cont_msg_info; /* Continuation message info */ + unsigned file_intent; /* R/W intent on file */ + H5O_t *ret_value; /* Return value */ - FUNC_ENTER_NOAPI(H5O_pin, NULL) + FUNC_ENTER_NOAPI(H5O_protect, NULL) /* check args */ HDassert(loc); @@ -1632,29 +1640,228 @@ H5O_pin(H5O_loc_t *loc, hid_t dxpl_id) HDassert(H5F_addr_defined(loc->addr)); /* Check for write access on the file */ - if(0 == (H5F_INTENT(loc->file) & H5F_ACC_RDWR)) + file_intent = H5F_INTENT(loc->file); + if((prot == H5AC_WRITE) && (0 == (file_intent & H5F_ACC_RDWR))) HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "no write intent on file") + /* Construct the user data for protect callback */ + udata.made_attempt = FALSE; + udata.v1_pfx_nmesgs = 0; + udata.common.f = loc->file; + udata.common.dxpl_id = dxpl_id; + udata.common.file_intent = file_intent; + udata.common.merged_null_msgs = 0; + udata.common.mesgs_modified = FALSE; + HDmemset(&cont_msg_info, 0, sizeof(cont_msg_info)); + udata.common.cont_msg_info = &cont_msg_info; + /* Lock the object header into the cache */ - if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_WRITE))) + if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, &udata, prot))) HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, NULL, "unable to load object header") - /* Check if the object header needs to be pinned */ - if(0 == oh->npins) { - /* Mark object header as un-evictable */ - if(H5AC_pin_protected_entry(oh) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTPIN, NULL, "unable to pin object header") + /* Check if there are any continuation messages to process */ + if(cont_msg_info.nmsgs > 0) { + size_t curr_msg; /* Current continuation message to process */ + H5O_chk_cache_ud_t chk_udata; /* User data for loading chunk */ + + /* Sanity check - we should only have continuation messages to process + * when the object header is actually loaded from the file. + */ + HDassert(udata.made_attempt == TRUE); + + /* Construct the user data for protecting chunks */ + chk_udata.decoding = TRUE; + chk_udata.oh = oh; + chk_udata.chunkno = UINT_MAX; /* Set to invalid value, for better error detection */ + chk_udata.common.f = loc->file; + chk_udata.common.dxpl_id = dxpl_id; + chk_udata.common.file_intent = file_intent; + chk_udata.common.merged_null_msgs = udata.common.merged_null_msgs; + chk_udata.common.mesgs_modified = udata.common.mesgs_modified; + chk_udata.common.cont_msg_info = &cont_msg_info; + + /* Read in continuation messages, until there are no more */ + curr_msg = 0; + while(curr_msg < cont_msg_info.nmsgs) { + H5O_chunk_proxy_t *chk_proxy; /* Proxy for chunk, to bring it into memory */ +#ifndef NDEBUG + unsigned chkcnt = oh->nchunks; /* Count of chunks (for sanity checking) */ +#endif /* NDEBUG */ + + /* Bring the chunk into the cache */ + /* (which adds to the object header */ + chk_udata.chunk_size = cont_msg_info.msgs[curr_msg].size; + if(NULL == (chk_proxy = (H5O_chunk_proxy_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR_CHK, cont_msg_info.msgs[curr_msg].addr, NULL, &chk_udata, prot))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, NULL, "unable to load object header chunk") + + /* Sanity check */ + HDassert(chk_proxy->oh == oh); + HDassert(chk_proxy->chunkno == chkcnt); + HDassert(oh->nchunks == (chkcnt + 1)); + + /* Release the chunk from the cache */ + if(H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR_CHK, cont_msg_info.msgs[curr_msg].addr, chk_proxy, H5AC__NO_FLAGS_SET) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, NULL, "unable to release object header chunk") + + /* Advance to next continuation message */ + curr_msg++; + } /* end while */ + + /* Release any continuation messages built up */ + if(cont_msg_info.msgs) + cont_msg_info.msgs = (H5O_cont_t *)H5FL_SEQ_FREE(H5O_cont_t, cont_msg_info.msgs); + + /* Pass back out some of the chunk's user data */ + udata.common.merged_null_msgs = chk_udata.common.merged_null_msgs; + udata.common.mesgs_modified = chk_udata.common.mesgs_modified; } /* end if */ - /* Increment the pin count */ - oh->npins++; + /* Check for incorrect # of object header messages, if we've just loaded + * this object header from the file + */ + if(udata.made_attempt) { + /* Check for incorrect # of messages in v1 object header */ + if(oh->version == H5O_VERSION_1 && + (oh->nmesgs + udata.common.merged_null_msgs) != udata.v1_pfx_nmesgs) { +/* Don't enforce the error on an incorrect # of object header messages bug + * unless strict format checking is enabled. This allows for older + * files, created with a version of the library that had a bug in tracking + * the correct # of header messages to be read in without the library + * erroring out here. -QAK + */ +#ifdef H5_STRICT_FORMAT_CHECKS + HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "corrupt object header - incorrect # of messages") +#else /* H5_STRICT_FORMAT_CHECKS */ + /* Mark object header prefix dirty later if we don't have write access */ + /* (object header will have been marked dirty during protect, if we + * have write access -QAK) + */ + if(prot != H5AC_WRITE) + oh->prefix_modified = TRUE; +#ifndef NDEBUG + else { + unsigned oh_status = 0; /* Object header entry cache status */ + + /* Check the object header's status in the metadata cache */ + if(H5AC_get_entry_status(loc->file, loc->addr, &oh_status) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, NULL, "unable to check metadata cache status for object header") + + /* Make certain that object header is not dirty */ + HDassert(!(oh_status & H5AC_ES__IS_DIRTY)); + } /* end else */ +#endif /* NDEBUG */ +#endif /* H5_STRICT_FORMAT_CHECKS */ + } /* end if */ + + /* Check for any messages that were modified while being read in */ + if(udata.common.mesgs_modified && prot != H5AC_WRITE) + oh->mesgs_modified = TRUE; + } /* end if */ + + /* Take care of loose ends for modifications made while bringing in the + * object header & chunks. + */ + if(prot == H5AC_WRITE) { + /* Check for the object header prefix being modified somehow */ + /* (usually through updating the # of object header messages) */ + if(oh->prefix_modified) { + /* Mark the header as dirty now */ + if(H5AC_mark_pinned_or_protected_entry_dirty(oh) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTMARKDIRTY, NULL, "unable to mark object header as dirty") + + /* Reset flag */ + oh->prefix_modified = FALSE; + } /* end if */ + + /* Check for deferred dirty messages */ + if(oh->mesgs_modified) { + unsigned u; /* Local index variable */ + + /* Loop through all messages, marking their chunks as dirty */ + /* (slightly inefficient, since we don't know exactly which messages + * were modified when the object header & chunks were brought in + * from the file, but this only can happen once per load -QAK) + */ + for(u = 0; u < oh->nmesgs; u++) { + /* Mark each chunk with a dirty message as dirty also */ + if(oh->mesg[u].dirty) { + H5O_chunk_proxy_t *chk_proxy; /* Chunk that message is in */ + + /* Protect chunk */ + if(NULL == (chk_proxy = H5O_chunk_protect(loc->file, dxpl_id, oh, oh->mesg[u].chunkno))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, NULL, "unable to load object header chunk") + + /* Unprotect chunk, marking it dirty */ + if(H5O_chunk_unprotect(loc->file, dxpl_id, oh, chk_proxy, H5AC__DIRTIED_FLAG) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, NULL, "unable to unprotect object header chunk") + } /* end if */ + } /* end for */ + + /* Reset flag */ + oh->mesgs_modified = FALSE; + } /* end if */ + } /* end if */ + +#ifdef H5O_DEBUG +H5O_assert(oh); +#endif /* H5O_DEBUG */ + + /* Set return value */ + ret_value = oh; + +done: + if(ret_value == NULL && oh) { + if(H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) < 0) + HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, NULL, "unable to release object header") + } /* end if */ + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_protect() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_pin + * + * Purpose: Pin an object header down for use during a sequence of message + * operations, which prevents the object header from being + * evicted from the cache. + * + * Return: Success: Pointer to the object header structure for the + * object. + * Failure: NULL + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Jul 13 2008 + * + *------------------------------------------------------------------------- + */ +H5O_t * +H5O_pin(const H5O_loc_t *loc, hid_t dxpl_id) +{ + H5O_t *oh = NULL; /* Object header */ + H5O_t *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(H5O_pin, NULL) + + /* check args */ + HDassert(loc); + + /* Get header */ + if(NULL == (oh = H5O_protect(loc, dxpl_id, H5AC_WRITE))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, NULL, "unable to protect object header") + + /* Increment the reference count on the object header */ + /* (which will pin it, if appropriate) */ + if(H5O_inc_rc(oh) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINC, NULL, "unable to increment reference count on object header") /* Set the return value */ ret_value = oh; done: /* Release the object header from the cache */ - if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, ret_value, H5AC__NO_FLAGS_SET) < 0) + if(oh && H5O_unprotect(loc, dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, NULL, "unable to release object header") FUNC_LEAVE_NOAPI(ret_value) @@ -1671,8 +1878,8 @@ done: * Failure: Negative * * Programmer: Quincey Koziol - * koziol@ncsa.uiuc.edu - * Dec 31 2002 + * koziol@hdfgroup.org + * Jul 13 2008 * *------------------------------------------------------------------------- */ @@ -1686,15 +1893,10 @@ H5O_unpin(H5O_t *oh) /* check args */ HDassert(oh); - /* Check if this is the last unpin operation */ - if(1 == oh->npins) { - /* Mark object header as evictable again */ - if(H5AC_unpin_entry(oh) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPIN, FAIL, "unable to unpin object header") - } /* end if */ - - /* Decrement the pin count */ - oh->npins--; + /* Decrement the reference count on the object header */ + /* (which will unpin it, if appropriate) */ + if(H5O_dec_rc(oh) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTDEC, FAIL, "unable to decrement reference count on object header") done: FUNC_LEAVE_NOAPI(ret_value) @@ -1702,6 +1904,42 @@ done: /*------------------------------------------------------------------------- + * Function: H5O_unprotect + * + * Purpose: Wrapper around H5AC_unprotect for use during a H5O_protect-> + * H5O_msg_append->...->H5O_msg_append->H5O_unprotect sequence of calls + * during an object's creation. + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Dec 31 2002 + * + *------------------------------------------------------------------------- + */ +herr_t +H5O_unprotect(const H5O_loc_t *loc, hid_t dxpl_id, H5O_t *oh, unsigned oh_flags) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5O_unprotect, FAIL) + + /* check args */ + HDassert(loc); + HDassert(oh); + + /* Unprotect the object header */ + if(H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, oh->chunk[0].addr, oh, oh_flags) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_unprotect() */ + + +/*------------------------------------------------------------------------- * Function: H5O_touch_oh * * Purpose: If FORCE is non-zero then create a modification time message @@ -1718,6 +1956,8 @@ done: herr_t H5O_touch_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh, hbool_t force) { + H5O_chunk_proxy_t *chk_proxy = NULL; /* Chunk that message is in */ + unsigned chk_flags = H5AC__NO_FLAGS_SET; /* Flags for unprotecting chunk */ time_t now; /* Current time */ herr_t ret_value = SUCCEED; /* Return value */ @@ -1756,6 +1996,10 @@ H5O_touch_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh, hbool_t force) oh->mesg[idx].flags = (uint8_t)mesg_flags; } /* end if */ + /* Protect chunk */ + if(NULL == (chk_proxy = H5O_chunk_protect(f, dxpl_id, oh, oh->mesg[idx].chunkno))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header chunk") + /* Allocate 'native' space, if necessary */ if(NULL == oh->mesg[idx].native) { if(NULL == (oh->mesg[idx].native = H5FL_MALLOC(time_t))) @@ -1767,19 +2011,24 @@ H5O_touch_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh, hbool_t force) /* Mark the message as dirty */ oh->mesg[idx].dirty = TRUE; + chk_flags |= H5AC__DIRTIED_FLAG; } /* end if */ else { /* XXX: For now, update access time & change fields in the object header */ /* (will need to add some code to update modification time appropriately) */ oh->atime = oh->ctime = now; - } /* end else */ - /* Mark object header as dirty in cache */ - if(H5AC_mark_pinned_or_protected_entry_dirty(oh) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTMARKDIRTY, FAIL, "unable to mark object header as dirty") + /* Mark object header as dirty in cache */ + if(H5AC_mark_pinned_or_protected_entry_dirty(oh) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTMARKDIRTY, FAIL, "unable to mark object header as dirty") + } /* end else */ } /* end if */ done: + /* Release chunk */ + if(chk_proxy && H5O_chunk_unprotect(f, dxpl_id, oh, chk_proxy, chk_flags) < 0) + HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to unprotect object header chunk") + FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_touch_oh() */ @@ -1810,13 +2059,9 @@ H5O_touch(const H5O_loc_t *loc, hbool_t force, hid_t dxpl_id) /* check args */ HDassert(loc); - HDassert(loc->file); - HDassert(H5F_addr_defined(loc->addr)); - if(0 == (H5F_INTENT(loc->file) & H5F_ACC_RDWR)) - HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "no write intent on file") /* Get the object header */ - if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_WRITE))) + if(NULL == (oh = H5O_protect(loc, dxpl_id, H5AC_WRITE))) HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header") /* Create/Update the modification time message */ @@ -1827,7 +2072,7 @@ H5O_touch(const H5O_loc_t *loc, hbool_t force, hid_t dxpl_id) oh_flags |= H5AC__DIRTIED_FLAG; done: - if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, oh_flags) < 0) + if(oh && H5O_unprotect(loc, dxpl_id, oh, oh_flags) < 0) HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header") FUNC_LEAVE_NOAPI(ret_value) @@ -1916,6 +2161,8 @@ herr_t H5O_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr) { H5O_t *oh = NULL; /* Object header information */ + H5O_loc_t loc; /* Object location for object to delete */ + unsigned oh_flags = H5AC__NO_FLAGS_SET; /* Flags for unprotecting object header */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5O_delete, FAIL) @@ -1924,16 +2171,24 @@ H5O_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr) HDassert(f); HDassert(H5F_addr_defined(addr)); + /* Set up the object location */ + loc.file = f; + loc.addr = addr; + loc.holding_file = FALSE; + /* Get the object header information */ - if(NULL == (oh = (H5O_t *)H5AC_protect(f, dxpl_id, H5AC_OHDR, addr, NULL, NULL, H5AC_WRITE))) + if(NULL == (oh = H5O_protect(&loc, dxpl_id, H5AC_WRITE))) HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header") /* Delete object */ if(H5O_delete_oh(f, dxpl_id, oh) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "can't delete object from file") + /* Mark object header as deleted */ + oh_flags = H5AC__DIRTIED_FLAG | H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG; + done: - if(oh && H5AC_unprotect(f, dxpl_id, H5AC_OHDR, addr, oh, H5AC__DIRTIED_FLAG | H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG) < 0) + if(oh && H5O_unprotect(&loc, dxpl_id, oh, oh_flags) < 0) HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header") FUNC_LEAVE_NOAPI(ret_value) @@ -2006,7 +2261,7 @@ H5O_obj_type(const H5O_loc_t *loc, H5O_type_t *obj_type, hid_t dxpl_id) FUNC_ENTER_NOAPI(H5O_obj_type, FAIL) /* Load the object header */ - if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ))) + if(NULL == (oh = H5O_protect(loc, dxpl_id, H5AC_READ))) HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header") /* Retrieve the type of the object */ @@ -2014,7 +2269,7 @@ H5O_obj_type(const H5O_loc_t *loc, H5O_type_t *obj_type, hid_t dxpl_id) HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to determine object type") done: - if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) < 0) + if(oh && H5O_unprotect(loc, dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header") FUNC_LEAVE_NOAPI(ret_value) @@ -2084,7 +2339,7 @@ H5O_obj_class(const H5O_loc_t *loc, hid_t dxpl_id) FUNC_ENTER_NOAPI_NOINIT(H5O_obj_class) /* Load the object header */ - if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ))) + if(NULL == (oh = H5O_protect(loc, dxpl_id, H5AC_READ))) HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, NULL, "unable to load object header") /* Test whether entry qualifies as a particular type of object */ @@ -2092,7 +2347,7 @@ H5O_obj_class(const H5O_loc_t *loc, hid_t dxpl_id) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, NULL, "unable to determine object type") done: - if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) < 0) + if(oh && H5O_unprotect(loc, dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, NULL, "unable to release object header") FUNC_LEAVE_NOAPI(ret_value) @@ -2355,7 +2610,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5O_get_hdr_info(const H5O_loc_t *oloc, hid_t dxpl_id, H5O_hdr_info_t *hdr) +H5O_get_hdr_info(const H5O_loc_t *loc, hid_t dxpl_id, H5O_hdr_info_t *hdr) { H5O_t *oh = NULL; /* Object header */ herr_t ret_value = SUCCEED; /* Return value */ @@ -2363,14 +2618,14 @@ H5O_get_hdr_info(const H5O_loc_t *oloc, hid_t dxpl_id, H5O_hdr_info_t *hdr) FUNC_ENTER_NOAPI(H5O_get_hdr_info, FAIL) /* Check args */ - HDassert(oloc); + HDassert(loc); HDassert(hdr); /* Reset the object header info structure */ HDmemset(hdr, 0, sizeof(*hdr)); /* Get the object header */ - if(NULL == (oh = (H5O_t *)H5AC_protect(oloc->file, dxpl_id, H5AC_OHDR, oloc->addr, NULL, NULL, H5AC_READ))) + if(NULL == (oh = H5O_protect(loc, dxpl_id, H5AC_READ))) HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header") /* Get the information for the object header */ @@ -2378,7 +2633,7 @@ H5O_get_hdr_info(const H5O_loc_t *oloc, hid_t dxpl_id, H5O_hdr_info_t *hdr) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't retrieve object header info") done: - if(oh && H5AC_unprotect(oloc->file, dxpl_id, H5AC_OHDR, oloc->addr, oh, H5AC__NO_FLAGS_SET) < 0) + if(oh && H5O_unprotect(loc, dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header") FUNC_LEAVE_NOAPI(ret_value) @@ -2494,7 +2749,7 @@ H5O_get_info(const H5O_loc_t *loc, hid_t dxpl_id, hbool_t want_ih_info, HDassert(oinfo); /* Get the object header */ - if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ))) + if(NULL == (oh = H5O_protect(loc, dxpl_id, H5AC_READ))) HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header") /* Reset the object info structure */ @@ -2582,7 +2837,7 @@ H5O_get_info(const H5O_loc_t *loc, hid_t dxpl_id, hbool_t want_ih_info, } /* end if */ done: - if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) < 0) + if(oh && H5O_unprotect(loc, dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header") FUNC_LEAVE_NOAPI(ret_value) @@ -2615,7 +2870,7 @@ H5O_get_create_plist(const H5O_loc_t *loc, hid_t dxpl_id, H5P_genplist_t *oc_pli HDassert(oc_plist); /* Get the object header */ - if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ))) + if(NULL == (oh = H5O_protect(loc, dxpl_id, H5AC_READ))) HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header") /* Set property values, if they were used for the object */ @@ -2637,7 +2892,7 @@ H5O_get_create_plist(const H5O_loc_t *loc, hid_t dxpl_id, H5P_genplist_t *oc_pli } /* end if */ done: - if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) < 0) + if(oh && H5O_unprotect(loc, dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header") FUNC_LEAVE_NOAPI(ret_value) @@ -2670,14 +2925,14 @@ H5O_get_nlinks(const H5O_loc_t *loc, hid_t dxpl_id, hsize_t *nlinks) HDassert(nlinks); /* Get the object header */ - if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ))) + if(NULL == (oh = H5O_protect(loc, dxpl_id, H5AC_READ))) HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header") /* Retrieve the # of link messages seen when the object header was loaded */ *nlinks = oh->link_msgs_seen; done: - if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) < 0) + if(oh && H5O_unprotect(loc, dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header") FUNC_LEAVE_NOAPI(ret_value) @@ -2785,22 +3040,22 @@ H5O_get_rc_and_type(const H5O_loc_t *loc, hid_t dxpl_id, unsigned *rc, H5O_type_ /* Check args */ HDassert(loc); - HDassert(rc); - HDassert(otype); /* Get the object header */ - if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ))) + if(NULL == (oh = H5O_protect(loc, dxpl_id, H5AC_READ))) HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header") /* Set the object's reference count */ - *rc = oh->nlink; + if(rc) + *rc = oh->nlink; /* Retrieve the type of the object */ - if(H5O_obj_type_real(oh, otype) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to determine object type") + if(otype) + if(H5O_obj_type_real(oh, otype) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to determine object type") done: - if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) < 0) + if(oh && H5O_unprotect(loc, dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header") FUNC_LEAVE_NOAPI(ret_value) @@ -2824,7 +3079,7 @@ H5O_free_visit_visited(void *item, void UNUSED *key, void UNUSED *operator_data/ { FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_free_visit_visited) - (void)H5FL_FREE(H5_obj_t, item); + item = H5FL_FREE(H5_obj_t, item); FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5O_free_visit_visited() */ @@ -3063,6 +3318,78 @@ done: /*------------------------------------------------------------------------- + * Function: H5O_inc_rc + * + * Purpose: Increments the reference count on an object header + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Jul 13 2008 + * + *------------------------------------------------------------------------- + */ +herr_t +H5O_inc_rc(H5O_t *oh) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5O_inc_rc, FAIL) + + /* check args */ + HDassert(oh); + + /* Pin the object header when the reference count goes above 0 */ + if(oh->rc == 0) + if(H5AC_pin_protected_entry(oh) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTPIN, FAIL, "unable to pin object header") + + /* Increment reference count */ + oh->rc++; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_inc_rc() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_dec_rc + * + * Purpose: Decrements the reference count on an object header + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Jul 13 2008 + * + *------------------------------------------------------------------------- + */ +herr_t +H5O_dec_rc(H5O_t *oh) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5O_dec_rc, FAIL) + + /* check args */ + HDassert(oh); + + /* Decrement reference count */ + oh->rc--; + + /* Unpin the object header when the reference count goes back to 0 */ + if(oh->rc == 0) + if(H5AC_unpin_entry(oh) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPIN, FAIL, "unable to unpin object header") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_dec_rc() */ + + +/*------------------------------------------------------------------------- * Function: H5O_free * * Purpose: Destroys an object header. @@ -3087,12 +3414,8 @@ H5O_free(H5O_t *oh) /* Destroy chunks */ if(oh->chunk) { - for(u = 0; u < oh->nchunks; u++) { - /* Verify that chunk is clean */ - HDassert(oh->chunk[u].dirty == 0); - + for(u = 0; u < oh->nchunks; u++) oh->chunk[u].image = H5FL_BLK_FREE(chunk_image, oh->chunk[u].image); - } /* end for */ oh->chunk = (H5O_chunk_t *)H5FL_SEQ_FREE(H5O_chunk_t, oh->chunk); } /* end if */ diff --git a/src/H5Oalloc.c b/src/H5Oalloc.c index bcd0749..764ce54 100644 --- a/src/H5Oalloc.c +++ b/src/H5Oalloc.c @@ -58,21 +58,24 @@ /* Local Prototypes */ /********************/ -static herr_t H5O_add_gap(H5O_t *oh, unsigned chunkno, unsigned idx, - uint8_t *new_gap_loc, size_t new_gap_size); -static herr_t H5O_eliminate_gap(H5O_t *oh, H5O_mesg_t *mesg, - uint8_t *new_gap_loc, size_t new_gap_size); -static herr_t H5O_alloc_null(H5O_t *oh, unsigned null_idx, +static herr_t H5O_add_gap(H5F_t *f, hid_t dxpl_id, H5O_t *oh, + H5O_chunk_proxy_t *chk_proxy, unsigned *chk_flags, + unsigned idx, uint8_t *new_gap_loc, size_t new_gap_size); +static herr_t H5O_eliminate_gap(H5F_t *f, hid_t dxpl_id, H5O_t *oh, + H5O_chunk_proxy_t *chk_proxy, unsigned *chk_flags, + H5O_mesg_t *mesg, uint8_t *new_gap_loc, size_t new_gap_size); +static herr_t H5O_alloc_null(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned null_idx, const H5O_msg_class_t *new_type, void *new_native, size_t new_size); static htri_t H5O_alloc_extend_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned chunkno, size_t size, unsigned * msg_idx); static unsigned H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t size); -static htri_t H5O_move_cont(H5F_t *f, H5O_t *oh, unsigned cont_u, hid_t dxpl_id); -static htri_t H5O_move_msgs_forward(H5F_t *f, H5O_t *oh, hid_t dxpl_id); -static htri_t H5O_merge_null(H5F_t *f, H5O_t *oh, hid_t dxpl_id); +static htri_t H5O_move_cont(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned cont_u); +static htri_t H5O_move_msgs_forward(H5F_t *f, hid_t dxpl_id, H5O_t *oh); +static htri_t H5O_merge_null(H5F_t *f, hid_t dxpl_id, H5O_t *oh); static htri_t H5O_remove_empty_chunks(H5F_t *f, hid_t dxpl_id, H5O_t *oh); -static herr_t H5O_alloc_shrink_chunk(H5F_t *f, H5O_t *oh, hid_t dxpl_id, unsigned chunkno); +static herr_t H5O_alloc_shrink_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, + unsigned chunkno); /*********************/ @@ -108,8 +111,8 @@ H5FL_EXTERN(H5O_cont_t); *------------------------------------------------------------------------- */ static herr_t -H5O_add_gap(H5O_t *oh, unsigned chunkno, unsigned idx, - uint8_t *new_gap_loc, size_t new_gap_size) +H5O_add_gap(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5O_chunk_proxy_t *chk_proxy, + unsigned *chk_flags, unsigned idx, uint8_t *new_gap_loc, size_t new_gap_size) { hbool_t merged_with_null; /* Whether the gap was merged with a null message */ unsigned u; /* Local index variable */ @@ -120,6 +123,8 @@ H5O_add_gap(H5O_t *oh, unsigned chunkno, unsigned idx, /* check args */ HDassert(oh); HDassert(oh->version > H5O_VERSION_1); + HDassert(chk_proxy); + HDassert(chk_flags); HDassert(new_gap_loc); HDassert(new_gap_size); @@ -128,13 +133,13 @@ H5O_add_gap(H5O_t *oh, unsigned chunkno, unsigned idx, for(u = 0; u < oh->nmesgs && !merged_with_null; u++) { /* Find a null message in the chunk with the new gap */ /* (a null message that's not the one we are eliminating) */ - if(H5O_NULL_ID == oh->mesg[u].type->id && oh->mesg[u].chunkno == chunkno + if(H5O_NULL_ID == oh->mesg[u].type->id && oh->mesg[u].chunkno == chk_proxy->chunkno && u != idx) { /* Sanity check - chunks with null messages shouldn't have a gap */ - HDassert(oh->chunk[chunkno].gap == 0); + HDassert(oh->chunk[chk_proxy->chunkno].gap == 0); /* Eliminate the gap in the chunk */ - if(H5O_eliminate_gap(oh, &oh->mesg[u], new_gap_loc, new_gap_size) < 0) + if(H5O_eliminate_gap(f, dxpl_id, oh, chk_proxy, chk_flags, &oh->mesg[u], new_gap_loc, new_gap_size) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "can't eliminate gap in chunk") /* Set flag to indicate that the gap was handled */ @@ -146,15 +151,15 @@ H5O_add_gap(H5O_t *oh, unsigned chunkno, unsigned idx, if(!merged_with_null) { /* Adjust message offsets after new gap forward in chunk */ for(u = 0; u < oh->nmesgs; u++) - if(oh->mesg[u].chunkno == chunkno && oh->mesg[u].raw > new_gap_loc) + if(oh->mesg[u].chunkno == chk_proxy->chunkno && oh->mesg[u].raw > new_gap_loc) oh->mesg[u].raw -= new_gap_size; /* Slide raw message info forward in chunk image */ HDmemmove(new_gap_loc, new_gap_loc + new_gap_size, - (size_t)((oh->chunk[chunkno].image + (oh->chunk[chunkno].size - H5O_SIZEOF_CHKSUM_OH(oh))) - (new_gap_loc + new_gap_size))); + (size_t)((oh->chunk[chk_proxy->chunkno].image + (oh->chunk[chk_proxy->chunkno].size - H5O_SIZEOF_CHKSUM_OH(oh))) - (new_gap_loc + new_gap_size))); /* Add existing gap size to new gap size */ - new_gap_size += oh->chunk[chunkno].gap; + new_gap_size += oh->chunk[chk_proxy->chunkno].gap; /* Merging with existing gap will allow for a new null message */ if(new_gap_size >= (size_t)H5O_SIZEOF_MSGHDR_OH(oh)) { @@ -166,16 +171,16 @@ H5O_add_gap(H5O_t *oh, unsigned chunkno, unsigned idx, HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate more space for messages") /* Increment new gap size */ - oh->chunk[chunkno].gap += new_gap_size; + oh->chunk[chk_proxy->chunkno].gap += new_gap_size; /* Create new null message, with the tail of the previous null message */ null_msg = &(oh->mesg[oh->nmesgs++]); null_msg->type = H5O_MSG_NULL; null_msg->native = NULL; null_msg->raw_size = new_gap_size - H5O_SIZEOF_MSGHDR_OH(oh); - null_msg->raw = (oh->chunk[chunkno].image + oh->chunk[chunkno].size) + null_msg->raw = (oh->chunk[chk_proxy->chunkno].image + oh->chunk[chk_proxy->chunkno].size) - (H5O_SIZEOF_CHKSUM_OH(oh) + null_msg->raw_size); - null_msg->chunkno = chunkno; + null_msg->chunkno = chk_proxy->chunkno; /* Zero out new null message's raw data */ if(null_msg->raw_size) @@ -185,10 +190,13 @@ H5O_add_gap(H5O_t *oh, unsigned chunkno, unsigned idx, null_msg->dirty = TRUE; /* Reset size of gap in chunk */ - oh->chunk[chunkno].gap = 0; + oh->chunk[chk_proxy->chunkno].gap = 0; } /* end if */ else - oh->chunk[chunkno].gap = new_gap_size; + oh->chunk[chk_proxy->chunkno].gap = new_gap_size; + + /* Mark the chunk as modified */ + *chk_flags |= H5AC__DIRTIED_FLAG; } /* end if */ done: @@ -199,7 +207,14 @@ done: /*------------------------------------------------------------------------- * Function: H5O_eliminate_gap * - * Purpose: Eliminate a gap in a chunk with a null message + * Purpose: Eliminate a gap in a chunk with a null message. + * + * Note: Sometimes this happens as a result of converting an existing + * non-null message to a null message, so we zero out the gap + * here, even though it might already be zero (when we're adding + * a gap to a chunk with an existing null message). (Mostly, + * this just simplifies the code, esp. with the necessary chunk + * locking -QAK) * * Return: Non-negative on success/Negative on failure * @@ -210,16 +225,20 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5O_eliminate_gap(H5O_t *oh, H5O_mesg_t *mesg, uint8_t *gap_loc, size_t gap_size) +H5O_eliminate_gap(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5O_chunk_proxy_t *chk_proxy, + unsigned *chk_flags, H5O_mesg_t *mesg, uint8_t *gap_loc, size_t gap_size) { uint8_t *move_start, *move_end; /* Pointers to area of messages to move */ hbool_t null_before_gap; /* Flag whether the null message is before the gap or not */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_eliminate_gap) + FUNC_ENTER_NOAPI_NOINIT(H5O_eliminate_gap) /* check args */ HDassert(oh); HDassert(oh->version > H5O_VERSION_1); + HDassert(chk_proxy); + HDassert(chk_flags); HDassert(mesg); HDassert(gap_loc); HDassert(gap_size); @@ -242,6 +261,7 @@ H5O_eliminate_gap(H5O_t *oh, H5O_mesg_t *mesg, uint8_t *gap_loc, size_t gap_size unsigned u; /* Local index variable */ /* Look for messages that need to move, to adjust raw pointers in chunk */ + /* (this doesn't change the moved messages 'dirty' state) */ for(u = 0; u < oh->nmesgs; u++) { uint8_t *msg_start; /* Start of encoded message in chunk */ @@ -282,10 +302,15 @@ H5O_eliminate_gap(H5O_t *oh, H5O_mesg_t *mesg, uint8_t *gap_loc, size_t gap_size /* Adjust size of null message */ mesg->raw_size += gap_size; + /* Set the gap size to zero for the chunk */ + oh->chunk[mesg->chunkno].gap = 0; + /* Mark null message as dirty */ mesg->dirty = TRUE; + *chk_flags |= H5AC__DIRTIED_FLAG; - FUNC_LEAVE_NOAPI(SUCCEED) +done: + FUNC_LEAVE_NOAPI(ret_value) } /* H5O_eliminate_gap() */ @@ -304,9 +329,11 @@ H5O_eliminate_gap(H5O_t *oh, H5O_mesg_t *mesg, uint8_t *gap_loc, size_t gap_size *------------------------------------------------------------------------- */ static herr_t -H5O_alloc_null(H5O_t *oh, unsigned null_idx, const H5O_msg_class_t *new_type, - void *new_native, size_t new_size) +H5O_alloc_null(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned null_idx, + const H5O_msg_class_t *new_type, void *new_native, size_t new_size) { + H5O_chunk_proxy_t *chk_proxy = NULL; /* Chunk that message is in */ + unsigned chk_flags = H5AC__NO_FLAGS_SET; /* Flags for unprotecting chunk */ H5O_mesg_t *alloc_msg; /* Pointer to null message to allocate out of */ herr_t ret_value = SUCCEED; /* Return value */ @@ -320,6 +347,10 @@ H5O_alloc_null(H5O_t *oh, unsigned null_idx, const H5O_msg_class_t *new_type, /* Point to null message to allocate out of */ alloc_msg = &oh->mesg[null_idx]; + /* Protect chunk */ + if(NULL == (chk_proxy = H5O_chunk_protect(f, dxpl_id, oh, alloc_msg->chunkno))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header chunk") + /* Check if there's a need to split the null message */ if(alloc_msg->raw_size > new_size) { /* Check for producing a gap in the chunk */ @@ -330,7 +361,7 @@ H5O_alloc_null(H5O_t *oh, unsigned null_idx, const H5O_msg_class_t *new_type, alloc_msg->raw_size = new_size; /* Add the gap to the chunk */ - if(H5O_add_gap(oh, alloc_msg->chunkno, null_idx, alloc_msg->raw + alloc_msg->raw_size, gap_size) < 0) + if(H5O_add_gap(f, dxpl_id, oh, chk_proxy, &chk_flags, null_idx, alloc_msg->raw + alloc_msg->raw_size, gap_size) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "can't insert gap in chunk") } /* end if */ else { @@ -356,19 +387,17 @@ H5O_alloc_null(H5O_t *oh, unsigned null_idx, const H5O_msg_class_t *new_type, /* Mark the message as dirty */ null_msg->dirty = TRUE; + chk_flags |= H5AC__DIRTIED_FLAG; /* Check for gap in new null message's chunk */ if(oh->chunk[null_msg->chunkno].gap > 0) { unsigned null_chunkno = null_msg->chunkno; /* Chunk w/gap */ /* Eliminate the gap in the chunk */ - if(H5O_eliminate_gap(oh, null_msg, + if(H5O_eliminate_gap(f, dxpl_id, oh, chk_proxy, &chk_flags, null_msg, ((oh->chunk[null_chunkno].image + oh->chunk[null_chunkno].size) - (H5O_SIZEOF_CHKSUM_OH(oh) + oh->chunk[null_chunkno].gap)), oh->chunk[null_chunkno].gap) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTREMOVE, FAIL, "can't eliminate gap in chunk") - - /* Set the gap size to zero for the chunk */ - oh->chunk[null_chunkno].gap = 0; } /* end if */ /* Set the size of the new "real" message */ @@ -382,8 +411,13 @@ H5O_alloc_null(H5O_t *oh, unsigned null_idx, const H5O_msg_class_t *new_type, /* Mark the new message as dirty */ alloc_msg->dirty = TRUE; + chk_flags |= H5AC__DIRTIED_FLAG; done: + /* Release chunk */ + if(chk_proxy && H5O_chunk_unprotect(f, dxpl_id, oh, chk_proxy, chk_flags) < 0) + HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to unprotect object header chunk") + FUNC_LEAVE_NOAPI(ret_value) } /* H5O_alloc_null() */ @@ -467,6 +501,8 @@ static htri_t H5O_alloc_extend_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned chunkno, size_t size, unsigned * msg_idx) { + H5O_chunk_proxy_t *chk_proxy = NULL; /* Chunk that message is in */ + unsigned chk_flags = H5AC__NO_FLAGS_SET; /* Flags for unprotecting chunk */ size_t delta; /* Change in chunk's size */ size_t aligned_size = H5O_ALIGN_OH(oh, size); uint8_t *old_image; /* Old address of chunk's image in memory */ @@ -500,7 +536,7 @@ H5O_alloc_extend_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned chunkno, == ((oh->chunk[chunkno].image + oh->chunk[chunkno].size) - (oh->chunk[chunkno].gap + H5O_SIZEOF_CHKSUM_OH(oh))))) { - extend_msg = u; + extend_msg = (int)u; break; } /* end if */ } /* end for */ @@ -516,7 +552,10 @@ H5O_alloc_extend_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned chunkno, /* Check for changing the chunk #0 data size enough to need adjusting the flags */ if(oh->version > H5O_VERSION_1 && chunkno == 0) { - uint64_t chunk0_size = oh->chunk[0].size - H5O_SIZEOF_HDR(oh); /* Size of chunk 0's data */ + uint64_t chunk0_size; /* Size of chunk 0's data */ + + HDassert(oh->chunk[0].size >= (size_t)H5O_SIZEOF_HDR(oh)); + chunk0_size = oh->chunk[0].size - (size_t)H5O_SIZEOF_HDR(oh); /* Check for moving from a 1-byte to a 2-byte size encoding */ if(chunk0_size <= 255 && (chunk0_size + delta) > 255) { @@ -546,16 +585,23 @@ H5O_alloc_extend_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned chunkno, else if(extended == FALSE) /* can't extend -- we are done */ HGOTO_DONE(FALSE) + /* Protect chunk */ + if(NULL == (chk_proxy = H5O_chunk_protect(f, dxpl_id, oh, chunkno))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header chunk") + /* Adjust object header prefix flags */ if(adjust_size_flags) { - oh->flags &= ~H5O_HDR_CHUNK0_SIZE; + oh->flags &= (uint8_t)~H5O_HDR_CHUNK0_SIZE; oh->flags |= new_size_flags; + + /* Mark object header as dirty in cache */ + if(H5AC_mark_pinned_or_protected_entry_dirty(oh) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTMARKDIRTY, FAIL, "unable to mark object header as dirty") } /* end if */ /* If we can extend an existing null message, take care of that */ if(extend_msg >= 0) { /* Adjust message size of existing null message */ - oh->mesg[extend_msg].dirty = TRUE; oh->mesg[extend_msg].raw_size += delta; } /* end if */ /* Create new null message for end of chunk */ @@ -566,11 +612,10 @@ H5O_alloc_extend_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned chunkno, HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate more space for messages") /* Set extension message */ - extend_msg = oh->nmesgs++; + extend_msg = (int)oh->nmesgs++; /* Initialize new null message */ oh->mesg[extend_msg].type = H5O_MSG_NULL; - oh->mesg[extend_msg].dirty = TRUE; oh->mesg[extend_msg].native = NULL; oh->mesg[extend_msg].raw = ((oh->chunk[chunkno].image + oh->chunk[chunkno].size) - (H5O_SIZEOF_CHKSUM_OH(oh) + oh->chunk[chunkno].gap)) @@ -579,13 +624,16 @@ H5O_alloc_extend_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned chunkno, oh->mesg[extend_msg].chunkno = chunkno; } /* end else */ + /* Mark the extended message as dirty */ + oh->mesg[extend_msg].dirty = TRUE; + chk_flags |= H5AC__DIRTIED_FLAG; + /* Allocate more memory space for chunk's image */ old_image = oh->chunk[chunkno].image; old_size = oh->chunk[chunkno].size; oh->chunk[chunkno].size += delta + extra_prfx_size; oh->chunk[chunkno].image = H5FL_BLK_REALLOC(chunk_image, old_image, oh->chunk[chunkno].size); oh->chunk[chunkno].gap = 0; - oh->chunk[chunkno].dirty = TRUE; if(NULL == oh->chunk[chunkno].image) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") @@ -599,6 +647,7 @@ H5O_alloc_extend_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned chunkno, oh->mesg[u].raw = oh->chunk[chunkno].image + extra_prfx_size + (oh->mesg[u].raw - old_image); /* Flag message as dirty directly */ + /* (we mark the entire chunk dirty when we update its size) */ oh->mesg[u].dirty = TRUE; } /* endif */ @@ -607,19 +656,39 @@ H5O_alloc_extend_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned chunkno, * it's size is directly encoded in the object header) */ if(chunkno > 0 && (H5O_CONT_ID == oh->mesg[u].type->id) && (((H5O_cont_t *)(oh->mesg[u].native))->chunkno == chunkno)) { + H5O_chunk_proxy_t *chk_proxy2 = NULL; /* Chunk that continuation message is in */ + unsigned chk_flags2 = H5AC__NO_FLAGS_SET; /* Flags for unprotecting chunk */ + unsigned cont_chunkno = oh->mesg[u].chunkno; /* Chunk # for continuation message */ + + /* Protect chunk containing continuation message */ + if(NULL == (chk_proxy2 = H5O_chunk_protect(f, dxpl_id, oh, cont_chunkno))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header chunk") + /* Adjust size in continuation message */ HDassert(((H5O_cont_t *)(oh->mesg[u].native))->size == old_size); ((H5O_cont_t *)(oh->mesg[u].native))->size = oh->chunk[chunkno].size; /* Flag continuation message as dirty */ oh->mesg[u].dirty = TRUE; + chk_flags2 |= H5AC__DIRTIED_FLAG; + + /* Release chunk containing continuation message */ + if(H5O_chunk_unprotect(f, dxpl_id, oh, chk_proxy2, chk_flags2) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to unprotect object header chunk") } /* end if */ } /* end for */ + /* Mark the chunk size in the cache as changed */ + chk_flags |= H5AC__SIZE_CHANGED_FLAG; + /* Set return value */ - *msg_idx = extend_msg; + *msg_idx = (unsigned)extend_msg; done: + /* Release chunk */ + if(chk_proxy && H5O_chunk_unprotect(f, dxpl_id, oh, chk_proxy, chk_flags) < 0) + HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to unprotect object header chunk") + FUNC_LEAVE_NOAPI(ret_value) } /* H5O_alloc_extend_chunk() */ @@ -672,6 +741,7 @@ H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t size) } alloc_info; H5O_mesg_t *curr_msg; /* Pointer to current message to operate on */ + H5O_chunk_proxy_t *chk_proxy; /* Chunk that message is in */ size_t cont_size; /*continuation message size */ size_t multi_size = 0; /* Size of all the messages in the last chunk */ int found_null = (-1); /* Best fit null message */ @@ -707,12 +777,12 @@ H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t size) for(u = 0, curr_msg = &oh->mesg[0]; u < oh->nmesgs; u++, curr_msg++) { if(curr_msg->type->id == H5O_NULL_ID) { if(cont_size == curr_msg->raw_size) { - found_null = u; + found_null = (int)u; break; } /* end if */ else if(curr_msg->raw_size > cont_size && (found_null < 0 || curr_msg->raw_size < oh->mesg[found_null].raw_size)) - found_null = u; + found_null = (int)u; } /* end if */ else if(curr_msg->type->id == H5O_CONT_ID) { /* Don't consider continuation messages (for now) */ @@ -753,7 +823,7 @@ H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t size) if(total_size >= cont_size) { if(curr_msg->type->id == H5O_ATTR_ID) { if(found_attr.msgno < 0 || total_size < found_attr.total_size) { - found_attr.msgno = u; + found_attr.msgno = (int)u; found_attr.gap_size = gap_size; found_attr.null_size = null_size; found_attr.total_size = total_size; @@ -762,7 +832,7 @@ H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t size) } /* end if */ else { if(found_other.msgno < 0 || total_size < found_other.total_size) { - found_other.msgno = u; + found_other.msgno = (int)u; found_other.gap_size = gap_size; found_other.null_size = null_size; found_other.total_size = total_size; @@ -835,7 +905,6 @@ H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t size) } /* end if */ chunkno = oh->nchunks++; - oh->chunk[chunkno].dirty = TRUE; oh->chunk[chunkno].addr = new_chunk_addr; oh->chunk[chunkno].size = size; oh->chunk[chunkno].gap = 0; @@ -861,9 +930,14 @@ H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t size) if(multi_size > 0) { /* Move all non-null messages in the last chunk to the new chunk. This * should be extremely rare so we don't care too much about minimizing - * the space used */ + * the space used. + */ H5O_mesg_t *null_msg; /* Pointer to new null message */ + /* Protect last chunk */ + if(NULL == (chk_proxy = H5O_chunk_protect(f, dxpl_id, oh, chunkno - 1))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, UFAIL, "unable to load object header chunk") + /* Copy each message to the new location */ for(u = 0, curr_msg = &oh->mesg[0]; u < oh->nmesgs; u++, curr_msg++) if(curr_msg->chunkno == chunkno - 1) { @@ -888,15 +962,15 @@ H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t size) } /* end if */ /* Create a null message spanning the entire last chunk */ - found_null = oh->nmesgs++; + found_null = (int)oh->nmesgs++; null_msg = &(oh->mesg[found_null]); null_msg->type = H5O_MSG_NULL; null_msg->dirty = TRUE; null_msg->native = NULL; - null_msg->raw = oh->chunk[chunkno-1].image + null_msg->raw = oh->chunk[chunkno - 1].image + ((chunkno == 1) ? H5O_SIZEOF_HDR(oh) : H5O_SIZEOF_CHKHDR_OH(oh)) - H5O_SIZEOF_CHKSUM_OH(oh) + H5O_SIZEOF_MSGHDR_OH(oh); - null_msg->raw_size = oh->chunk[chunkno-1].size + null_msg->raw_size = oh->chunk[chunkno - 1].size - ((chunkno == 1) ? H5O_SIZEOF_HDR(oh) : H5O_SIZEOF_CHKHDR_OH(oh)) - H5O_SIZEOF_MSGHDR_OH(oh); null_msg->chunkno = chunkno - 1; @@ -904,16 +978,23 @@ H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t size) HDassert(null_msg->raw_size >= cont_size); /* Remove any gap in the chunk */ - oh->chunk[chunkno-1].gap = 0; + oh->chunk[chunkno - 1].gap = 0; + /* Release chunk, marking it dirty */ + if(H5O_chunk_unprotect(f, dxpl_id, oh, chk_proxy, H5AC__DIRTIED_FLAG) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, UFAIL, "unable to unprotect object header chunk") } else if(found_null < 0) { /* Move message (that will be replaced with continuation message) - * to new chunk, if necessary. - */ + * to new chunk, if necessary. + */ H5O_mesg_t *null_msg; /* Pointer to new null message */ + /* Protect chunk */ + if(NULL == (chk_proxy = H5O_chunk_protect(f, dxpl_id, oh, oh->mesg[found_other.msgno].chunkno))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, UFAIL, "unable to load object header chunk") + /* Create null message for space that message to copy currently occupies */ - found_null = oh->nmesgs++; + found_null = (int)oh->nmesgs++; null_msg = &(oh->mesg[found_null]); null_msg->type = H5O_MSG_NULL; null_msg->native = NULL; @@ -922,7 +1003,6 @@ H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t size) null_msg->chunkno = oh->mesg[found_other.msgno].chunkno; /* Copy the message to move (& its prefix) to its new location */ - /* (Chunk is already dirty, no need to mark it) */ HDmemcpy(p, oh->mesg[found_other.msgno].raw - H5O_SIZEOF_MSGHDR_OH(oh), oh->mesg[found_other.msgno].raw_size + H5O_SIZEOF_MSGHDR_OH(oh)); @@ -965,6 +1045,10 @@ H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t size) /* Mark the new null message as dirty */ null_msg->dirty = TRUE; + + /* Release chunk, marking it dirty */ + if(H5O_chunk_unprotect(f, dxpl_id, oh, chk_proxy, H5AC__DIRTIED_FLAG) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, UFAIL, "unable to unprotect object header chunk") } /* end if */ HDassert(found_null >= 0); @@ -975,9 +1059,13 @@ H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t size) oh->mesg[idx].dirty = TRUE; oh->mesg[idx].native = NULL; oh->mesg[idx].raw = p + H5O_SIZEOF_MSGHDR_OH(oh); - oh->mesg[idx].raw_size = size - (H5O_SIZEOF_CHKHDR_OH(oh) + H5O_SIZEOF_MSGHDR_OH(oh)); + oh->mesg[idx].raw_size = size - (size_t)(H5O_SIZEOF_CHKHDR_OH(oh) + H5O_SIZEOF_MSGHDR_OH(oh)); oh->mesg[idx].chunkno = chunkno; + /* Insert the new chunk into the cache */ + if(H5O_chunk_add(f, dxpl_id, oh, chunkno) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, UFAIL, "can't add new chunk to cache") + /* Initialize the continuation information */ if(NULL == (cont = H5FL_MALLOC(H5O_cont_t))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, UFAIL, "memory allocation failed") @@ -986,7 +1074,7 @@ H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t size) cont->chunkno = chunkno; /* Split the null message and point at continuation message */ - if(H5O_alloc_null(oh, (unsigned)found_null, H5O_MSG_CONT, cont, cont_size) < 0) + if(H5O_alloc_null(f, dxpl_id, oh, (unsigned)found_null, H5O_MSG_CONT, cont, cont_size) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, UFAIL, "can't split null message") /* Set return value */ @@ -1074,7 +1162,7 @@ H5O_alloc(H5F_t *f, hid_t dxpl_id, H5O_t *oh, const H5O_msg_class_t *type, } /* end if */ /* Split the null message and point at continuation message */ - if(H5O_alloc_null(oh, idx, type, NULL, aligned_size) < 0) + if(H5O_alloc_null(f, dxpl_id, oh, idx, type, NULL, aligned_size) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, UFAIL, "can't split null message") /* Mark object header as dirty in cache */ @@ -1107,6 +1195,8 @@ herr_t H5O_release_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5O_mesg_t *mesg, hbool_t adj_link) { + H5O_chunk_proxy_t *chk_proxy = NULL; /* Chunk that message is in */ + unsigned chk_flags = H5AC__NO_FLAGS_SET; /* Flags for unprotecting chunk */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5O_release_mesg, FAIL) @@ -1123,6 +1213,10 @@ H5O_release_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5O_mesg_t *mesg, HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "unable to delete file space for object header message") } /* end if */ + /* Protect chunk */ + if(NULL == (chk_proxy = H5O_chunk_protect(f, dxpl_id, oh, mesg->chunkno))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to protect object header chunk") + /* Free any native information */ H5O_msg_free_mesg(mesg); @@ -1136,20 +1230,22 @@ H5O_release_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5O_mesg_t *mesg, /* Mark the message as modified */ mesg->dirty = TRUE; + chk_flags |= H5AC__DIRTIED_FLAG; /* Check if chunk has a gap currently */ if(oh->chunk[mesg->chunkno].gap) { /* Eliminate the gap in the chunk */ - if(H5O_eliminate_gap(oh, mesg, + if(H5O_eliminate_gap(f, dxpl_id, oh, chk_proxy, &chk_flags, mesg, ((oh->chunk[mesg->chunkno].image + oh->chunk[mesg->chunkno].size) - (H5O_SIZEOF_CHKSUM_OH(oh) + oh->chunk[mesg->chunkno].gap)), oh->chunk[mesg->chunkno].gap) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTREMOVE, FAIL, "can't eliminate gap in chunk") - - /* Set the gap size to zero for the chunk */ - oh->chunk[mesg->chunkno].gap = 0; } /* end if */ done: + /* Release chunk, if not already done */ + if(chk_proxy && H5O_chunk_unprotect(f, dxpl_id, oh, chk_proxy, chk_flags) < 0) + HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to unprotect object header chunk") + FUNC_LEAVE_NOAPI(ret_value) } /* H5O_release_mesg() */ @@ -1168,18 +1264,13 @@ done: *------------------------------------------------------------------------- */ static htri_t -H5O_move_cont(H5F_t *f, H5O_t *oh, unsigned cont_u, hid_t dxpl_id) +H5O_move_cont(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned cont_u) { - unsigned v; /* local index variable */ - H5O_mesg_t *cont_msg; /* pointer to the continuation message */ - H5O_mesg_t *nonnull_msg; /* pointer to the current message to operate on */ - H5O_mesg_t *null_msg; /* pointer to the current message to operate on */ - size_t total_size=0; /* total size of nonnull messages in the chunk pointed to by cont message */ - size_t move_size=0; /* size of the message to be moved */ - uint8_t *move_start, *move_end; /* pointers to area of messages to move */ - size_t gap_size; /* size of gap produced */ + H5O_chunk_proxy_t *chk_proxy = NULL; /* Chunk that continuation message is in */ + H5O_mesg_t *cont_msg; /* Pointer to the continuation message */ unsigned deleted_chunkno; /* Chunk # to delete */ - htri_t ret_value = FALSE; /* Return value */ + unsigned chk_flags = H5AC__NO_FLAGS_SET; /* Flags for unprotecting chunk */ + htri_t ret_value = TRUE; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5O_move_cont) @@ -1187,81 +1278,133 @@ H5O_move_cont(H5F_t *f, H5O_t *oh, unsigned cont_u, hid_t dxpl_id) HDassert(f); HDassert(oh); + /* Get initial information */ cont_msg = &oh->mesg[cont_u]; H5O_LOAD_NATIVE(f, dxpl_id, 0, oh, cont_msg, FAIL) deleted_chunkno = ((H5O_cont_t *)(cont_msg->native))->chunkno; - /* proceed further only if continuation message is pointing to the last chunk */ - if(deleted_chunkno != (oh->nchunks - 1)) - HGOTO_DONE(FALSE) - - /* find size of all nonnull messages in the chunk pointed to by the continuation message */ - for(v = 0, nonnull_msg = &oh->mesg[0]; v < oh->nmesgs; v++, nonnull_msg++) - if(nonnull_msg->chunkno == deleted_chunkno && nonnull_msg->type->id != H5O_NULL_ID) { - HDassert(nonnull_msg->type->id != H5O_CONT_ID); - total_size += nonnull_msg->raw_size + H5O_SIZEOF_MSGHDR_OH(oh); - } - - /* check if messages can fit into the continuation message */ - if(total_size && total_size <= (cont_msg->raw_size + H5O_SIZEOF_MSGHDR_OH(oh))) { - - /* convert continuation message into a null message */ - if(H5O_release_mesg(f, dxpl_id, oh, cont_msg, TRUE) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "unable to convert into null message") - - move_start = cont_msg->raw - H5O_SIZEOF_MSGHDR_OH(oh); - move_end = cont_msg->raw + cont_msg->raw_size; - - /* move message(s) forward into continuation message */ - for(v = 0, nonnull_msg = &oh->mesg[0]; v < oh->nmesgs; v++, nonnull_msg++) - if(nonnull_msg->chunkno == deleted_chunkno && nonnull_msg->type->id != H5O_NULL_ID) { - move_size = nonnull_msg->raw_size + H5O_SIZEOF_MSGHDR_OH(oh); - HDmemcpy(move_start, nonnull_msg->raw - H5O_SIZEOF_MSGHDR_OH(oh), move_size); - nonnull_msg->raw = move_start + H5O_SIZEOF_MSGHDR_OH(oh); - nonnull_msg->chunkno = cont_msg->chunkno; - nonnull_msg->dirty = TRUE; - move_start += move_size; - } - - HDassert(move_start <= move_end); - - /* check if there is space remaining in the continuation message */ - /* the remaining space can be gap or a null message */ - gap_size = move_end - move_start; - if(gap_size >= (size_t)H5O_SIZEOF_MSGHDR_OH(oh)) { - cont_msg->raw_size = gap_size - H5O_SIZEOF_MSGHDR_OH(oh); - cont_msg->raw = move_start + H5O_SIZEOF_MSGHDR_OH(oh); - cont_msg->dirty = TRUE; - } else { - if(gap_size && (H5O_add_gap(oh, cont_msg->chunkno, cont_u, move_start, gap_size) < 0)) - HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "can't insert gap in chunk") - /* Release any information/memory for continuation message */ - H5O_msg_free_mesg(cont_msg); - if(cont_u < (oh->nmesgs - 1)) - HDmemmove(&oh->mesg[cont_u], &oh->mesg[cont_u + 1], ((oh->nmesgs - 1) - cont_u) * sizeof(H5O_mesg_t)); - oh->nmesgs--; - } - - /* remove all null messages in deleted chunk from list of messages */ - /* Note: unsigned v wrapping around at the end */ - for (v = oh->nmesgs - 1, null_msg = &oh->mesg[v]; v < oh->nmesgs; v--, null_msg--) - if(null_msg->type->id == H5O_NULL_ID && null_msg->chunkno == deleted_chunkno) { + /* Check if continuation message is pointing to the last chunk */ + if(deleted_chunkno == (oh->nchunks - 1)) { + size_t nonnull_size; /* Total size of nonnull messages in the chunk pointed to by cont message */ + H5O_mesg_t *curr_msg; /* Pointer to the current message to operate on */ + size_t gap_size; /* Size of gap produced */ + unsigned v; /* Local index variable */ + + /* Find size of all nonnull messages in the chunk pointed to by the continuation message */ + nonnull_size = 0; + for(v = 0, curr_msg = &oh->mesg[0]; v < oh->nmesgs; v++, curr_msg++) + if(curr_msg->chunkno == deleted_chunkno && curr_msg->type->id != H5O_NULL_ID) { + HDassert(curr_msg->type->id != H5O_CONT_ID); + nonnull_size += curr_msg->raw_size + H5O_SIZEOF_MSGHDR_OH(oh); + } /* end if */ - /* Release any information/memory for message */ - H5O_msg_free_mesg(null_msg); + /* Size of gap in chunk w/continuation message */ + gap_size = oh->chunk[cont_msg->chunkno].gap; + + /* Check if messages can fit into the continuation message + gap size */ + /* (Could count any null messages in the chunk w/the continuation + * message also, but that is pretty complex. -QAK) + */ + if(nonnull_size && nonnull_size <= (gap_size + cont_msg->raw_size + H5O_SIZEOF_MSGHDR_OH(oh))) { + uint8_t *move_start, *move_end; /* Pointers to area of messages to move */ + unsigned cont_chunkno; /* Chunk number for continuation message */ + + /* Get continuation info */ + move_start = cont_msg->raw - H5O_SIZEOF_MSGHDR_OH(oh); + move_end = cont_msg->raw + cont_msg->raw_size; + cont_chunkno = cont_msg->chunkno; + + /* Convert continuation message into a null message */ + if(H5O_release_mesg(f, dxpl_id, oh, cont_msg, TRUE) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "unable to convert into null message") + + /* Protect chunk */ + if(NULL == (chk_proxy = H5O_chunk_protect(f, dxpl_id, oh, cont_chunkno))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to protect object header chunk") + + /* Move message(s) forward into continuation message */ + for(v = 0, curr_msg = &oh->mesg[0]; v < oh->nmesgs; v++, curr_msg++) + /* Look for messages in chunk to delete */ + if(curr_msg->chunkno == deleted_chunkno) { + /* Move messages out of chunk to delete */ + if(curr_msg->type->id != H5O_NULL_ID) { + size_t move_size; /* Size of the message to be moved */ + + /* Compute size of message to move */ + move_size = curr_msg->raw_size + H5O_SIZEOF_MSGHDR_OH(oh); + + /* Move message out of deleted chunk */ + HDmemcpy(move_start, curr_msg->raw - H5O_SIZEOF_MSGHDR_OH(oh), move_size); + curr_msg->raw = move_start + H5O_SIZEOF_MSGHDR_OH(oh); + curr_msg->chunkno = cont_chunkno; + curr_msg->dirty = TRUE; + chk_flags |= H5AC__DIRTIED_FLAG; + + /* Adjust location to move messages to */ + move_start += move_size; + } /* end else */ + } /* end if */ + + HDassert(move_start <= (move_end + gap_size)); + + /* Check if there is space remaining in the continuation message */ + /* (The remaining space can be gap or a null message) */ + gap_size += (size_t)(move_end - move_start); + if(gap_size >= (size_t)H5O_SIZEOF_MSGHDR_OH(oh)) { + /* Adjust size of null (was continuation) message */ + cont_msg->raw_size = gap_size - H5O_SIZEOF_MSGHDR_OH(oh); + cont_msg->raw = move_start + H5O_SIZEOF_MSGHDR_OH(oh); + cont_msg->dirty = TRUE; + chk_flags |= H5AC__DIRTIED_FLAG; + } /* end if */ + else { + /* Check if there is space that should be a gap */ + if(gap_size > 0) { + /* Convert remnant into gap in chunk */ + if(H5O_add_gap(f, dxpl_id, oh, chk_proxy, &chk_flags, cont_u, move_start, gap_size) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "can't insert gap in chunk") + } /* end if */ - if(v < (oh->nmesgs - 1)) - HDmemmove(&oh->mesg[v], &oh->mesg[v + 1], ((oh->nmesgs - 1) - v) * sizeof(H5O_mesg_t)); - oh->nmesgs--; - } /* end if */ + /* Release any information/memory for continuation message */ + H5O_msg_free_mesg(cont_msg); + if(cont_u < (oh->nmesgs - 1)) + HDmemmove(&oh->mesg[cont_u], &oh->mesg[cont_u + 1], ((oh->nmesgs - 1) - cont_u) * sizeof(H5O_mesg_t)); + oh->nmesgs--; + } /* end else */ - (void)H5FL_BLK_FREE(chunk_image, oh->chunk[deleted_chunkno].image); + /* Move message(s) forward into continuation message */ + /* Note: unsigned v wrapping around at the end */ + for(v = oh->nmesgs - 1, curr_msg = &oh->mesg[v]; v < oh->nmesgs; v--, curr_msg--) + /* Look for messages in chunk to delete */ + if(curr_msg->chunkno == deleted_chunkno) { + /* Remove all null messages in deleted chunk from list of messages */ + if(curr_msg->type->id == H5O_NULL_ID) { + /* Release any information/memory for message */ + H5O_msg_free_mesg(curr_msg); + chk_flags |= H5AC__DIRTIED_FLAG; + + /* Remove from message list */ + if(v < (oh->nmesgs - 1)) + HDmemmove(&oh->mesg[v], &oh->mesg[v + 1], ((oh->nmesgs - 1) - v) * sizeof(H5O_mesg_t)); + oh->nmesgs--; + } /* end if */ + } /* end if */ - oh->nchunks--; - ret_value = TRUE; + /* Remove chunk from list of chunks */ + oh->chunk[deleted_chunkno].image = H5FL_BLK_FREE(chunk_image, oh->chunk[deleted_chunkno].image); + oh->nchunks--; + } /* end if */ + else + ret_value = FALSE; } /* end if */ + else + ret_value = FALSE; done: + /* Release chunk, if not already done */ + if(chk_proxy && H5O_chunk_unprotect(f, dxpl_id, oh, chk_proxy, chk_flags) < 0) + HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to unprotect object header chunk") + FUNC_LEAVE_NOAPI(ret_value) } /* H5O_move_cont() */ @@ -1277,14 +1420,11 @@ done: * Programmer: Quincey Koziol * koziol@ncsa.uiuc.edu * Oct 17 2005 - * Modifications: - * Feb. 2009: Vailin Choi - * Add changes to move messages forward into "continuation" message * *------------------------------------------------------------------------- */ static htri_t -H5O_move_msgs_forward(H5F_t *f, H5O_t *oh, hid_t dxpl_id) +H5O_move_msgs_forward(H5F_t *f, hid_t dxpl_id, H5O_t *oh) { hbool_t packed_msg; /* Flag to indicate that messages were packed */ hbool_t did_packing = FALSE; /* Whether any messages were packed */ @@ -1326,6 +1466,12 @@ H5O_move_msgs_forward(H5F_t *f, H5O_t *oh, hid_t dxpl_id) /* Don't swap messages if the second message is also a null message */ /* (We'll merge them together later, in another routine) */ if(H5O_NULL_ID != nonnull_msg->type->id) { + H5O_chunk_proxy_t *null_chk_proxy; /* Chunk that message is in */ + + /* Protect chunk */ + if(NULL == (null_chk_proxy = H5O_chunk_protect(f, dxpl_id, oh, curr_msg->chunkno))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header chunk") + /* Copy raw data for non-null message to new location */ HDmemmove(curr_msg->raw - H5O_SIZEOF_MSGHDR_OH(oh), nonnull_msg->raw - H5O_SIZEOF_MSGHDR_OH(oh), nonnull_msg->raw_size + H5O_SIZEOF_MSGHDR_OH(oh)); @@ -1339,11 +1485,12 @@ H5O_move_msgs_forward(H5F_t *f, H5O_t *oh, hid_t dxpl_id) /* Mark null message dirty */ /* (since we need to re-encode its message header) */ - /* (also, marking this message dirty means we - * don't have to mark chunk as dirty) - */ curr_msg->dirty = TRUE; + /* Release chunk, marking it dirty */ + if(H5O_chunk_unprotect(f, dxpl_id, oh, null_chk_proxy, H5AC__DIRTIED_FLAG) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to unprotect object header chunk") + /* Set the flag to indicate that the null message * was packed - if its not at the end its chunk, * we'll move it again on the next pass. @@ -1360,23 +1507,29 @@ H5O_move_msgs_forward(H5F_t *f, H5O_t *oh, hid_t dxpl_id) } /* end if */ } /* end if */ else { - H5O_mesg_t *null_msg; /* Pointer to current message to operate on */ - unsigned v; /* Local index variable */ - htri_t status; + H5O_mesg_t *null_msg; /* Pointer to current message to operate on */ + unsigned v; /* Local index variable */ + /* Check if messages in chunk pointed to can replace continuation message */ if(H5O_CONT_ID == curr_msg->type->id) { - if((status = H5O_move_cont(f, oh, u, dxpl_id)) < 0) + htri_t status; /* Status from moving messages */ + + if((status = H5O_move_cont(f, dxpl_id, oh, u)) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "Error in moving messages into cont message") - else if(status > 0) { /* message(s) got moved into "continuation" message */ + else if(status > 0) { /* Message(s) got moved into "continuation" message */ packed_msg = TRUE; break; - } - } + } /* end else-if */ + } /* end if */ /* Loop over messages again, looking for large enough null message in earlier chunk */ for(v = 0, null_msg = &oh->mesg[0]; v < oh->nmesgs; v++, null_msg++) { if(H5O_NULL_ID == null_msg->type->id && curr_msg->chunkno > null_msg->chunkno && curr_msg->raw_size <= null_msg->raw_size) { + H5O_chunk_proxy_t *null_chk_proxy; /* Chunk that null message is in */ + H5O_chunk_proxy_t *curr_chk_proxy; /* Chunk that message is in */ + unsigned null_chk_flags = H5AC__NO_FLAGS_SET; /* Flags for unprotecting null chunk */ + unsigned curr_chk_flags = H5AC__NO_FLAGS_SET; /* Flags for unprotecting curr chunk */ unsigned old_chunkno; /* Old message information */ uint8_t *old_raw; @@ -1384,15 +1537,19 @@ H5O_move_msgs_forward(H5F_t *f, H5O_t *oh, hid_t dxpl_id) old_chunkno = curr_msg->chunkno; old_raw = curr_msg->raw; + /* Protect chunks */ + if(NULL == (null_chk_proxy = H5O_chunk_protect(f, dxpl_id, oh, null_msg->chunkno))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header chunk") + if(NULL == (curr_chk_proxy = H5O_chunk_protect(f, dxpl_id, oh, curr_msg->chunkno))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header chunk") + /* Copy raw data for non-null message to new chunk */ HDmemcpy(null_msg->raw - H5O_SIZEOF_MSGHDR_OH(oh), curr_msg->raw - H5O_SIZEOF_MSGHDR_OH(oh), curr_msg->raw_size + H5O_SIZEOF_MSGHDR_OH(oh)); - /* Mark null message's chunk as dirty, since the raw data image changed */ - oh->chunk[null_msg->chunkno].dirty = TRUE; - /* Point non-null message at null message's space */ curr_msg->chunkno = null_msg->chunkno; curr_msg->raw = null_msg->raw; + curr_chk_flags |= H5AC__DIRTIED_FLAG; /* Change information for null message */ if(curr_msg->raw_size == null_msg->raw_size) { @@ -1403,18 +1560,24 @@ H5O_move_msgs_forward(H5F_t *f, H5O_t *oh, hid_t dxpl_id) /* Mark null message dirty */ null_msg->dirty = TRUE; + null_chk_flags |= H5AC__DIRTIED_FLAG; + + /* Release current chunk, marking it dirty */ + if(H5O_chunk_unprotect(f, dxpl_id, oh, curr_chk_proxy, curr_chk_flags) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to unprotect object header chunk") /* Check for gap in null message's chunk */ if(oh->chunk[old_chunkno].gap > 0) { /* Eliminate the gap in the chunk */ - if(H5O_eliminate_gap(oh, null_msg, + if(H5O_eliminate_gap(f, dxpl_id, oh, null_chk_proxy, &null_chk_flags, null_msg, ((oh->chunk[old_chunkno].image + oh->chunk[old_chunkno].size) - (H5O_SIZEOF_CHKSUM_OH(oh) + oh->chunk[old_chunkno].gap)), oh->chunk[old_chunkno].gap) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTREMOVE, FAIL, "can't eliminate gap in chunk") - - /* Set the gap size to zero for the chunk */ - oh->chunk[old_chunkno].gap = 0; } /* end if */ + + /* Release null chunk, marking it dirty */ + if(H5O_chunk_unprotect(f, dxpl_id, oh, null_chk_proxy, null_chk_flags) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to unprotect object header chunk") } /* end if */ else { unsigned new_null_msg; /* Message index for new null message */ @@ -1426,8 +1589,12 @@ H5O_move_msgs_forward(H5F_t *f, H5O_t *oh, hid_t dxpl_id) /* Adjust the size of the null message being eliminated */ null_msg->raw_size = curr_msg->raw_size; + /* Mark null message dirty */ + null_msg->dirty = TRUE; + null_chk_flags |= H5AC__DIRTIED_FLAG; + /* Add the gap to the chunk */ - if(H5O_add_gap(oh, null_msg->chunkno, v, null_msg->raw + null_msg->raw_size, gap_size) < 0) + if(H5O_add_gap(f, dxpl_id, oh, null_chk_proxy, &null_chk_flags, v, null_msg->raw + null_msg->raw_size, gap_size) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "can't insert gap in chunk") /* Re-use message # for new null message taking place of non-null message */ @@ -1440,6 +1607,7 @@ H5O_move_msgs_forward(H5F_t *f, H5O_t *oh, hid_t dxpl_id) /* Mark null message dirty */ null_msg->dirty = TRUE; + null_chk_flags |= H5AC__DIRTIED_FLAG; /* Create new null message for previous location of non-null message */ if(oh->nmesgs >= oh->alloc_nmesgs) { @@ -1454,6 +1622,10 @@ H5O_move_msgs_forward(H5F_t *f, H5O_t *oh, hid_t dxpl_id) new_null_msg = oh->nmesgs++; } /* end else */ + /* Release null message's chunk, marking it dirty */ + if(H5O_chunk_unprotect(f, dxpl_id, oh, null_chk_proxy, null_chk_flags) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to unprotect object header chunk") + /* Initialize new null message to take over non-null message's location */ oh->mesg[new_null_msg].type = H5O_MSG_NULL; oh->mesg[new_null_msg].native = NULL; @@ -1463,18 +1635,20 @@ H5O_move_msgs_forward(H5F_t *f, H5O_t *oh, hid_t dxpl_id) /* Mark new null message dirty */ oh->mesg[new_null_msg].dirty = TRUE; + curr_chk_flags |= H5AC__DIRTIED_FLAG; /* Check for gap in new null message's chunk */ if(oh->chunk[old_chunkno].gap > 0) { /* Eliminate the gap in the chunk */ - if(H5O_eliminate_gap(oh, &oh->mesg[new_null_msg], + if(H5O_eliminate_gap(f, dxpl_id, oh, curr_chk_proxy, &curr_chk_flags, &oh->mesg[new_null_msg], ((oh->chunk[old_chunkno].image + oh->chunk[old_chunkno].size) - (H5O_SIZEOF_CHKSUM_OH(oh) + oh->chunk[old_chunkno].gap)), oh->chunk[old_chunkno].gap) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTREMOVE, FAIL, "can't eliminate gap in chunk") - - /* Set the gap size to zero for the chunk */ - oh->chunk[old_chunkno].gap = 0; } /* end if */ + + /* Release new null message's chunk, marking it dirty */ + if(H5O_chunk_unprotect(f, dxpl_id, oh, curr_chk_proxy, curr_chk_flags) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to unprotect object header chunk") } /* end else */ /* Indicate that we packed messages */ @@ -1523,7 +1697,7 @@ done: *------------------------------------------------------------------------- */ static htri_t -H5O_merge_null(H5F_t *f, H5O_t *oh, hid_t dxpl_id) +H5O_merge_null(H5F_t *f, hid_t dxpl_id, H5O_t *oh) { hbool_t merged_msg; /* Flag to indicate that messages were merged */ hbool_t did_merging = FALSE; /* Whether any messages were merged */ @@ -1557,11 +1731,14 @@ H5O_merge_null(H5F_t *f, H5O_t *oh, hid_t dxpl_id) /* Loop over messages again, looking for null message in same chunk */ for(v = 0, curr_msg2 = &oh->mesg[0]; v < oh->nmesgs; v++, curr_msg2++) { if(u != v && H5O_NULL_ID == curr_msg2->type->id && curr_msg->chunkno == curr_msg2->chunkno) { + ssize_t adj_raw; /* Amount to adjust raw message pointer */ + size_t adj_raw_size; /* Amount to adjust raw message size */ /* Check for second message after first message */ if((curr_msg->raw + curr_msg->raw_size) == (curr_msg2->raw - H5O_SIZEOF_MSGHDR_OH(oh))) { /* Extend first null message length to cover second null message */ - curr_msg->raw_size += (H5O_SIZEOF_MSGHDR_OH(oh) + curr_msg2->raw_size); + adj_raw = 0; + adj_raw_size = H5O_SIZEOF_MSGHDR_OH(oh) + curr_msg2->raw_size; /* Message has been merged */ merged_msg = TRUE; @@ -1569,8 +1746,8 @@ H5O_merge_null(H5F_t *f, H5O_t *oh, hid_t dxpl_id) /* Check for second message before first message */ else if((curr_msg->raw - H5O_SIZEOF_MSGHDR_OH(oh)) == (curr_msg2->raw + curr_msg2->raw_size)) { /* Adjust first message address and extend length to cover second message */ - curr_msg->raw -= (H5O_SIZEOF_MSGHDR_OH(oh) + curr_msg2->raw_size); - curr_msg->raw_size += (H5O_SIZEOF_MSGHDR_OH(oh) + curr_msg2->raw_size); + adj_raw = -((ssize_t)(H5O_SIZEOF_MSGHDR_OH(oh) + curr_msg2->raw_size)); + adj_raw_size = H5O_SIZEOF_MSGHDR_OH(oh) + curr_msg2->raw_size; /* Message has been merged */ merged_msg = TRUE; @@ -1578,12 +1755,26 @@ H5O_merge_null(H5F_t *f, H5O_t *oh, hid_t dxpl_id) /* Second message has been merged, delete it */ if(merged_msg) { + H5O_chunk_proxy_t *curr_chk_proxy; /* Chunk that message is in */ + /* Release any information/memory for second message */ H5O_msg_free_mesg(curr_msg2); + /* Protect chunk */ + if(NULL == (curr_chk_proxy = H5O_chunk_protect(f, dxpl_id, oh, curr_msg->chunkno))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header chunk") + + /* Adjust first message address and extend length to cover second message */ + curr_msg->raw += adj_raw; + curr_msg->raw_size += adj_raw_size; + /* Mark first message as dirty */ curr_msg->dirty = TRUE; + /* Release new null message's chunk, marking it dirty */ + if(H5O_chunk_unprotect(f, dxpl_id, oh, curr_chk_proxy, H5AC__DIRTIED_FLAG) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to unprotect object header chunk") + /* Remove second message from list of messages */ if(v < (oh->nmesgs - 1)) HDmemmove(&oh->mesg[v], &oh->mesg[v + 1], ((oh->nmesgs - 1) - v) * sizeof(H5O_mesg_t)); @@ -1594,7 +1785,7 @@ H5O_merge_null(H5F_t *f, H5O_t *oh, hid_t dxpl_id) /* If the merged message is too large, shrink the chunk */ if(curr_msg->raw_size >= H5O_MESG_MAX_SIZE) - if(H5O_alloc_shrink_chunk(f, oh, dxpl_id, curr_msg->chunkno) < 0) + if(H5O_alloc_shrink_chunk(f, dxpl_id, oh, curr_msg->chunkno) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTPACK, FAIL, "unable to shrink chunk") /* Get out of loop */ @@ -1679,6 +1870,20 @@ H5O_remove_empty_chunks(H5F_t *f, hid_t dxpl_id, H5O_t *oh) /* Decode current continuation message if necessary */ H5O_LOAD_NATIVE(f, dxpl_id, 0, oh, cont_msg, FAIL) + /* Check if the chunkno needs to be set */ + /* (should only occur when the continuation message is first decoded) */ + if(0 == ((H5O_cont_t *)(cont_msg->native))->chunkno) { + unsigned w; /* Local index variable */ + + /* Find chunk that this continuation message points to */ + for(w = 0; w < oh->nchunks; w++) + if(oh->chunk[w].addr == ((H5O_cont_t *)(cont_msg->native))->addr) { + ((H5O_cont_t *)(cont_msg->native))->chunkno = w; + break; + } /* end if */ + HDassert(((H5O_cont_t *)(cont_msg->native))->chunkno > 0); + } /* end if */ + /* Check for correct chunk to delete */ if(oh->chunk[null_msg->chunkno].addr == ((H5O_cont_t *)(cont_msg->native))->addr) break; @@ -1687,6 +1892,7 @@ H5O_remove_empty_chunks(H5F_t *f, hid_t dxpl_id, H5O_t *oh) /* Must be a continuation message that points to chunk containing null message */ HDassert(v < oh->nmesgs); HDassert(cont_msg); + HDassert(((H5O_cont_t *)(cont_msg->native))->chunkno == null_msg->chunkno); /* Initialize information about null message */ null_msg_no = u; @@ -1701,12 +1907,28 @@ H5O_remove_empty_chunks(H5F_t *f, hid_t dxpl_id, H5O_t *oh) */ /* Free memory for chunk image */ - (void)H5FL_BLK_FREE(chunk_image, oh->chunk[null_msg->chunkno].image); + oh->chunk[null_msg->chunkno].image = H5FL_BLK_FREE(chunk_image, oh->chunk[null_msg->chunkno].image); /* Remove chunk from list of chunks */ - if(null_msg->chunkno < (oh->nchunks - 1)) + if(null_msg->chunkno < (oh->nchunks - 1)) { HDmemmove(&oh->chunk[null_msg->chunkno], &oh->chunk[null_msg->chunkno + 1], ((oh->nchunks - 1) - null_msg->chunkno) * sizeof(H5O_chunk_t)); + /* Adjust chunk number for any chunk proxies that are in the cache */ + for(u = null_msg->chunkno; u < (oh->nchunks - 1); u++) { + unsigned chk_proxy_status = 0; /* Metadata cache status of chunk proxy for chunk */ + + /* Check the chunk proxy's status in the metadata cache */ + if(H5AC_get_entry_status(f, oh->chunk[u].addr, &chk_proxy_status) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to check metadata cache status for chunk proxy") + + /* If the entry is in the cache, update its chunk index */ + if(chk_proxy_status & H5AC_ES__IN_CACHE) { + if(H5O_chunk_update_idx(f, dxpl_id, oh, u) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "unable to update index for chunk proxy") + } /* end if */ + } /* end for */ + } /* end if */ + /* Decrement # of chunks */ /* (Don't bother reducing size of chunk array for now -QAK) */ oh->nchunks--; @@ -1740,9 +1962,24 @@ H5O_remove_empty_chunks(H5F_t *f, hid_t dxpl_id, H5O_t *oh) /* Decode current continuation message if necessary */ H5O_LOAD_NATIVE(f, dxpl_id, 0, oh, curr_msg, FAIL) - /* Check for pointer to chunk after deleted chunk */ - if(((H5O_cont_t *)(curr_msg->native))->chunkno > deleted_chunkno) - ((H5O_cont_t *)(curr_msg->native))->chunkno--; + /* Check if the chunkno needs to be set */ + /* (should only occur when the continuation message is first decoded) */ + if(0 == ((H5O_cont_t *)(curr_msg->native))->chunkno) { + unsigned w; /* Local index variable */ + + /* Find chunk that this continuation message points to */ + for(w = 0; w < oh->nchunks; w++) + if(oh->chunk[w].addr == ((H5O_cont_t *)(curr_msg->native))->addr) { + ((H5O_cont_t *)(curr_msg->native))->chunkno = w; + break; + } /* end if */ + HDassert(((H5O_cont_t *)(curr_msg->native))->chunkno > 0); + } /* end if */ + else { + /* Check for pointer to chunk after deleted chunk */ + if(((H5O_cont_t *)(curr_msg->native))->chunkno > deleted_chunkno) + ((H5O_cont_t *)(curr_msg->native))->chunkno--; + } /* end else */ } /* end if */ } /* end for */ @@ -1802,14 +2039,14 @@ H5O_condense_header(H5F_t *f, H5O_t *oh, hid_t dxpl_id) rescan_header = FALSE; /* Scan for messages that can be moved earlier in chunks */ - result = H5O_move_msgs_forward(f, oh, dxpl_id); + result = H5O_move_msgs_forward(f, dxpl_id, oh); if(result < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTPACK, FAIL, "can't move header messages forward") if(result > 0) rescan_header = TRUE; /* Scan for adjacent null messages & merge them */ - result = H5O_merge_null(f, oh, dxpl_id); + result = H5O_merge_null(f, dxpl_id, oh); if(result < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTPACK, FAIL, "can't pack null header messages") if(result > 0) @@ -1846,13 +2083,11 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5O_alloc_shrink_chunk(H5F_t *f, - H5O_t *oh, - hid_t dxpl_id, - unsigned chunkno) +H5O_alloc_shrink_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned chunkno) { H5O_chunk_t *chunk = &oh->chunk[chunkno]; /* Chunk to shrink */ - H5O_mesg_t *curr_msg; + H5O_chunk_proxy_t *chk_proxy = NULL; /* Metadata cache proxy for chunk to shrink */ + H5O_mesg_t *curr_msg; /* Current message to examine */ uint8_t *old_image = chunk->image; /* Old address of chunk's image in memory */ size_t old_size = chunk->size; /* Old size of chunk */ size_t new_size = chunk->size - chunk->gap; /* Size of shrunk chunk */ @@ -1869,20 +2104,25 @@ H5O_alloc_shrink_chunk(H5F_t *f, FUNC_ENTER_NOAPI_NOINIT(H5O_alloc_shrink_chunk) /* check args */ - HDassert(f != NULL); + HDassert(f); + HDassert(oh); + + /* Protect chunk */ + if(NULL == (chk_proxy = H5O_chunk_protect(f, dxpl_id, oh, chunkno))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to protect object header chunk") /* Loop backwards to increase the chance of seeing more null messages at the * end of the chunk. Note that we rely on unsigned u wrapping around at the * end. */ - for (u = oh->nmesgs - 1, curr_msg = &oh->mesg[u]; u < oh->nmesgs; u--, curr_msg--) { - if ((H5O_NULL_ID == curr_msg->type->id) && (chunkno == curr_msg->chunkno)) { + for(u = oh->nmesgs - 1, curr_msg = &oh->mesg[u]; u < oh->nmesgs; u--, curr_msg--) { + if((H5O_NULL_ID == curr_msg->type->id) && (chunkno == curr_msg->chunkno)) { size_t shrink_size = curr_msg->raw_size + sizeof_msghdr; /* Amount to shrink the chunk by */ /* If the current message is not at the end of the chunk, copy the * data after it (except the checksum). */ - if (curr_msg->raw + curr_msg->raw_size + if(curr_msg->raw + curr_msg->raw_size < old_image + new_size - sizeof_chksum) { unsigned v; /* Index */ H5O_mesg_t *curr_msg2; @@ -1893,8 +2133,8 @@ H5O_alloc_shrink_chunk(H5F_t *f, (size_t)(old_image + new_size - sizeof_chksum - src)); /* Update the raw data pointers for messages after this one */ - for (v = 0, curr_msg2 = &oh->mesg[0]; v < oh->nmesgs; v++, curr_msg2++) - if ((chunkno == curr_msg2->chunkno) && (curr_msg2->raw > curr_msg->raw)) + for(v = 0, curr_msg2 = &oh->mesg[0]; v < oh->nmesgs; v++, curr_msg2++) + if((chunkno == curr_msg2->chunkno) && (curr_msg2->raw > curr_msg->raw)) curr_msg2->raw -= shrink_size; } /* end if */ @@ -1905,7 +2145,7 @@ H5O_alloc_shrink_chunk(H5F_t *f, H5O_msg_free_mesg(curr_msg); /* Remove the deleted null message from list of messages */ - if (u < (oh->nmesgs - 1)) + if(u < (oh->nmesgs - 1)) HDmemmove(&oh->mesg[u], &oh->mesg[u+1], ((oh->nmesgs - 1) - u) * sizeof(H5O_mesg_t)); /* Decrement # of messages */ @@ -1931,7 +2171,7 @@ H5O_alloc_shrink_chunk(H5F_t *f, /* update the new chunk size */ new_size += oh->mesg[oh->nmesgs].raw_size + sizeof_msghdr; - } + } /* end if */ /* Check for changing the chunk #0 data size enough to need adjusting the flags */ if(oh->version > H5O_VERSION_1 && chunkno == 0) { @@ -1939,19 +2179,19 @@ H5O_alloc_shrink_chunk(H5F_t *f, size_t orig_prfx_size = 1 << (oh->flags & H5O_HDR_CHUNK0_SIZE); /* Original prefix size */ /* Check for moving to a 1-byte size encoding */ - if (orig_prfx_size > 1 && chunk0_newsize <= 255) { + if(orig_prfx_size > 1 && chunk0_newsize <= 255) { less_prfx_size = orig_prfx_size - 1; new_size_flags = H5O_HDR_CHUNK0_1; adjust_size_flags = TRUE; } /* end if */ /* Check for moving to a 2-byte size encoding */ - else if (orig_prfx_size > 2 && chunk0_newsize <= 65535) { + else if(orig_prfx_size > 2 && chunk0_newsize <= 65535) { less_prfx_size = orig_prfx_size - 2; new_size_flags = H5O_HDR_CHUNK0_2; adjust_size_flags = TRUE; } /* end if */ /* Check for moving to a 4-byte size encoding */ - else if (orig_prfx_size > 4 && chunk0_newsize <= 4294967295) { + else if(orig_prfx_size > 4 && chunk0_newsize <= 4294967295) { less_prfx_size = orig_prfx_size - 4; new_size_flags = H5O_HDR_CHUNK0_4; adjust_size_flags = TRUE; @@ -1976,38 +2216,51 @@ H5O_alloc_shrink_chunk(H5F_t *f, chunk->size = new_size; chunk->image = H5FL_BLK_REALLOC(chunk_image, old_image, chunk->size); chunk->gap = 0; - chunk->dirty = TRUE; - if (NULL == oh->chunk[chunkno].image) + if(NULL == oh->chunk[chunkno].image) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") /* Spin through existing messages, adjusting them */ - for (u = 0, curr_msg = &oh->mesg[0]; u < oh->nmesgs; u++, curr_msg++) { - if (adjust_size_flags || (chunk->image != old_image)) + for(u = 0, curr_msg = &oh->mesg[0]; u < oh->nmesgs; u++, curr_msg++) { + if(adjust_size_flags || (chunk->image != old_image)) /* Adjust raw addresses for messages in this chunk to reflect new 'image' address */ - if (curr_msg->chunkno == chunkno) + if(curr_msg->chunkno == chunkno) curr_msg->raw = chunk->image - less_prfx_size + (curr_msg->raw - old_image); /* Find continuation message which points to this chunk and adjust chunk's size */ /* (Chunk 0 doesn't have a continuation message that points to it and * its size is directly encoded in the object header) */ - if (chunkno > 0 && (H5O_CONT_ID == curr_msg->type->id) && - (((H5O_cont_t *)(curr_msg->native))->chunkno == chunkno)) { + if(chunkno > 0 && (H5O_CONT_ID == curr_msg->type->id) && + (((H5O_cont_t *)(curr_msg->native))->chunkno == chunkno)) { + H5O_chunk_proxy_t *cont_chk_proxy; /* Chunk that message is in */ + + /* Protect chunk */ + if(NULL == (cont_chk_proxy = H5O_chunk_protect(f, dxpl_id, oh, curr_msg->chunkno))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to protect object header chunk") + /* Adjust size of continuation message */ HDassert(((H5O_cont_t *)(curr_msg->native))->size == old_size); ((H5O_cont_t *)(curr_msg->native))->size = chunk->size; /* Flag continuation message as dirty */ curr_msg->dirty = TRUE; + + /* Release chunk, marking it dirty */ + if(H5O_chunk_unprotect(f, dxpl_id, oh, cont_chk_proxy, H5AC__DIRTIED_FLAG) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to unprotect object header chunk") } /* end if */ } /* end for */ HDassert(new_size <= old_size); /* Free the unused space in the file */ - if (H5MF_xfree(f, H5FD_MEM_OHDR, dxpl_id, chunk->addr + new_size, (hsize_t)(old_size - new_size)) < 0) + if(H5MF_xfree(f, H5FD_MEM_OHDR, dxpl_id, chunk->addr + new_size, (hsize_t)(old_size - new_size)) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to shrink object header chunk") done: + /* Release chunk, marking it dirty */ + if(chk_proxy && H5O_chunk_unprotect(f, dxpl_id, oh, chk_proxy, H5AC__DIRTIED_FLAG) < 0) + HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to unprotect object header chunk") + FUNC_LEAVE_NOAPI(ret_value) } /* H5O_alloc_shrink_chunk() */ diff --git a/src/H5Oattribute.c b/src/H5Oattribute.c index 72f02df..bfa9ba0 100644 --- a/src/H5Oattribute.c +++ b/src/H5Oattribute.c @@ -223,7 +223,6 @@ H5O_attr_create(const H5O_loc_t *loc, hid_t dxpl_id, H5A_t *attr) { H5O_t *oh = NULL; /* Pointer to actual object header */ H5O_ainfo_t ainfo; /* Attribute information for object */ - unsigned oh_flags = H5AC__NO_FLAGS_SET; /* Metadata cache flags for object header */ htri_t shared_mesg; /* Should this message be stored in the Shared Message table? */ herr_t ret_value = SUCCEED; /* Return value */ @@ -233,9 +232,9 @@ H5O_attr_create(const H5O_loc_t *loc, hid_t dxpl_id, H5A_t *attr) HDassert(loc); HDassert(attr); - /* Protect the object header to iterate over */ - if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_WRITE))) - HGOTO_ERROR(H5E_ATTR, H5E_CANTPROTECT, FAIL, "unable to load object header") + /* Pin the object header */ + if(NULL == (oh = H5O_pin(loc, dxpl_id))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTPIN, FAIL, "unable to pin object header") /* Check if this object already has attribute information */ if(oh->version > H5O_VERSION_1) { @@ -396,12 +395,9 @@ H5O_attr_create(const H5O_loc_t *loc, hid_t dxpl_id, H5A_t *attr) if(H5O_touch_oh(loc->file, dxpl_id, oh, FALSE) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTUPDATE, FAIL, "unable to update time on object") - /* Indicate that the object header was modified */ - oh_flags |= H5AC__DIRTIED_FLAG; - done: - if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, oh_flags) < 0) - HDONE_ERROR(H5E_ATTR, H5E_CANTUNPROTECT, FAIL, "unable to release object header") + if(oh && H5O_unpin(oh) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTUNPIN, FAIL, "unable to unpin object header") FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_attr_create() */ @@ -487,7 +483,7 @@ H5O_attr_open_by_name(const H5O_loc_t *loc, const char *name, hid_t dxpl_id) HDassert(name); /* Protect the object header to iterate over */ - if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ))) + if(NULL == (oh = H5O_protect(loc, dxpl_id, H5AC_READ))) HGOTO_ERROR(H5E_ATTR, H5E_CANTPROTECT, NULL, "unable to load object header") /* Check for attribute info stored */ @@ -544,7 +540,7 @@ H5O_attr_open_by_name(const H5O_loc_t *loc, const char *name, hid_t dxpl_id) } /* end else */ done: - if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) < 0) + if(oh && H5O_unprotect(loc, dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_ATTR, H5E_CANTUNPROTECT, NULL, "unable to release object header") FUNC_LEAVE_NOAPI(ret_value) @@ -628,7 +624,7 @@ H5O_attr_open_by_idx(const H5O_loc_t *loc, H5_index_t idx_type, HGOTO_ERROR(H5E_ATTR, H5E_BADITER, NULL, "can't locate attribute") /* Protect the object header to iterate over */ - if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ))) + if(NULL == (oh = H5O_protect(loc, dxpl_id, H5AC_READ))) HGOTO_ERROR(H5E_ATTR, H5E_CANTPROTECT, NULL, "unable to load object header") /* Find out whether it has already been opened. If it has, close the object @@ -654,7 +650,7 @@ H5O_attr_open_by_idx(const H5O_loc_t *loc, H5_index_t idx_type, } /* end if */ done: - if(oh && H5AC_unprotect(loc->file, H5AC_ind_dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) < 0) + if(oh && H5O_unprotect(loc, dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_ATTR, H5E_CANTUNPROTECT, NULL, "unable to release object header") FUNC_LEAVE_NOAPI(ret_value) @@ -836,6 +832,8 @@ H5O_attr_write_cb(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/, unsigned UNUSED sequence, hbool_t *oh_modified, void *_udata/*in,out*/) { H5O_iter_wrt_t *udata = (H5O_iter_wrt_t *)_udata; /* Operator user data */ + H5O_chunk_proxy_t *chk_proxy = NULL; /* Chunk that message is in */ + unsigned chk_flags = H5AC__NO_FLAGS_SET; /* Flags for unprotecting chunk */ herr_t ret_value = H5_ITER_CONT; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5O_attr_write_cb) @@ -847,14 +845,35 @@ H5O_attr_write_cb(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/, /* Check for correct attribute message to modify */ if(0 == HDstrcmp(((H5A_t *)mesg->native)->shared->name, udata->attr->shared->name)) { + /* Protect chunk */ + if(NULL == (chk_proxy = H5O_chunk_protect(udata->f, udata->dxpl_id, oh, mesg->chunkno))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTPROTECT, H5_ITER_ERROR, "unable to load object header chunk") + + /* Allocate storage for the message's data, if necessary */ + if(NULL == ((H5A_t *)mesg->native)->shared->data) + if(NULL == (((H5A_t *)mesg->native)->shared->data = H5FL_BLK_MALLOC(attr_buf, udata->attr->shared->data_size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, H5_ITER_ERROR, "memory allocation failed") + + /* Copy the data into the header message */ + /* (Needs to occur before updating the shared message, or the hash + * value on the old & new messages will be the same) + */ + HDmemcpy(((H5A_t *)mesg->native)->shared->data, udata->attr->shared->data, udata->attr->shared->data_size); + + /* Mark the message as modified */ + mesg->dirty = TRUE; + chk_flags |= H5AC__DIRTIED_FLAG; + + /* Release chunk */ + if(H5O_chunk_unprotect(udata->f, udata->dxpl_id, oh, chk_proxy, chk_flags) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTUNPROTECT, H5_ITER_ERROR, "unable to unprotect object header chunk") + chk_proxy = NULL; + /* Update the shared attribute in the SOHM storage */ if(mesg->flags & H5O_MSG_FLAG_SHARED) if(H5O_attr_update_shared(udata->f, udata->dxpl_id, oh, udata->attr, (H5O_shared_t *)mesg->native) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTUPDATE, H5_ITER_ERROR, "unable to update attribute in shared storage") - /* Mark message as dirty */ - mesg->dirty = TRUE; - /* Indicate that the object header was modified */ *oh_modified = TRUE; @@ -866,6 +885,10 @@ H5O_attr_write_cb(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/, } /* end if */ done: + /* Release chunk, if not already done */ + if(chk_proxy && H5O_chunk_unprotect(udata->f, udata->dxpl_id, oh, chk_proxy, chk_flags) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTUNPROTECT, H5_ITER_ERROR, "unable to unprotect object header chunk") + FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_attr_write_cb() */ @@ -887,7 +910,6 @@ H5O_attr_write(const H5O_loc_t *loc, hid_t dxpl_id, H5A_t *attr) { H5O_t *oh = NULL; /* Pointer to actual object header */ H5O_ainfo_t ainfo; /* Attribute information for object */ - unsigned oh_flags = H5AC__NO_FLAGS_SET; /* Metadata cache flags for object header */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5O_attr_write) @@ -896,9 +918,9 @@ H5O_attr_write(const H5O_loc_t *loc, hid_t dxpl_id, H5A_t *attr) HDassert(loc); HDassert(attr); - /* Protect the object header to iterate over */ - if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_WRITE))) - HGOTO_ERROR(H5E_ATTR, H5E_CANTPROTECT, FAIL, "unable to load object header") + /* Pin the object header */ + if(NULL == (oh = H5O_pin(loc, dxpl_id))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTPIN, FAIL, "unable to pin object header") /* Check for attribute info stored */ ainfo.fheap_addr = HADDR_UNDEF; @@ -939,12 +961,9 @@ H5O_attr_write(const H5O_loc_t *loc, hid_t dxpl_id, H5A_t *attr) if(H5O_touch_oh(loc->file, dxpl_id, oh, FALSE) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTUPDATE, FAIL, "unable to update time on object") - /* Indicate that the object header was modified */ - oh_flags |= H5AC__DIRTIED_FLAG; - done: - if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, oh_flags) < 0) - HDONE_ERROR(H5E_ATTR, H5E_CANTUNPROTECT, FAIL, "unable to release object header") + if(oh && H5O_unpin(oh) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTUNPIN, FAIL, "unable to unpin object header") FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_attr_write */ @@ -1015,6 +1034,8 @@ H5O_attr_rename_mod_cb(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/, unsigned UNUSED sequence, hbool_t *oh_modified, void *_udata/*in,out*/) { H5O_iter_ren_t *udata = (H5O_iter_ren_t *)_udata; /* Operator user data */ + H5O_chunk_proxy_t *chk_proxy = NULL; /* Chunk that message is in */ + unsigned chk_flags = H5AC__NO_FLAGS_SET; /* Flags for unprotecting chunk */ herr_t ret_value = H5_ITER_CONT; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5O_attr_rename_mod_cb) @@ -1028,6 +1049,10 @@ H5O_attr_rename_mod_cb(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/, if(HDstrcmp(((H5A_t *)mesg->native)->shared->name, udata->old_name) == 0) { unsigned old_version = ((H5A_t *)mesg->native)->shared->version; /* Old version of the attribute */ + /* Protect chunk */ + if(NULL == (chk_proxy = H5O_chunk_protect(udata->f, udata->dxpl_id, oh, mesg->chunkno))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTPROTECT, H5_ITER_ERROR, "unable to load object header chunk") + /* Change the name for the attribute */ H5MM_xfree(((H5A_t *)mesg->native)->shared->name); ((H5A_t *)mesg->native)->shared->name = H5MM_xstrdup(udata->new_name); @@ -1038,6 +1063,12 @@ H5O_attr_rename_mod_cb(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/, /* Mark the message as modified */ mesg->dirty = TRUE; + chk_flags |= H5AC__DIRTIED_FLAG; + + /* Release chunk */ + if(H5O_chunk_unprotect(udata->f, udata->dxpl_id, oh, chk_proxy, chk_flags) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTUNPROTECT, H5_ITER_ERROR, "unable to unprotect object header chunk") + chk_proxy = NULL; /* Check for shared message */ if(mesg->flags & H5O_MSG_FLAG_SHARED) { @@ -1098,6 +1129,10 @@ H5O_attr_rename_mod_cb(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/, } /* end if */ done: + /* Release chunk, if not already done */ + if(chk_proxy && H5O_chunk_unprotect(udata->f, udata->dxpl_id, oh, chk_proxy, chk_flags) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTUNPROTECT, H5_ITER_ERROR, "unable to unprotect object header chunk") + FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_attr_rename_mod_cb() */ @@ -1120,7 +1155,6 @@ H5O_attr_rename(const H5O_loc_t *loc, hid_t dxpl_id, const char *old_name, { H5O_t *oh = NULL; /* Pointer to actual object header */ H5O_ainfo_t ainfo; /* Attribute information for object */ - unsigned oh_flags = H5AC__NO_FLAGS_SET; /* Metadata cache flags for object header */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5O_attr_rename) @@ -1130,9 +1164,9 @@ H5O_attr_rename(const H5O_loc_t *loc, hid_t dxpl_id, const char *old_name, HDassert(old_name); HDassert(new_name); - /* Protect the object header to iterate over */ - if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_WRITE))) - HGOTO_ERROR(H5E_ATTR, H5E_CANTPROTECT, FAIL, "unable to load object header") + /* Pin the object header */ + if(NULL == (oh = H5O_pin(loc, dxpl_id))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTPIN, FAIL, "unable to pin object header") /* Check for attribute info stored */ ainfo.fheap_addr = HADDR_UNDEF; @@ -1184,12 +1218,9 @@ H5O_attr_rename(const H5O_loc_t *loc, hid_t dxpl_id, const char *old_name, if(H5O_touch_oh(loc->file, dxpl_id, oh, FALSE) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTUPDATE, FAIL, "unable to update time on object") - /* Indicate that the object header was modified */ - oh_flags |= H5AC__DIRTIED_FLAG; - done: - if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, oh_flags) < 0) - HDONE_ERROR(H5E_ATTR, H5E_CANTUNPROTECT, FAIL, "unable to release object header") + if(oh && H5O_unpin(oh) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTUNPIN, FAIL, "unable to unpin object header") FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_attr_rename */ @@ -1226,7 +1257,7 @@ H5O_attr_iterate_real(hid_t loc_id, const H5O_loc_t *loc, hid_t dxpl_id, HDassert(attr_op); /* Protect the object header to iterate over */ - if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ))) + if(NULL == (oh = H5O_protect(loc, dxpl_id, H5AC_READ))) HGOTO_ERROR(H5E_ATTR, H5E_CANTPROTECT, FAIL, "unable to load object header") /* Check for attribute info stored */ @@ -1244,7 +1275,7 @@ H5O_attr_iterate_real(hid_t loc_id, const H5O_loc_t *loc, hid_t dxpl_id, HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index specified") /* Release the object header */ - if(H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) < 0) + if(H5O_unprotect(loc, dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTUNPROTECT, FAIL, "unable to release object header") oh = NULL; @@ -1258,7 +1289,7 @@ H5O_attr_iterate_real(hid_t loc_id, const H5O_loc_t *loc, hid_t dxpl_id, HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "error building attribute table") /* Release the object header */ - if(H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) < 0) + if(H5O_unprotect(loc, dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTUNPROTECT, FAIL, "unable to release object header") oh = NULL; @@ -1273,7 +1304,7 @@ H5O_attr_iterate_real(hid_t loc_id, const H5O_loc_t *loc, hid_t dxpl_id, done: /* Release resources */ - if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) < 0) + if(oh && H5O_unprotect(loc, dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_ATTR, H5E_CANTUNPROTECT, FAIL, "unable to release object header") if(atable.attrs && H5A_attr_release_table(&atable) < 0) HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "unable to release attribute table") @@ -1511,7 +1542,6 @@ H5O_attr_remove(const H5O_loc_t *loc, const char *name, hid_t dxpl_id) H5O_t *oh = NULL; /* Pointer to actual object header */ H5O_ainfo_t ainfo; /* Attribute information for object */ htri_t ainfo_exists = FALSE; /* Whether the attribute info exists in the file */ - unsigned oh_flags = H5AC__NO_FLAGS_SET; /* Metadata cache flags for object header */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5O_attr_remove) @@ -1520,9 +1550,9 @@ H5O_attr_remove(const H5O_loc_t *loc, const char *name, hid_t dxpl_id) HDassert(loc); HDassert(name); - /* Protect the object header to iterate over */ - if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_WRITE))) - HGOTO_ERROR(H5E_ATTR, H5E_CANTPROTECT, FAIL, "unable to load object header") + /* Pin the object header */ + if(NULL == (oh = H5O_pin(loc, dxpl_id))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTPIN, FAIL, "unable to pin object header") /* Check for attribute info stored */ ainfo.fheap_addr = HADDR_UNDEF; @@ -1568,12 +1598,9 @@ H5O_attr_remove(const H5O_loc_t *loc, const char *name, hid_t dxpl_id) if(H5O_touch_oh(loc->file, dxpl_id, oh, FALSE) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTUPDATE, FAIL, "unable to update time on object") - /* Indicate that the object header was modified */ - oh_flags |= H5AC__DIRTIED_FLAG; - done: - if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, oh_flags) < 0) - HDONE_ERROR(H5E_ATTR, H5E_CANTUNPROTECT, FAIL, "unable to release object header") + if(oh && H5O_unpin(oh) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTUNPIN, FAIL, "unable to unpin object header") FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_attr_remove() */ @@ -1599,7 +1626,6 @@ H5O_attr_remove_by_idx(const H5O_loc_t *loc, H5_index_t idx_type, H5O_t *oh = NULL; /* Pointer to actual object header */ H5O_ainfo_t ainfo; /* Attribute information for object */ htri_t ainfo_exists = FALSE; /* Whether the attribute info exists in the file */ - unsigned oh_flags = H5AC__NO_FLAGS_SET; /* Metadata cache flags for object header */ H5A_attr_table_t atable = {0, NULL}; /* Table of attributes */ herr_t ret_value = SUCCEED; /* Return value */ @@ -1608,9 +1634,9 @@ H5O_attr_remove_by_idx(const H5O_loc_t *loc, H5_index_t idx_type, /* Check arguments */ HDassert(loc); - /* Protect the object header to iterate over */ - if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_WRITE))) - HGOTO_ERROR(H5E_ATTR, H5E_CANTPROTECT, FAIL, "unable to load object header") + /* Pin the object header */ + if(NULL == (oh = H5O_pin(loc, dxpl_id))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTPIN, FAIL, "unable to pin object header") /* Check for attribute info stored */ ainfo.fheap_addr = HADDR_UNDEF; @@ -1664,12 +1690,9 @@ H5O_attr_remove_by_idx(const H5O_loc_t *loc, H5_index_t idx_type, if(H5O_touch_oh(loc->file, dxpl_id, oh, FALSE) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTUPDATE, FAIL, "unable to update time on object") - /* Indicate that the object header was modified */ - oh_flags |= H5AC__DIRTIED_FLAG; - done: - if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, oh_flags) < 0) - HDONE_ERROR(H5E_ATTR, H5E_CANTUNPROTECT, FAIL, "unable to release object header") + if(oh && H5O_unpin(oh) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTUNPIN, FAIL, "unable to unpin object header") if(atable.attrs && H5A_attr_release_table(&atable) < 0) HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "unable to release attribute table") @@ -1797,7 +1820,7 @@ H5O_attr_exists(const H5O_loc_t *loc, const char *name, hid_t dxpl_id) HDassert(name); /* Protect the object header to iterate over */ - if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ))) + if(NULL == (oh = H5O_protect(loc, dxpl_id, H5AC_READ))) HGOTO_ERROR(H5E_ATTR, H5E_CANTPROTECT, FAIL, "unable to load object header") /* Check for attribute info stored */ @@ -1835,7 +1858,7 @@ H5O_attr_exists(const H5O_loc_t *loc, const char *name, hid_t dxpl_id) } /* end else */ done: - if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) < 0) + if(oh && H5O_unprotect(loc, dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_ATTR, H5E_CANTUNPROTECT, FAIL, "unable to release object header") FUNC_LEAVE_NOAPI(ret_value) @@ -1951,7 +1974,7 @@ H5O_attr_count(const H5O_loc_t *loc, hid_t dxpl_id) HDassert(loc); /* Protect the object header to iterate over */ - if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ))) + if(NULL == (oh = H5O_protect(loc, dxpl_id, H5AC_READ))) HGOTO_ERROR(H5E_ATTR, H5E_CANTPROTECT, FAIL, "unable to load object header") /* Retrieve # of attributes on object */ @@ -1962,7 +1985,7 @@ H5O_attr_count(const H5O_loc_t *loc, hid_t dxpl_id) ret_value = (int)nattrs; done: - if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) < 0) + if(oh && H5O_unprotect(loc, dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_ATTR, H5E_CANTUNPROTECT, FAIL, "unable to release object header") FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5Ocache.c b/src/H5Ocache.c index 780d5bb..95f3d3a 100644 --- a/src/H5Ocache.c +++ b/src/H5Ocache.c @@ -39,6 +39,7 @@ #include "H5FLprivate.h" /* Free lists */ #include "H5MFprivate.h" /* File memory management */ #include "H5Opkg.h" /* Object headers */ +#include "H5WBprivate.h" /* Wrapped Buffers */ /****************/ @@ -74,25 +75,31 @@ static herr_t H5O_dest(H5F_t *f, H5O_t *oh); static herr_t H5O_clear(H5F_t *f, H5O_t *oh, hbool_t destroy); static herr_t H5O_size(const H5F_t *f, const H5O_t *oh, size_t *size_ptr); +static H5O_chunk_proxy_t *H5O_cache_chk_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_udata1, + void *_udata2); +static herr_t H5O_cache_chk_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5O_chunk_proxy_t *chk_proxy, unsigned UNUSED * flags_ptr); +static herr_t H5O_cache_chk_dest(H5F_t *f, H5O_chunk_proxy_t *chk_proxy); +static herr_t H5O_cache_chk_clear(H5F_t *f, H5O_chunk_proxy_t *chk_proxy, hbool_t destroy); +static herr_t H5O_cache_chk_size(const H5F_t *f, const H5O_chunk_proxy_t *chk_proxy, size_t *size_ptr); -/*********************/ -/* Package Variables */ -/*********************/ - +/* Chunk proxy routines */ +static herr_t H5O_chunk_proxy_dest(H5O_chunk_proxy_t *chunk_proxy); -/*****************************/ -/* Library Private Variables */ -/*****************************/ +/* Chunk routines */ +static herr_t H5O_chunk_deserialize(H5O_t *oh, haddr_t addr, size_t len, + const uint8_t *image, H5O_common_cache_ud_t *udata, hbool_t *dirty); +static herr_t H5O_chunk_serialize(const H5F_t *f, H5O_t *oh, unsigned chunkno); -/* Declare external the free list for H5O_unknown_t's */ -H5FL_EXTERN(H5O_unknown_t); +/* Misc. routines */ +static herr_t H5O_add_cont_msg(H5O_cont_msgs_t *cont_msg_info, + const H5O_cont_t *cont); -/*******************/ -/* Local Variables */ -/*******************/ +/*********************/ +/* Package Variables */ +/*********************/ -/* H5O inherits cache-like properties from H5AC */ +/* H5O object header prefix inherits cache-like properties from H5AC */ const H5AC_class_t H5AC_OHDR[1] = {{ H5AC_OHDR_ID, (H5AC_load_func_t)H5O_load, @@ -103,6 +110,37 @@ const H5AC_class_t H5AC_OHDR[1] = {{ (H5AC_size_func_t)H5O_size, }}; +/* H5O object header chunk inherits cache-like properties from H5AC */ +const H5AC_class_t H5AC_OHDR_CHK[1] = {{ + H5AC_OHDR_CHK_ID, + (H5AC_load_func_t)H5O_cache_chk_load, + (H5AC_flush_func_t)H5O_cache_chk_flush, + (H5AC_dest_func_t)H5O_cache_chk_dest, + (H5AC_clear_func_t)H5O_cache_chk_clear, + (H5AC_notify_func_t)NULL, + (H5AC_size_func_t)H5O_cache_chk_size, +}}; + +/* Declare external the free list for H5O_unknown_t's */ +H5FL_EXTERN(H5O_unknown_t); + +/* Declare extern the free list for H5O_chunk_proxy_t's */ +H5FL_EXTERN(H5O_chunk_proxy_t); + +/* Declare the free list for H5O_cont_t sequences */ +H5FL_SEQ_DEFINE(H5O_cont_t); + + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/*******************/ +/* Local Variables */ +/*******************/ + + /*------------------------------------------------------------------------- * Function: H5O_load @@ -121,18 +159,17 @@ const H5AC_class_t H5AC_OHDR[1] = {{ */ static H5O_t * H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1, - void UNUSED * _udata2) + void *_udata2) { H5O_t *oh = NULL; /* Object header read in */ + H5O_cache_ud_t *udata = (H5O_cache_ud_t *)_udata2; /* User data for callback */ + H5WB_t *wb = NULL; /* Wrapped buffer for prefix data */ uint8_t read_buf[H5O_SPEC_READ_SIZE]; /* Buffer for speculative read */ const uint8_t *p; /* Pointer into buffer to decode */ + uint8_t *buf; /* Buffer to decode */ size_t spec_read_size; /* Size of buffer to speculatively read in */ size_t prefix_size; /* Size of object header prefix */ - unsigned nmesgs; /* Total # of messages in this object header */ - unsigned curmesg = 0; /* Current message being decoded in object header */ - unsigned merged_null_msgs = 0; /* Number of null messages merged together */ - haddr_t chunk_addr; /* Address of first chunk */ - size_t chunk_size; /* Size of first chunk */ + size_t buf_size; /* Size of prefix+chunk #0 buffer */ haddr_t eoa; /* Relative end of file address */ H5O_t *ret_value; /* Return value */ @@ -142,7 +179,9 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1, HDassert(f); HDassert(H5F_addr_defined(addr)); HDassert(!_udata1); - HDassert(!_udata2); + HDassert(udata); + HDassert(udata->common.f); + HDassert(udata->common.cont_msg_info); /* Make certain we don't speculatively read off the end of the file */ if(HADDR_UNDEF == (eoa = H5F_get_eoa(f, H5FD_MEM_OHDR))) @@ -161,8 +200,8 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1, HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* File-specific, non-stored information */ - oh->sizeof_size = H5F_SIZEOF_SIZE(f); - oh->sizeof_addr = H5F_SIZEOF_ADDR(f); + oh->sizeof_size = H5F_SIZEOF_SIZE(udata->common.f); + oh->sizeof_addr = H5F_SIZEOF_ADDR(udata->common.f); /* Check for presence of magic number */ /* (indicates version 2 or later) */ @@ -180,9 +219,6 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1, if(oh->flags & ~H5O_HDR_ALL_FLAGS) HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "unknown object header status flag(s)") - /* Number of messages (to allocate initially) */ - nmesgs = 1; - /* Number of links to object (unless overridden by refcount message) */ oh->nlink = 1; @@ -207,7 +243,7 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1, UINT16DECODE(p, oh->max_compact); UINT16DECODE(p, oh->min_dense); if(oh->max_compact < oh->min_dense) - HGOTO_ERROR(H5E_OHDR, H5E_VERSION, NULL, "bad object header attribute phase change values") + HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "bad object header attribute phase change values") } /* end if */ else { oh->max_compact = H5O_CRT_ATTR_MAX_COMPACT_DEF; @@ -217,26 +253,26 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1, /* First chunk size */ switch(oh->flags & H5O_HDR_CHUNK0_SIZE) { case 0: /* 1 byte size */ - chunk_size = *p++; + oh->chunk0_size = *p++; break; case 1: /* 2 byte size */ - UINT16DECODE(p, chunk_size); + UINT16DECODE(p, oh->chunk0_size); break; case 2: /* 4 byte size */ - UINT32DECODE(p, chunk_size); + UINT32DECODE(p, oh->chunk0_size); break; case 3: /* 8 byte size */ - UINT64DECODE(p, chunk_size); + UINT64DECODE(p, oh->chunk0_size); break; default: HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "bad size for chunk 0") } /* end switch */ - if(chunk_size > 0 && chunk_size < H5O_SIZEOF_MSGHDR_OH(oh)) - HGOTO_ERROR(H5E_OHDR, H5E_VERSION, NULL, "bad object header chunk size") + if(oh->chunk0_size > 0 && oh->chunk0_size < H5O_SIZEOF_MSGHDR_OH(oh)) + HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "bad object header chunk size") } /* end if */ else { /* Version */ @@ -251,7 +287,7 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1, p++; /* Number of messages */ - UINT16DECODE(p, nmesgs); + UINT16DECODE(p, udata->v1_pfx_nmesgs); /* Link count */ UINT32DECODE(p, oh->nlink); @@ -264,10 +300,10 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1, oh->min_dense = 0; /* First chunk size */ - UINT32DECODE(p, chunk_size); - if((nmesgs > 0 && chunk_size < H5O_SIZEOF_MSGHDR_OH(oh)) || - (nmesgs == 0 && chunk_size > 0)) - HGOTO_ERROR(H5E_OHDR, H5E_VERSION, NULL, "bad object header chunk size") + UINT32DECODE(p, oh->chunk0_size); + if((udata->v1_pfx_nmesgs > 0 && oh->chunk0_size < H5O_SIZEOF_MSGHDR_OH(oh)) || + (udata->v1_pfx_nmesgs == 0 && oh->chunk0_size > 0)) + HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "bad object header chunk size") /* Reserved, in version 1 (for 8-byte alignment padding) */ p += 4; @@ -277,356 +313,44 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1, prefix_size = (size_t)(p - (const uint8_t *)read_buf); HDassert((size_t)prefix_size == (size_t)(H5O_SIZEOF_HDR(oh) - H5O_SIZEOF_CHKSUM_OH(oh))); - /* Compute first chunk address */ - chunk_addr = addr + (hsize_t)prefix_size; + /* Compute the size of the buffer used */ + buf_size = oh->chunk0_size + (size_t)H5O_SIZEOF_HDR(oh); - /* Allocate the message array */ - oh->alloc_nmesgs = (nmesgs > 0) ? nmesgs : 1; - if(NULL == (oh->mesg = H5FL_SEQ_MALLOC(H5O_mesg_t, oh->alloc_nmesgs))) - HGOTO_ERROR(H5E_OHDR, H5E_CANTALLOC, NULL, "memory allocation failed") - - /* Read each chunk from disk */ - while(H5F_addr_defined(chunk_addr)) { - unsigned chunkno; /* Current chunk's index */ -#ifndef NDEBUG - unsigned nullcnt; /* Count of null messages (for sanity checking gaps in chunks) */ -#endif /* NDEBUG */ - uint8_t *eom_ptr; /* Pointer to end of messages for a chunk */ - - /* Increase chunk array size, if necessary */ - if(oh->nchunks >= oh->alloc_nchunks) { - unsigned na = MAX(H5O_NCHUNKS, oh->alloc_nchunks * 2); /* Double # of chunks allocated */ - H5O_chunk_t *x = H5FL_SEQ_REALLOC(H5O_chunk_t, oh->chunk, (size_t)na); - - if(!x) - HGOTO_ERROR(H5E_OHDR, H5E_CANTALLOC, NULL, "memory allocation failed") - oh->alloc_nchunks = na; - oh->chunk = x; - } /* end if */ - - /* Init the chunk data info */ - chunkno = oh->nchunks++; - oh->chunk[chunkno].dirty = FALSE; - oh->chunk[chunkno].gap = 0; - if(chunkno == 0) { - /* First chunk's 'image' includes room for the object header prefix */ - oh->chunk[0].addr = addr; - oh->chunk[0].size = chunk_size + H5O_SIZEOF_HDR(oh); - } /* end if */ - else { - oh->chunk[chunkno].addr = chunk_addr; - oh->chunk[chunkno].size = chunk_size; - } /* end else */ - if(NULL == (oh->chunk[chunkno].image = H5FL_BLK_MALLOC(chunk_image, oh->chunk[chunkno].size))) - HGOTO_ERROR(H5E_OHDR, H5E_CANTALLOC, NULL, "memory allocation failed") - - /* Handle chunk 0 as special case */ - if(chunkno == 0) { - /* Check for speculative read of first chunk containing all the data needed */ - if(spec_read_size >= oh->chunk[0].size) - HDmemcpy(oh->chunk[0].image, read_buf, oh->chunk[0].size); - else { - /* Copy the object header prefix into chunk 0's image */ - HDmemcpy(oh->chunk[0].image, read_buf, prefix_size); - - /* Read the chunk raw data */ - /* (probably re-reads some data we already retrieved, but since - * we have to do the I/O operation anyway, we might as - * well avoid memcpy()ing the data in our buffer already) - */ - if(H5F_block_read(f, H5FD_MEM_OHDR, chunk_addr, (oh->chunk[0].size - prefix_size), - dxpl_id, (oh->chunk[0].image + prefix_size)) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "unable to read object header data") - } /* end else */ - - /* Point into chunk image to decode */ - p = oh->chunk[0].image + prefix_size; - } /* end if */ - else { - /* Read the chunk raw data */ - if(H5F_block_read(f, H5FD_MEM_OHDR, chunk_addr, chunk_size, dxpl_id, oh->chunk[chunkno].image) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "unable to read object header data") + /* Check if the speculative read was large enough to parse the first chunk */ + if(spec_read_size < buf_size) { + /* Wrap the local buffer for serialized header info */ + if(NULL == (wb = H5WB_wrap(read_buf, sizeof(read_buf)))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "can't wrap buffer") - /* Point into chunk image to decode */ - p = oh->chunk[chunkno].image; - } /* end else */ + /* Get a pointer to a buffer that's large enough for serialized header */ + if(NULL == (buf = (uint8_t *)H5WB_actual(wb, buf_size))) + HGOTO_ERROR(H5E_OHDR, H5E_NOSPACE, NULL, "can't get actual buffer") - /* Check for magic # on chunks > 0 in later versions of the format */ - if(chunkno > 0 && oh->version > H5O_VERSION_1) { - /* Magic number */ - if(HDmemcmp(p, H5O_CHK_MAGIC, (size_t)H5_SIZEOF_MAGIC)) - HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "wrong object header chunk signature") - p += H5_SIZEOF_MAGIC; - } /* end if */ + /* Copy existing raw data into new buffer */ + HDmemcpy(buf, read_buf, spec_read_size); - /* Decode messages from this chunk */ - eom_ptr = oh->chunk[chunkno].image + (oh->chunk[chunkno].size - H5O_SIZEOF_CHKSUM_OH(oh)); -#ifndef NDEBUG - nullcnt = 0; -#endif /* NDEBUG */ - while(p < eom_ptr) { - unsigned mesgno; /* Current message to operate on */ - size_t mesg_size; /* Size of message read in */ - unsigned id; /* ID (type) of current message */ - uint8_t flags; /* Flags for current message */ - H5O_msg_crt_idx_t crt_idx = 0; /* Creation index for current message */ - - /* Decode message prefix info */ - - /* Version # */ - if(oh->version == H5O_VERSION_1) - UINT16DECODE(p, id) - else - id = *p++; - - /* Check for unknown message ID getting encoded in file */ - if(id == H5O_UNKNOWN_ID) - HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "'unknown' message ID encoded in file?!?") - - /* Message size */ - UINT16DECODE(p, mesg_size); - HDassert(mesg_size == H5O_ALIGN_OH(oh, mesg_size)); - - /* Message flags */ - flags = *p++; - if(flags & ~H5O_MSG_FLAG_BITS) - HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "unknown flag for message") - if((flags & H5O_MSG_FLAG_SHARED) && (flags & H5O_MSG_FLAG_DONTSHARE)) - HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad flag combination for message") - if((flags & H5O_MSG_FLAG_WAS_UNKNOWN) && (flags & H5O_MSG_FLAG_FAIL_IF_UNKNOWN)) - HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad flag combination for message") - if((flags & H5O_MSG_FLAG_WAS_UNKNOWN) && !(flags & H5O_MSG_FLAG_MARK_IF_UNKNOWN)) - HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad flag combination for message") - - /* Reserved bytes/creation index */ - if(oh->version == H5O_VERSION_1) - p += 3; /*reserved*/ - else { - /* Only decode creation index if they are being tracked */ - if(oh->flags & H5O_HDR_ATTR_CRT_ORDER_TRACKED) - UINT16DECODE(p, crt_idx); - } /* end else */ - - /* Try to detect invalidly formatted object header message that - * extends past end of chunk. - */ - if(p + mesg_size > eom_ptr) - HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "corrupt object header") - -#ifndef NDEBUG - /* Increment count of null messages */ - if(H5O_NULL_ID == id) - nullcnt++; -#endif /* NDEBUG */ - - /* Check for combining two adjacent 'null' messages */ - if((H5F_INTENT(f) & H5F_ACC_RDWR) && - H5O_NULL_ID == id && oh->nmesgs > 0 && - H5O_NULL_ID == oh->mesg[oh->nmesgs - 1].type->id && - oh->mesg[oh->nmesgs - 1].chunkno == chunkno) { - - /* Combine adjacent null messages */ - mesgno = oh->nmesgs - 1; - oh->mesg[mesgno].raw_size += H5O_SIZEOF_MSGHDR_OH(oh) + mesg_size; - oh->mesg[mesgno].dirty = TRUE; - merged_null_msgs++; - } /* end if */ - else { - /* Check if we need to extend message table to hold the new message */ - if(oh->nmesgs >= oh->alloc_nmesgs) - if(H5O_alloc_msgs(oh, (size_t)1) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTALLOC, NULL, "can't allocate more space for messages") - - /* Get index for message */ - mesgno = oh->nmesgs++; - - /* Initialize information about message */ - oh->mesg[mesgno].dirty = FALSE; - oh->mesg[mesgno].flags = flags; - oh->mesg[mesgno].crt_idx = crt_idx; - oh->mesg[mesgno].native = NULL; - oh->mesg[mesgno].raw = (uint8_t *)p; /* Casting away const OK - QAK */ - oh->mesg[mesgno].raw_size = mesg_size; - oh->mesg[mesgno].chunkno = chunkno; - - /* Point unknown messages at 'unknown' message class */ - /* (Usually from future versions of the library) */ - if(id >= NELMTS(H5O_msg_class_g) || NULL == H5O_msg_class_g[id]) { - H5O_unknown_t *unknown; /* Pointer to "unknown" message info */ - - /* Allocate "unknown" message info */ - if(NULL == (unknown = H5FL_MALLOC(H5O_unknown_t))) - HGOTO_ERROR(H5E_OHDR, H5E_CANTALLOC, NULL, "memory allocation failed") - - /* Save the original message type ID */ - *unknown = id; - - /* Save 'native' form of unknown message */ - oh->mesg[mesgno].native = unknown; - - /* Set message to "unknown" class */ - oh->mesg[mesgno].type = H5O_msg_class_g[H5O_UNKNOWN_ID]; - - /* Check for "fail if unknown" message flag */ - if(flags & H5O_MSG_FLAG_FAIL_IF_UNKNOWN) - HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, NULL, "unknown message with 'fail if unknown' flag found") - /* Check for "mark if unknown" message flag, etc. */ - else if((flags & H5O_MSG_FLAG_MARK_IF_UNKNOWN) && - !(flags & H5O_MSG_FLAG_WAS_UNKNOWN) && - (H5F_INTENT(f) & H5F_ACC_RDWR)) { - - /* Mark the message as "unknown" */ - /* This is a bit aggressive, since the application may - * never change anything about the object (metadata or - * raw data), but we can sort out the finer details - * when/if we start using the flag - QAK - */ - /* Also, it's possible that this functionality may not - * get invoked if the object header is brought into - * the metadata cache in some other "weird" way, like - * using H5Ocopy() - QAK - */ - oh->mesg[mesgno].flags |= H5O_MSG_FLAG_WAS_UNKNOWN; - - /* Mark the message and object header as dirty */ - oh->mesg[mesgno].dirty = TRUE; - oh->cache_info.is_dirty = TRUE; - } /* end if */ - } /* end if */ - else - /* Set message class for "known" messages */ - oh->mesg[mesgno].type = H5O_msg_class_g[id]; - } /* end else */ - - /* Advance decode pointer past message */ - p += mesg_size; - - /* Check for 'gap' at end of chunk */ - if((eom_ptr - p) > 0 && (eom_ptr - p) < H5O_SIZEOF_MSGHDR_OH(oh)) { - /* Gaps can only occur in later versions of the format */ - HDassert(oh->version > H5O_VERSION_1); - - /* Gaps should only occur in chunks with no null messages */ - HDassert(nullcnt == 0); - - /* Set gap information for chunk */ - oh->chunk[chunkno].gap = (size_t)(eom_ptr - p); - - /* Increment location in chunk */ - p += oh->chunk[chunkno].gap; - } /* end if */ - } /* end while */ - - /* Check for correct checksum on chunks, in later versions of the format */ - if(oh->version > H5O_VERSION_1) { - uint32_t stored_chksum; /* Checksum from file */ - uint32_t computed_chksum; /* Checksum computed in memory */ - - /* Metadata checksum */ - UINT32DECODE(p, stored_chksum); - - /* Compute checksum on chunk */ - computed_chksum = H5_checksum_metadata(oh->chunk[chunkno].image, (oh->chunk[chunkno].size - H5O_SIZEOF_CHKSUM), 0); - - /* Verify checksum */ - if(stored_chksum != computed_chksum) - HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "incorrect metadata checksum for object header chunk") - } /* end if */ - - /* Sanity check */ - HDassert(p == oh->chunk[chunkno].image + oh->chunk[chunkno].size); - - /* Check for another chunk to read in & parse */ - for(chunk_addr = HADDR_UNDEF; !H5F_addr_defined(chunk_addr) && curmesg < oh->nmesgs; ++curmesg) { - /* Check if next message to examine is a continuation message */ - if(H5O_CONT_ID == oh->mesg[curmesg].type->id) { - H5O_cont_t *cont; - unsigned ioflags = 0; /* Flags for decode routine */ - - /* Decode continuation message */ - cont = (H5O_cont_t *)(H5O_MSG_CONT->decode)(f, dxpl_id, NULL, 0, &ioflags, oh->mesg[curmesg].raw); - cont->chunkno = oh->nchunks; /*the next chunk to allocate */ - - /* Save 'native' form of continuation message */ - oh->mesg[curmesg].native = cont; - - /* Set up to read in next chunk */ - chunk_addr = cont->addr; - chunk_size = cont->size; - - /* Mark the object header as dirty if the message was changed by decoding */ - if((ioflags & H5O_DECODEIO_DIRTY) && (H5F_get_intent(f) & H5F_ACC_RDWR)) { - oh->mesg[curmesg].dirty = TRUE; - oh->cache_info.is_dirty = TRUE; - } - } /* end if */ - /* Check if next message to examine is a ref. count message */ - else if(H5O_REFCOUNT_ID == oh->mesg[curmesg].type->id) { - H5O_refcount_t *refcount; - unsigned ioflags = 0; /* Flags for decode routine */ - - /* Decode ref. count message */ - HDassert(oh->version > H5O_VERSION_1); - refcount = (H5O_refcount_t *)(H5O_MSG_REFCOUNT->decode)(f, dxpl_id, NULL, 0, &ioflags, oh->mesg[curmesg].raw); - - /* Save 'native' form of ref. count message */ - oh->mesg[curmesg].native = refcount; - - /* Set object header values */ - oh->has_refcount_msg = TRUE; - oh->nlink = *refcount; - - /* Mark the object header as dirty if the message was changed by decoding */ - if((ioflags & H5O_DECODEIO_DIRTY) && (H5F_get_intent(f) & H5F_ACC_RDWR)) { - oh->mesg[curmesg].dirty = TRUE; - oh->cache_info.is_dirty = TRUE; - } - } /* end if */ - /* Check if next message to examine is a link message */ - else if(H5O_LINK_ID == oh->mesg[curmesg].type->id) { - /* Increment the count of link messages */ - oh->link_msgs_seen++; - } /* end if */ - /* Check if next message to examine is an attribute message */ - else if(H5O_ATTR_ID == oh->mesg[curmesg].type->id) { - /* Increment the count of attribute messages */ - oh->attr_msgs_seen++; - } /* end if */ - } /* end for */ - } /* end while */ - - /* Mark the object header dirty if we've merged a message */ - if(merged_null_msgs) - oh->cache_info.is_dirty = TRUE; + /* Read rest of the raw data */ + if(H5F_block_read(f, H5FD_MEM_OHDR, (addr + spec_read_size), (buf_size - spec_read_size), dxpl_id, (buf + spec_read_size)) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "unable to read object header data") + } /* end if */ + else + buf = read_buf; -/* Don't check for the incorrect # of object header messages bug unless we've - * enabled strict format checking. This allows for older files, created with - * a version of the library that had a bug in tracking the correct # of header - * messages to be read in without the library fussing about things. -QAK - */ -#ifdef H5_STRICT_FORMAT_CHECKS - /* Sanity check for the correct # of messages in object header */ - if(oh->version == H5O_VERSION_1) - if((oh->nmesgs + merged_null_msgs) != nmesgs) - HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "corrupt object header - too few messages") -#else /* H5_STRICT_FORMAT_CHECKS */ - /* Check for incorrect # of messages in object header and if we have write - * access on the file, flag the object header as dirty, so it gets fixed. - */ - if(oh->version == H5O_VERSION_1) - if((oh->nmesgs + merged_null_msgs) != nmesgs && - (H5F_get_intent(f) & H5F_ACC_RDWR)) - oh->cache_info.is_dirty = TRUE; -#endif /* H5_STRICT_FORMAT_CHECKS */ + /* Parse the first chunk */ + if(H5O_chunk_deserialize(oh, addr, oh->chunk0_size, buf, &(udata->common), &oh->cache_info.is_dirty) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "can't deserialize first object header chunk") -#ifdef H5O_DEBUG -H5O_assert(oh); -#endif /* H5O_DEBUG */ + /* Note that we've loaded the object header from the file */ + udata->made_attempt = TRUE; /* Set return value */ ret_value = oh; done: + /* Release resources */ + if(wb && H5WB_unwrap(wb) < 0) + HDONE_ERROR(H5E_OHDR, H5E_CLOSEERROR, NULL, "can't close wrapped buffer") + /* Release the [possibly partially initialized] object header on errors */ if(!ret_value && oh) if(H5O_free(oh) < 0) @@ -664,7 +388,6 @@ H5O_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t UNUSED addr, H5O_t * /* flush */ if(oh->cache_info.is_dirty) { uint8_t *p; /* Pointer to object header prefix buffer */ - unsigned u; /* Local index variable */ #ifdef H5O_DEBUG H5O_assert(oh); @@ -678,7 +401,10 @@ H5O_assert(oh); * on the entire block of memory needs to be updated if anything is * modified */ if(oh->version > H5O_VERSION_1) { - uint64_t chunk0_size = oh->chunk[0].size - H5O_SIZEOF_HDR(oh); /* Size of chunk 0's data */ + uint64_t chunk0_size; /* Size of chunk 0's data */ + + HDassert(oh->chunk[0].size >= (size_t)H5O_SIZEOF_HDR(oh)); + chunk0_size = oh->chunk[0].size - (size_t)H5O_SIZEOF_HDR(oh); /* Verify magic number */ HDassert(!HDmemcmp(p, H5O_HDR_MAGIC, H5_SIZEOF_MAGIC)); @@ -749,7 +475,7 @@ H5O_assert(oh); UINT32ENCODE(p, oh->nlink); /* First chunk size */ - UINT32ENCODE(p, (oh->chunk[0].size - H5O_SIZEOF_HDR(oh))); + UINT32ENCODE(p, (oh->chunk[0].size - (size_t)H5O_SIZEOF_HDR(oh))); /* Zero to alignment */ HDmemset(p, 0, (size_t)(H5O_SIZEOF_HDR(oh) - 12)); @@ -757,57 +483,14 @@ H5O_assert(oh); } /* end else */ HDassert((size_t)(p - oh->chunk[0].image) == (size_t)(H5O_SIZEOF_HDR(oh) - H5O_SIZEOF_CHKSUM_OH(oh))); - /* Mark chunk 0 as dirty, since the object header prefix has been updated */ - /* (this could be more sophisticated and track whether any prefix fields - * have been changed, which could save I/O accesses if the - * messages in chunk 0 haven't changed - QAK) - */ - HDassert(H5F_addr_eq(addr, oh->chunk[0].addr)); - oh->chunk[0].dirty = TRUE; - - /* Encode any dirty messages */ - if(H5O_flush_msgs(f, oh) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTFLUSH, FAIL, "unable to flush object header messages") - - /* Write each chunk to disk, if it's dirty */ - for(u = 0; u < oh->nchunks; u++) { - /* Sanity checks */ - if(oh->version > H5O_VERSION_1) - /* Make certain the magic # is present */ - HDassert(!HDmemcmp(oh->chunk[u].image, (u == 0 ? H5O_HDR_MAGIC : H5O_CHK_MAGIC), H5_SIZEOF_MAGIC)); - else - /* Gaps should never occur in version 1 of the format */ - HDassert(oh->chunk[u].gap == 0); - - /* Write out chunk, if it's dirty */ - if(oh->chunk[u].dirty) { - /* Extra work, for later versions of the format */ - if(oh->version > H5O_VERSION_1) { - uint32_t metadata_chksum; /* Computed metadata checksum value */ - - /* Check for gap in chunk & zero it out */ - if(oh->chunk[u].gap) - HDmemset((oh->chunk[u].image + oh->chunk[u].size) - - (H5O_SIZEOF_CHKSUM + oh->chunk[u].gap), 0, oh->chunk[u].gap); - - /* Compute metadata checksum */ - metadata_chksum = H5_checksum_metadata(oh->chunk[u].image, (oh->chunk[u].size - H5O_SIZEOF_CHKSUM), 0); - - /* Metadata checksum */ - p = oh->chunk[u].image + (oh->chunk[u].size - H5O_SIZEOF_CHKSUM); - UINT32ENCODE(p, metadata_chksum); - } /* end if */ + /* Serialize messages for this chunk */ + if(H5O_chunk_serialize(f, oh, (unsigned)0) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTSERIALIZE, FAIL, "unable to serialize first object header chunk") - /* Write the chunk out */ - HDassert(H5F_addr_defined(oh->chunk[u].addr)); - if(H5F_block_write(f, H5FD_MEM_OHDR, oh->chunk[u].addr, - oh->chunk[u].size, dxpl_id, oh->chunk[u].image) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to write object header chunk to disk") - - /* Mark chunk as clean now */ - oh->chunk[u].dirty = FALSE; - } /* end if */ - } /* end for */ + /* Write the chunk out */ + HDassert(H5F_addr_defined(oh->chunk[0].addr)); + if(H5F_block_write(f, H5FD_MEM_OHDR, oh->chunk[0].addr, oh->chunk[0].size, dxpl_id, oh->chunk[0].image) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to write object header chunk to disk") /* Mark object header as clean now */ oh->cache_info.is_dirty = FALSE; @@ -845,6 +528,7 @@ H5O_dest(H5F_t *f, H5O_t *oh) /* check args */ HDassert(oh); + HDassert(oh->rc == 0); /* Verify that node is clean */ HDassert(!oh->cache_info.is_dirty); @@ -893,17 +577,13 @@ H5O_clear(H5F_t *f, H5O_t *oh, hbool_t destroy) /* check args */ HDassert(oh); - /* Mark chunks as clean */ - for(u = 0; u < oh->nchunks; u++) - oh->chunk[u].dirty = FALSE; - /* Mark messages as clean */ for(u = 0; u < oh->nmesgs; u++) oh->mesg[u].dirty = FALSE; #ifndef NDEBUG - /* Reset the number of messages dirtied by decoding */ - oh->ndecode_dirtied = 0; + /* Reset the number of messages dirtied by decoding */ + oh->ndecode_dirtied = 0; #endif /* NDEBUG */ /* Mark whole header as clean */ @@ -935,22 +615,767 @@ done: static herr_t H5O_size(const H5F_t UNUSED *f, const H5O_t *oh, size_t *size_ptr) { - size_t size; /* Running sum of the object header's size */ - unsigned u; /* Local index variable */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_size) /* check args */ HDassert(oh); HDassert(size_ptr); - /* Add sizes of all the chunks */ - /* (includes size of prefix, in chunk 0) */ - for(u = 0, size = 0; u < oh->nchunks; u++) - size += oh->chunk[u].size; - - *size_ptr = size; + /* Report the object header's prefix+first chunk length */ + *size_ptr = (size_t)H5O_SIZEOF_HDR(oh) + oh->chunk0_size; FUNC_LEAVE_NOAPI(SUCCEED) } /* H5O_size() */ + +/*------------------------------------------------------------------------- + * Function: H5O_cache_chk_load + * + * Purpose: Loads an object header continuation chunk from disk. + * + * Return: Success: Pointer to the new object header chunk proxy. + * Failure: NULL + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Jul 12 2008 + * + *------------------------------------------------------------------------- + */ +static H5O_chunk_proxy_t * +H5O_cache_chk_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1, + void *_udata2) +{ + H5O_chunk_proxy_t *chk_proxy = NULL; /* Chunk proxy object */ + H5O_chk_cache_ud_t *udata = (H5O_chk_cache_ud_t *)_udata2; /* User data for callback */ + H5WB_t *wb = NULL; /* Wrapped buffer for prefix data */ + uint8_t chunk_buf[H5O_SPEC_READ_SIZE]; /* Buffer for speculative read */ + uint8_t *buf; /* Buffer to decode */ + H5O_chunk_proxy_t *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5O_cache_chk_load) + + /* Check arguments */ + HDassert(f); + HDassert(H5F_addr_defined(addr)); + HDassert(udata); + HDassert(udata->oh); + + /* Allocate space for the object header data structure */ + if(NULL == (chk_proxy = H5FL_CALLOC(H5O_chunk_proxy_t))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTALLOC, NULL, "memory allocation failed") + + /* Wrap the local buffer for serialized header info */ + if(NULL == (wb = H5WB_wrap(chunk_buf, sizeof(chunk_buf)))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "can't wrap buffer") + + /* Get a pointer to a buffer that's large enough for serialized header */ + if(NULL == (buf = (uint8_t *)H5WB_actual(wb, udata->chunk_size))) + HGOTO_ERROR(H5E_OHDR, H5E_NOSPACE, NULL, "can't get actual buffer") + + /* Read rest of the raw data */ + if(H5F_block_read(f, H5FD_MEM_OHDR, addr, udata->chunk_size, dxpl_id, buf) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "unable to read object header continuation chunk") + + /* Check if we are still decoding the object header */ + /* (as opposed to bringing a piece of it back from the file) */ + if(udata->decoding) { + /* Sanity check */ + HDassert(udata->common.f); + HDassert(udata->common.cont_msg_info); + + /* Parse the chunk */ + if(H5O_chunk_deserialize(udata->oh, addr, udata->chunk_size, buf, &(udata->common), &chk_proxy->cache_info.is_dirty) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "can't deserialize object header chunk") + + /* Set the fields for the chunk proxy */ + chk_proxy->oh = udata->oh; + chk_proxy->chunkno = udata->oh->nchunks - 1; + } /* end if */ + else { + /* Sanity check */ + HDassert(udata->chunkno < udata->oh->nchunks); + + /* Set the fields for the chunk proxy */ + chk_proxy->oh = udata->oh; + chk_proxy->chunkno = udata->chunkno; + + /* Sanity check that the chunk representation we have in memory is the same + * as the one being brought in from disk. + */ + HDassert(0 == HDmemcmp(buf, chk_proxy->oh->chunk[chk_proxy->chunkno].image, chk_proxy->oh->chunk[chk_proxy->chunkno].size)); + } /* end else */ + + /* Increment reference count of object header */ + if(H5O_inc_rc(udata->oh) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINC, NULL, "can't increment reference count on object header") + + /* Set return value */ + ret_value = chk_proxy; + +done: + /* Release resources */ + if(wb && H5WB_unwrap(wb) < 0) + HDONE_ERROR(H5E_OHDR, H5E_CLOSEERROR, NULL, "can't close wrapped buffer") + + /* Release the [possibly partially initialized] object header on errors */ + if(!ret_value && chk_proxy) + if(H5O_chunk_proxy_dest(chk_proxy) < 0) + HDONE_ERROR(H5E_OHDR, H5E_CANTRELEASE, NULL, "unable to destroy object header chunk proxy") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_cache_chk_load() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_cache_chk_flush + * + * Purpose: Flushes (and destroys) an object header continuation chunk. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Jul 12 2008 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O_cache_chk_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, + H5O_chunk_proxy_t *chk_proxy, unsigned UNUSED * flags_ptr) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5O_cache_chk_flush) + + /* flush */ + if(chk_proxy->cache_info.is_dirty) { + /* Serialize messages for this chunk */ + if(H5O_chunk_serialize(f, chk_proxy->oh, chk_proxy->chunkno) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTSERIALIZE, FAIL, "unable to serialize object header continuation chunk") + + /* Write the chunk out */ + HDassert(H5F_addr_defined(chk_proxy->oh->chunk[chk_proxy->chunkno].addr)); + HDassert(H5F_addr_eq(addr, chk_proxy->oh->chunk[chk_proxy->chunkno].addr)); + if(H5F_block_write(f, H5FD_MEM_OHDR, addr, chk_proxy->oh->chunk[chk_proxy->chunkno].size, dxpl_id, chk_proxy->oh->chunk[chk_proxy->chunkno].image) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to write object header continuation chunk to disk") + + /* Mark object header as clean now */ + chk_proxy->cache_info.is_dirty = FALSE; + } /* end if */ + + /* Destroy the object header, if requested */ + if(destroy) + if(H5O_cache_chk_dest(f, chk_proxy) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to destroy object header continuation chunk data") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_cache_chk_flush() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_cache_chk_dest + * + * Purpose: Destroys an object header continuation chunk. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * July 12, 2008 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O_cache_chk_dest(H5F_t *f, H5O_chunk_proxy_t *chk_proxy) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5O_cache_chk_dest) + + /* Check arguments */ + HDassert(chk_proxy); + HDassert(chk_proxy->chunkno > 0); + + /* Verify that node is clean */ + HDassert(chk_proxy->cache_info.is_dirty == FALSE); + + /* If we're going to free the space on disk, the address must be valid */ + HDassert(!chk_proxy->cache_info.free_file_space_on_destroy || H5F_addr_defined(chk_proxy->cache_info.addr)); + + /* Check for releasing file space for object header */ + if(chk_proxy->cache_info.free_file_space_on_destroy) { + /* Release the space on disk */ + /* (XXX: Nasty usage of internal DXPL value! -QAK) */ + if(H5MF_xfree(f, H5FD_MEM_OHDR, H5AC_dxpl_id, chk_proxy->oh->chunk[chk_proxy->chunkno].addr, (hsize_t)chk_proxy->oh->chunk[chk_proxy->chunkno].size) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to free object header continuation chunk") + } /* end if */ + + /* Destroy object header chunk proxy */ + if(H5O_chunk_proxy_dest(chk_proxy) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "unable to destroy object header chunk proxy") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_cache_chk_dest() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_cache_chk_clear + * + * Purpose: Mark a object header continuation chunk in memory as non-dirty. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * July 12, 2008 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O_cache_chk_clear(H5F_t *f, H5O_chunk_proxy_t *chk_proxy, hbool_t destroy) +{ + unsigned u; /* Local index variable */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI_NOINIT(H5O_cache_chk_clear) + + /* check args */ + HDassert(chk_proxy); + + /* Mark messages in chunk as clean */ + for(u = 0; u < chk_proxy->oh->nmesgs; u++) + if(chk_proxy->oh->mesg[u].chunkno == chk_proxy->chunkno) + chk_proxy->oh->mesg[u].dirty = FALSE; + + /* Mark as clean */ + chk_proxy->cache_info.is_dirty = FALSE; + + if(destroy) + if(H5O_cache_chk_dest(f, chk_proxy) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to destroy object header continuation chunk data") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_cache_chk_clear() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_cache_chk_size + * + * Purpose: Compute the size in bytes of the specified instance of + * an object header continuation chunk on disk, and return it in + * *len_ptr. On failure, the value of *len_ptr is undefined. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * July 12, 2008 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O_cache_chk_size(const H5F_t UNUSED *f, const H5O_chunk_proxy_t *chk_proxy, size_t *size_ptr) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_cache_chk_size) + + /* check args */ + HDassert(chk_proxy); + HDassert(size_ptr); + + /* Report the object header continuation chunk's length */ + *size_ptr = chk_proxy->oh->chunk[chk_proxy->chunkno].size; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5O_cache_chk_size() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_add_cont_msg + * + * Purpose: Add information from a continuation message to the list of + * continuation messages in the object header + * + * Return: Success: SUCCEED + * Failure: FAIL + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * July 12, 2008 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O_add_cont_msg(H5O_cont_msgs_t *cont_msg_info, const H5O_cont_t *cont) +{ + unsigned contno; /* Continuation message index */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5O_add_cont_msg) + + /* Check arguments */ + HDassert(cont_msg_info); + HDassert(cont); + + /* Increase chunk array size, if necessary */ + if(cont_msg_info->nmsgs >= cont_msg_info->alloc_nmsgs) { + unsigned na = MAX(H5O_NCHUNKS, cont_msg_info->alloc_nmsgs * 2); /* Double # of messages allocated */ + H5O_cont_t *x = H5FL_SEQ_REALLOC(H5O_cont_t, cont_msg_info->msgs, (size_t)na); + + if(!x) + HGOTO_ERROR(H5E_OHDR, H5E_NOSPACE, FAIL, "memory allocation failed") + cont_msg_info->alloc_nmsgs = na; + cont_msg_info->msgs = x; + } /* end if */ + + /* Init the continuation message info */ + contno = cont_msg_info->nmsgs++; + cont_msg_info->msgs[contno].addr = cont->addr; + cont_msg_info->msgs[contno].size = cont->size; + cont_msg_info->msgs[contno].chunkno = cont->chunkno; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5O_add_cont_msg() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_chunk_deserialize + * + * Purpose: Deserialize a chunk for an object header + * + * Return: Success: SUCCEED + * Failure: FAIL + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * July 12, 2008 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O_chunk_deserialize(H5O_t *oh, haddr_t addr, size_t len, const uint8_t *image, + H5O_common_cache_ud_t *udata, hbool_t *dirty) +{ + const uint8_t *p; /* Pointer into buffer to decode */ + uint8_t *eom_ptr; /* Pointer to end of messages for a chunk */ + unsigned curmesg; /* Current message being decoded in object header */ + unsigned merged_null_msgs = 0; /* Number of null messages merged together */ + unsigned chunkno; /* Current chunk's index */ +#ifndef NDEBUG + unsigned nullcnt; /* Count of null messages (for sanity checking gaps in chunks) */ +#endif /* NDEBUG */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5O_chunk_deserialize) + + /* Check arguments */ + HDassert(oh); + HDassert(image); + HDassert(udata->f); + HDassert(udata->cont_msg_info); + + /* Increase chunk array size, if necessary */ + if(oh->nchunks >= oh->alloc_nchunks) { + unsigned na = MAX(H5O_NCHUNKS, oh->alloc_nchunks * 2); /* Double # of chunks allocated */ + H5O_chunk_t *x = H5FL_SEQ_REALLOC(H5O_chunk_t, oh->chunk, (size_t)na); + + if(!x) + HGOTO_ERROR(H5E_OHDR, H5E_CANTALLOC, FAIL, "memory allocation failed") + oh->alloc_nchunks = na; + oh->chunk = x; + } /* end if */ + + /* Init the chunk data info */ + chunkno = oh->nchunks++; + oh->chunk[chunkno].gap = 0; + if(chunkno == 0) { + /* First chunk's 'image' includes room for the object header prefix */ + oh->chunk[0].addr = addr; + oh->chunk[0].size = len + (size_t)H5O_SIZEOF_HDR(oh); + } /* end if */ + else { + oh->chunk[chunkno].addr = addr; + oh->chunk[chunkno].size = len; + } /* end else */ + if(NULL == (oh->chunk[chunkno].image = H5FL_BLK_MALLOC(chunk_image, oh->chunk[chunkno].size))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTALLOC, FAIL, "memory allocation failed") + + /* Copy disk image into chunk's image */ + HDmemcpy(oh->chunk[chunkno].image, image, oh->chunk[chunkno].size); + + /* Point into chunk image to decode */ + p = oh->chunk[chunkno].image; + + /* Handle chunk 0 as special case */ + if(chunkno == 0) + /* Skip over [already decoded] prefix */ + p += (size_t)(H5O_SIZEOF_HDR(oh) - H5O_SIZEOF_CHKSUM_OH(oh)); + /* Check for magic # on chunks > 0 in later versions of the format */ + else if(chunkno > 0 && oh->version > H5O_VERSION_1) { + /* Magic number */ + if(HDmemcmp(p, H5O_CHK_MAGIC, (size_t)H5_SIZEOF_MAGIC)) + HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "wrong object header chunk signature") + p += H5_SIZEOF_MAGIC; + } /* end if */ + + /* Save # of messages already inspected */ + curmesg = oh->nmesgs; + + /* Decode messages from this chunk */ + eom_ptr = oh->chunk[chunkno].image + (oh->chunk[chunkno].size - H5O_SIZEOF_CHKSUM_OH(oh)); +#ifndef NDEBUG + nullcnt = 0; +#endif /* NDEBUG */ + while(p < eom_ptr) { + unsigned mesgno; /* Current message to operate on */ + size_t mesg_size; /* Size of message read in */ + unsigned id; /* ID (type) of current message */ + uint8_t flags; /* Flags for current message */ + H5O_msg_crt_idx_t crt_idx = 0; /* Creation index for current message */ + + /* Decode message prefix info */ + + /* Version # */ + if(oh->version == H5O_VERSION_1) + UINT16DECODE(p, id) + else + id = *p++; + + /* Check for unknown message ID getting encoded in file */ + if(id == H5O_UNKNOWN_ID) + HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "'unknown' message ID encoded in file?!?") + + /* Message size */ + UINT16DECODE(p, mesg_size); + HDassert(mesg_size == H5O_ALIGN_OH(oh, mesg_size)); + + /* Message flags */ + flags = *p++; + if(flags & ~H5O_MSG_FLAG_BITS) + HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unknown flag for message") + if((flags & H5O_MSG_FLAG_SHARED) && (flags & H5O_MSG_FLAG_DONTSHARE)) + HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "bad flag combination for message") + if((flags & H5O_MSG_FLAG_WAS_UNKNOWN) && (flags & H5O_MSG_FLAG_FAIL_IF_UNKNOWN)) + HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "bad flag combination for message") + if((flags & H5O_MSG_FLAG_WAS_UNKNOWN) && !(flags & H5O_MSG_FLAG_MARK_IF_UNKNOWN)) + HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "bad flag combination for message") + + /* Reserved bytes/creation index */ + if(oh->version == H5O_VERSION_1) + p += 3; /*reserved*/ + else { + /* Only decode creation index if they are being tracked */ + if(oh->flags & H5O_HDR_ATTR_CRT_ORDER_TRACKED) + UINT16DECODE(p, crt_idx); + } /* end else */ + + /* Try to detect invalidly formatted object header message that + * extends past end of chunk. + */ + if(p + mesg_size > eom_ptr) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "corrupt object header") + +#ifndef NDEBUG + /* Increment count of null messages */ + if(H5O_NULL_ID == id) + nullcnt++; +#endif /* NDEBUG */ + + /* Check for combining two adjacent 'null' messages */ + if((udata->file_intent & H5F_ACC_RDWR) && + H5O_NULL_ID == id && oh->nmesgs > 0 && + H5O_NULL_ID == oh->mesg[oh->nmesgs - 1].type->id && + oh->mesg[oh->nmesgs - 1].chunkno == chunkno) { + + /* Combine adjacent null messages */ + mesgno = oh->nmesgs - 1; + oh->mesg[mesgno].raw_size += H5O_SIZEOF_MSGHDR_OH(oh) + mesg_size; + oh->mesg[mesgno].dirty = TRUE; + merged_null_msgs++; + udata->merged_null_msgs++; + } /* end if */ + else { + /* Check if we need to extend message table to hold the new message */ + if(oh->nmesgs >= oh->alloc_nmesgs) + if(H5O_alloc_msgs(oh, (size_t)1) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTALLOC, FAIL, "can't allocate more space for messages") + + /* Get index for message */ + mesgno = oh->nmesgs++; + + /* Initialize information about message */ + oh->mesg[mesgno].dirty = FALSE; + oh->mesg[mesgno].flags = flags; + oh->mesg[mesgno].crt_idx = crt_idx; + oh->mesg[mesgno].native = NULL; + oh->mesg[mesgno].raw = (uint8_t *)p; /* Casting away const OK - QAK */ + oh->mesg[mesgno].raw_size = mesg_size; + oh->mesg[mesgno].chunkno = chunkno; + + /* Point unknown messages at 'unknown' message class */ + /* (Usually from future versions of the library) */ + if(id >= NELMTS(H5O_msg_class_g) || NULL == H5O_msg_class_g[id]) { + H5O_unknown_t *unknown; /* Pointer to "unknown" message info */ + + /* Allocate "unknown" message info */ + if(NULL == (unknown = H5FL_MALLOC(H5O_unknown_t))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTALLOC, FAIL, "memory allocation failed") + + /* Save the original message type ID */ + *unknown = id; + + /* Save 'native' form of unknown message */ + oh->mesg[mesgno].native = unknown; + + /* Set message to "unknown" class */ + oh->mesg[mesgno].type = H5O_msg_class_g[H5O_UNKNOWN_ID]; + + /* Check for "fail if unknown" message flag */ + if(flags & H5O_MSG_FLAG_FAIL_IF_UNKNOWN) + HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, FAIL, "unknown message with 'fail if unknown' flag found") + /* Check for "mark if unknown" message flag, etc. */ + else if((flags & H5O_MSG_FLAG_MARK_IF_UNKNOWN) && + !(flags & H5O_MSG_FLAG_WAS_UNKNOWN) && + (udata->file_intent & H5F_ACC_RDWR)) { + + /* Mark the message as "unknown" */ + /* This is a bit aggressive, since the application may + * never change anything about the object (metadata or + * raw data), but we can sort out the finer details + * when/if we start using the flag - QAK + */ + /* Also, it's possible that this functionality may not + * get invoked if the object header is brought into + * the metadata cache in some other "weird" way, like + * using H5Ocopy() - QAK + */ + oh->mesg[mesgno].flags |= H5O_MSG_FLAG_WAS_UNKNOWN; + + /* Mark the message and chunk as dirty */ + oh->mesg[mesgno].dirty = TRUE; + udata->mesgs_modified = TRUE; + *dirty = TRUE; + } /* end if */ + } /* end if */ + else + /* Set message class for "known" messages */ + oh->mesg[mesgno].type = H5O_msg_class_g[id]; + } /* end else */ + + /* Advance decode pointer past message */ + p += mesg_size; + + /* Check for 'gap' at end of chunk */ + if((eom_ptr - p) > 0 && (eom_ptr - p) < H5O_SIZEOF_MSGHDR_OH(oh)) { + /* Gaps can only occur in later versions of the format */ + HDassert(oh->version > H5O_VERSION_1); + + /* Gaps should only occur in chunks with no null messages */ + HDassert(nullcnt == 0); + + /* Set gap information for chunk */ + oh->chunk[chunkno].gap = (size_t)(eom_ptr - p); + + /* Increment location in chunk */ + p += oh->chunk[chunkno].gap; + } /* end if */ + } /* end while */ + + /* Check for correct checksum on chunks, in later versions of the format */ + if(oh->version > H5O_VERSION_1) { + uint32_t stored_chksum; /* Checksum from file */ + uint32_t computed_chksum; /* Checksum computed in memory */ + + /* Metadata checksum */ + UINT32DECODE(p, stored_chksum); + + /* Compute checksum on chunk */ + computed_chksum = H5_checksum_metadata(oh->chunk[chunkno].image, (oh->chunk[chunkno].size - H5O_SIZEOF_CHKSUM), 0); + + /* Verify checksum */ + if(stored_chksum != computed_chksum) + HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL, "incorrect metadata checksum for object header chunk") + } /* end if */ + + /* Sanity check */ + HDassert(p == oh->chunk[chunkno].image + oh->chunk[chunkno].size); + + /* Do some inspection/interpretation of new messages from this chunk */ + /* (detect continuation messages, ref. count messages, etc.) */ + while(curmesg < oh->nmesgs) { + /* Check if next message to examine is a continuation message */ + if(H5O_CONT_ID == oh->mesg[curmesg].type->id) { + H5O_cont_t *cont; + unsigned ioflags = 0; /* Flags for decode routine */ + + /* Decode continuation message */ + cont = (H5O_cont_t *)(H5O_MSG_CONT->decode)(udata->f, udata->dxpl_id, NULL, 0, &ioflags, oh->mesg[curmesg].raw); + cont->chunkno = udata->cont_msg_info->nmsgs + 1; /*the next continuation message/chunk */ + + /* Save 'native' form of continuation message */ + oh->mesg[curmesg].native = cont; + + /* Add to continuation messages left to interpret */ + if(H5O_add_cont_msg(udata->cont_msg_info, cont) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't add continuation message") + + /* Mark the message & chunk as dirty if the message was changed by decoding */ + if((ioflags & H5O_DECODEIO_DIRTY) && (udata->file_intent & H5F_ACC_RDWR)) { + oh->mesg[curmesg].dirty = TRUE; + udata->mesgs_modified = TRUE; + *dirty = TRUE; + } /* end if */ + } /* end if */ + /* Check if next message to examine is a ref. count message */ + else if(H5O_REFCOUNT_ID == oh->mesg[curmesg].type->id) { + H5O_refcount_t *refcount; + unsigned ioflags = 0; /* Flags for decode routine */ + + /* Decode ref. count message */ + HDassert(oh->version > H5O_VERSION_1); + refcount = (H5O_refcount_t *)(H5O_MSG_REFCOUNT->decode)(udata->f, udata->dxpl_id, NULL, 0, &ioflags, oh->mesg[curmesg].raw); + + /* Save 'native' form of ref. count message */ + oh->mesg[curmesg].native = refcount; + + /* Set object header values */ + oh->has_refcount_msg = TRUE; + oh->nlink = *refcount; + + /* Mark the message & chunk as dirty if the message was changed by decoding */ + if((ioflags & H5O_DECODEIO_DIRTY) && (udata->file_intent & H5F_ACC_RDWR)) { + oh->mesg[curmesg].dirty = TRUE; + udata->mesgs_modified = TRUE; + *dirty = TRUE; + } /* end if */ + } /* end if */ + /* Check if next message to examine is a link message */ + else if(H5O_LINK_ID == oh->mesg[curmesg].type->id) { + /* Increment the count of link messages */ + oh->link_msgs_seen++; + } /* end if */ + /* Check if next message to examine is an attribute message */ + else if(H5O_ATTR_ID == oh->mesg[curmesg].type->id) { + /* Increment the count of attribute messages */ + oh->attr_msgs_seen++; + } /* end if */ + + /* Advance to next message */ + curmesg++; + } /* end while */ + + /* Mark the chunk dirty if we've merged null messages */ + if(merged_null_msgs) { + udata->mesgs_modified = TRUE; + *dirty = TRUE; + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5O_chunk_deserialize() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_chunk_serialize + * + * Purpose: Serialize a chunk for an object header + * + * Return: Success: SUCCEED + * Failure: FAIL + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * July 12, 2008 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O_chunk_serialize(const H5F_t *f, H5O_t *oh, unsigned chunkno) +{ + H5O_mesg_t *curr_msg; /* Pointer to current message being operated on */ + unsigned u; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5O_chunk_serialize) + + /* Check arguments */ + HDassert(f); + HDassert(oh); + + /* Encode any dirty messages in this chunk */ + for(u = 0, curr_msg = &oh->mesg[0]; u < oh->nmesgs; u++, curr_msg++) + if(curr_msg->dirty && curr_msg->chunkno == chunkno) + /* Casting away const OK -QAK */ + if(H5O_msg_flush((H5F_t *)f, oh, curr_msg) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, FAIL, "unable to encode object header message") + + /* Sanity checks */ + if(oh->version > H5O_VERSION_1) + /* Make certain the magic # is present */ + HDassert(!HDmemcmp(oh->chunk[chunkno].image, (chunkno == 0 ? H5O_HDR_MAGIC : H5O_CHK_MAGIC), H5_SIZEOF_MAGIC)); + else + /* Gaps should never occur in version 1 of the format */ + HDassert(oh->chunk[chunkno].gap == 0); + + /* Extra work, for later versions of the format */ + if(oh->version > H5O_VERSION_1) { + uint32_t metadata_chksum; /* Computed metadata checksum value */ + uint8_t *p; /* Pointer into object header chunk */ + + /* Check for gap in chunk & zero it out */ + if(oh->chunk[chunkno].gap) + HDmemset((oh->chunk[chunkno].image + oh->chunk[chunkno].size) - + (H5O_SIZEOF_CHKSUM + oh->chunk[chunkno].gap), 0, oh->chunk[chunkno].gap); + + /* Compute metadata checksum */ + metadata_chksum = H5_checksum_metadata(oh->chunk[chunkno].image, (oh->chunk[chunkno].size - H5O_SIZEOF_CHKSUM), 0); + + /* Metadata checksum */ + p = oh->chunk[chunkno].image + (oh->chunk[chunkno].size - H5O_SIZEOF_CHKSUM); + UINT32ENCODE(p, metadata_chksum); + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5O_chunk_serialize() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_chunk_proxy_dest + * + * Purpose: Destroy a chunk proxy object + * + * Return: Success: SUCCEED + * Failure: FAIL + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * July 13, 2008 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O_chunk_proxy_dest(H5O_chunk_proxy_t *chk_proxy) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5O_chunk_proxy_dest) + + /* Check arguments */ + HDassert(chk_proxy); + + /* Decrement reference count of object header */ + if(H5O_dec_rc(chk_proxy->oh) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTDEC, FAIL, "can't decrement reference count on object header") + + /* Release the chunk proxy object */ + chk_proxy = H5FL_FREE(H5O_chunk_proxy_t, chk_proxy); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5O_chunk_proxy_dest() */ + diff --git a/src/H5Ochunk.c b/src/H5Ochunk.c new file mode 100644 index 0000000..59102b6 --- /dev/null +++ b/src/H5Ochunk.c @@ -0,0 +1,359 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*------------------------------------------------------------------------- + * + * Created: H5Ochunk.c + * Jul 13 2008 + * Quincey Koziol <koziol@hdfgroup.org> + * + * Purpose: Object header chunk routines. + * + *------------------------------------------------------------------------- + */ + +/****************/ +/* Module Setup */ +/****************/ + +#define H5O_PACKAGE /*suppress error about including H5Opkg */ + +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Opkg.h" /* Object headers */ + + +/****************/ +/* Local Macros */ +/****************/ + + +/******************/ +/* Local Typedefs */ +/******************/ + + +/********************/ +/* Package Typedefs */ +/********************/ + + +/********************/ +/* Local Prototypes */ +/********************/ + + +/*********************/ +/* Package Variables */ +/*********************/ + +/* Declare the free list for H5O_chunk_proxy_t's */ +H5FL_DEFINE(H5O_chunk_proxy_t); + + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/*******************/ +/* Local Variables */ +/*******************/ + + + +/*------------------------------------------------------------------------- + * Function: H5O_chunk_add + * + * Purpose: Add new chunk for object header to metadata cache + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Jul 13 2008 + * + *------------------------------------------------------------------------- + */ +herr_t +H5O_chunk_add(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned idx) +{ + H5O_chunk_proxy_t *chk_proxy = NULL; /* Proxy for chunk, to mark it dirty in the cache */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5O_chunk_add, FAIL) + + /* check args */ + HDassert(f); + HDassert(oh); + HDassert(idx < oh->nchunks); + HDassert(idx > 0); + + /* Allocate space for the object header data structure */ + if(NULL == (chk_proxy = H5FL_CALLOC(H5O_chunk_proxy_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + + /* Set the values in the chunk proxy */ + chk_proxy->oh = oh; + chk_proxy->chunkno = idx; + + /* Insert the chunk proxy into the cache */ + if(H5AC_set(f, dxpl_id, H5AC_OHDR_CHK, oh->chunk[idx].addr, chk_proxy, H5AC__NO_FLAGS_SET) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "unable to cache object header chunk") + chk_proxy = NULL; + + /* Increment reference count on object header */ + if(H5O_inc_rc(oh) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINC, FAIL, "can't increment reference count on object header") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_chunk_add() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_chunk_protect + * + * Purpose: Protect an object header chunk for modifications + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Jul 17 2008 + * + *------------------------------------------------------------------------- + */ +H5O_chunk_proxy_t * +H5O_chunk_protect(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned idx) +{ + H5O_chunk_proxy_t *chk_proxy; /* Proxy for protected chunk */ + H5O_chunk_proxy_t *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(H5O_chunk_protect, NULL) + + /* check args */ + HDassert(f); + HDassert(oh); + HDassert(idx < oh->nchunks); + + /* Check for protecting first chunk */ + if(0 == idx) { + /* Create new "fake" chunk proxy for first chunk */ + /* (since the first chunk is already handled by the H5O_t object) */ + if(NULL == (chk_proxy = H5FL_CALLOC(H5O_chunk_proxy_t))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTALLOC, NULL, "memory allocation failed") + + /* Set chunk proxy fields */ + chk_proxy->oh = oh; + chk_proxy->chunkno = idx; + } /* end if */ + else { + H5O_chk_cache_ud_t chk_udata; /* User data for loading chunk */ + + /* Construct the user data for protecting chunk proxy */ + /* (and _not_ decoding it) */ + HDmemset(&chk_udata, 0, sizeof(chk_udata)); + chk_udata.oh = oh; + chk_udata.chunkno = idx; + chk_udata.chunk_size = oh->chunk[idx].size; + + /* Get the chunk proxy */ + if(NULL == (chk_proxy = (H5O_chunk_proxy_t *)H5AC_protect(f, dxpl_id, H5AC_OHDR_CHK, oh->chunk[idx].addr, NULL, &chk_udata, H5AC_WRITE))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, NULL, "unable to load object header chunk") + + /* Sanity check */ + HDassert(chk_proxy->oh == oh); + HDassert(chk_proxy->chunkno == idx); + } /* end else */ + + /* Set return value */ + ret_value = chk_proxy; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_chunk_protect() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_chunk_unprotect + * + * Purpose: Unprotect an object header chunk after modifications + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Jul 17 2008 + * + *------------------------------------------------------------------------- + */ +herr_t +H5O_chunk_unprotect(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5O_chunk_proxy_t *chk_proxy, + unsigned chk_flags) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5O_chunk_unprotect, FAIL) + + /* check args */ + HDassert(f); + HDassert(oh); + HDassert(chk_proxy); + HDassert(!(chk_flags & (unsigned)~(H5AC__DIRTIED_FLAG | H5AC__SIZE_CHANGED_FLAG))); + + /* Check for releasing first chunk */ + if(0 == chk_proxy->chunkno) { + /* Check for resizing the first chunk */ + if(chk_flags & H5AC__SIZE_CHANGED_FLAG) { + /* Resize object header in cache */ + if(H5AC_resize_pinned_entry(oh, oh->chunk[0].size) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTRESIZE, FAIL, "unable to resize chunk in cache") + } /* end if */ + /* Check for dirtying the first chunk */ + else if(chk_flags & H5AC__DIRTIED_FLAG) { + /* Mark object header as dirty in cache */ + if(H5AC_mark_pinned_or_protected_entry_dirty(oh) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTMARKDIRTY, FAIL, "unable to mark object header as dirty") + } /* end else/if */ + else { + /* Sanity check */ + HDassert(0 && "Unknown chunk proxy flag(s)?!?"); + } /* end else */ + + /* Free fake chunk proxy */ + chk_proxy = H5FL_FREE(H5O_chunk_proxy_t, chk_proxy); + } /* end if */ + else { + /* Release the chunk proxy from the cache, marking it dirty */ + if(H5AC_unprotect(f, dxpl_id, H5AC_OHDR_CHK, oh->chunk[chk_proxy->chunkno].addr, chk_proxy, chk_flags) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header chunk") + } /* end else */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_chunk_unprotect() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_chunk_update_idx + * + * Purpose: Update the chunk index for a chunk proxy + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Jul 13 2008 + * + *------------------------------------------------------------------------- + */ +herr_t +H5O_chunk_update_idx(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned idx) +{ + H5O_chunk_proxy_t *chk_proxy; /* Proxy for chunk, to mark it dirty in the cache */ + H5O_chk_cache_ud_t chk_udata; /* User data for loading chunk */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5O_chunk_update_idx, FAIL) + + /* check args */ + HDassert(f); + HDassert(oh); + HDassert(idx < oh->nchunks); + HDassert(idx > 0); + + /* Construct the user data for protecting chunk proxy */ + /* (and _not_ decoding it) */ + HDmemset(&chk_udata, 0, sizeof(chk_udata)); + chk_udata.oh = oh; + chk_udata.chunkno = idx; + chk_udata.chunk_size = oh->chunk[idx].size; + + /* Get the chunk proxy */ + if(NULL == (chk_proxy = (H5O_chunk_proxy_t *)H5AC_protect(f, dxpl_id, H5AC_OHDR_CHK, oh->chunk[idx].addr, NULL, &chk_udata, H5AC_WRITE))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header chunk") + + /* Update index for chunk proxy in cache */ + chk_proxy->chunkno = idx; + + /* Release the chunk proxy from the cache, marking it deleted */ + if(H5AC_unprotect(f, dxpl_id, H5AC_OHDR_CHK, oh->chunk[idx].addr, chk_proxy, H5AC__DIRTIED_FLAG) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header chunk") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_chunk_update_idx() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_chunk_delete + * + * Purpose: Notify metadata cache that a chunk has been deleted + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Jul 13 2008 + * + *------------------------------------------------------------------------- + */ +herr_t +H5O_chunk_delete(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned idx) +{ + H5O_chunk_proxy_t *chk_proxy; /* Proxy for chunk, to mark it dirty in the cache */ + H5O_chk_cache_ud_t chk_udata; /* User data for loading chunk */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5O_chunk_delete, FAIL) + + /* check args */ + HDassert(f); + HDassert(oh); + HDassert(idx < oh->nchunks); + HDassert(idx > 0); + + /* Construct the user data for protecting chunk proxy */ + /* (and _not_ decoding it) */ + HDmemset(&chk_udata, 0, sizeof(chk_udata)); + chk_udata.oh = oh; + chk_udata.chunkno = idx; + chk_udata.chunk_size = oh->chunk[idx].size; + + /* Get the chunk proxy */ + if(NULL == (chk_proxy = (H5O_chunk_proxy_t *)H5AC_protect(f, dxpl_id, H5AC_OHDR_CHK, oh->chunk[idx].addr, NULL, &chk_udata, H5AC_WRITE))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header chunk") + + /* Sanity check */ + HDassert(chk_proxy->oh == oh); + HDassert(chk_proxy->chunkno == idx); + + /* Release the chunk proxy from the cache, marking it deleted */ + if(H5AC_unprotect(f, dxpl_id, H5AC_OHDR_CHK, oh->chunk[idx].addr, chk_proxy, (H5AC__DIRTIED_FLAG | H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG)) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header chunk") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_chunk_delete() */ + diff --git a/src/H5Ocont.c b/src/H5Ocont.c index df336dd..7f9dd47 100644 --- a/src/H5Ocont.c +++ b/src/H5Ocont.c @@ -224,7 +224,7 @@ H5O_cont_free(void *mesg) *------------------------------------------------------------------------- */ static herr_t -H5O_cont_delete(H5F_t *f, hid_t dxpl_id, H5O_t UNUSED *open_oh, void *_mesg) +H5O_cont_delete(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, void *_mesg) { H5O_cont_t *mesg = (H5O_cont_t *) _mesg; herr_t ret_value = SUCCEED; /* Return value */ @@ -235,9 +235,10 @@ H5O_cont_delete(H5F_t *f, hid_t dxpl_id, H5O_t UNUSED *open_oh, void *_mesg) HDassert(f); HDassert(mesg); - /* Release space for chunk */ - if(H5MF_xfree(f, H5FD_MEM_OHDR, dxpl_id, mesg->addr, (hsize_t)mesg->size) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to free object header chunk") + /* Notify the cache that the chunk has been deleted */ + /* (releases the space for the chunk) */ + if(H5O_chunk_delete(f, dxpl_id, open_oh, mesg->chunkno) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "unable to remove chunk from cache") done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5Ocopy.c b/src/H5Ocopy.c index f9bf533..163e525 100644 --- a/src/H5Ocopy.c +++ b/src/H5Ocopy.c @@ -316,7 +316,7 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, HDassert(cpy_info); /* Get source object header */ - if(NULL == (oh_src = (H5O_t *)H5AC_protect(oloc_src->file, dxpl_id, H5AC_OHDR, oloc_src->addr, NULL, NULL, H5AC_READ))) + if(NULL == (oh_src = H5O_protect(oloc_src, dxpl_id, H5AC_READ))) HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header") /* Get pointer to object class for this object */ @@ -354,15 +354,19 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, oh_dst->max_compact = oh_src->max_compact; oh_dst->min_dense = oh_src->min_dense; - /* Initialize size of chunk array. The destination always has only one - * chunk. + /* Initialize size of chunk array. Start off with zero chunks so this field + * is consistent with the current state of the chunk array. This is + * important if an error occurs. */ - oh_dst->alloc_nchunks = oh_dst->nchunks = 1; + oh_dst->alloc_nchunks = oh_dst->nchunks = 0; - /* Allocate memory for the chunk array */ - if(NULL == (oh_dst->chunk = H5FL_SEQ_MALLOC(H5O_chunk_t, oh_dst->alloc_nchunks))) + /* Allocate memory for the chunk array - always start with 1 chunk */ + if(NULL == (oh_dst->chunk = H5FL_SEQ_MALLOC(H5O_chunk_t, 1))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + /* Update number of allocated chunks. There are still no chunks used. */ + oh_dst->alloc_nchunks = 1; + /* Allocate memory for "deleted" array. This array marks the message in * the source that shouldn't be copied to the destination. */ @@ -575,10 +579,12 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") /* Set dest. chunk information */ - oh_dst->chunk[0].dirty = TRUE; oh_dst->chunk[0].size = (size_t)dst_oh_size; oh_dst->chunk[0].gap = dst_oh_gap; + /* Update size of chunk array. The destination now has one chunk. */ + oh_dst->nchunks = 1; + /* Set up raw pointers and copy messages that didn't need special * treatment. This has to happen after the destination header has been * allocated. @@ -732,7 +738,7 @@ done: HDfree(deleted); /* Release pointer to source object header and its derived objects */ - if(oh_src && H5AC_unprotect(oloc_src->file, dxpl_id, H5AC_OHDR, oloc_src->addr, oh_src, H5AC__NO_FLAGS_SET) < 0) + if(oh_src && H5O_unprotect(oloc_src, dxpl_id, oh_src, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header") /* Release pointer to destination object header */ @@ -1124,8 +1130,13 @@ H5O_copy_expand_ref(H5F_t *file_src, void *_src_ref, hid_t dxpl_id, dst_oloc.addr = HADDR_UNDEF; /* Attempt to copy object from source to destination file */ - if(H5O_copy_obj_by_ref(&src_oloc, dxpl_id, &dst_oloc, &dst_root_loc, cpy_info) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object") + if(src_oloc.addr != (haddr_t)0) { + if(H5O_copy_obj_by_ref(&src_oloc, dxpl_id, &dst_oloc, &dst_root_loc, cpy_info) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object") + } /* end if */ + else + /* Set parameters so the reference is written as all 0's */ + HDmemset(&dst_oloc.addr, 0, sizeof(dst_oloc.addr)); /* Set the object reference info for the destination file */ p = (uint8_t *)(&dst_ref[i]); @@ -1136,7 +1147,7 @@ H5O_copy_expand_ref(H5F_t *file_src, void *_src_ref, hid_t dxpl_id, else if(H5R_DATASET_REGION == ref_type) { hdset_reg_ref_t *src_ref = (hdset_reg_ref_t *)_src_ref; hdset_reg_ref_t *dst_ref = (hdset_reg_ref_t *)_dst_ref; - uint8_t *buf; /* Buffer to store serialized selection in */ + uint8_t *buf = NULL; /* Buffer to store serialized selection in */ H5HG_t hobjid; /* Heap object ID */ size_t buf_size; /* Length of object in heap */ @@ -1147,30 +1158,35 @@ H5O_copy_expand_ref(H5F_t *file_src, void *_src_ref, hid_t dxpl_id, H5F_addr_decode(src_oloc.file, (const uint8_t **)&p, &(hobjid.addr)); INT32DECODE(p, hobjid.idx); - /* Get the dataset region from the heap (allocate inside routine) */ - if((buf = (uint8_t *)H5HG_read(src_oloc.file, dxpl_id, &hobjid, NULL, &buf_size)) == NULL) - HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, FAIL, "Unable to read dataset region information") - - /* Get the object oid for the dataset */ - p = (uint8_t *)buf; - H5F_addr_decode(src_oloc.file, (const uint8_t **)&p, &(src_oloc.addr)); - dst_oloc.addr = HADDR_UNDEF; - - /* copy the object pointed by the ref to the destination */ - if(H5O_copy_obj_by_ref(&src_oloc, dxpl_id, &dst_oloc, &dst_root_loc, cpy_info) < 0) { - H5MM_xfree(buf); - HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object") - } /* end if */ - - /* Serialize object ID */ - p = (uint8_t *)buf; - H5F_addr_encode(dst_oloc.file, &p, dst_oloc.addr); - - /* Save the serialized buffer to the destination */ - if(H5HG_insert(dst_oloc.file, dxpl_id, buf_size, buf, &hobjid) < 0) { - H5MM_xfree(buf); - HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "Unable to write dataset region information") + if(hobjid.addr != (haddr_t)0) { + /* Get the dataset region from the heap (allocate inside routine) */ + if((buf = (uint8_t *)H5HG_read(src_oloc.file, dxpl_id, &hobjid, NULL, &buf_size)) == NULL) + HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, FAIL, "Unable to read dataset region information") + + /* Get the object oid for the dataset */ + p = (uint8_t *)buf; + H5F_addr_decode(src_oloc.file, (const uint8_t **)&p, &(src_oloc.addr)); + dst_oloc.addr = HADDR_UNDEF; + + /* copy the object pointed by the ref to the destination */ + if(H5O_copy_obj_by_ref(&src_oloc, dxpl_id, &dst_oloc, &dst_root_loc, cpy_info) < 0) { + H5MM_xfree(buf); + HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object") + } /* end if */ + + /* Serialize object ID */ + p = (uint8_t *)buf; + H5F_addr_encode(dst_oloc.file, &p, dst_oloc.addr); + + /* Save the serialized buffer to the destination */ + if(H5HG_insert(dst_oloc.file, dxpl_id, buf_size, buf, &hobjid) < 0) { + H5MM_xfree(buf); + HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "Unable to write dataset region information") + } /* end if */ } /* end if */ + else + /* Set parameters so the reference is written as all 0's */ + HDmemset(&hobjid, 0, sizeof(hobjid)); /* Set the dataset region reference info for the destination file */ p = (uint8_t *)(&dst_ref[i]); diff --git a/src/H5Odbg.c b/src/H5Odbg.c index 9285f4b..8661cfe 100644 --- a/src/H5Odbg.c +++ b/src/H5Odbg.c @@ -377,10 +377,6 @@ H5O_debug_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh, haddr_t addr, FILE *stream, i HDfprintf(stream, "%*sChunk %d...\n", indent, "", i); - HDfprintf(stream, "%*s%-*s %t\n", indent + 3, "", MAX(0, fwidth - 3), - "Dirty:", - oh->chunk[i].dirty); - HDfprintf(stream, "%*s%-*s %a\n", indent + 3, "", MAX(0, fwidth - 3), "Address:", oh->chunk[i].addr); @@ -538,6 +534,7 @@ herr_t H5O_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int fwidth) { H5O_t *oh = NULL; /* Object header to display */ + H5O_loc_t loc; /* Object location for object to delete */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5O_debug, FAIL) @@ -549,14 +546,19 @@ H5O_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int f HDassert(indent >= 0); HDassert(fwidth >= 0); - if(NULL == (oh = (H5O_t *)H5AC_protect(f, dxpl_id, H5AC_OHDR, addr, NULL, NULL, H5AC_READ))) + /* Set up the object location */ + loc.file = f; + loc.addr = addr; + loc.holding_file = FALSE; + + if(NULL == (oh = H5O_protect(&loc, dxpl_id, H5AC_READ))) HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header") /* debug */ H5O_debug_real(f, dxpl_id, oh, addr, stream, indent, fwidth); done: - if(oh && H5AC_unprotect(f, dxpl_id, H5AC_OHDR, addr, oh, H5AC__NO_FLAGS_SET) < 0) + if(oh && H5O_unprotect(&loc, dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header") FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5Omessage.c b/src/H5Omessage.c index fc6146a..e2355ae 100644 --- a/src/H5Omessage.c +++ b/src/H5Omessage.c @@ -127,21 +127,17 @@ H5O_msg_create(const H5O_loc_t *loc, unsigned type_id, unsigned mesg_flags, HDassert(0 == (mesg_flags & ~H5O_MSG_FLAG_BITS)); HDassert(mesg); - /* Check for write access on the file */ - if(0 == (H5F_INTENT(loc->file) & H5F_ACC_RDWR)) - HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "no write intent on file") - - /* Protect the object header */ - if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_WRITE))) - HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header") + /* Pin the object header */ + if(NULL == (oh = H5O_pin(loc, dxpl_id))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTPIN, FAIL, "unable to pin object header") /* Go append message to object header */ if(H5O_msg_append_oh(loc->file, dxpl_id, oh, type_id, mesg_flags, update_flags, mesg) < 0) HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to append to object header") done: - if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header") + if(oh && H5O_unpin(oh) < 0) + HDONE_ERROR(H5E_OHDR, H5E_CANTUNPIN, FAIL, "unable to unpin object header") FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_msg_create() */ @@ -280,21 +276,17 @@ H5O_msg_write(const H5O_loc_t *loc, unsigned type_id, unsigned mesg_flags, HDassert(mesg); HDassert(0 == (mesg_flags & ~H5O_MSG_FLAG_BITS)); - /* Check for write access on the file */ - if(0 == (H5F_INTENT(loc->file) & H5F_ACC_RDWR)) - HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "no write intent on file") - - /* Protect the object header */ - if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_WRITE))) - HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header") + /* Pin the object header */ + if(NULL == (oh = H5O_pin(loc, dxpl_id))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTPIN, FAIL, "unable to pin object header") /* Call the "real" modify routine */ if(H5O_msg_write_real(loc->file, dxpl_id, oh, type, mesg_flags, update_flags, mesg) < 0) HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to write object header message") done: - if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header") + if(oh && H5O_unpin(oh) < 0) + HDONE_ERROR(H5E_OHDR, H5E_CANTUNPIN, FAIL, "unable to unpin object header") FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_msg_write() */ @@ -484,7 +476,7 @@ H5O_msg_read(const H5O_loc_t *loc, unsigned type_id, void *mesg, HDassert(type_id < NELMTS(H5O_msg_class_g)); /* Get the object header */ - if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ))) + if(NULL == (oh = H5O_protect(loc, dxpl_id, H5AC_READ))) HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, NULL, "unable to load object header") /* Call the "real" read routine */ @@ -492,7 +484,7 @@ H5O_msg_read(const H5O_loc_t *loc, unsigned type_id, void *mesg, HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "unable to load object header") done: - if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) < 0) + if(oh && H5O_unprotect(loc, dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, NULL, "unable to release object header") FUNC_LEAVE_NOAPI(ret_value) @@ -809,14 +801,14 @@ H5O_msg_count(const H5O_loc_t *loc, unsigned type_id, hid_t dxpl_id) HDassert(type); /* Load the object header */ - if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ))) + if(NULL == (oh = H5O_protect(loc, dxpl_id, H5AC_READ))) HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header") /* Count the messages of the correct type */ ret_value = H5O_msg_count_real(oh, type); done: - if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) < 0) + if(oh && H5O_unprotect(loc, dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header") FUNC_LEAVE_NOAPI(ret_value) @@ -890,7 +882,7 @@ H5O_msg_exists(const H5O_loc_t *loc, unsigned type_id, hid_t dxpl_id) HDassert(type_id < NELMTS(H5O_msg_class_g)); /* Load the object header */ - if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ))) + if(NULL == (oh = H5O_protect(loc, dxpl_id, H5AC_READ))) HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header") /* Call the "real" exists routine */ @@ -898,7 +890,7 @@ H5O_msg_exists(const H5O_loc_t *loc, unsigned type_id, hid_t dxpl_id) HGOTO_ERROR(H5E_OHDR, H5E_READERROR, FAIL, "unable to verify object header message") done: - if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) != SUCCEED) + if(oh && H5O_unprotect(loc, dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header") FUNC_LEAVE_NOAPI(ret_value) @@ -986,17 +978,17 @@ H5O_msg_remove(const H5O_loc_t *loc, unsigned type_id, int sequence, hbool_t adj type = H5O_msg_class_g[type_id]; /* map the type ID to the actual type object */ HDassert(type); - /* Protect the object header to iterate over */ - if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_WRITE))) - HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header") + /* Pin the object header */ + if(NULL == (oh = H5O_pin(loc, dxpl_id))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTPIN, FAIL, "unable to pin object header") /* Call the "real" remove routine */ if((ret_value = H5O_msg_remove_real(loc->file, oh, type, sequence, NULL, NULL, adj_link, dxpl_id)) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "unable to remove object header message") done: - if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header") + if(oh && H5O_unpin(oh) < 0) + HDONE_ERROR(H5E_OHDR, H5E_CANTUNPIN, FAIL, "unable to unpin object header") FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_msg_remove() */ @@ -1038,17 +1030,17 @@ H5O_msg_remove_op(const H5O_loc_t *loc, unsigned type_id, int sequence, type = H5O_msg_class_g[type_id]; /* map the type ID to the actual type object */ HDassert(type); - /* Protect the object header to iterate over */ - if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_WRITE))) - HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header") + /* Pin the object header */ + if(NULL == (oh = H5O_pin(loc, dxpl_id))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTPIN, FAIL, "unable to pin object header") /* Call the "real" remove routine */ if((ret_value = H5O_msg_remove_real(loc->file, oh, type, sequence, op, op_data, adj_link, dxpl_id)) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "unable to remove object header message") done: - if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header") + if(oh && H5O_unpin(oh) < 0) + HDONE_ERROR(H5E_OHDR, H5E_CANTUNPIN, FAIL, "unable to unpin object header") FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_msg_remove_op() */ @@ -1230,7 +1222,7 @@ H5O_msg_iterate(const H5O_loc_t *loc, unsigned type_id, HDassert(op); /* Protect the object header to iterate over */ - if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ))) + if(NULL == (oh = H5O_protect(loc, dxpl_id, H5AC_READ))) HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header") /* Call the "real" iterate routine */ @@ -1238,7 +1230,7 @@ H5O_msg_iterate(const H5O_loc_t *loc, unsigned type_id, HERROR(H5E_OHDR, H5E_BADITER, "unable to iterate over object header messages"); done: - if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) < 0) + if(oh && H5O_unprotect(loc, dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header") FUNC_LEAVE_NOAPI(ret_value) @@ -1962,7 +1954,9 @@ H5O_copy_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned idx, const H5O_msg_class_t *type, const void *mesg, unsigned mesg_flags, unsigned update_flags) { + H5O_chunk_proxy_t *chk_proxy = NULL; /* Chunk that message is in */ H5O_mesg_t *idx_msg = &oh->mesg[idx]; /* Pointer to message to modify */ + unsigned chk_flags = H5AC__NO_FLAGS_SET; /* Flags for unprotecting chunk */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5O_copy_mesg) @@ -1974,6 +1968,10 @@ H5O_copy_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned idx, HDassert(type->copy); HDassert(mesg); + /* Protect chunk */ + if(NULL == (chk_proxy = H5O_chunk_protect(f, dxpl_id, oh, idx_msg->chunkno))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header chunk") + /* Reset existing native information for the header's message */ H5O_msg_reset_real(type, idx_msg->native); @@ -1986,17 +1984,23 @@ H5O_copy_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned idx, /* Mark the message as modified */ idx_msg->dirty = TRUE; + chk_flags |= H5AC__DIRTIED_FLAG; + + /* Release chunk */ + if(H5O_chunk_unprotect(f, dxpl_id, oh, chk_proxy, chk_flags) < 0) + HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to unprotect object header chunk") + chk_proxy = NULL; /* Update the modification time, if requested */ if(update_flags & H5O_UPDATE_TIME) if(H5O_touch_oh(f, dxpl_id, oh, FALSE) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTUPDATE, FAIL, "unable to update time on object") - /* Mark object header as dirty in cache */ - if(H5AC_mark_pinned_or_protected_entry_dirty(oh) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTMARKDIRTY, FAIL, "unable to mark object header as dirty") - done: + /* Release chunk, if not already released */ + if(chk_proxy && H5O_chunk_unprotect(f, dxpl_id, oh, chk_proxy, chk_flags) < 0) + HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to unprotect object header chunk") + FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_copy_mesg() */ @@ -2183,9 +2187,8 @@ H5O_msg_flush(H5F_t *f, H5O_t *oh, H5O_mesg_t *mesg) HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, FAIL, "unable to encode object header message") } /* end if */ - /* Pass "modifiedness" from message to chunk */ + /* Mark the message as clean now */ mesg->dirty = FALSE; - oh->chunk[mesg->chunkno].dirty = TRUE; done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5Opkg.h b/src/H5Opkg.h index b575e29..69f9ff1 100644 --- a/src/H5Opkg.h +++ b/src/H5Opkg.h @@ -253,7 +253,6 @@ struct H5O_mesg_t { }; typedef struct H5O_chunk_t { - hbool_t dirty; /*dirty flag */ haddr_t addr; /*chunk file address */ size_t size; /*chunk size */ size_t gap; /*space at end of chunk too small for null message */ @@ -268,9 +267,6 @@ struct H5O_t { size_t sizeof_size; /* Size of file sizes */ size_t sizeof_addr; /* Size of file addresses */ - /* Misc. information (not stored) */ - unsigned npins; /* Number of times the header is pinned */ - /* Debugging information (not stored) */ #ifdef H5O_ENABLE_BAD_MESG_COUNT hbool_t store_bad_mesg_count; /* Flag to indicate that a bad message count should be stored */ @@ -282,6 +278,12 @@ struct H5O_t { size_t ndecode_dirtied; /* Number of messages dirtied by decoding */ #endif /* NDEBUG */ + /* Chunk management information (not stored) */ + size_t rc; /* Reference count of [continuation] chunks using this structure */ + size_t chunk0_size; /* Size of serialized first chunk */ + hbool_t mesgs_modified; /* Whether any messages were modified when the object header was deserialized */ + hbool_t prefix_modified; /* Whether prefix was modified when the object header was deserialized */ + /* Object information (stored) */ hbool_t has_refcount_msg; /* Whether the object has a ref. count message */ unsigned nlink; /*link count */ @@ -332,10 +334,55 @@ typedef struct H5O_addr_map_t { hsize_t inc_ref_count; /* Number of deferred increments to reference count */ } H5O_addr_map_t; - -/* H5O inherits cache-like properties from H5AC */ +/* Stack of continuation messages to interpret */ +typedef struct H5O_cont_msgs_t { + size_t nmsgs; /* Number of continuation messages found so far */ + size_t alloc_nmsgs; /* Continuation messages allocated */ + H5O_cont_t *msgs; /* Array of continuation messages */ +} H5O_cont_msgs_t; + +/* Common callback information for loading object header prefix from disk */ +typedef struct H5O_common_cache_ud_t { + H5F_t *f; /* Pointer to file for object header/chunk */ + hid_t dxpl_id; /* DXPL for operation */ + unsigned file_intent; /* Read/write intent for file */ + unsigned merged_null_msgs; /* Number of null messages merged together */ + hbool_t mesgs_modified; /* Whether any messages were modified when the object header was deserialized */ + H5O_cont_msgs_t *cont_msg_info; /* Pointer to continuation messages to work on */ +} H5O_common_cache_ud_t; + +/* Callback information for loading object header prefix from disk */ +typedef struct H5O_cache_ud_t { + hbool_t made_attempt; /* Whether the deserialize routine was already attempted */ + unsigned v1_pfx_nmesgs; /* Number of messages from v1 prefix header */ + H5O_common_cache_ud_t common; /* Common object header cache callback info */ +} H5O_cache_ud_t; + +/* Structure representing each chunk in the cache */ +typedef struct H5O_chunk_proxy_t { + H5AC_info_t cache_info; /* Information for metadata cache functions, _must_ be */ + /* first field in structure */ + + H5O_t *oh; /* Object header for this chunk */ + unsigned chunkno; /* Chunk number for this chunk */ +} H5O_chunk_proxy_t; + +/* Callback information for loading object header chunk from disk */ +typedef struct H5O_chk_cache_ud_t { + hbool_t decoding; /* Whether the object header is being decoded */ + H5O_t *oh; /* Object header for this chunk */ + unsigned chunkno; /* Index of chunk being brought in (for re-loads) */ + size_t chunk_size; /* Chunk size */ + H5O_common_cache_ud_t common; /* Common object header cache callback info */ +} H5O_chk_cache_ud_t; + + +/* H5O object header inherits cache-like properties from H5AC */ H5_DLLVAR const H5AC_class_t H5AC_OHDR[1]; +/* H5O object header chunk inherits cache-like properties from H5AC */ +H5_DLLVAR const H5AC_class_t H5AC_OHDR_CHK[1]; + /* Header message ID to class mapping */ H5_DLLVAR const H5O_msg_class_t *const H5O_msg_class_g[H5O_MSG_TYPES]; @@ -480,6 +527,9 @@ H5_DLL herr_t H5O_flush_msgs(H5F_t *f, H5O_t *oh); H5_DLL hid_t H5O_open_by_loc(const H5G_loc_t *obj_loc, hid_t lapl_id, hid_t dxpl_id, hbool_t app_ref); H5_DLL herr_t H5O_delete_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, H5O_mesg_t *mesg); H5_DLL const H5O_obj_class_t *H5O_obj_class_real(H5O_t *oh); +H5_DLL int H5O_link_oh(H5F_t *f, int adjust, hid_t dxpl_id, H5O_t *oh, hbool_t *deleted); +H5_DLL herr_t H5O_inc_rc(H5O_t *oh); +H5_DLL herr_t H5O_dec_rc(H5O_t *oh); H5_DLL herr_t H5O_free(H5O_t *oh); /* Object header message routines */ @@ -502,6 +552,15 @@ H5_DLL void *H5O_msg_copy_file(const H5O_msg_class_t *type, H5F_t *file_src, H5_DLL herr_t H5O_msg_iterate_real(H5F_t *f, H5O_t *oh, const H5O_msg_class_t *type, const H5O_mesg_operator_t *op, void *op_data, hid_t dxpl_id); +/* Object header chunk routines */ +H5_DLL herr_t H5O_chunk_add(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned idx); +H5_DLL H5O_chunk_proxy_t *H5O_chunk_protect(H5F_t *f, hid_t dxpl_id, H5O_t *oh, + unsigned idx); +H5_DLL herr_t H5O_chunk_unprotect(H5F_t *f, hid_t dxpl_id, H5O_t *oh, + H5O_chunk_proxy_t *chk_proxy, unsigned chk_flags); +H5_DLL herr_t H5O_chunk_update_idx(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned idx); +H5_DLL herr_t H5O_chunk_delete(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned idx); + /* Collect storage info for btree and heap */ H5_DLL herr_t H5O_attr_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5_ih_info_t *bh_info); @@ -548,6 +607,7 @@ H5_DLL htri_t H5O_is_attr_dense_test(hid_t oid); H5_DLL herr_t H5O_num_attrs_test(hid_t oid, hsize_t *nattrs); H5_DLL herr_t H5O_attr_dense_info_test(hid_t oid, hsize_t *name_count, hsize_t *corder_count); H5_DLL herr_t H5O_check_msg_marked_test(hid_t oid, hbool_t flag_val); +H5_DLL herr_t H5O_expunge_chunks_test(const H5O_loc_t *oloc, hid_t dxpl_id); #endif /* H5O_TESTING */ /* Object header debugging routines */ diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index 04338e9..a23767b 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -37,6 +37,7 @@ #include "H5Spublic.h" /* Dataspace functions */ /* Private headers needed by this file */ +#include "H5ACprivate.h" /* Metadata cache */ #include "H5Fprivate.h" /* File access */ #include "H5SLprivate.h" /* Skip lists */ #include "H5Tprivate.h" /* Datatype functions */ @@ -676,9 +677,11 @@ H5_DLL herr_t H5O_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, H5_DLL herr_t H5O_open(H5O_loc_t *loc); H5_DLL herr_t H5O_close(H5O_loc_t *loc); H5_DLL int H5O_link(const H5O_loc_t *loc, int adjust, hid_t dxpl_id); -H5_DLL int H5O_link_oh(H5F_t *f, int adjust, hid_t dxpl_id, H5O_t *oh, unsigned *oh_flags); -H5_DLL H5O_t *H5O_pin(H5O_loc_t *loc, hid_t dxpl_id); +H5_DLL H5O_t *H5O_protect(const H5O_loc_t *loc, hid_t dxpl_id, H5AC_protect_t prot); +H5_DLL H5O_t *H5O_pin(const H5O_loc_t *loc, hid_t dxpl_id); H5_DLL herr_t H5O_unpin(H5O_t *oh); +H5_DLL herr_t H5O_unprotect(const H5O_loc_t *loc, hid_t dxpl_id, H5O_t *oh, + unsigned oh_flags); H5_DLL herr_t H5O_touch(const H5O_loc_t *loc, hbool_t force, hid_t dxpl_id); H5_DLL herr_t H5O_touch_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh, hbool_t force); diff --git a/src/H5Oshared.c b/src/H5Oshared.c index cdd9778..4a9c2bb 100644 --- a/src/H5Oshared.c +++ b/src/H5Oshared.c @@ -256,12 +256,12 @@ H5O_shared_link_adj(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, * is possible, for example, if an attribute's datatype is shared in * the same object header the attribute is in. Adjust the link * count directly. */ - unsigned oh_flags = H5AC__NO_FLAGS_SET; /* This is used only to satisfy H5O_link_oh */ + hbool_t deleted = FALSE; /* This is used only to satisfy H5O_link_oh */ - if(H5O_link_oh(f, adjust, dxpl_id, open_oh, &oh_flags) < 0) + if(H5O_link_oh(f, adjust, dxpl_id, open_oh, &deleted) < 0) HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, "unable to adjust shared object link count") - HDassert(!(oh_flags & H5AC__DELETED_FLAG)); + HDassert(!deleted); } else /* The shared message is in another object header */ if(H5O_link(&oloc, adjust, dxpl_id) < 0) diff --git a/src/H5Otest.c b/src/H5Otest.c index 041194a..77b7540 100644 --- a/src/H5Otest.c +++ b/src/H5Otest.c @@ -98,7 +98,7 @@ H5O_is_attr_dense_test(hid_t oid) { H5O_t *oh = NULL; /* Object header */ H5O_ainfo_t ainfo; /* Attribute information for object */ - H5O_loc_t *loc; /* Pointer to object's location */ + H5O_loc_t *loc; /* Pointer to object's location */ htri_t ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5O_is_attr_dense_test, FAIL) @@ -108,7 +108,7 @@ H5O_is_attr_dense_test(hid_t oid) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found") /* Get the object header */ - if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, H5AC_ind_dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ))) + if(NULL == (oh = H5O_protect(loc, H5AC_ind_dxpl_id, H5AC_READ))) HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header") /* Check for attribute info stored */ @@ -130,7 +130,7 @@ H5O_is_attr_dense_test(hid_t oid) ret_value = FALSE; done: - if(oh && H5AC_unprotect(loc->file, H5AC_ind_dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) < 0) + if(oh && H5O_unprotect(loc, H5AC_ind_dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header") FUNC_LEAVE_NOAPI(ret_value) @@ -173,7 +173,7 @@ H5O_is_attr_empty_test(hid_t oid) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found") /* Get the object header */ - if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, H5AC_ind_dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ))) + if(NULL == (oh = H5O_protect(loc, H5AC_ind_dxpl_id, H5AC_READ))) HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header") /* Check for attribute info stored */ @@ -217,7 +217,7 @@ done: /* Release resources */ if(bt2_name && H5B2_close(bt2_name, H5AC_ind_dxpl_id) < 0) HDONE_ERROR(H5E_OHDR, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for name index") - if(oh && H5AC_unprotect(loc->file, H5AC_ind_dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) < 0) + if(oh && H5O_unprotect(loc, H5AC_ind_dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header") FUNC_LEAVE_NOAPI(ret_value) @@ -260,7 +260,7 @@ H5O_num_attrs_test(hid_t oid, hsize_t *nattrs) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found") /* Get the object header */ - if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, H5AC_ind_dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ))) + if(NULL == (oh = H5O_protect(loc, H5AC_ind_dxpl_id, H5AC_READ))) HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header") /* Check for attribute info stored */ @@ -301,7 +301,7 @@ done: /* Release resources */ if(bt2_name && H5B2_close(bt2_name, H5AC_ind_dxpl_id) < 0) HDONE_ERROR(H5E_OHDR, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for name index") - if(oh && H5AC_unprotect(loc->file, H5AC_ind_dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) < 0) + if(oh && H5O_unprotect(loc, H5AC_ind_dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header") FUNC_LEAVE_NOAPI(ret_value) @@ -346,7 +346,7 @@ H5O_attr_dense_info_test(hid_t oid, hsize_t *name_count, hsize_t *corder_count) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found") /* Get the object header */ - if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, H5AC_ind_dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ))) + if(NULL == (oh = H5O_protect(loc, H5AC_ind_dxpl_id, H5AC_READ))) HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header") /* Check for attribute info stored */ @@ -390,7 +390,7 @@ done: HDONE_ERROR(H5E_OHDR, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for name index") if(bt2_corder && H5B2_close(bt2_corder, H5AC_ind_dxpl_id) < 0) HDONE_ERROR(H5E_OHDR, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for creation order index") - if(oh && H5AC_unprotect(loc->file, H5AC_ind_dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) < 0) + if(oh && H5O_unprotect(loc, H5AC_ind_dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header") FUNC_LEAVE_NOAPI(ret_value) @@ -434,7 +434,7 @@ H5O_check_msg_marked_test(hid_t oid, hbool_t flag_val) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found") /* Get the object header */ - if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, H5AC_ind_dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ))) + if(NULL == (oh = H5O_protect(loc, H5AC_ind_dxpl_id, H5AC_READ))) HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header") /* Locate "unknown" message */ @@ -453,9 +453,68 @@ H5O_check_msg_marked_test(hid_t oid, hbool_t flag_val) HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "'unknown' message type not found") done: - if(oh && H5AC_unprotect(loc->file, H5AC_ind_dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) < 0) + if(oh && H5O_unprotect(loc, H5AC_ind_dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header") FUNC_LEAVE_NOAPI(ret_value) } /* H5O_check_msg_marked_test() */ + +/*-------------------------------------------------------------------------- + NAME + H5O_expunge_chunks_test + PURPOSE + Expunge all the chunks for an object header from the cache. + USAGE + herr_t H5O_expunge_chunks_test(f, dxpl_id, loc) + H5F_t *f; IN: Pointer to file that object is within + hid_t dxpl_id; IN: DXPL to use for operation + H5O_loc_t *loc; IN: Object location for object header to expunge + RETURNS + Non-negative on success, negative on failure + DESCRIPTION + Iterates over all the chunks for an object header an expunges each from the + metadata cache. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + DO NOT USE THIS FUNCTION FOR ANYTHING EXCEPT TESTING + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5O_expunge_chunks_test(const H5O_loc_t *loc, hid_t dxpl_id) +{ + H5O_t *oh = NULL; /* Object header */ + haddr_t chk_addr[16]; /* Array of chunk addresses */ + unsigned nchunks; /* Number of chunks in object header */ + unsigned u; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5O_expunge_chunks_test, FAIL) + + /* Get the object header */ + if(NULL == (oh = H5O_protect(loc, dxpl_id, H5AC_WRITE))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to protect object header") + + /* Safety check */ + nchunks = oh->nchunks; + HDassert(nchunks < NELMTS(chk_addr)); + + /* Iterate over all the chunks, saving the chunk addresses */ + for(u = 0; u < oh->nchunks; u++) + chk_addr[u] = oh->chunk[u].addr; + + /* Release the object header */ + if(H5O_unprotect(loc, dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to unprotect object header") + + /* Iterate over all the saved chunk addresses, evicting them from the cache */ + /* (in reverse order, so that chunk #0 is unpinned) */ + for(u = nchunks - 1; u < nchunks; u--) + if(H5AC_expunge_entry(loc->file, dxpl_id, (u == 0 ? H5AC_OHDR : H5AC_OHDR_CHK), chk_addr[u], H5AC__NO_FLAGS_SET) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTEXPUNGE, FAIL, "unable to expunge object header chunk") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5O_expunge_chunks_test() */ + @@ -309,7 +309,7 @@ herr_t H5Rcreate(void *ref, hid_t loc_id, const char *name, H5R_type_t ref_type, hid_t space_id) { H5G_loc_t loc; /* File location */ - H5S_t *space; /* Pointer to dataspace containing region */ + H5S_t *space = NULL; /* Pointer to dataspace containing region */ herr_t ret_value; /* Return value */ FUNC_ENTER_API(H5Rcreate, FAIL) @@ -326,6 +326,8 @@ H5Rcreate(void *ref, hid_t loc_id, const char *name, H5R_type_t ref_type, hid_t HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type") if(ref_type != H5R_OBJECT && ref_type != H5R_DATASET_REGION) HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "reference type not supported") + if(space_id == (-1) && ref_type == H5R_DATASET_REGION) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "reference region dataspace id must be valid") if(space_id != (-1) && (NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace") @@ -366,8 +368,9 @@ H5R_dereference(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type, const void *_re H5O_loc_t oloc; /* Object location */ H5G_name_t path; /* Path of object */ H5G_loc_t loc; /* Group location */ + unsigned rc; /* Reference count of object */ H5O_type_t obj_type; /* Type of object */ - hid_t ret_value; + hid_t ret_value; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5R_dereference) @@ -415,8 +418,9 @@ H5R_dereference(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type, const void *_re HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (unknown reference type)") } /* end switch */ - /* Check to make certain that this object hasn't been deleted since the reference was created */ - if(H5O_link(&oloc, 0, dxpl_id) <= 0) + /* Get the # of links for object, and its type */ + /* (To check to make certain that this object hasn't been deleted since the reference was created) */ + if(H5O_get_rc_and_type(&oloc, dxpl_id, &rc, &obj_type) < 0 || 0 == rc) HGOTO_ERROR(H5E_REFERENCE, H5E_LINKCOUNT, FAIL, "dereferencing deleted object") /* Construct a group location for opening the object */ @@ -424,10 +428,6 @@ H5R_dereference(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type, const void *_re loc.oloc = &oloc; loc.path = &path; - /* Get the type of the object */ - if(H5O_obj_type(&oloc, &obj_type, dxpl_id) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to get object type") - /* Open the object */ switch(obj_type) { case H5O_TYPE_GROUP: @@ -688,6 +688,7 @@ H5R_get_obj_type(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type, const void *_ref, H5O_type_t *obj_type) { H5O_loc_t oloc; /* Object location */ + unsigned rc; /* Reference count of object */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5R_get_obj_type) @@ -736,14 +737,11 @@ H5R_get_obj_type(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type, HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (unknown reference type)") } /* end switch */ - /* Check to make certain that this object hasn't been deleted since the reference was created */ - if(H5O_link(&oloc, 0, dxpl_id) <= 0) + /* Get the # of links for object, and its type */ + /* (To check to make certain that this object hasn't been deleted since the reference was created) */ + if(H5O_get_rc_and_type(&oloc, dxpl_id, &rc, obj_type) < 0 || 0 == rc) HGOTO_ERROR(H5E_REFERENCE, H5E_LINKCOUNT, FAIL, "dereferencing deleted object") - /* Get the object type */ - if(H5O_obj_type(&oloc, obj_type, dxpl_id) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to get object type") - done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5R_get_obj_type() */ @@ -25,7 +25,6 @@ /* Headers */ /***********/ #include "H5private.h" /* Generic Functions */ -#include "H5ACprivate.h" /* Metadata cache */ #include "H5Eprivate.h" /* Error handling */ #include "H5Fpkg.h" /* File access */ #include "H5FLprivate.h" /* Free Lists */ @@ -2247,7 +2246,7 @@ H5SM_read_mesg(H5F_t *f, const H5SM_sohm_t *mesg, H5HF_t *fheap, HGOTO_ERROR(H5E_SOHM, H5E_CANTLOAD, FAIL, "unable to open object header") /* Load the object header from the cache */ - if(NULL == (oh = (H5O_t *)H5AC_protect(oloc.file, dxpl_id, H5AC_OHDR, oloc.addr, NULL, NULL, H5AC_READ))) + if(NULL == (oh = H5O_protect(&oloc, dxpl_id, H5AC_READ))) HGOTO_ERROR(H5E_SOHM, H5E_CANTPROTECT, FAIL, "unable to load object header") } /* end if */ else @@ -2276,7 +2275,7 @@ H5SM_read_mesg(H5F_t *f, const H5SM_sohm_t *mesg, H5HF_t *fheap, done: /* Close the object header if we opened one and had an error */ if(oh && oh != open_oh) { - if(H5AC_unprotect(oloc.file, dxpl_id, H5AC_OHDR, oloc.addr, oh, H5AC__NO_FLAGS_SET) < 0) + if(oh && H5O_unprotect(&oloc, dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to release object header") if(H5O_close(&oloc) < 0) HDONE_ERROR(H5E_SOHM, H5E_CANTCLOSEOBJ, FAIL, "unable to close object header") diff --git a/src/H5Smpio.c b/src/H5Smpio.c index 72d61e6..f535122 100644 --- a/src/H5Smpio.c +++ b/src/H5Smpio.c @@ -482,9 +482,6 @@ done: FUNC_LEAVE_NOAPI(ret_value); } - - - /*------------------------------------------------------------------------- * Function: H5S_mpio_span_hyper_type @@ -511,7 +508,6 @@ H5S_mpio_span_hyper_type( const H5S_t *space, hsize_t *extra_offset, hbool_t *is_derived_type ) { - MPI_Datatype span_type; H5S_hyper_span_t *ospan; H5S_hyper_span_info_t *odown; @@ -588,9 +584,9 @@ H5S_obtain_datatype(const hsize_t size[], MPI_Datatype bas_type; MPI_Datatype temp_type; MPI_Datatype tempinner_type; - MPI_Datatype *inner_type; - int *blocklen; - MPI_Aint *disp; + MPI_Datatype *inner_type = NULL; + int *blocklen = NULL; + MPI_Aint *disp = NULL; MPI_Aint stride; H5S_hyper_span_info_t *down; H5S_hyper_span_t *tspan; @@ -612,7 +608,7 @@ H5S_obtain_datatype(const hsize_t size[], down = span->down; tspan = span; - /* obtain the number of span tree for this dimension */ + /* Obtain the number of span tree nodes for this dimension */ outercount = 0; while(tspan) { tspan = tspan->next; @@ -623,32 +619,27 @@ H5S_obtain_datatype(const hsize_t size[], /* MPI2 hasn't been widely acccepted, adding H5_HAVE_MPI2 for the future use */ #ifdef H5_HAVE_MPI2 - MPI_Type_extent(MPI_Aint, &sizeaint); MPI_Type_extent(MPI_Datatype, &sizedtype); blocklen = (int *)HDcalloc((size_t)outercount, sizeof(int)); disp = (MPI_Aint *)HDcalloc((size_t)outercount, sizeaint); inner_type = (MPI_Datatype *)HDcalloc((size_t)outercount, sizedtype); - #else - blocklen = (int *)HDcalloc((size_t)outercount, sizeof(int)); disp = (MPI_Aint *)HDcalloc((size_t)outercount, sizeof(MPI_Aint)); inner_type = (MPI_Datatype *)HDcalloc((size_t)outercount, sizeof(MPI_Datatype)); - #endif - tspan = span; outercount = 0; /* if this is the fastest changing dimension, it is the base case for derived datatype. */ - if(down == NULL){ + if(down == NULL) { HDassert(dimindex <= 1); - if(MPI_SUCCESS != (mpi_code = MPI_Type_contiguous((int)elmt_size, MPI_BYTE,&bas_type))) + if(MPI_SUCCESS != (mpi_code = MPI_Type_contiguous((int)elmt_size, MPI_BYTE, &bas_type))) HMPI_GOTO_ERROR(FAIL, "MPI_Type_contiguous failed", mpi_code); if(MPI_SUCCESS != (mpi_code = MPI_Type_commit(&bas_type))) @@ -664,42 +655,42 @@ H5S_obtain_datatype(const hsize_t size[], if(MPI_SUCCESS != (mpi_code = MPI_Type_hindexed(outercount, blocklen, disp, bas_type, span_type))) HMPI_GOTO_ERROR(FAIL, "MPI_Type_hindexed failed", mpi_code); } /* end if */ - else {/* dimindex is the rank of the dimension */ + else { /* dimindex is the rank of the dimension */ HDassert(dimindex > 1); - /* Calculate the total bytes of the lower dimension */ + /* Calculate the total bytes of the lower dimensions */ total_lowd = 1; /* one dimension down */ - total_lowd1 = 1; /* two dimensions down */ + total_lowd1 = 1; /* two dimensions down */ - for ( i = dimindex-1; i > 0; i--) - total_lowd = total_lowd * size[i]; + for(i = dimindex - 1; i > 0; i--) + total_lowd = total_lowd * size[i]; - for ( i = dimindex-1; i > 1; i--) - total_lowd1 = total_lowd1 * size[i]; + for(i = dimindex - 1; i > 1; i--) + total_lowd1 = total_lowd1 * size[i]; - while(tspan) { + while(tspan) { /* Displacement should be in byte and should have dimension information */ /* First using MPI Type vector to build derived data type for this span only */ /* Need to calculate the disp in byte for this dimension. */ /* Calculate the total bytes of the lower dimension */ - disp[outercount] = tspan->low*total_lowd*elmt_size; + disp[outercount] = tspan->low * total_lowd * elmt_size; blocklen[outercount] = 1; /* generating inner derived datatype by using MPI_Type_hvector */ - if(FAIL == H5S_obtain_datatype(size,tspan->down->head,&temp_type,elmt_size,dimindex-1)) + if(FAIL == H5S_obtain_datatype(size, tspan->down->head, &temp_type, elmt_size, dimindex - 1)) HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL,"couldn't obtain MPI derived data type") if(MPI_SUCCESS != (mpi_code = MPI_Type_commit(&temp_type))) HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code); /* building the inner vector datatype */ - stride = total_lowd*elmt_size; + stride = total_lowd * elmt_size; innercount = tspan->nelem; - if(MPI_SUCCESS != (mpi_code = MPI_Type_hvector(innercount,1,stride,temp_type,&tempinner_type))) + if(MPI_SUCCESS != (mpi_code = MPI_Type_hvector(innercount, 1, stride, temp_type, &tempinner_type))) HMPI_GOTO_ERROR(FAIL, "MPI_Type_hvector failed", mpi_code); if(MPI_SUCCESS != (mpi_code = MPI_Type_commit(&tempinner_type))) @@ -719,18 +710,23 @@ H5S_obtain_datatype(const hsize_t size[], } /* end else */ if(inner_type != NULL && down != NULL) { - for(i = 0; i < outercount; i++) - if(MPI_SUCCESS != (mpi_code = MPI_Type_free(&inner_type[i]))) - HMPI_GOTO_ERROR(FAIL, "MPI_Type_free failed", mpi_code); } /* end if */ - if(inner_type != NULL) +done: + if(inner_type != NULL) { + if(down != NULL) { + for(i = 0; i < outercount; i++) + if(MPI_SUCCESS != (mpi_code = MPI_Type_free(&inner_type[i]))) + HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code); + } /* end if */ + HDfree(inner_type); + } /* end if */ if(blocklen != NULL) HDfree(blocklen); if(disp != NULL) HDfree(disp); -done: + FUNC_LEAVE_NOAPI(ret_value) } /* end H5S_obtain_datatype() */ @@ -1863,12 +1863,6 @@ H5T_get_class(const H5T_t *dt, htri_t internal) assert(dt); - /* Lie to the user if they have a VL string and tell them it's in the string class */ - if(dt->shared->type==H5T_VLEN && dt->shared->u.vlen.type==H5T_VLEN_STRING) - ret_value=H5T_STRING; - else - ret_value=dt->shared->type; - /* Externally, a VL string is a string; internally, a VL string is a VL. */ if(internal) { ret_value=dt->shared->type; diff --git a/src/H5config.h.in b/src/H5config.h.in index bdc8ed4..90d1361 100644 --- a/src/H5config.h.in +++ b/src/H5config.h.in @@ -301,7 +301,7 @@ /* Define if `struct timezone' is defined */ #undef HAVE_STRUCT_TIMEZONE -/* Define to 1 if `struct tm' is a member of `tm_zone'. */ +/* Define to 1 if `tm_zone' is a member of `struct tm'. */ #undef HAVE_STRUCT_TM_TM_ZONE /* Define if `struct videoconfig' is defined */ diff --git a/src/H5public.h b/src/H5public.h index d23c922..687c665 100644 --- a/src/H5public.h +++ b/src/H5public.h @@ -71,10 +71,10 @@ extern "C" { /* Version numbers */ #define H5_VERS_MAJOR 1 /* For major interface/format changes */ #define H5_VERS_MINOR 9 /* For minor interface/format changes */ -#define H5_VERS_RELEASE 66 /* For tweaks, bug-fixes, or development */ +#define H5_VERS_RELEASE 67 /* For tweaks, bug-fixes, or development */ #define H5_VERS_SUBRELEASE "FA_a4" /* For pre-releases like snap0 */ /* Empty string for real releases. */ -#define H5_VERS_INFO "HDF5 library version: 1.9.66-FA_a4" /* Full version string */ +#define H5_VERS_INFO "HDF5 library version: 1.9.67-FA_a4" /* Full version string */ #define H5check() H5check_version(H5_VERS_MAJOR,H5_VERS_MINOR, \ H5_VERS_RELEASE) diff --git a/src/H5trace.c b/src/H5trace.c index 8c83505..84f8436 100644 --- a/src/H5trace.c +++ b/src/H5trace.c @@ -684,6 +684,7 @@ H5_trace (const double *returning, const char *func, const char *type, ...) case H5F_FILE_SPACE_VFD: fprintf(out, "H5F_FILE_SPACE_VFD"); break; + case H5F_FILE_SPACE_NTYPES: default: fprintf(out, "%ld", (long)fs_type); break; @@ -726,6 +727,7 @@ H5_trace (const double *returning, const char *func, const char *type, ...) case H5FD_MEM_OHDR: fprintf(out, "H5FD_MEM_OHDR"); break; + case H5FD_MEM_NTYPES: default: fprintf(out, "%ld", (long)mem_type); break; diff --git a/src/Makefile.am b/src/Makefile.am index 39b765e..e3f3cdc 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -76,7 +76,7 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \ H5MF.c H5MFaggr.c H5MFdbg.c H5MFsection.c \ H5MM.c H5MP.c H5MPtest.c \ H5O.c H5Oainfo.c H5Oalloc.c H5Oattr.c \ - H5Oattribute.c H5Obogus.c H5Obtreek.c H5Ocache.c \ + H5Oattribute.c H5Obogus.c H5Obtreek.c H5Ocache.c H5Ochunk.c \ H5Ocont.c H5Ocopy.c H5Odbg.c H5Odrvinfo.c H5Odtype.c H5Oefl.c \ H5Ofill.c H5Ofsinfo.c H5Oginfo.c \ H5Olayout.c \ diff --git a/src/Makefile.in b/src/Makefile.in index 1f42fc0..d55f175 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, @@ -127,26 +127,27 @@ am_libhdf5_la_OBJECTS = H5.lo H5checksum.lo H5dbg.lo H5system.lo \ H5Lexternal.lo H5lib_settings.lo H5MF.lo H5MFaggr.lo \ H5MFdbg.lo H5MFsection.lo H5MM.lo H5MP.lo H5MPtest.lo H5O.lo \ H5Oainfo.lo H5Oalloc.lo H5Oattr.lo H5Oattribute.lo H5Obogus.lo \ - H5Obtreek.lo H5Ocache.lo H5Ocont.lo H5Ocopy.lo H5Odbg.lo \ - H5Odrvinfo.lo H5Odtype.lo H5Oefl.lo H5Ofill.lo H5Ofsinfo.lo \ - H5Oginfo.lo H5Olayout.lo H5Olinfo.lo H5Olink.lo H5Omessage.lo \ - H5Omtime.lo H5Oname.lo H5Onull.lo H5Opline.lo H5Orefcount.lo \ - H5Osdspace.lo H5Oshared.lo H5Oshmesg.lo H5Ostab.lo \ - H5Ostorage.lo H5Otest.lo H5Ounknown.lo H5P.lo H5Pacpl.lo \ - H5Pdapl.lo H5Pdcpl.lo H5Pdeprec.lo H5Pdxpl.lo H5Pfapl.lo \ - H5Pfcpl.lo H5Pfmpl.lo H5Pgcpl.lo H5Pint.lo H5Plapl.lo \ - H5Plcpl.lo H5Pocpl.lo H5Pocpypl.lo H5Pstrcpl.lo H5Ptest.lo \ - H5R.lo H5Rdeprec.lo H5RC.lo H5RS.lo H5S.lo H5Sall.lo H5Sdbg.lo \ - H5Shyper.lo H5Smpio.lo H5Snone.lo H5Spoint.lo H5Sselect.lo \ - H5Stest.lo H5SL.lo H5SM.lo H5SMbtree2.lo H5SMcache.lo \ - H5SMmessage.lo H5SMtest.lo H5ST.lo H5T.lo H5Tarray.lo \ - H5Tbit.lo H5Tcommit.lo H5Tcompound.lo H5Tconv.lo H5Tcset.lo \ - H5Tdbg.lo H5Tdeprec.lo H5Tenum.lo H5Tfields.lo H5Tfixed.lo \ - H5Tfloat.lo H5Tinit.lo H5Tnative.lo H5Toffset.lo H5Toh.lo \ - H5Topaque.lo H5Torder.lo H5Tpad.lo H5Tprecis.lo H5Tstrpad.lo \ - H5Tvisit.lo H5Tvlen.lo H5TS.lo H5V.lo H5WB.lo H5Z.lo \ - H5Zdeflate.lo H5Zfletcher32.lo H5Znbit.lo H5Zshuffle.lo \ - H5Zszip.lo H5Zscaleoffset.lo H5Ztrans.lo + H5Obtreek.lo H5Ocache.lo H5Ochunk.lo H5Ocont.lo H5Ocopy.lo \ + H5Odbg.lo H5Odrvinfo.lo H5Odtype.lo H5Oefl.lo H5Ofill.lo \ + H5Ofsinfo.lo H5Oginfo.lo H5Olayout.lo H5Olinfo.lo H5Olink.lo \ + H5Omessage.lo H5Omtime.lo H5Oname.lo H5Onull.lo H5Opline.lo \ + H5Orefcount.lo H5Osdspace.lo H5Oshared.lo H5Oshmesg.lo \ + H5Ostab.lo H5Ostorage.lo H5Otest.lo H5Ounknown.lo H5P.lo \ + H5Pacpl.lo H5Pdapl.lo H5Pdcpl.lo H5Pdeprec.lo H5Pdxpl.lo \ + H5Pfapl.lo H5Pfcpl.lo H5Pfmpl.lo H5Pgcpl.lo H5Pint.lo \ + H5Plapl.lo H5Plcpl.lo H5Pocpl.lo H5Pocpypl.lo H5Pstrcpl.lo \ + H5Ptest.lo H5R.lo H5Rdeprec.lo H5RC.lo H5RS.lo H5S.lo \ + H5Sall.lo H5Sdbg.lo H5Shyper.lo H5Smpio.lo H5Snone.lo \ + H5Spoint.lo H5Sselect.lo H5Stest.lo H5SL.lo H5SM.lo \ + H5SMbtree2.lo H5SMcache.lo H5SMmessage.lo H5SMtest.lo H5ST.lo \ + H5T.lo H5Tarray.lo H5Tbit.lo H5Tcommit.lo H5Tcompound.lo \ + H5Tconv.lo H5Tcset.lo H5Tdbg.lo H5Tdeprec.lo H5Tenum.lo \ + H5Tfields.lo H5Tfixed.lo H5Tfloat.lo H5Tinit.lo H5Tnative.lo \ + H5Toffset.lo H5Toh.lo H5Topaque.lo H5Torder.lo H5Tpad.lo \ + H5Tprecis.lo H5Tstrpad.lo H5Tvisit.lo H5Tvlen.lo H5TS.lo \ + H5V.lo H5WB.lo H5Z.lo H5Zdeflate.lo H5Zfletcher32.lo \ + H5Znbit.lo H5Zshuffle.lo H5Zszip.lo H5Zscaleoffset.lo \ + H5Ztrans.lo libhdf5_la_OBJECTS = $(am_libhdf5_la_OBJECTS) libhdf5_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ @@ -444,7 +445,7 @@ CHECK_CLEANFILES = *.chkexe *.chklog *.clog # Add libtool shared library version numbers to the HDF5 library # See libtool versioning documentation online. LT_VERS_INTERFACE = 6 -LT_VERS_REVISION = 56 +LT_VERS_REVISION = 57 LT_VERS_AGE = 0 H5detect_CFLAGS = -g $(AM_CFLAGS) @@ -495,7 +496,7 @@ libhdf5_la_SOURCES = H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \ H5MF.c H5MFaggr.c H5MFdbg.c H5MFsection.c \ H5MM.c H5MP.c H5MPtest.c \ H5O.c H5Oainfo.c H5Oalloc.c H5Oattr.c \ - H5Oattribute.c H5Obogus.c H5Obtreek.c H5Ocache.c \ + H5Oattribute.c H5Obogus.c H5Obtreek.c H5Ocache.c H5Ochunk.c \ H5Ocont.c H5Ocopy.c H5Odbg.c H5Odrvinfo.c H5Odtype.c H5Oefl.c \ H5Ofill.c H5Ofsinfo.c H5Oginfo.c \ H5Olayout.c \ @@ -825,6 +826,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Obogus.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Obtreek.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Ocache.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Ochunk.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Ocont.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Ocopy.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Odbg.Plo@am__quote@ diff --git a/test/Makefile.in b/test/Makefile.in index ab9e3ee..55dc9a5 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, diff --git a/test/cache_common.h b/test/cache_common.h index 0e20b97..9a7ac9f 100644 --- a/test/cache_common.h +++ b/test/cache_common.h @@ -516,7 +516,7 @@ struct expected_entry_status /* global variable externs: */ -extern const char *FILENAME[]; +extern const char *FILENAME[3]; extern hbool_t write_permitted; extern hbool_t pass; /* set to false on error */ diff --git a/test/objcopy.c b/test/objcopy.c index b8579a8..2ab0059 100755 --- a/test/objcopy.c +++ b/test/objcopy.c @@ -7851,6 +7851,168 @@ error: /*------------------------------------------------------------------------- + * Function: test_copy_null_ref + * + * Purpose: Creates 2 datasets with references, one with object and + * the other with region references. Copies these datasets + * to a new file without expanding references, causing them + * to become NULL. Next, copies these references to a third + * file with expanding references, to verify that NULL + * references are handled correctly. + * + * Return: Success: 0 + * Failure: number of errors + * + * Programmer: Neil Fortner + * Wednesday, March 31, 2005 + * + *------------------------------------------------------------------------- + */ +static int +test_copy_null_ref(hid_t fcpl_src, hid_t fcpl_dst, hid_t fapl) +{ + hid_t fid1 = -1, fid2 = -1; /* File IDs */ + hid_t sid = -1; /* Dataspace ID */ + hid_t pid = -1; /* Object copy property list ID */ + hid_t did1 = -1, did2 = -1; /* Dataset IDs */ + hsize_t dim1d[1] = {2}; /* Dataset dimensions */ + hobj_ref_t obj_buf[2]; /* Buffer for object refs */ + hdset_reg_ref_t reg_buf[2]; /* Buffer for region refs */ + char zeros[MAX(sizeof(obj_buf),sizeof(reg_buf))]; /* Array of zeros, for memcmp */ + char src_filename[NAME_BUF_SIZE]; + char mid_filename[NAME_BUF_SIZE]; + char dst_filename[NAME_BUF_SIZE]; + + TESTING("H5Ocopy(): NULL references"); + + /* Initialize "zeros" array */ + HDmemset(zeros, 0, sizeof(zeros)); + + /* Initialize the filenames */ + h5_fixname(FILENAME[0], fapl, src_filename, sizeof src_filename); + h5_fixname(FILENAME[1], fapl, mid_filename, sizeof mid_filename); + h5_fixname(FILENAME[2], fapl, dst_filename, sizeof dst_filename); + + /* Reset file address checking info */ + addr_reset(); + + /* Create source file */ + if((fid1 = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, fapl)) < 0) + TEST_ERROR + + /* Create dataspace */ + if((sid = H5Screate_simple(1, dim1d, NULL)) < 0) TEST_ERROR + + /* Create object reference dataset at SRC file */ + if((did1 = H5Dcreate2(fid1, "obj_ref_dset", H5T_STD_REF_OBJ, sid, + H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + + /* Create region reference dataset at SRC file */ + if((did2 = H5Dcreate2(fid1, "reg_ref_dset", H5T_STD_REF_DSETREG, + sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + + /* Create references */ + if(H5Rcreate(&obj_buf[0], did1, ".", H5R_OBJECT, -1) < 0) TEST_ERROR + if(H5Rcreate(&obj_buf[1], did2, ".", H5R_OBJECT, -1) < 0) TEST_ERROR + if(H5Rcreate(®_buf[0], did1, ".", H5R_DATASET_REGION, sid) < 0) + TEST_ERROR + if(H5Rcreate(®_buf[1], did2, ".", H5R_DATASET_REGION, sid) < 0) + TEST_ERROR + + /* Write data into file */ + if(H5Dwrite(did1, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, obj_buf) + < 0) TEST_ERROR + if(H5Dwrite(did2, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, H5P_DEFAULT, + reg_buf) < 0) TEST_ERROR + + /* Close datasets */ + if(H5Dclose(did1) < 0) TEST_ERROR + if(H5Dclose(did2) < 0) TEST_ERROR + + /* Create middle file */ + if((fid2 = H5Fcreate(mid_filename, H5F_ACC_TRUNC, fcpl_src, fapl)) < 0) + TEST_ERROR + + /* Copy the source file to the middle file. Note the expand references + * flag is not set. */ + if(H5Ocopy(fid1, "/", fid2, "/A", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + + /* Close source file */ + if(H5Fclose(fid1) < 0) TEST_ERROR + + /* Open copied datasets */ + if((did1 = H5Dopen2(fid2, "/A/obj_ref_dset", H5P_DEFAULT)) < 0) TEST_ERROR + if((did2 = H5Dopen2(fid2, "/A/reg_ref_dset", H5P_DEFAULT)) < 0) TEST_ERROR + + /* Read copied datasets */ + if(H5Dread(did1, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, obj_buf) + < 0) TEST_ERROR + if(H5Dread(did2, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, H5P_DEFAULT, + reg_buf) < 0) TEST_ERROR + + /* Verify that the references contain only "0" bytes */ + if(HDmemcmp(obj_buf, zeros, sizeof(obj_buf))) TEST_ERROR + if(HDmemcmp(reg_buf, zeros, sizeof(reg_buf))) TEST_ERROR + + /* Close datasets */ + if(H5Dclose(did1) < 0) TEST_ERROR + if(H5Dclose(did2) < 0) TEST_ERROR + + /* Create destination file */ + if((fid1 = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, fapl)) < 0) + TEST_ERROR + + /* Create object copy property list */ + if((pid = H5Pcreate(H5P_OBJECT_COPY)) < 0) TEST_ERROR + + /* Set the "expand references" flag */ + if(H5Pset_copy_object(pid, H5O_COPY_EXPAND_REFERENCE_FLAG) < 0) TEST_ERROR + + /* Copy the middle file to the destination file. Note the expand references + * flag *is* set, even though the references are now NULL. */ + if(H5Ocopy(fid2, "/", fid1, "/AA", pid, H5P_DEFAULT) < 0) TEST_ERROR + + /* Close source file */ + if(H5Fclose(fid2) < 0) TEST_ERROR + + /* Open copied datasets */ + if((did1 = H5Dopen2(fid1, "/AA/A/obj_ref_dset", H5P_DEFAULT)) < 0) TEST_ERROR + if((did2 = H5Dopen2(fid1, "/AA/A/reg_ref_dset", H5P_DEFAULT)) < 0) TEST_ERROR + + /* Read copied datasets */ + if(H5Dread(did1, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, obj_buf) + < 0) TEST_ERROR + if(H5Dread(did2, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, H5P_DEFAULT, + reg_buf) < 0) TEST_ERROR + + /* Verify that the references contain only "0" bytes */ + if(HDmemcmp(obj_buf, zeros, sizeof(obj_buf))) TEST_ERROR + if(HDmemcmp(reg_buf, zeros, sizeof(reg_buf))) TEST_ERROR + + /* Close */ + if(H5Pclose(pid) < 0) TEST_ERROR + if(H5Dclose(did1) < 0) TEST_ERROR + if(H5Dclose(did2) < 0) TEST_ERROR + if(H5Fclose(fid1) < 0) TEST_ERROR + if(H5Sclose(sid) < 0) TEST_ERROR + + PASSED(); + return 0; + +error: + H5E_BEGIN_TRY { + H5Pclose(pid); + H5Dclose(did1); + H5Dclose(did2); + H5Fclose(fid1); + H5Fclose(fid2); + H5Sclose(sid); + } H5E_END_TRY; + return 1; +} /* end test_copy_null_ref */ + + +/*------------------------------------------------------------------------- * Function: test_copy_option * * Purpose: Create a group in SRC file and copy it to DST file @@ -8319,7 +8481,8 @@ main(void) nerrors += test_copy_same_file_named_datatype(fcpl_src, my_fapl); nerrors += test_copy_old_layout(fcpl_dst, my_fapl); - } + nerrors += test_copy_null_ref(fcpl_src, fcpl_dst, my_fapl); + } /* TODO: not implemented nerrors += test_copy_mount(my_fapl); diff --git a/test/ohdr.c b/test/ohdr.c index 5bccf6e..16f1957 100644 --- a/test/ohdr.c +++ b/test/ohdr.c @@ -104,7 +104,7 @@ test_cont(char *filename, hid_t fapl) if(H5AC_flush(f, H5P_DATASET_XFER_DEFAULT) < 0) FAIL_STACK_ERROR - if(H5AC_expunge_entry(f, H5P_DATASET_XFER_DEFAULT, H5AC_OHDR, oh_locA.addr, H5AC__NO_FLAGS_SET) < 0) + if(H5O_expunge_chunks_test(&oh_locA, H5P_DATASET_XFER_DEFAULT) < 0) FAIL_STACK_ERROR if(H5O_get_hdr_info(&oh_locA, H5P_DATASET_XFER_DEFAULT, &hdr_info) < 0) diff --git a/testpar/Makefile.in b/testpar/Makefile.in index 86218ea..bee63d0 100644 --- a/testpar/Makefile.in +++ b/testpar/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, diff --git a/tools/Makefile.in b/tools/Makefile.in index f403257..2dc3fd3 100644 --- a/tools/Makefile.in +++ b/tools/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, @@ -432,7 +432,7 @@ clean-libtool: # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): - @failcom='exit 1'; \ + @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ @@ -457,7 +457,7 @@ $(RECURSIVE_TARGETS): fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): - @failcom='exit 1'; \ + @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ diff --git a/tools/h5copy/Makefile.in b/tools/h5copy/Makefile.in index 113abba..48052b3 100644 --- a/tools/h5copy/Makefile.in +++ b/tools/h5copy/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, diff --git a/tools/h5diff/Makefile.in b/tools/h5diff/Makefile.in index e11ee1f..5d381ec 100644 --- a/tools/h5diff/Makefile.in +++ b/tools/h5diff/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, diff --git a/tools/h5dump/Makefile.in b/tools/h5dump/Makefile.in index 1791da5..0cb51f8 100644 --- a/tools/h5dump/Makefile.in +++ b/tools/h5dump/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, diff --git a/tools/h5import/Makefile.in b/tools/h5import/Makefile.in index 620d0c0..c59b2cb 100755 --- a/tools/h5import/Makefile.in +++ b/tools/h5import/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, diff --git a/tools/h5jam/Makefile.in b/tools/h5jam/Makefile.in index fe7fbd7..2c89e4f 100644 --- a/tools/h5jam/Makefile.in +++ b/tools/h5jam/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, diff --git a/tools/h5ls/Makefile.in b/tools/h5ls/Makefile.in index fdd09c6..54a9324 100644 --- a/tools/h5ls/Makefile.in +++ b/tools/h5ls/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, diff --git a/tools/h5repack/Makefile.in b/tools/h5repack/Makefile.in index aa7781e..7cb956e 100644 --- a/tools/h5repack/Makefile.in +++ b/tools/h5repack/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, diff --git a/tools/h5stat/Makefile.in b/tools/h5stat/Makefile.in index a9bedaa..040423e 100644 --- a/tools/h5stat/Makefile.in +++ b/tools/h5stat/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, diff --git a/tools/lib/Makefile.in b/tools/lib/Makefile.in index 09c8edf..d55d229 100644 --- a/tools/lib/Makefile.in +++ b/tools/lib/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, diff --git a/tools/lib/h5tools_utils.c b/tools/lib/h5tools_utils.c index 82e9ab9..c5bc761 100644 --- a/tools/lib/h5tools_utils.c +++ b/tools/lib/h5tools_utils.c @@ -315,7 +315,7 @@ print_version(const char *progname) { printf("%s: Version %u.%u.%u%s%s\n", progname, H5_VERS_MAJOR, H5_VERS_MINOR, H5_VERS_RELEASE, - H5_VERS_SUBRELEASE[0] ? "-" : "", H5_VERS_SUBRELEASE); + ((char *)H5_VERS_SUBRELEASE)[0] ? "-" : "", H5_VERS_SUBRELEASE); } diff --git a/tools/misc/Makefile.in b/tools/misc/Makefile.in index 0b8ccb6..1ad6097 100644 --- a/tools/misc/Makefile.in +++ b/tools/misc/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, diff --git a/vms/c++/test/check.com b/vms/c++/test/check.com index 18323ec..cd523c3 100644 --- a/vms/c++/test/check.com +++ b/vms/c++/test/check.com @@ -20,5 +20,4 @@ $ type sys$input Running C++ tests $! $ run testhdf5 -$ run dsets $ exit diff --git a/vms/src/h5pubconf.h b/vms/src/h5pubconf.h index 950ce17..462408d 100644 --- a/vms/src/h5pubconf.h +++ b/vms/src/h5pubconf.h @@ -489,13 +489,13 @@ #define H5_PACKAGE_NAME "HDF5" /* Define to the full name and version of this package. */ -#define H5_PACKAGE_STRING "HDF5 1.9.66-FA_a4" +#define H5_PACKAGE_STRING "HDF5 1.9.67-FA_a4" /* Define to the one symbol short name of this package. */ #define H5_PACKAGE_TARNAME "hdf5" /* Define to the version of this package. */ -#define H5_PACKAGE_VERSION "1.9.66-FA_a4" +#define H5_PACKAGE_VERSION "1.9.67-FA_a4" /* Width for printf() for type `long long' or `__int64', use `ll' */ #define H5_PRINTF_LL_WIDTH "ll" @@ -651,7 +651,7 @@ /* #undef H5_USING_MEMCHECKER */ /* Version number of package */ -#define H5_VERSION "1.9.66-FA_a4" +#define H5_VERSION "1.9.67-FA_a4" /* Define if vsnprintf() returns the correct value for formatted strings that don't fit into size allowed */ diff --git a/vms/tools/h5copy/check_h5copy.com b/vms/tools/h5copy/check_h5copy.com index e73dd56..df83c88 100644 --- a/vms/tools/h5copy/check_h5copy.com +++ b/vms/tools/h5copy/check_h5copy.com @@ -17,6 +17,12 @@ $ ! $ ! This command file tests h5copy utility. The command file has to $ ! run in the [hdf5-top.tools.h5copy.testfiles] directory. $ ! +$ type sys$input + +=================================== + Testing h5copy utiltity +=================================== + $ ! $ ! Define h5copy symbols $ ! diff --git a/vms/tools/h5ls/check_h5ls.com b/vms/tools/h5ls/check_h5ls.com index daa601d..e155afa 100644 --- a/vms/tools/h5ls/check_h5ls.com +++ b/vms/tools/h5ls/check_h5ls.com @@ -17,6 +17,13 @@ $ ! $ ! This command file tests h5ls utility. The command file has to $ ! run in the [hdf5-top.tools.testfiles] directory. $ ! +$ type sys$input + +=================================== + Testing h5ls utiltity +=================================== + +$ $ ! $ ! Define h5ls symbol $ ! diff --git a/windows/misc/typegen/h5libsettings/h5libsettings.vcproj b/windows/misc/typegen/h5libsettings/h5libsettings.vcproj index 6f19395..8a86079 100644 --- a/windows/misc/typegen/h5libsettings/h5libsettings.vcproj +++ b/windows/misc/typegen/h5libsettings/h5libsettings.vcproj @@ -104,8 +104,8 @@ />
<Tool
Name="VCPostBuildEventTool"
- Description="Generating H5lib_settings.h"
- CommandLine="if not exist "$(TargetDir)..\..\H5lib_settings.h" "$(TargetPath)" > "$(TargetDir)..\..\H5lib_settings.h""
+ Description="Generating H5lib_settings.c"
+ CommandLine="if not exist "$(TargetDir)..\..\H5lib_settings.c" "$(TargetPath)" > "$(TargetDir)..\..\H5lib_settings.c""
/>
</Configuration>
<Configuration
diff --git a/windows/proj/hdf5/hdf5.vcproj b/windows/proj/hdf5/hdf5.vcproj index 2bc2d64..350c2fe 100644 --- a/windows/proj/hdf5/hdf5.vcproj +++ b/windows/proj/hdf5/hdf5.vcproj @@ -930,6 +930,10 @@ >
</File>
<File
+ RelativePath="..\..\..\src\H5Ochunk.c"
+ >
+ </File>
+ <File
RelativePath="..\..\..\src\H5Ocont.c"
>
</File>
diff --git a/windows/proj/hdf5dll/hdf5dll.vcproj b/windows/proj/hdf5dll/hdf5dll.vcproj index c755e83..cfeacec 100644 --- a/windows/proj/hdf5dll/hdf5dll.vcproj +++ b/windows/proj/hdf5dll/hdf5dll.vcproj @@ -1017,6 +1017,10 @@ >
</File>
<File
+ RelativePath="..\..\..\src\H5Ochunk.c"
+ >
+ </File>
+ <File
RelativePath="..\..\..\src\H5Ocont.c"
>
</File>
diff --git a/windows/src/H5pubconf.h b/windows/src/H5pubconf.h index 8b3eb55..a55c5d5 100755 --- a/windows/src/H5pubconf.h +++ b/windows/src/H5pubconf.h @@ -479,13 +479,13 @@ #define H5_PACKAGE_NAME "HDF5" /* Define to the full name and version of this package. */ -#define H5_PACKAGE_STRING "HDF5 1.9.66-FA_a4" +#define H5_PACKAGE_STRING "HDF5 1.9.67-FA_a4" /* Define to the one symbol short name of this package. */ #define H5_PACKAGE_TARNAME "hdf5" /* Define to the version of this package. */ -#define H5_PACKAGE_VERSION "1.9.66-FA_a4" +#define H5_PACKAGE_VERSION "1.9.67-FA_a4" /* Width for printf() for type `long long' or `__int64', use `ll' */ #define H5_PRINTF_LL_WIDTH "I64" @@ -642,7 +642,7 @@ /* #undef H5_USING_MEMCHECKER */ /* Version number of package */ -#define H5_VERSION "1.9.66-FA_a4" +#define H5_VERSION "1.9.67-FA_a4" /* Define if vsnprintf() returns the correct value for formatted strings that don't fit into size allowed */ |