return cpt;
}
+static int lnet_md_validate(const struct lnet_md *umd);
+
static struct lnet_libmd *
lnet_md_build(const struct lnet_md *umd, int unlink)
{
struct lnet_libmd *lmd;
unsigned int size;
+ if (lnet_md_validate(umd) != 0)
+ return ERR_PTR(-EINVAL);
+
if (umd->options & LNET_MD_KIOV)
niov = umd->length;
else
}
/* must be called with resource lock held */
-static int
+static void
lnet_md_link(struct lnet_libmd *md, lnet_handler_t handler, int cpt)
{
struct lnet_res_container *container = the_lnet.ln_md_containers[cpt];
/* NB we are passed an allocated, but inactive md.
- * if we return success, caller may lnet_md_unlink() it.
- * otherwise caller may only lnet_md_free() it.
+ * Caller may lnet_md_unlink() it, or may lnet_md_free() it.
*/
/* This implementation doesn't know how to create START events or
* disable END events. Best to LASSERT our caller is compliant so
LASSERT(list_empty(&md->md_list));
list_add(&md->md_list, &container->rec_active);
-
- return 0;
}
void lnet_assert_handler_unused(lnet_handler_t handler)
* \param handle On successful returns, a handle to the newly created MD is
* saved here. This handle can be used later in LNetMDUnlink().
*
+ * The ME will either be linked to the new MD, or it will be freed.
+ *
* \retval 0 On success.
* \retval -EINVAL If \a umd is not valid.
* \retval -ENOMEM If new MD cannot be allocated.
- * \retval -ENOENT Either \a meh or \a umd.eq_handle does not point to a
- * valid object. Note that it's OK to supply a NULL \a umd.eq_handle by
- * calling LNetInvalidateHandle() on it.
- * \retval -EBUSY If the ME pointed to by \a meh is already associated with
- * a MD.
*/
int
LNetMDAttach(struct lnet_me *me, const struct lnet_md *umd,
LIST_HEAD(drops);
struct lnet_libmd *md;
int cpt;
- int rc;
LASSERT(the_lnet.ln_refcount > 0);
-
- if (lnet_md_validate(umd) != 0)
- return -EINVAL;
+ LASSERT(!me->me_md);
if ((umd->options & (LNET_MD_OP_GET | LNET_MD_OP_PUT)) == 0) {
CERROR("Invalid option: no MD_OP set\n");
- return -EINVAL;
- }
-
- md = lnet_md_build(umd, unlink);
- if (IS_ERR(md))
- return PTR_ERR(md);
+ md = ERR_PTR(-EINVAL);
+ } else
+ md = lnet_md_build(umd, unlink);
cpt = me->me_cpt;
-
lnet_res_lock(cpt);
- if (me->me_md)
- rc = -EBUSY;
- else
- rc = lnet_md_link(md, umd->handler, cpt);
+ if (IS_ERR(md)) {
+ lnet_me_unlink(me);
+ lnet_res_unlock(cpt);
+ return PTR_ERR(md);
+ }
- if (rc != 0)
- goto out_unlock;
+ lnet_md_link(md, umd->handler, cpt);
/* attach this MD to portal of ME and check if it matches any
* blocked msgs on this portal */
lnet_recv_delayed_msg_list(&matches);
return 0;
-
-out_unlock:
- lnet_res_unlock(cpt);
- lnet_md_free(md);
- return rc;
}
EXPORT_SYMBOL(LNetMDAttach);
* \retval 0 On success.
* \retval -EINVAL If \a umd is not valid.
* \retval -ENOMEM If new MD cannot be allocated.
- * \retval -ENOENT \a umd.eq_handle does not point to a valid EQ. Note that
- * it's OK to supply a NULL \a umd.eq_handle by calling
- * LNetInvalidateHandle() on it.
*/
int
LNetMDBind(const struct lnet_md *umd, enum lnet_unlink unlink,
LASSERT(the_lnet.ln_refcount > 0);
- if (lnet_md_validate(umd) != 0)
- return -EINVAL;
-
if ((umd->options & (LNET_MD_OP_GET | LNET_MD_OP_PUT)) != 0) {
CERROR("Invalid option: GET|PUT illegal on active MDs\n");
return -EINVAL;
cpt = lnet_res_lock_current();
- rc = lnet_md_link(md, umd->handler, cpt);
- if (rc != 0)
- goto out_unlock;
+ lnet_md_link(md, umd->handler, cpt);
lnet_md2handle(handle, md);
lnet_res_unlock(cpt);
return 0;
- out_unlock:
- lnet_res_unlock(cpt);
-
out_free:
lnet_md_free(md);
return rc;