- lib_md_deconstruct(nal, md, &ret->status_out);
- lib_md_unlink(nal, md);
- ret->rc = PTL_OK;
-
- state_unlock(nal, &flags);
-
- return (PTL_OK);
-}
-
-int do_PtlMDUpdate_internal(nal_cb_t * nal, void *private, void *v_args,
- void *v_ret)
-{
- /*
- * Incoming:
- * ptl_handle_md_t md_in
- * ptl_md_t * old_inout
- * ptl_md_t * new_inout
- * ptl_handle_eq_t testq_in
- * ptl_seq_t sequence_in
- *
- * Outgoing:
- * ptl_md_t * old_inout
- * ptl_md_t * new_inout
- */
- PtlMDUpdate_internal_in *args = v_args;
- PtlMDUpdate_internal_out *ret = v_ret;
- lib_md_t *md;
- lib_eq_t *test_eq = NULL;
- ptl_md_t *new = &args->new_inout;
- unsigned long flags;
-
- state_lock(nal, &flags);
-
- md = ptl_handle2md(&args->md_in, nal);
- if (md == NULL) {
- ret->rc = PTL_MD_INVALID;
- goto out;
- }
-
- if (args->old_inout_valid)
- lib_md_deconstruct(nal, md, &ret->old_inout);
-
- if (!args->new_inout_valid) {
- ret->rc = PTL_OK;
- goto out;
- }
-
- /* XXX fttb, the new MD must be the same type wrt fragmentation */
- if (((new->options ^ md->options) &
- (PTL_MD_IOVEC | PTL_MD_KIOV)) != 0) {
- ret->rc = PTL_MD_INVALID;
- goto out;
- }
-
- if (new->niov > md->md_niov) {
- ret->rc = PTL_IOV_TOO_MANY;
- goto out;
- }
-
- if (new->niov < md->md_niov) {
- ret->rc = PTL_IOV_TOO_SMALL;
- goto out;
- }
-
- if (!PtlHandleIsEqual (args->testq_in, PTL_EQ_NONE)) {
- test_eq = ptl_handle2eq(&args->testq_in, nal);
- if (test_eq == NULL) {
- ret->rc = PTL_EQ_INVALID;
- goto out;
- }
- }
-
- if (md->pending != 0) {
- ret->rc = PTL_MD_NO_UPDATE;
- goto out;
- }
-
- if (test_eq == NULL ||
- test_eq->sequence == args->sequence_in) {
- lib_me_t *me = md->me;
- int unlink = (md->md_flags & PTL_MD_FLAG_AUTO_UNLINK) ?
- PTL_UNLINK : PTL_RETAIN;
-
- // #warning this does not track eq refcounts properly
- ret->rc = lib_md_build(nal, md, private,
- new, &new->eventq, unlink);
-
- md->me = me;
- } else {
- ret->rc = PTL_MD_NO_UPDATE;
- }