summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/H5FD.c157
1 files changed, 100 insertions, 57 deletions
diff --git a/src/H5FD.c b/src/H5FD.c
index 5ec101e..30cbbee 100644
--- a/src/H5FD.c
+++ b/src/H5FD.c
@@ -2082,7 +2082,7 @@ H5FDread(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t size
/* Do the real work */
if (H5FD_read(file, type, dxpl_id, addr, size, buf)<0)
- HRETURN_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "file read request failed");
+ HRETURN_ERROR(H5E_VFL, H5E_READERROR, FAIL, "file read request failed");
FUNC_LEAVE(SUCCEED);
}
@@ -2127,76 +2127,111 @@ H5FD_read(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t siz
#endif
/* Check if this information is in the metadata accumulator */
- if((file->feature_flags&H5FD_FEAT_ACCUMULATE_METADATA) &&
- H5F_addr_overlap(addr,size,file->accum_loc,file->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 */
+ if((file->feature_flags&H5FD_FEAT_ACCUMULATE_METADATA) && type!=H5FD_MEM_DRAW) {
+ /* Current read overlaps with metadata accumulator */
+ if(H5F_addr_overlap(addr,size,file->accum_loc,file->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 */
#ifndef NDEBUG
- hsize_t tempamount_read; /* Amount to read at a time */
+ hsize_t tempamount_read; /* Amount to read at a time */
#endif /* NDEBUG */
- hsize_t read_off; /* Offset to read from */
+ hsize_t read_off; /* Offset to read from */
- /* Double check that we aren't reading raw data */
- assert(type!=H5FD_MEM_DRAW);
+ /* Double check that we aren't reading raw data */
+ assert(type!=H5FD_MEM_DRAW);
- /* Read the part before the metadata accumulator */
- if(addr<file->accum_loc) {
- /* Set the amount to read */
- H5_ASSIGN_OVERFLOW(amount_read,file->accum_loc-addr,hsize_t,size_t);
+ /* Read the part before the metadata accumulator */
+ if(addr<file->accum_loc) {
+ /* Set the amount to read */
+ H5_ASSIGN_OVERFLOW(amount_read,file->accum_loc-addr,hsize_t,size_t);
- /* Dispatch to driver */
- if ((file->cls->read)(file, type, dxpl_id, addr, amount_read, read_buf)<0)
- HRETURN_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver read request failed");
+ /* Dispatch to driver */
+ if ((file->cls->read)(file, type, dxpl_id, addr, amount_read, read_buf)<0)
+ HRETURN_ERROR(H5E_VFL, H5E_READERROR, FAIL, "driver read request failed");
- /* Adjust the buffer, address & size */
- read_buf+=amount_read;
- addr+=amount_read;
- size-=amount_read;
- } /* end if */
+ /* Adjust the buffer, address & size */
+ read_buf+=amount_read;
+ addr+=amount_read;
+ size-=amount_read;
+ } /* end if */
- /* Copy the part overlapping the metadata accumulator */
- if(size>0 && (addr>=file->accum_loc && addr<(file->accum_loc+file->accum_size))) {
- /* Set the offset to "read" from */
- read_off=addr-file->accum_loc;
+ /* Copy the part overlapping the metadata accumulator */
+ if(size>0 && (addr>=file->accum_loc && addr<(file->accum_loc+file->accum_size))) {
+ /* Set the offset to "read" from */
+ read_off=addr-file->accum_loc;
- /* Set the amount to "read" */
+ /* Set the amount to "read" */
#ifndef NDEBUG
- tempamount_read = file->accum_size-read_off;
- H5_CHECK_OVERFLOW(tempamount_read,hsize_t,size_t);
- amount_read = MIN(size, (size_t)tempamount_read);
+ tempamount_read = file->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)(file->accum_size-read_off));
+ amount_read = MIN(size, (size_t)(file->accum_size-read_off));
#endif /* NDEBUG */
- /* Copy the data out of the buffer */
- HDmemcpy(read_buf,file->meta_accum+read_off,amount_read);
+ /* Copy the data out of the buffer */
+ HDmemcpy(read_buf,file->meta_accum+read_off,amount_read);
- /* Adjust the buffer, address & size */
- read_buf+=amount_read;
- addr+=amount_read;
- size-=amount_read;
- } /* end if */
+ /* Adjust the buffer, address & size */
+ read_buf+=amount_read;
+ addr+=amount_read;
+ size-=amount_read;
+ } /* end if */
+
+ /* Read the part after the metadata accumulator */
+ if(size>0 && addr>=(file->accum_loc+file->accum_size)) {
+ /* Dispatch to driver */
+ if ((file->cls->read)(file, type, dxpl_id, addr, size, read_buf)<0)
+ HRETURN_ERROR(H5E_VFL, H5E_READERROR, FAIL, "driver read request failed");
- /* Read the part after the metadata accumulator */
- if(size>0 && addr>=(file->accum_loc+file->accum_size)) {
- /* Dispatch to driver */
- if ((file->cls->read)(file, type, dxpl_id, addr, size, read_buf)<0)
- HRETURN_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver read request failed");
+ /* Adjust the buffer, address & size */
+ read_buf+=size;
+ addr+=size;
+ size-=size;
+ } /* end if */
- /* Adjust the buffer, address & size */
- read_buf+=size;
- addr+=size;
- size-=size;
+ /* Make certain we've read it all */
+ assert(size==0);
} /* end if */
+ /* Current read doesn't overlap with metadata accumulator, read it into accumulator */
+ else {
+ /* Flush current contents, if dirty */
+ if(file->accum_dirty) {
+ if ((file->cls->write)(file, H5FD_MEM_DEFAULT, dxpl_id, file->accum_loc, file->accum_size, file->meta_accum)<0)
+ HRETURN_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "driver write request failed");
+
+ /* Reset accumulator dirty flag */
+ file->accum_dirty=FALSE;
+ } /* end if */
+
+ /* Cache the new piece of metadata */
+ /* Check if we need to reallocate the buffer */
+ if(size>file->accum_buf_size) {
+ /* Reallocate the metadata accumulator buffer */
+ if ((file->meta_accum=H5FL_BLK_REALLOC(meta_accum,file->meta_accum,size))==NULL)
+ HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer");
- /* Make certain we've read it all */
- assert(size==0);
+ /* Note the new buffer size */
+ file->accum_buf_size=size;
+ } /* end if */
+
+ /* Update accumulator information */
+ file->accum_loc=addr;
+ file->accum_size=size;
+ file->accum_dirty=FALSE;
+
+ /* Read into accumulator */
+ if ((file->cls->read)(file, H5FD_MEM_DEFAULT, dxpl_id, file->accum_loc, file->accum_size, file->meta_accum)<0)
+ HRETURN_ERROR(H5E_VFL, H5E_READERROR, FAIL, "driver read request failed");
+
+ /* Copy into buffer */
+ HDmemcpy(buf,file->meta_accum,size);
+ } /* end else */
} /* end if */
else {
/* Dispatch to driver */
if ((file->cls->read)(file, type, dxpl_id, addr, size, buf)<0)
- HRETURN_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver read request failed");
+ HRETURN_ERROR(H5E_VFL, H5E_READERROR, FAIL, "driver read request failed");
} /* end else */
FUNC_LEAVE(SUCCEED);
@@ -2243,7 +2278,7 @@ H5FDwrite(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t siz
/* The real work */
if (H5FD_write(file, type, dxpl_id, addr, size, buf)<0)
- HRETURN_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "file write request failed");
+ HRETURN_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "file write request failed");
FUNC_LEAVE(SUCCEED);
}
@@ -2295,7 +2330,7 @@ H5FD_write(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t si
/* Check if there is already metadata in the accumulator */
if(file->accum_size>0) {
/* Check if the piece of metadata being written adjoins or is inside the metadata accumulator */
- if((addr>=file->accum_loc && addr <(file->accum_loc+file->accum_size))
+ if((addr>=file->accum_loc && addr<=(file->accum_loc+file->accum_size))
|| ((addr+size)>file->accum_loc && (addr+size)<=(file->accum_loc+file->accum_size))
|| (addr<file->accum_loc && (addr+size)>file->accum_loc)) {
@@ -2416,8 +2451,12 @@ H5FD_write(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t si
/* New piece of metadata doesn't adjoin or overlap the existing accumulator */
else {
/* Write out the existing metadata accumulator, with dispatch to driver */
- if ((file->cls->write)(file, H5FD_MEM_DEFAULT, dxpl_id, file->accum_loc, file->accum_size, file->meta_accum)<0)
- HRETURN_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver write request failed");
+ if(file->accum_dirty) {
+ if ((file->cls->write)(file, H5FD_MEM_DEFAULT, dxpl_id, file->accum_loc, file->accum_size, file->meta_accum)<0)
+ HRETURN_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "driver write request failed");
+ /* Reset accumulator dirty flag */
+ file->accum_dirty=FALSE;
+ } /* end if */
/* Cache the new piece of metadata */
/* Check if we need to reallocate the buffer */
@@ -2430,10 +2469,12 @@ H5FD_write(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t si
file->accum_buf_size=size;
} /* end if */
- /* Store the piece of metadata in the accumulator */
+ /* Update the metadata accumulator information */
file->accum_loc=addr;
file->accum_size=size;
file->accum_dirty=TRUE;
+
+ /* Store the piece of metadata in the accumulator */
HDmemcpy(file->meta_accum,buf,size);
} /* end else */
} /* end if */
@@ -2449,17 +2490,19 @@ H5FD_write(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t si
file->accum_buf_size=size;
} /* end if */
- /* Store the piece of metadata in the accumulator */
+ /* Update the metadata accumulator information */
file->accum_loc=addr;
file->accum_size=size;
file->accum_dirty=TRUE;
+
+ /* Store the piece of metadata in the accumulator */
HDmemcpy(file->meta_accum,buf,size);
} /* end else */
} /* end if */
else {
/* Dispatch to driver */
if ((file->cls->write)(file, type, dxpl_id, addr, size, buf)<0)
- HRETURN_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver write request failed");
+ HRETURN_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "driver write request failed");
} /* end else */
FUNC_LEAVE(SUCCEED);