/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
* vim:expandtab:shiftwidth=8:tabstop=8:
*
- * lib/lib-me.c
- * Match Entry management routines
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
- * Copyright (c) 2001-2003 Cluster File Systems, Inc.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
*
- * This file is part of Lustre, http://www.lustre.org
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
*
- * Lustre is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
*
- * Lustre is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
*
- * You should have received a copy of the GNU General Public License
- * along with Lustre; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * GPL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved
+ * Use is subject to license terms.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lnet/lnet/lib-me.c
+ *
+ * Match Entry management routines
*/
#define DEBUG_SUBSYSTEM S_LNET
#include <lnet/lib-lnet.h>
+static int
+lnet_me_match_portal(lnet_portal_t *ptl, lnet_process_id_t id,
+ __u64 match_bits, __u64 ignore_bits)
+{
+ struct list_head *mhash = NULL;
+ int unique;
+
+ LASSERT (!(lnet_portal_is_unique(ptl) &&
+ lnet_portal_is_wildcard(ptl)));
+
+ /* prefer to check w/o any lock */
+ unique = lnet_match_is_unique(id, match_bits, ignore_bits);
+ if (likely(lnet_portal_is_unique(ptl) ||
+ lnet_portal_is_wildcard(ptl)))
+ goto match;
+
+ /* unset, new portal */
+ if (unique) {
+ mhash = lnet_portal_mhash_alloc();
+ if (mhash == NULL)
+ return -ENOMEM;
+ }
+
+ LNET_LOCK();
+ if (lnet_portal_is_unique(ptl) ||
+ lnet_portal_is_wildcard(ptl)) {
+ /* someone set it before me */
+ if (mhash != NULL)
+ lnet_portal_mhash_free(mhash);
+ LNET_UNLOCK();
+ goto match;
+ }
+
+ /* still not set */
+ LASSERT (ptl->ptl_mhash == NULL);
+ if (unique) {
+ ptl->ptl_mhash = mhash;
+ lnet_portal_setopt(ptl, LNET_PTL_MATCH_UNIQUE);
+ } else {
+ lnet_portal_setopt(ptl, LNET_PTL_MATCH_WILDCARD);
+ }
+ LNET_UNLOCK();
+ return 0;
+
+ match:
+ if (lnet_portal_is_unique(ptl) && !unique)
+ return -EPERM;
+
+ if (lnet_portal_is_wildcard(ptl) && unique)
+ return -EPERM;
+
+ return 0;
+}
+
int
LNetMEAttach(unsigned int portal,
- lnet_process_id_t match_id,
+ lnet_process_id_t match_id,
__u64 match_bits, __u64 ignore_bits,
- lnet_unlink_t unlink, lnet_ins_pos_t pos,
+ lnet_unlink_t unlink, lnet_ins_pos_t pos,
lnet_handle_me_t *handle)
{
- lnet_me_t *me;
+ lnet_me_t *me;
+ lnet_portal_t *ptl;
+ struct list_head *head;
+ int rc;
LASSERT (the_lnet.ln_init);
LASSERT (the_lnet.ln_refcount > 0);
-
+
if (portal >= the_lnet.ln_nportals)
return -EINVAL;
+ ptl = &the_lnet.ln_portals[portal];
+ rc = lnet_me_match_portal(ptl, match_id, match_bits, ignore_bits);
+ if (rc != 0)
+ return rc;
+
me = lnet_me_alloc();
if (me == NULL)
return -ENOMEM;
lnet_initialise_handle (&me->me_lh, LNET_COOKIE_TYPE_ME);
+ head = lnet_portal_me_head(portal, match_id, match_bits);
+ LASSERT (head != NULL);
+
if (pos == LNET_INS_AFTER)
- list_add_tail(&me->me_list, &(the_lnet.ln_portals[portal].ptl_ml));
+ list_add_tail(&me->me_list, head);
else
- list_add(&me->me_list, &(the_lnet.ln_portals[portal].ptl_ml));
+ list_add(&me->me_list, head);
lnet_me2handle(handle, me);
return 0;
}
-int
-LNetMEInsert(lnet_handle_me_t current_meh,
- lnet_process_id_t match_id,
+int
+LNetMEInsert(lnet_handle_me_t current_meh,
+ lnet_process_id_t match_id,
__u64 match_bits, __u64 ignore_bits,
lnet_unlink_t unlink, lnet_ins_pos_t pos,
lnet_handle_me_t *handle)
{
lnet_me_t *current_me;
lnet_me_t *new_me;
+ lnet_portal_t *ptl;
- LASSERT (the_lnet.ln_init);
+ LASSERT (the_lnet.ln_init);
LASSERT (the_lnet.ln_refcount > 0);
-
+
new_me = lnet_me_alloc();
if (new_me == NULL)
return -ENOMEM;
return -ENOENT;
}
+ LASSERT (current_me->me_portal < the_lnet.ln_nportals);
+
+ ptl = &the_lnet.ln_portals[current_me->me_portal];
+ if (lnet_portal_is_unique(ptl)) {
+ /* nosense to insertion on unique portal */
+ lnet_me_free (new_me);
+ LNET_UNLOCK();
+ return -EPERM;
+ }
+
+ new_me->me_portal = current_me->me_portal;
new_me->me_match_id = match_id;
new_me->me_match_bits = match_bits;
new_me->me_ignore_bits = ignore_bits;
lnet_initialise_handle (&new_me->me_lh, LNET_COOKIE_TYPE_ME);
if (pos == LNET_INS_AFTER)
- list_add_tail(&new_me->me_list, ¤t_me->me_list);
- else
list_add(&new_me->me_list, ¤t_me->me_list);
+ else
+ list_add_tail(&new_me->me_list, ¤t_me->me_list);
lnet_me2handle(handle, new_me);
int
LNetMEUnlink(lnet_handle_me_t meh)
{
- lnet_me_t *me;
- int rc;
+ lnet_me_t *me;
+ lnet_libmd_t *md;
+ lnet_event_t ev;
- LASSERT (the_lnet.ln_init);
+ LASSERT (the_lnet.ln_init);
LASSERT (the_lnet.ln_refcount > 0);
-
+
LNET_LOCK();
me = lnet_handle2me(&meh);
if (me == NULL) {
- rc = -ENOENT;
- } else {
- lnet_me_unlink(me);
- rc = 0;
+ LNET_UNLOCK();
+ return -ENOENT;
}
- LNET_UNLOCK();
+ md = me->me_md;
+ if (md != NULL &&
+ md->md_eq != NULL &&
+ md->md_refcount == 0) {
+ lnet_build_unlink_event(md, &ev);
+ lnet_enq_event_locked(md->md_eq, &ev);
+ }
- return (rc);
+ lnet_me_unlink(me);
+
+ LNET_UNLOCK();
+ return 0;
}
/* call with LNET_LOCK please */