spin_unlock_irq(&sk->sk_error_queue.lock); 
spin_unlock_bh(&sk->sk_error_queue.lock); 
int ip_recv_error(struct sock *sk, struct msghdr *msg, int len){	struct sock_exterr_skb *serr;	struct sk_buff *skb, *skb2;	struct sockaddr_in *sin;	struct {		struct sock_extended_err ee;		struct sockaddr_in	 offender;	} errhdr;	int err;	int copied;	err = -EAGAIN;	skb = skb_dequeue(&sk->sk_error_queue);	if (skb == NULL)		goto out;	copied = skb->len;	if (copied > len) {		msg->msg_flags |= MSG_TRUNC;		copied = len;	}	err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);	if (err)		goto out_free_skb;	sock_recv_timestamp(msg, sk, skb);	serr = SKB_EXT_ERR(skb);	sin = (struct sockaddr_in *)msg->msg_name;	if (sin) {		sin->sin_family = AF_INET;		sin->sin_addr.s_addr = *(u32*)(skb->nh.raw + serr->addr_offset);		sin->sin_port = serr->port;		memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));	}	memcpy(&errhdr.ee, &serr->ee, sizeof(struct sock_extended_err));	sin = &errhdr.offender;	sin->sin_family = AF_UNSPEC;	if (serr->ee.ee_origin == SO_EE_ORIGIN_ICMP) {		struct inet_sock *inet = inet_sk(sk);		sin->sin_family = AF_INET;		sin->sin_addr.s_addr = skb->nh.iph->saddr;		sin->sin_port = 0;		memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));		if (inet->cmsg_flags)			ip_cmsg_recv(msg, skb);	}	put_cmsg(msg, SOL_IP, IP_RECVERR, sizeof(errhdr), &errhdr);	/* Now we could try to dump offended packet options */	msg->msg_flags |= MSG_ERRQUEUE;	err = copied;	/* Reset and regenerate socket error */	spin_lock_irq(&sk->sk_error_queue.lock);	sk->sk_err = 0;	if ((skb2 = skb_peek(&sk->sk_error_queue)) != NULL) {		sk->sk_err = SKB_EXT_ERR(skb2)->ee.ee_errno;		spin_unlock_irq(&sk->sk_error_queue.lock);		sk->sk_error_report(sk);	} else		spin_unlock_irq(&sk->sk_error_queue.lock);out_free_skb:		kfree_skb(skb);out:	return err;}
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/e0f9f8586a0b21fb3c7a4ead3804008d57dfdef7/ip_sockglue.c/buggy/net/ipv4/ip_sockglue.c