Re: [PATCH 12/14] [TIPC] Added subscription cancellation capability

2006-10-16 Thread David Miller
From: Per Liden [EMAIL PROTECTED]
Date: Fri, 13 Oct 2006 13:37:53 +0200

 From: Lijun Chen [EMAIL PROTECTED]
 
 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 [EMAIL PROTECTED]
 Signed-off-by: Per Liden [EMAIL PROTECTED]

Applied, but had some trailing whitespace additions to cleanup
and would you please ask all patch authors to provide proper
signed-off-by lines in the future?  Thanks.
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 12/14] [TIPC] Added subscription cancellation capability

2006-10-13 Thread Per Liden
From: Lijun Chen [EMAIL PROTECTED]

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 [EMAIL PROTECTED]
Signed-off-by: Per Liden [EMAIL PROTECTED]
---
 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