diff options
Diffstat (limited to 'src/H5Ffamily.c')
-rw-r--r-- | src/H5Ffamily.c | 678 |
1 files changed, 371 insertions, 307 deletions
diff --git a/src/H5Ffamily.c b/src/H5Ffamily.c index 025039c..dba22f1 100644 --- a/src/H5Ffamily.c +++ b/src/H5Ffamily.c @@ -1,25 +1,25 @@ /* * Copyright (C) 1997 Spizella Software - * All rights reserved. + * All rights reserved. * * Programmer: Robb Matzke <matzke@llnl.gov> - * Monday, November 10, 1997 - * - * Purpose: Implements a family of files that acts as a single hdf5 - * file. The purpose is to be able to split a huge file on a - * 64-bit platform, transfer all the <2GB members to a 32-bit - * platform, and then access the entire huge file on the 32-bit - * platform. - * - * All family members are logically the same size although their - * physical sizes may vary. The logical member size is - * determined by looking at the physical size of the first - * member and rounding that up to the next power of two. When - * creating a file family, the first member is created with a - * predefined physical size (actually, this happens when the - * file family is flushed, and can be quite time consuming on - * file systems that don't implement holes, like nfs). - * + * Monday, November 10, 1997 + * + * Purpose: Implements a family of files that acts as a single hdf5 + * file. The purpose is to be able to split a huge file on a + * 64-bit platform, transfer all the <2GB members to a 32-bit + * platform, and then access the entire huge file on the 32-bit + * platform. + * + * All family members are logically the same size although their + * physical sizes may vary. The logical member size is + * determined by looking at the physical size of the first + * member and rounding that up to the next power of two. When + * creating a file family, the first member is created with a + * predefined physical size (actually, this happens when the + * file family is flushed, and can be quite time consuming on + * file systems that don't implement holes, like nfs). + * */ #include <H5private.h> #include <H5Eprivate.h> @@ -27,7 +27,7 @@ #include <H5MMprivate.h> #define PABLO_MASK H5F_family -static hbool_t interface_initialize_g = FALSE; +static hbool_t interface_initialize_g = FALSE; #define INTERFACE_INIT NULL /* @@ -38,81 +38,104 @@ static hbool_t interface_initialize_g = FALSE; * Smaller values result in files of a more manageable size (from a human * perspective) but also limit the total logical size of the hdf5 file. */ -#define H5F_FAM_DFLT_NBITS 26u /*64MB */ - -#define H5F_FAM_MASK(N) (((uint64)1<<(N))-1) -#define H5F_FAM_OFFSET(ADDR,N) ((off_t)((ADDR)->offset & H5F_FAM_MASK(N))) -#define H5F_FAM_MEMBNO(ADDR,N) ((intn)((ADDR)->offset >> N)) - -static hbool_t H5F_fam_access(const char *name, int mode, H5F_search_t *key); -static H5F_low_t *H5F_fam_open(const char *name, uintn flags, H5F_search_t *); -static herr_t H5F_fam_close(H5F_low_t *lf); -static herr_t H5F_fam_read(H5F_low_t *lf, const haddr_t *addr, size_t size, - uint8 *buf); -static herr_t H5F_fam_write(H5F_low_t *lf, const haddr_t *addr, size_t size, +#define H5F_FAM_DFLT_NBITS 26u /*64MB */ + +#define H5F_FAM_MASK(N) (((uint64)1<<(N))-1) +#define H5F_FAM_OFFSET(ADDR,N) ((off_t)((ADDR)->offset & H5F_FAM_MASK(N))) +#define H5F_FAM_MEMBNO(ADDR,N) ((intn)((ADDR)->offset >> N)) + +static hbool_t H5F_fam_access(const char *name, + const H5F_access_t *access_parms, int mode, + H5F_search_t *key/*out*/); +static H5F_low_t *H5F_fam_open(const char *name, + const H5F_access_t *access_parms, uintn flags, + H5F_search_t *key/*out*/); +static herr_t H5F_fam_close(H5F_low_t *lf, const H5F_access_t *access_parms); +static herr_t H5F_fam_read(H5F_low_t *lf, const H5F_access_t *access_parms, + const haddr_t *addr, size_t size, uint8 *buf); +static herr_t H5F_fam_write(H5F_low_t *lf, const H5F_access_t *access_parms, + const haddr_t *addr, size_t size, const uint8 *buf); -static herr_t H5F_fam_flush(H5F_low_t *lf); - -const H5F_low_class_t H5F_LOW_FAM[1] = {{ - H5F_fam_access, /* access method */ - H5F_fam_open, /* open method */ - H5F_fam_close, /* close method */ - H5F_fam_read, /* read method */ - H5F_fam_write, /* write method */ - H5F_fam_flush, /* flush method */ - NULL, /* extend method */ +static herr_t H5F_fam_flush(H5F_low_t *lf, const H5F_access_t *access_parms); + +const H5F_low_class_t H5F_LOW_FAMILY_g[1] = {{ + H5F_fam_access, /* access method */ + H5F_fam_open, /* open method */ + H5F_fam_close, /* close method */ + H5F_fam_read, /* read method */ + H5F_fam_write, /* write method */ + H5F_fam_flush, /* flush method */ + NULL, /* extend method */ }}; /*------------------------------------------------------------------------- - * Function: H5F_fam_open + * Function: H5F_fam_open * - * Purpose: Opens a file family with the specified base name. The name - * should contain a printf-style "%d" field which will be - * expanded with a zero-origin family member number. + * Purpose: Opens a file family with the specified base name. The name + * should contain a printf-style "%d" field which will be + * expanded with a zero-origin family member number. * - * Bugs: We don't check for overflow on the name, so keep it under - * 4kb, please. Also, we don't actually check for the `%d' - * field because we assume that the caller already did. Who - * knows what happens when all the family member names are the - * same! + * Bugs: We don't check for overflow on the name, so keep it under + * 4kb, please. Also, we don't actually check for the `%d' + * field because we assume that the caller already did. Who + * knows what happens when all the family member names are the + * same! * - * Return: Success: Low-level file pointer + * Return: Success: Low-level file pointer * - * Failure: NULL + * Failure: NULL * - * Programmer: Robb Matzke - * Monday, November 10, 1997 + * Programmer: Robb Matzke + * Monday, November 10, 1997 * * Modifications: * *------------------------------------------------------------------------- */ -static H5F_low_t * -H5F_fam_open(const char *name, uintn flags, H5F_search_t *key /*out */ ) +static H5F_low_t * +H5F_fam_open(const char *name, const H5F_access_t *access_parms, + uintn flags, H5F_search_t *key/*out*/) { - H5F_low_t *ret_value = NULL, *lf = NULL; - H5F_low_t *member = NULL; /*a family member */ - char member_name[4096]; /*name of family member */ - intn membno; /*member number (zero-origin) */ - size_t nbits = H5F_FAM_DFLT_NBITS; /*num bits in an offset */ - haddr_t tmp_addr; /*temporary address */ + H5F_low_t *ret_value = NULL; + H5F_low_t *lf = NULL; + H5F_low_t *member = NULL; /*a family member */ + char member_name[4096]; /*name of family member */ + intn membno; /*member number (zero-origin) */ + size_t nbits = H5F_FAM_DFLT_NBITS; /*num bits in an offset */ + haddr_t tmp_addr; /*temporary address */ + const H5F_low_class_t *memb_type; /*type of family member */ FUNC_ENTER(H5F_fam_open, NULL); + assert (access_parms); + assert (H5F_LOW_FAMILY==access_parms->driver); + + /* + * Use the default file driver or the specified driver for each of the + * family members. + */ + if (access_parms->u.fam.memb_access) { + memb_type = H5F_low_class (access_parms->u.fam.memb_access->driver); + } else { + memb_type = H5F_low_class (H5F_LOW_DFLT); + } + /* * If we're truncating the file then delete all but the first family - * member. Use the default number of bits for the offset. + * member. Use the default number of bits for the offset. */ - if ((flags & H5F_ACC_WRITE) && (flags & H5F_ACC_TRUNC)) { - for (membno = 1; /*void */ ; membno++) { - sprintf(member_name, name, membno); - if (!H5F_low_access(H5F_LOW_DFLT, member_name, F_OK, NULL)) { - break; - } else if (unlink(member_name) < 0) { - HGOTO_ERROR(H5E_IO, H5E_CANTINIT, NULL, "can't delete member"); - } - } + if ((flags & H5F_ACC_RDWR) && (flags & H5F_ACC_TRUNC)) { + for (membno = 1; /*void*/; membno++) { + sprintf(member_name, name, membno); + if (!H5F_low_access(memb_type, member_name, + access_parms->u.fam.memb_access, + F_OK, NULL)) { + break; + } else if (unlink(member_name) < 0) { + HGOTO_ERROR(H5E_IO, H5E_CANTINIT, NULL, "can't delete member"); + } + } } /* Create the file descriptor */ lf = H5MM_xcalloc(1, sizeof(H5F_low_t)); @@ -120,33 +143,34 @@ H5F_fam_open(const char *name, uintn flags, H5F_search_t *key /*out */ ) lf->u.fam.flags = (flags & ~H5F_ACC_CREAT); /* Open all existing members */ - for (membno = 0; /*void */ ; membno++) { - sprintf(member_name, name, membno); - - /* - * Open the family member. After the first member is opened or created, - * turn off the creation flag so we don't create a zillion family - * members. - */ - member = H5F_low_open(H5F_LOW_DFLT, member_name, flags, - 0 == membno ? key : NULL); - if (!member) { - if (0 == membno) { - HGOTO_ERROR(H5E_IO, H5E_CANTOPENFILE, NULL, - "can't open first family member"); - } - break; - } - flags &= ~H5F_ACC_CREAT; - - /* Add the member to the family */ - if (lf->u.fam.nmemb >= lf->u.fam.nalloc) { - lf->u.fam.nalloc = MAX(100, 2 * lf->u.fam.nalloc); - lf->u.fam.memb = H5MM_xrealloc(lf->u.fam.memb, - lf->u.fam.nalloc * sizeof(H5F_low_t *)); - } - lf->u.fam.memb[lf->u.fam.nmemb++] = member; - member = NULL; + for (membno = 0; /*void*/; membno++) { + sprintf(member_name, name, membno); + + /* + * Open the family member. After the first member is opened or + * created, turn off the creation flag so we don't create a zillion + * family members. + */ + member = H5F_low_open(memb_type, member_name, + access_parms->u.fam.memb_access, flags, + 0 == membno ? key : NULL); + if (!member) { + if (0 == membno) { + HGOTO_ERROR(H5E_IO, H5E_CANTOPENFILE, NULL, + "can't open first family member"); + } + break; + } + flags &= ~H5F_ACC_CREAT; + + /* Add the member to the family */ + if (lf->u.fam.nmemb >= lf->u.fam.nalloc) { + lf->u.fam.nalloc = MAX(100, 2 * lf->u.fam.nalloc); + lf->u.fam.memb = H5MM_xrealloc(lf->u.fam.memb, + lf->u.fam.nalloc * sizeof(H5F_low_t *)); + } + lf->u.fam.memb[lf->u.fam.nmemb++] = member; + member = NULL; } /* @@ -155,32 +179,36 @@ H5F_fam_open(const char *name, uintn flags, H5F_search_t *key /*out */ ) * member. */ if (lf->u.fam.nmemb >= 2) { - size_t size = H5F_low_size(lf->u.fam.memb[0], &tmp_addr); - for (nbits = 8 * sizeof(size_t) - 1; nbits > 0; --nbits) { - size_t mask = (size_t) 1 << nbits; - if (size & mask) { - if (size != mask) { - size++; + size_t size = H5F_low_size(lf->u.fam.memb[0], &tmp_addr); + for (nbits=8*sizeof(size_t)-1; nbits>0; --nbits) { + size_t mask = (size_t)1 << nbits; + if (size & mask) { + if (size != mask) { + size++; #ifdef H5F_DEBUG - fprintf(stderr, "HDF5-DIAG: family member size was rounded up " - "to a power of 2"); + fprintf(stderr, "HDF5-DIAG: family member size was rounded up " + "to a power of 2"); #endif - } - break; - } - } + } + break; + } + } } lf->u.fam.offset_bits = nbits; #ifdef H5F_DEBUG if (nbits >= 30) { - fprintf(stderr, "HDF5-DIAG: family members are %dGB\n", 1 << (nbits - 30)); + fprintf(stderr, "HDF5-DIAG: family members are %dGB\n", + 1 << (nbits-30)); } else if (nbits >= 20) { - fprintf(stderr, "HDF5-DIAG: family members are %dMB\n", 1 << (nbits - 20)); + fprintf(stderr, "HDF5-DIAG: family members are %dMB\n", + 1 << (nbits-20)); } else if (nbits >= 10) { - fprintf(stderr, "HDF5-DIAG: family members are %dkB\n", 1 << (nbits - 10)); + fprintf(stderr, "HDF5-DIAG: family members are %dkB\n", + 1 << (nbits-10)); } else { - fprintf(stderr, "HDF5-DIAG: family members are %d bytes\n", 1 << nbits); + fprintf(stderr, "HDF5-DIAG: family members are %d bytes\n", + 1 << nbits); } #endif @@ -188,50 +216,51 @@ H5F_fam_open(const char *name, uintn flags, H5F_search_t *key /*out */ ) * Get the total family size and store it in the max_addr field. */ assert(lf->u.fam.nmemb >= 1); - lf->eof.offset = (size_t) 1 << lf->u.fam.offset_bits; - lf->eof.offset *= (lf->u.fam.nmemb - 1); - lf->eof.offset += lf->u.fam.memb[lf->u.fam.nmemb - 1]->eof.offset; + lf->eof.offset = (size_t)1 << lf->u.fam.offset_bits; + lf->eof.offset *= (lf->u.fam.nmemb-1); + lf->eof.offset += lf->u.fam.memb[lf->u.fam.nmemb-1]->eof.offset; HRETURN(lf); done: if (!ret_value) { - if (lf) { - H5F_fam_close(lf); - H5MM_xfree(lf); - } + if (lf) { + H5F_fam_close(lf, access_parms); + H5MM_xfree(lf); + } } FUNC_LEAVE(ret_value); } /*------------------------------------------------------------------------- - * Function: H5F_fam_close + * Function: H5F_fam_close * - * Purpose: Closes all members of a file family and releases resources - * used by the file descriptor. + * Purpose: Closes all members of a file family and releases resources + * used by the file descriptor. * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * Monday, November 10, 1997 + * Programmer: Robb Matzke + * Monday, November 10, 1997 * * Modifications: * *------------------------------------------------------------------------- */ static herr_t -H5F_fam_close(H5F_low_t *lf) +H5F_fam_close(H5F_low_t *lf, const H5F_access_t *access_parms) { - intn membno; + intn membno; FUNC_ENTER(H5F_fam_close, FAIL); assert(lf); for (membno = 0; membno < lf->u.fam.nmemb; membno++) { - lf->u.fam.memb[membno] = H5F_low_close(lf->u.fam.memb[membno]); + lf->u.fam.memb[membno] = H5F_low_close(lf->u.fam.memb[membno], + access_parms->u.fam.memb_access); } H5MM_xfree(lf->u.fam.memb); H5MM_xfree(lf->u.fam.name); @@ -240,36 +269,37 @@ H5F_fam_close(H5F_low_t *lf) } /*------------------------------------------------------------------------- - * Function: H5F_fam_read + * Function: H5F_fam_read * - * Purpose: Reads a chunk of contiguous data from the file family. - * Reading past the physical end of a file returns zeros instead - * of failing. We must insure that if the logical end of file is - * before the physical end of file that we will read zeros there - * also (the only time this can happen is if we create a family - * and then close it before the first member is filled, since - * flushing the file causes the first member to be physically - * extended to it's maximum size). + * Purpose: Reads a chunk of contiguous data from the file family. + * Reading past the physical end of a file returns zeros instead + * of failing. We must insure that if the logical end of file is + * before the physical end of file that we will read zeros there + * also (the only time this can happen is if we create a family + * and then close it before the first member is filled, since + * flushing the file causes the first member to be physically + * extended to it's maximum size). * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * Monday, November 10, 1997 + * Programmer: Robb Matzke + * Monday, November 10, 1997 * * Modifications: * *------------------------------------------------------------------------- */ static herr_t -H5F_fam_read(H5F_low_t *lf, const haddr_t *addr, size_t size, uint8 *buf) +H5F_fam_read(H5F_low_t *lf, const H5F_access_t *access_parms, + const haddr_t *addr, size_t size, uint8 *buf) { - size_t nbytes; - haddr_t cur_addr; - uintn membno; - off_t offset; - size_t member_size; + size_t nbytes; + haddr_t cur_addr; + uintn membno; + off_t offset; + size_t member_size; FUNC_ENTER(H5F_fam_read, FAIL); @@ -283,154 +313,168 @@ H5F_fam_read(H5F_low_t *lf, const haddr_t *addr, size_t size, uint8 *buf) cur_addr = *addr; while (size > 0) { - if (membno >= lf->u.fam.nmemb) { - HDmemset(buf, 0, size); - break; - } else { - nbytes = MIN(size, member_size - offset); - cur_addr.offset = offset; - if (H5F_low_read(lf->u.fam.memb[membno], &cur_addr, - nbytes, buf) < 0) { - HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, - "can't read from family member"); - } - buf += nbytes; - size -= nbytes; - membno++; - offset = 0; - } + if (membno >= lf->u.fam.nmemb) { + HDmemset(buf, 0, size); + break; + } else { + nbytes = MIN(size, member_size - offset); + cur_addr.offset = offset; + if (H5F_low_read(lf->u.fam.memb[membno], + access_parms->u.fam.memb_access, + &cur_addr, nbytes, buf) < 0) { + HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, + "can't read from family member"); + } + buf += nbytes; + size -= nbytes; + membno++; + offset = 0; + } } FUNC_LEAVE(SUCCEED); } /*------------------------------------------------------------------------- - * Function: H5F_fam_write + * Function: H5F_fam_write * - * Purpose: Writes BUF to the family of files. The superclass has - * already insured that we aren't writing past the logical end - * of file, so this function will extend the physical file to - * accommodate the new data if necessary. + * Purpose: Writes BUF to the family of files. The superclass has + * already insured that we aren't writing past the logical end + * of file, so this function will extend the physical file to + * accommodate the new data if necessary. * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * Monday, November 10, 1997 + * Programmer: Robb Matzke + * Monday, November 10, 1997 * * Modifications: * *------------------------------------------------------------------------- */ static herr_t -H5F_fam_write(H5F_low_t *lf, const haddr_t *addr, size_t size, - const uint8 *buf) +H5F_fam_write(H5F_low_t *lf, const H5F_access_t *access_parms, + const haddr_t *addr, size_t size, const uint8 *buf) { - size_t nbytes; - haddr_t cur_addr, max_addr; - uintn membno; - off_t offset; - H5F_low_t *member = NULL; - char member_name[4096]; - intn i; - size_t member_size; - + size_t nbytes; + haddr_t cur_addr, max_addr; + uintn membno; + off_t offset; + H5F_low_t *member = NULL; + char member_name[4096]; + intn i; + size_t member_size; + const H5F_low_class_t *memb_type = NULL; + FUNC_ENTER(H5F_fam_write, FAIL); + /* Check args */ assert(lf); assert(addr && H5F_addr_defined(addr)); assert(buf); + assert (access_parms); + assert (H5F_LOW_FAMILY==access_parms->driver); + /* Get the member driver */ + if (access_parms->u.fam.memb_access) { + memb_type = H5F_low_class (access_parms->u.fam.memb_access->driver); + } else { + memb_type = H5F_low_class (H5F_LOW_DFLT); + } + member_size = (size_t) 1 << lf->u.fam.offset_bits; membno = H5F_FAM_MEMBNO(addr, lf->u.fam.offset_bits); offset = H5F_FAM_OFFSET(addr, lf->u.fam.offset_bits); cur_addr = *addr; while (size > 0) { - nbytes = MIN(size, member_size - offset); - cur_addr.offset = offset; - - if (membno >= lf->u.fam.nmemb) { - /* - * We're writing past the end of the last family member--create the - * new family member(s) - */ - for (i = lf->u.fam.nmemb; i <= membno; i++) { - sprintf(member_name, lf->u.fam.name, i); - member = H5F_low_open(H5F_LOW_DFLT, member_name, - lf->u.fam.flags | H5F_ACC_CREAT, - NULL); - if (!member) { - HRETURN_ERROR(H5E_IO, H5E_CANTOPENFILE, FAIL, - "can't create a new member"); - } - /* - * For members in the middle, set their logical eof to the - * maximum possible value. - */ - if (i < membno) { - H5F_addr_reset(&max_addr); - H5F_addr_inc(&max_addr, member_size); - H5F_low_seteof(member, &max_addr); - } - if (lf->u.fam.nmemb >= lf->u.fam.nalloc) { - lf->u.fam.nalloc *= 2; - lf->u.fam.memb = H5MM_xrealloc(lf->u.fam.memb, - (lf->u.fam.nalloc * - sizeof(H5F_low_t *))); - } - lf->u.fam.memb[lf->u.fam.nmemb++] = member; - } - } - /* - * Make sure the logical eof is large enough to handle the request. - */ - max_addr = cur_addr; - H5F_addr_inc(&max_addr, nbytes); - H5F_low_seteof(lf->u.fam.memb[membno], &max_addr); - - /* Write the data to the member */ - if (H5F_low_write(lf->u.fam.memb[membno], &cur_addr, - nbytes, buf) < 0) { - HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, - "can't write to family member"); - } - buf += nbytes; - size -= nbytes; - membno++; - offset = 0; + nbytes = MIN(size, member_size - offset); + cur_addr.offset = offset; + + if (membno >= lf->u.fam.nmemb) { + /* + * We're writing past the end of the last family member--create the + * new family member(s) + */ + for (i = lf->u.fam.nmemb; i <= membno; i++) { + sprintf(member_name, lf->u.fam.name, i); + member = H5F_low_open(memb_type, member_name, + access_parms->u.fam.memb_access, + lf->u.fam.flags | H5F_ACC_CREAT, + NULL); + if (!member) { + HRETURN_ERROR(H5E_IO, H5E_CANTOPENFILE, FAIL, + "can't create a new member"); + } + /* + * For members in the middle, set their logical eof to the + * maximum possible value. + */ + if (i < membno) { + H5F_addr_reset(&max_addr); + H5F_addr_inc(&max_addr, member_size); + H5F_low_seteof(member, &max_addr); + } + if (lf->u.fam.nmemb >= lf->u.fam.nalloc) { + lf->u.fam.nalloc *= 2; + lf->u.fam.memb = H5MM_xrealloc(lf->u.fam.memb, + (lf->u.fam.nalloc * + sizeof(H5F_low_t *))); + } + lf->u.fam.memb[lf->u.fam.nmemb++] = member; + } + } + /* + * Make sure the logical eof is large enough to handle the request. + */ + max_addr = cur_addr; + H5F_addr_inc(&max_addr, nbytes); + H5F_low_seteof(lf->u.fam.memb[membno], &max_addr); + + /* Write the data to the member */ + if (H5F_low_write(lf->u.fam.memb[membno], + access_parms->u.fam.memb_access, + &cur_addr, nbytes, buf) < 0) { + HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, + "can't write to family member"); + } + buf += nbytes; + size -= nbytes; + membno++; + offset = 0; } FUNC_LEAVE(SUCCEED); } /*------------------------------------------------------------------------- - * Function: H5F_fam_flush + * Function: H5F_fam_flush * - * Purpose: Flushes all data to disk and makes sure that the first member - * is as large as a member can be so we can accurately detect - * the member size if we open this file for read access at a - * later date. + * Purpose: Flushes all data to disk and makes sure that the first member + * is as large as a member can be so we can accurately detect + * the member size if we open this file for read access at a + * later date. * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * Monday, November 10, 1997 + * Programmer: Robb Matzke + * Monday, November 10, 1997 * * Modifications: * *------------------------------------------------------------------------- */ static herr_t -H5F_fam_flush(H5F_low_t *lf) +H5F_fam_flush(H5F_low_t *lf, const H5F_access_t *access_parms) { - int membno, nerrors = 0; - uint8 buf[1]; - haddr_t addr1, addr2, addr3; - size_t max_offset; + int membno, nerrors = 0; + uint8 buf[1]; + haddr_t addr1, addr2, addr3; + size_t max_offset; FUNC_ENTER(H5F_fam_flush, FAIL); @@ -444,98 +488,118 @@ H5F_fam_flush(H5F_low_t *lf) max_offset = H5F_FAM_MASK(lf->u.fam.offset_bits); H5F_addr_reset(&addr1); H5F_addr_inc(&addr1, max_offset); - H5F_low_size(lf->u.fam.memb[0], &addr2); /*remember logical eof */ + H5F_low_size(lf->u.fam.memb[0], &addr2); /*remember logical eof */ addr3 = addr1; H5F_addr_inc(&addr3, (size_t) 1); - H5F_low_seteof(lf->u.fam.memb[0], &addr3); /*prevent a warning */ - if (H5F_low_read(lf->u.fam.memb[0], &addr1, 1, buf) < 0) { - HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, - "can't read from first family member"); + H5F_low_seteof(lf->u.fam.memb[0], &addr3); /*prevent a warning */ + if (H5F_low_read(lf->u.fam.memb[0], access_parms->u.fam.memb_access, + &addr1, 1, buf) < 0) { + HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, + "can't read from first family member"); } - if (H5F_low_write(lf->u.fam.memb[0], &addr1, 1, buf) < 0) { - HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, - "can't write to first family member"); + if (H5F_low_write(lf->u.fam.memb[0], access_parms->u.fam.memb_access, + &addr1, 1, buf) < 0) { + HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, + "can't write to first family member"); } - H5F_low_seteof(lf->u.fam.memb[0], &addr2); /*reset old eof */ + H5F_low_seteof(lf->u.fam.memb[0], &addr2); /*reset old eof */ /* - * Flush each member file. Don't return an error status until we've + * Flush each member file. Don't return an error status until we've * flushed as much as possible. */ for (membno = 0; membno < lf->u.fam.nmemb; membno++) { - if (H5F_low_flush(lf->u.fam.memb[membno]) < 0) { - nerrors++; - } + if (H5F_low_flush(lf->u.fam.memb[membno], + access_parms->u.fam.memb_access) < 0) { + nerrors++; + } } if (nerrors) { - HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, - "can't flush family member"); + HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, + "can't flush family member"); } FUNC_LEAVE(SUCCEED); } /*------------------------------------------------------------------------- - * Function: H5F_fam_access + * Function: H5F_fam_access * - * Purpose: Determines if all members of the file family can be accessed - * and returns the key for the first member of the family. + * Purpose: Determines if all members of the file family can be accessed + * and returns the key for the first member of the family. * - * Return: Success: TRUE or FALSE + * Return: Success: TRUE or FALSE * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * Monday, November 10, 1997 + * Programmer: Robb Matzke + * Monday, November 10, 1997 * * Modifications: * *------------------------------------------------------------------------- */ static hbool_t -H5F_fam_access(const char *name, int mode, H5F_search_t *key /*out */ ) +H5F_fam_access(const char *name, const H5F_access_t *access_parms, + int mode, H5F_search_t *key/*out*/) { - intn membno; - char member_name[4096]; - hbool_t status; - hbool_t ret_value = FALSE; + intn membno; + char member_name[4096]; + hbool_t status; + hbool_t ret_value = FALSE; + const H5F_low_class_t *memb_type = NULL; FUNC_ENTER(H5F_fam_access, FAIL); + /* Check args */ + assert (name && *name); + assert (access_parms); + assert (H5F_LOW_FAMILY==access_parms->driver); + + /* Get the driver for the family members */ + if (access_parms->u.fam.memb_access) { + memb_type = H5F_low_class (access_parms->u.fam.memb_access->driver); + } else { + memb_type = H5F_low_class (H5F_LOW_DFLT); + } + + /* Access the members */ for (membno=0; /*void*/; membno++) { - sprintf(member_name, name, membno); - status = H5F_low_access(H5F_LOW_DFLT, member_name, mode, - 0 == membno ? key : NULL); - - if (!status) { - if (F_OK == mode) { - /* - * If we didn't find a member then we must have gotten to the end - * of the family. As long as we found the first member(s) the - * family exists. - */ - ret_value = membno > 0 ? TRUE : FALSE; + sprintf(member_name, name, membno); + status = H5F_low_access(memb_type, member_name, NULL, mode, + 0 == membno ? key : NULL); + + if (!status) { + if (F_OK == mode) { + /* + * If we didn't find a member then we must have gotten to the + * end of the family. As long as we found the first + * member(s) the family exists. + */ + ret_value = membno > 0 ? TRUE : FALSE; break; - } else if (H5F_low_access(H5F_LOW_DFLT, member_name, F_OK, NULL)) { - /* - * The file exists but didn't have the write access permissions. - */ + } else if (H5F_low_access(memb_type, member_name, + access_parms->u.fam.memb_access, + F_OK, NULL)) { + /* + * The file exists but didn't have the write access permissions. + */ ret_value = FALSE; break; - } else { - /* - * The file doesn't exist because we got to the end of the - * family. - */ + } else { + /* + * The file doesn't exist because we got to the end of the + * family. + */ ret_value = TRUE; break; - } - } - if (status < 0) { - HRETURN_ERROR(H5E_IO, H5E_CANTOPENFILE, FAIL, - "access method failed for a member file"); - } + } + } + if (status < 0) { + HRETURN_ERROR(H5E_IO, H5E_CANTOPENFILE, FAIL, + "access method failed for a member file"); + } } FUNC_LEAVE(ret_value); |