diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2007-05-10 23:25:58 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2007-05-10 23:25:58 (GMT) |
commit | 00a50871bb7e561515f81cebd45c2de03b6cc9d4 (patch) | |
tree | 4442fdf4b72fb7e3d2d03ebee6fa9c1fc503106b /src/H5O.c | |
parent | 670d598ff7a017cc4cbe1331b30ad645f04514a9 (diff) | |
download | hdf5-00a50871bb7e561515f81cebd45c2de03b6cc9d4.zip hdf5-00a50871bb7e561515f81cebd45c2de03b6cc9d4.tar.gz hdf5-00a50871bb7e561515f81cebd45c2de03b6cc9d4.tar.bz2 |
[svn-r13747] Description:
Fix H5O_msg_iterate() and H5O_link() to protect cache entries with
better permissions.
Tested on:
Mac OS X/32 10.4.9 (amazon)
FreeBSD/32 6.2 (duty)
FreeBSD/64 6.2 (liberty)
Diffstat (limited to 'src/H5O.c')
-rw-r--r-- | src/H5O.c | 128 |
1 files changed, 65 insertions, 63 deletions
@@ -978,6 +978,7 @@ 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 */ @@ -987,81 +988,82 @@ H5O_link(const H5O_loc_t *loc, int adjust, hid_t dxpl_id) HDassert(loc); HDassert(loc->file); HDassert(H5F_addr_defined(loc->addr)); - if(adjust != 0 && 0 == (H5F_INTENT(loc->file) & H5F_ACC_RDWR)) - HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "no write intent on file") /* get header */ - if(NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_WRITE))) + oh_acc = adjust ? H5AC_WRITE : H5AC_READ; + if(NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, oh_acc))) HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header") - /* adjust link count */ - if(adjust < 0) { - /* Check for too large of an adjustment */ - if((unsigned)(-adjust) > oh->nlink) - HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, "link count would be negative") - oh->nlink += adjust; - oh_flags |= H5AC__DIRTIED_FLAG; - - /* Check if the object should be deleted */ - if(oh->nlink == 0) { - /* Check if the object is still open by the user */ - if(H5FO_opened(loc->file, loc->addr) != NULL) { - /* Flag the object to be deleted when it's closed */ - if(H5FO_mark(loc->file, loc->addr, TRUE) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "can't mark object for deletion") + /* Check for adjusting link count */ + if(adjust) { + if(adjust < 0) { + /* Check for too large of an adjustment */ + if((unsigned)(-adjust) > oh->nlink) + HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, "link count would be negative") + oh->nlink += adjust; + oh_flags |= H5AC__DIRTIED_FLAG; + + /* Check if the object should be deleted */ + if(oh->nlink == 0) { + /* Check if the object is still open by the user */ + if(H5FO_opened(loc->file, loc->addr) != NULL) { + /* Flag the object to be deleted when it's closed */ + if(H5FO_mark(loc->file, loc->addr, TRUE) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "can't mark object for deletion") + } /* end if */ + else { + /* Delete object right now */ + if(H5O_delete_oh(loc->file, dxpl_id, oh) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "can't delete object from file") + + /* Mark the object header as deleted */ + oh_flags = H5C__DELETED_FLAG; + } /* end else */ } /* end if */ - else { - /* Delete object right now */ - if(H5O_delete_oh(loc->file, dxpl_id, oh) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "can't delete object from file") - - /* Mark the object header as deleted */ - oh_flags = H5C__DELETED_FLAG; - } /* end else */ - } /* end if */ - } else if (adjust > 0) { - /* A new object, or one that will be deleted */ - if(oh->nlink == 0) { - /* Check if the object is current open, but marked for deletion */ - if(H5FO_marked(loc->file, loc->addr) > 0) { - /* Remove "delete me" flag on the object */ - if(H5FO_mark(loc->file, loc->addr, FALSE) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "can't mark object for deletion") + } else { + /* A new object, or one that will be deleted */ + if(oh->nlink == 0) { + /* Check if the object is current open, but marked for deletion */ + if(H5FO_marked(loc->file, loc->addr) > 0) { + /* Remove "delete me" flag on the object */ + if(H5FO_mark(loc->file, loc->addr, FALSE) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "can't mark object for deletion") + } /* end if */ } /* end if */ - } /* end if */ - oh->nlink += adjust; - oh_flags |= H5AC__DIRTIED_FLAG; - } /* end if */ + oh->nlink += adjust; + oh_flags |= H5AC__DIRTIED_FLAG; + } /* end if */ - /* Check for operations on refcount message */ - if(oh->version > H5O_VERSION_1) { - /* Check if the object has a refcount message already */ - if(oh->has_refcount_msg) { - /* Check for removing refcount message */ - if(oh->nlink <= 1) { - if(H5O_msg_remove_real(loc->file, oh, H5O_MSG_REFCOUNT, H5O_ALL, NULL, NULL, TRUE, dxpl_id) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete refcount message") - oh->has_refcount_msg = FALSE; + /* Check for operations on refcount message */ + if(oh->version > H5O_VERSION_1) { + /* Check if the object has a refcount message already */ + if(oh->has_refcount_msg) { + /* Check for removing refcount message */ + if(oh->nlink <= 1) { + if(H5O_msg_remove_real(loc->file, oh, H5O_MSG_REFCOUNT, H5O_ALL, NULL, NULL, TRUE, dxpl_id) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete refcount message") + oh->has_refcount_msg = FALSE; + } /* end if */ + /* Update refcount message with new link count */ + else { + H5O_refcount_t refcount = oh->nlink; + + if(H5O_msg_write_real(loc->file, 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") + } /* end else */ } /* end if */ - /* Update refcount message with new link count */ else { - H5O_refcount_t refcount = oh->nlink; - - if(H5O_msg_write_real(loc->file, 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") + /* Check for adding refcount message to object */ + if(oh->nlink > 1) { + H5O_refcount_t refcount = oh->nlink; + + if(H5O_msg_append_real(loc->file, 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") + oh->has_refcount_msg = TRUE; + } /* end if */ } /* end else */ } /* end if */ - else { - /* Check for adding refcount message to object */ - if(oh->nlink > 1) { - H5O_refcount_t refcount = oh->nlink; - - if(H5O_msg_append_real(loc->file, 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") - oh->has_refcount_msg = TRUE; - } /* end if */ - } /* end else */ } /* end if */ /* Set return value */ |