diff options
Diffstat (limited to 'net/tipc')
| -rw-r--r-- | net/tipc/subscr.c | 29 | 
1 files changed, 15 insertions, 14 deletions
diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c index 11c9ae00837..642437231ad 100644 --- a/net/tipc/subscr.c +++ b/net/tipc/subscr.c @@ -263,9 +263,9 @@ static void subscr_cancel(struct tipc_subscr *s,   *   * Called with subscriber lock held.   */ -static struct tipc_subscription *subscr_subscribe(struct tipc_subscr *s, -					     struct tipc_subscriber *subscriber) -{ +static int subscr_subscribe(struct tipc_subscr *s, +			    struct tipc_subscriber *subscriber, +			    struct tipc_subscription **sub_p) {  	struct tipc_subscription *sub;  	int swap; @@ -276,23 +276,21 @@ static struct tipc_subscription *subscr_subscribe(struct tipc_subscr *s,  	if (s->filter & htohl(TIPC_SUB_CANCEL, swap)) {  		s->filter &= ~htohl(TIPC_SUB_CANCEL, swap);  		subscr_cancel(s, subscriber); -		return NULL; +		return 0;  	}  	/* Refuse subscription if global limit exceeded */  	if (atomic_read(&subscription_count) >= TIPC_MAX_SUBSCRIPTIONS) {  		pr_warn("Subscription rejected, limit reached (%u)\n",  			TIPC_MAX_SUBSCRIPTIONS); -		subscr_terminate(subscriber); -		return NULL; +		return -EINVAL;  	}  	/* Allocate subscription object */  	sub = kmalloc(sizeof(*sub), GFP_ATOMIC);  	if (!sub) {  		pr_warn("Subscription rejected, no memory\n"); -		subscr_terminate(subscriber); -		return NULL; +		return -ENOMEM;  	}  	/* Initialize subscription object */ @@ -306,8 +304,7 @@ static struct tipc_subscription *subscr_subscribe(struct tipc_subscr *s,  	    (sub->seq.lower > sub->seq.upper)) {  		pr_warn("Subscription rejected, illegal request\n");  		kfree(sub); -		subscr_terminate(subscriber); -		return NULL; +		return -EINVAL;  	}  	INIT_LIST_HEAD(&sub->nameseq_list);  	list_add(&sub->subscription_list, &subscriber->subscription_list); @@ -320,8 +317,8 @@ static struct tipc_subscription *subscr_subscribe(struct tipc_subscr *s,  			     (Handler)subscr_timeout, (unsigned long)sub);  		k_start_timer(&sub->timer, sub->timeout);  	} - -	return sub; +	*sub_p = sub; +	return 0;  }  /* Handle one termination request for the subscriber */ @@ -335,10 +332,14 @@ static void subscr_conn_msg_event(int conid, struct sockaddr_tipc *addr,  				  void *usr_data, void *buf, size_t len)  {  	struct tipc_subscriber *subscriber = usr_data; -	struct tipc_subscription *sub; +	struct tipc_subscription *sub = NULL;  	spin_lock_bh(&subscriber->lock); -	sub = subscr_subscribe((struct tipc_subscr *)buf, subscriber); +	if (subscr_subscribe((struct tipc_subscr *)buf, subscriber, &sub) < 0) { +		spin_unlock_bh(&subscriber->lock); +		subscr_terminate(subscriber); +		return; +	}  	if (sub)  		tipc_nametbl_subscribe(sub);  	spin_unlock_bh(&subscriber->lock);  | 
