From: Per Liden <per.liden@ericsson.com>
To: David Miller <davem@davemloft.net>
Cc: netdev@vger.kernel.org, Lijun Chen <chenli@nortel.com>
Subject: [PATCH 12/14] [TIPC] Added subscription cancellation capability
Date: Fri, 13 Oct 2006 13:37:53 +0200 [thread overview]
Message-ID: <11607394754005-git-send-email-per.liden@ericsson.com> (raw)
In-Reply-To: <Pine.LNX.4.64.0610131330350.30166@ulinpc219.uab.ericsson.se>
From: Lijun Chen <chenli@nortel.com>
This patch allows a TIPC application to cancel an existing
topology service subscription by re-requesting the subscription
with the TIPC_SUB_CANCEL filter bit set. (All other bits of
the cancel request must match the original subscription request.)
Signed-off-by: Allan Stephens <allan.stephens@windriver.com>
Signed-off-by: Per Liden <per.liden@ericsson.com>
---
include/linux/tipc.h | 1 +
net/tipc/subscr.c | 99 ++++++++++++++++++++++++++++++++++++++++++--------
2 files changed, 85 insertions(+), 15 deletions(-)
diff --git a/include/linux/tipc.h b/include/linux/tipc.h
index 243a15f..bea4694 100644
--- a/include/linux/tipc.h
+++ b/include/linux/tipc.h
@@ -129,6 +129,7 @@ #define TIPC_CONN_SHUTDOWN 5
#define TIPC_SUB_PORTS 0x01 /* filter for port availability */
#define TIPC_SUB_SERVICE 0x02 /* filter for service availability */
+#define TIPC_SUB_CANCEL 0x04 /* cancel a subscription */
#if 0
/* The following filter options are not currently implemented */
#define TIPC_SUB_NO_BIND_EVTS 0x04 /* filter out "publish" events */
diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c
index c51600b..77a87c2 100644
--- a/net/tipc/subscr.c
+++ b/net/tipc/subscr.c
@@ -155,7 +155,7 @@ void tipc_subscr_report_overlap(struct s
sub->seq.upper, found_lower, found_upper);
if (!tipc_subscr_overlap(sub, found_lower, found_upper))
return;
- if (!must && (sub->filter != TIPC_SUB_PORTS))
+ if (!must && !(sub->filter & TIPC_SUB_PORTS))
return;
subscr_send_event(sub, found_lower, found_upper, event, port_ref, node);
}
@@ -176,6 +176,13 @@ static void subscr_timeout(struct subscr
if (subscriber == NULL)
return;
+ /* Validate timeout (in case subscription is being cancelled) */
+
+ if (sub->timeout == TIPC_WAIT_FOREVER) {
+ tipc_ref_unlock(subscriber_ref);
+ return;
+ }
+
/* Unlink subscription from name table */
tipc_nametbl_unsubscribe(sub);
@@ -199,6 +206,20 @@ static void subscr_timeout(struct subscr
}
/**
+ * subscr_del - delete a subscription within a subscription list
+ *
+ * Called with subscriber locked.
+ */
+
+static void subscr_del(struct subscription *sub)
+{
+ tipc_nametbl_unsubscribe(sub);
+ list_del(&sub->subscription_list);
+ kfree(sub);
+ atomic_dec(&topsrv.subscription_count);
+}
+
+/**
* subscr_terminate - terminate communication with a subscriber
*
* Called with subscriber locked. Routine must temporarily release this lock
@@ -227,12 +248,9 @@ static void subscr_terminate(struct subs
k_cancel_timer(&sub->timer);
k_term_timer(&sub->timer);
}
- tipc_nametbl_unsubscribe(sub);
- list_del(&sub->subscription_list);
- dbg("Term: Removed sub %u,%u,%u from subscriber %x list\n",
+ dbg("Term: Removing sub %u,%u,%u from subscriber %x list\n",
sub->seq.type, sub->seq.lower, sub->seq.upper, subscriber);
- kfree(sub);
- atomic_dec(&topsrv.subscription_count);
+ subscr_del(sub);
}
/* Sever connection to subscriber */
@@ -253,6 +271,49 @@ static void subscr_terminate(struct subs
}
/**
+ * subscr_cancel - handle subscription cancellation request
+ *
+ * Called with subscriber locked. Routine must temporarily release this lock
+ * to enable the subscription timeout routine to finish without deadlocking;
+ * the lock is then reclaimed to allow caller to release it upon return.
+ *
+ * Note that fields of 's' use subscriber's endianness!
+ */
+
+static void subscr_cancel(struct tipc_subscr *s,
+ struct subscriber *subscriber)
+{
+ struct subscription *sub;
+ struct subscription *sub_temp;
+ int found = 0;
+
+ /* Find first matching subscription, exit if not found */
+
+ list_for_each_entry_safe(sub, sub_temp, &subscriber->subscription_list,
+ subscription_list) {
+ if (!memcmp(s, &sub->evt.s, sizeof(struct tipc_subscr))) {
+ found = 1;
+ break;
+ }
+ }
+ if (!found)
+ return;
+
+ /* Cancel subscription timer (if used), then delete subscription */
+
+ if (sub->timeout != TIPC_WAIT_FOREVER) {
+ sub->timeout = TIPC_WAIT_FOREVER;
+ spin_unlock_bh(subscriber->lock);
+ k_cancel_timer(&sub->timer);
+ k_term_timer(&sub->timer);
+ spin_lock_bh(subscriber->lock);
+ }
+ dbg("Cancel: removing sub %u,%u,%u from subscriber %x list\n",
+ sub->seq.type, sub->seq.lower, sub->seq.upper, subscriber);
+ subscr_del(sub);
+}
+
+/**
* subscr_subscribe - create subscription for subscriber
*
* Called with subscriber locked
@@ -263,6 +324,21 @@ static void subscr_subscribe(struct tipc
{
struct subscription *sub;
+ /* Determine/update subscriber's endianness */
+
+ if (s->filter & (TIPC_SUB_PORTS | TIPC_SUB_SERVICE))
+ subscriber->swap = 0;
+ else
+ subscriber->swap = 1;
+
+ /* Detect & process a subscription cancellation request */
+
+ if (s->filter & htohl(TIPC_SUB_CANCEL, subscriber->swap)) {
+ s->filter &= ~htohl(TIPC_SUB_CANCEL, subscriber->swap);
+ subscr_cancel(s, subscriber);
+ return;
+ }
+
/* Refuse subscription if global limit exceeded */
if (atomic_read(&topsrv.subscription_count) >= tipc_max_subscriptions) {
@@ -281,13 +357,6 @@ static void subscr_subscribe(struct tipc
return;
}
- /* Determine/update subscriber's endianness */
-
- if ((s->filter == TIPC_SUB_PORTS) || (s->filter == TIPC_SUB_SERVICE))
- subscriber->swap = 0;
- else
- subscriber->swap = 1;
-
/* Initialize subscription object */
memset(sub, 0, sizeof(*sub));
@@ -296,8 +365,8 @@ static void subscr_subscribe(struct tipc
sub->seq.upper = htohl(s->seq.upper, subscriber->swap);
sub->timeout = htohl(s->timeout, subscriber->swap);
sub->filter = htohl(s->filter, subscriber->swap);
- if ((((sub->filter != TIPC_SUB_PORTS)
- && (sub->filter != TIPC_SUB_SERVICE)))
+ if ((!(sub->filter & TIPC_SUB_PORTS)
+ == !(sub->filter & TIPC_SUB_SERVICE))
|| (sub->seq.lower > sub->seq.upper)) {
warn("Subscription rejected, illegal request\n");
kfree(sub);
--
1.4.1
next prev parent reply other threads:[~2006-10-13 11:38 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-10-13 11:37 [PATCH 0/14] TIPC updates Per Liden
2006-10-13 11:37 ` [PATCH 1/14] [TIPC] Add missing unlock in port timeout code Per Liden
2006-10-17 4:39 ` David Miller
2006-10-13 11:37 ` [PATCH 2/14] [TIPC] Debug print buffer enhancements and fixes Per Liden
2006-10-17 4:43 ` David Miller
2006-10-13 11:37 ` [PATCH 3/14] [TIPC] Stream socket can now send > 66000 bytes at a time Per Liden
2006-10-17 4:44 ` David Miller
2006-10-13 11:37 ` [PATCH 4/14] [TIPC] Added duplicate node address detection capability Per Liden
2006-10-17 4:45 ` David Miller
2006-10-13 11:37 ` [PATCH 5/14] [TIPC] Optimize wakeup logic when socket has no waiting processes Per Liden
2006-10-17 4:48 ` David Miller
2006-10-13 11:37 ` [PATCH 6/14] [TIPC] Remove code bloat introduced by print buffer rework Per Liden
2006-10-17 4:49 ` David Miller
2006-10-13 11:37 ` [PATCH 7/14] [TIPC] Add support for Ethernet VLANs Per Liden
2006-10-17 4:50 ` David Miller
2006-10-13 11:37 ` [PATCH 8/14] [TIPC] Fix socket receive queue NULL pointer dereference on SMP systems Per Liden
2006-10-17 4:55 ` David Miller
2006-10-13 11:37 ` [PATCH 9/14] [TIPC] Name publication events now delivered in chronological order Per Liden
2006-10-13 23:13 ` Bill Fink
2006-10-16 8:50 ` Per Liden
2006-10-16 20:59 ` David Miller
2006-10-17 4:56 ` David Miller
2006-10-13 11:37 ` [PATCH 10/14] [TIPC] Fixed slow link reactivation when link tolerance is large Per Liden
2006-10-17 4:57 ` David Miller
2006-10-13 11:37 ` [PATCH 11/14] [TIPC] Can now list multicast link on an isolated network node Per Liden
2006-10-17 4:58 ` David Miller
2006-10-13 11:37 ` Per Liden [this message]
2006-10-17 5:00 ` [PATCH 12/14] [TIPC] Added subscription cancellation capability David Miller
2006-10-13 11:37 ` [PATCH 13/14] [TIPC] Unrecognized configuration command now returns error message Per Liden
2006-10-17 5:01 ` David Miller
2006-10-13 11:37 ` [PATCH 14/14] [TIPC] Updated TIPC version number to 1.6.2 Per Liden
2006-10-17 5:01 ` David Miller
2006-10-17 5:04 ` [PATCH 0/14] TIPC updates David Miller
2006-10-18 8:24 ` Per Liden
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=11607394754005-git-send-email-per.liden@ericsson.com \
--to=per.liden@ericsson.com \
--cc=chenli@nortel.com \
--cc=davem@davemloft.net \
--cc=netdev@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).