diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2002-03-27 20:25:03 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2002-03-27 20:25:03 (GMT) |
commit | 7e9738f290af26d1bf4ab9db64544d9a89505f0a (patch) | |
tree | e5e0986486cbd1440a6acd3adf14cc533c70cfe0 | |
parent | 30aa868e1082ddd7cc59b4f0716434f4a02fcbdd (diff) | |
download | hdf5-7e9738f290af26d1bf4ab9db64544d9a89505f0a.zip hdf5-7e9738f290af26d1bf4ab9db64544d9a89505f0a.tar.gz hdf5-7e9738f290af26d1bf4ab9db64544d9a89505f0a.tar.bz2 |
[svn-r5096] Purpose:
Bug Fix
Description:
The H5Gget_objinfo() function was not setting the 'fileno' field in the
H5G_stat_t struct passed in.
Solution:
Added a "file serial number" to each file currently open in the library
and put that in the 'fileno' field. If a file is opened twice (with
H5Fopen) and the VFL driver detects that it is the same file (i.e. the
two file structures have the same "shared file info" in the library's
memory structures), they will have the same serial number.
This serial number has two drawbacks:
- If a VFL driver doesn't/can't detect that two calls to H5Fopen with
the same file actually _are_ the same file, each will get a
different serial number
- If the same file is closed and re-opened, the serial number will be
different.
It is be possible to fix the second drawback for many VFL drivers, but it
would be a lot of effort and probably isn't worth it until we've got a
good reason to do it. Dunno if we'll ever be able to fix the first
drawback...
Platforms tested:
FreeBSD 4.5 (sleipnir)
VS: ----------------------------------------------------------------------
-rw-r--r-- | src/H5F.c | 39 | ||||
-rw-r--r-- | src/H5FD.c | 57 | ||||
-rw-r--r-- | src/H5FDprivate.h | 1 | ||||
-rw-r--r-- | src/H5FDpublic.h | 1 | ||||
-rw-r--r-- | src/H5Fprivate.h | 1 | ||||
-rw-r--r-- | src/H5G.c | 12 |
6 files changed, 106 insertions, 5 deletions
@@ -3222,7 +3222,7 @@ H5F_sizeof_size(const H5F_t *f) /*------------------------------------------------------------------------- - * Function: H5F_get_intent + * Function: H5F_get_driver_id * * Purpose: Quick and dirty routine to retrieve the file's 'driver_id' value * (Mainly added to stop non-file routines from poking about in the @@ -3251,6 +3251,43 @@ H5F_get_driver_id(const H5F_t *f) /*------------------------------------------------------------------------- + * Function: H5F_get_fileno + * + * Purpose: Quick and dirty routine to retrieve the file's 'fileno' value + * (Mainly added to stop non-file routines from poking about in the + * H5F_t data structure) + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu> + * March 27, 2002 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_get_fileno(const H5F_t *f, unsigned long *filenum) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER(H5F_get_fileno, FAIL); + + assert(f); + assert(f->shared); + assert(f->shared->lf); + assert(filenum); + + /* Retrieve the file's serial number */ + if(H5FD_get_fileno(f->shared->lf,filenum)<0) + HRETURN_ERROR(H5E_FILE, H5E_BADRANGE, FAIL, "can't retrieve fileno"); + +done: + FUNC_LEAVE(ret_value); +} /* end H5F_get_fileno() */ + + +/*------------------------------------------------------------------------- * Function: H5F_block_read * * Purpose: Reads some data from a file/server/etc into a buffer. @@ -38,6 +38,20 @@ static haddr_t H5FD_real_alloc(H5FD_t *file, H5FD_mem_t type, hsize_t size); /* Declare a PQ free list to manage the metadata accumulator buffer */ H5FL_BLK_DEFINE_STATIC(meta_accum); +/* Static local variables */ + +/* Global count of the number of H5FD_t's handed out. This is used as a + * "serial number" for files that are currently open and is used for the + * 'fileno[2]' field in H5G_stat_t. However, if a VFL driver is not able + * to detect whether two files are the same, a file that has been opened + * by H5Fopen more than once with that VFL driver will have two different + * serial numbers. :-/ + * + * Also, if a file is opened, the 'fileno[2]' field is retrieved for an + * object and the file is closed and re-opened, the 'fileno[2]' value will + * be different. + */ +static unsigned long file_serial_no[2]; /*------------------------------------------------------------------------- * Function: H5FD_init_interface @@ -66,6 +80,9 @@ H5FD_init_interface(void) "unable to initialize interface"); } + /* Reset the file serial numbers */ + HDmemset(file_serial_no,0,sizeof(file_serial_no)); + FUNC_LEAVE(SUCCEED); } @@ -801,6 +818,14 @@ H5FD_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr) if (H5FD_query(file, &(file->feature_flags))<0) HRETURN_ERROR(H5E_VFL, H5E_CANTINIT, NULL, "unable to query file driver"); + /* Increment the global serial number & assign it to this H5FD_t object */ + if(++file_serial_no[0]==0) { + /* (Just error out if we wrap both numbers around for now...) */ + if(++file_serial_no[1]==0) + HRETURN_ERROR(H5E_VFL, H5E_CANTINIT, NULL, "unable to get file serial number"); + } /* end if */ + HDmemcpy(file->fileno,file_serial_no,sizeof(file_serial_no)); + FUNC_LEAVE(file); } @@ -2509,3 +2534,35 @@ H5FD_flush(H5FD_t *file) FUNC_LEAVE(SUCCEED); } + + +/*------------------------------------------------------------------------- + * Function: H5FD_get_fileno + * + * Purpose: Quick and dirty routine to retrieve the file's 'fileno' value + * (Mainly added to stop non-file routines from poking about in the + * H5FD_t data structure) + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu> + * March 27, 2002 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5FD_get_fileno(const H5FD_t *file, unsigned long *filenum) +{ + FUNC_ENTER(H5FD_get_fileno, FAIL); + + assert(file); + assert(filenum); + + /* Retrieve the file's serial number */ + HDmemcpy(filenum,file->fileno,sizeof(file->fileno)); + + FUNC_LEAVE(SUCCEED); +} /* end H5F_get_fileno() */ + diff --git a/src/H5FDprivate.h b/src/H5FDprivate.h index bd633d0..6e0c919 100644 --- a/src/H5FDprivate.h +++ b/src/H5FDprivate.h @@ -39,5 +39,6 @@ __DLL__ herr_t H5FD_read(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t a __DLL__ herr_t H5FD_write(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t size, const void *buf); __DLL__ herr_t H5FD_flush(H5FD_t *file); +__DLL__ herr_t H5FD_get_fileno(const H5FD_t *file, unsigned long *filenum); #endif /* !_H5FDprivate_H */ diff --git a/src/H5FDpublic.h b/src/H5FDpublic.h index d288307..81a63f5 100644 --- a/src/H5FDpublic.h +++ b/src/H5FDpublic.h @@ -153,6 +153,7 @@ typedef struct H5FD_free_t { struct H5FD_t { hid_t driver_id; /*driver ID for this file*/ const H5FD_class_t *cls; /*constant class info */ + unsigned long fileno[2]; /* File serial number */ unsigned long feature_flags; /* VFL Driver feature Flags */ hsize_t threshold; /* Threshold for alignment */ diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index 2b43757..8a77e7a 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -331,6 +331,7 @@ struct H5S_t; __DLL__ herr_t H5F_init(void); __DLL__ unsigned H5F_get_intent(const H5F_t *f); __DLL__ hid_t H5F_get_driver_id(const H5F_t *f); +__DLL__ herr_t H5F_get_fileno(const H5F_t *f, unsigned long *filenum); /* Functions that operate on array storage */ __DLL__ herr_t H5F_arr_create(H5F_t *f, @@ -2044,7 +2044,7 @@ H5G_get_objinfo (H5G_entry_t *loc, const char *name, hbool_t follow_link, if (H5G_CACHED_SLINK==obj_ent.type) { /* Named object is a symbolic link */ if (NULL==H5O_read (&grp_ent, H5O_STAB, 0, &stab_mesg) || - NULL==(s=H5HL_peek (grp_ent.file, stab_mesg.heap_addr, + NULL==(s=H5HL_peek (grp_ent.file, stab_mesg.heap_addr, obj_ent.cache.slink.lval_offset))) { HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL, "unable to read symbolic link value"); @@ -2069,11 +2069,15 @@ H5G_get_objinfo (H5G_entry_t *loc, const char *name, hbool_t follow_link, if (NULL==H5O_read(&obj_ent, H5O_MTIME, 0, &(statbuf->mtime))) { H5E_clear(); statbuf->mtime = 0; - } + } /* end if */ statbuf->type = H5G_get_type(&obj_ent); H5E_clear(); /*clear errors resulting from checking type*/ - } - } + } /* end else */ + + /* Common code to retrieve the file's fileno */ + if(H5F_get_fileno(obj_ent.file,statbuf->fileno)<0) + HRETURN_ERROR (H5E_FILE, H5E_BADVALUE, FAIL, "unable to read fileno"); + } /* end if */ FUNC_LEAVE (SUCCEED); } |