Esempio n. 1
0
File: sock.c Progetto: nhanh0/hah
struct sock *sk_alloc(int family, int priority, int zero_it)
{
	struct sock *sk = kmem_cache_alloc(sk_cachep, priority);

	if(sk && zero_it) {
		memset(sk, 0, sizeof(struct sock));
		sk->family = family;
		sock_lock_init(sk);
	}

	return sk;
}
Esempio n. 2
0
/**
 *	sk_alloc - All socket objects are allocated here
 *	@family - protocol family
 *	@priority - for allocation (%GFP_KERNEL, %GFP_ATOMIC, etc)
 *	@zero_it - zeroes the allocated sock
 *	@slab - alternate slab
 *
 *	All socket objects are allocated here. If @zero_it is non-zero
 *	it should have the size of the are to be zeroed, because the
 *	private slabcaches have different sizes of the generic struct sock.
 *	1 has been kept as a way to say sizeof(struct sock).
 */
struct sock *sk_alloc(int family, int priority, int zero_it, kmem_cache_t *slab)
{
	struct sock *sk = NULL;

	if (!slab)
		slab = sk_cachep;
	sk = kmem_cache_alloc(slab, priority);
	if (sk) {
		if (zero_it) {
			memset(sk, 0,
			       zero_it == 1 ? sizeof(struct sock) : zero_it);
			sk->sk_family = family;
			sock_lock_init(sk);
		}
		sk->sk_slab = slab;
	}
	return sk;
}
Esempio n. 3
0
/**
 *	sk_alloc - All socket objects are allocated here
 *	@family: protocol family
 *	@priority: for allocation (%GFP_KERNEL, %GFP_ATOMIC, etc)
 *	@prot: struct proto associated with this new sock instance
 *	@zero_it: if we should zero the newly allocated sock
 */
struct sock *sk_alloc(int family, gfp_t priority,
		      struct proto *prot, int zero_it)
{
	struct sock *sk = NULL;
	kmem_cache_t *slab = prot->slab;

	if (slab != NULL)
		sk = kmem_cache_alloc(slab, priority);
	else
		sk = kmalloc(prot->obj_size, priority);

	if (sk) {
		if (zero_it) {
			memset(sk, 0, prot->obj_size);
			sk->sk_family = family;
			/*
			 * See comment in struct sock definition to understand
			 * why we need sk_prot_creator -acme
			 */
			sk->sk_prot = sk->sk_prot_creator = prot;
			sock_lock_init(sk);
		}
		
		if (security_sk_alloc(sk, family, priority))
			goto out_free;

		if (!try_module_get(prot->owner))
			goto out_free;
	}
	return sk;

out_free:
	if (slab != NULL)
		kmem_cache_free(slab, sk);
	else
		kfree(sk);
	return NULL;
}
Esempio n. 4
0
struct sock *sk_clone(struct sock *sk, const gfp_t priority)
{
	struct sock *newsk = sk_alloc(sk->sk_family, priority, sk->sk_prot, 0);

	if (newsk != NULL) {
		struct sk_filter *filter;

		memcpy(newsk, sk, sk->sk_prot->obj_size);

		/* SANITY */
		sk_node_init(&newsk->sk_node);
		sock_lock_init(newsk);
		bh_lock_sock(newsk);

		atomic_set(&newsk->sk_rmem_alloc, 0);
		atomic_set(&newsk->sk_wmem_alloc, 0);
		atomic_set(&newsk->sk_omem_alloc, 0);
		skb_queue_head_init(&newsk->sk_receive_queue);
		skb_queue_head_init(&newsk->sk_write_queue);

		rwlock_init(&newsk->sk_dst_lock);
		rwlock_init(&newsk->sk_callback_lock);

		newsk->sk_dst_cache	= NULL;
		newsk->sk_wmem_queued	= 0;
		newsk->sk_forward_alloc = 0;
		newsk->sk_send_head	= NULL;
		newsk->sk_backlog.head	= newsk->sk_backlog.tail = NULL;
		newsk->sk_userlocks	= sk->sk_userlocks & ~SOCK_BINDPORT_LOCK;

		sock_reset_flag(newsk, SOCK_DONE);
		skb_queue_head_init(&newsk->sk_error_queue);

		filter = newsk->sk_filter;
		if (filter != NULL)
			sk_filter_charge(newsk, filter);

		if (sk->sk_create_child)
			sk->sk_create_child(sk, newsk);

		if (unlikely(xfrm_sk_clone_policy(newsk))) {
			/* It is still raw copy of parent, so invalidate
			 * destructor and make plain sk_free() */
			newsk->sk_destruct = NULL;
			sk_free(newsk);
			newsk = NULL;
			goto out;
		}

		newsk->sk_err	   = 0;
		newsk->sk_priority = 0;
		atomic_set(&newsk->sk_refcnt, 2);

		/*
		 * Increment the counter in the same struct proto as the master
		 * sock (sk_refcnt_debug_inc uses newsk->sk_prot->socks, that
		 * is the same as sk->sk_prot->socks, as this field was copied
		 * with memcpy).
		 *
		 * This _changes_ the previous behaviour, where
		 * tcp_create_openreq_child always was incrementing the
		 * equivalent to tcp_prot->socks (inet_sock_nr), so this have
		 * to be taken into account in all callers. -acme
		 */
		sk_refcnt_debug_inc(newsk);
		newsk->sk_socket = NULL;
		newsk->sk_sleep	 = NULL;

		if (newsk->sk_prot->sockets_allocated)
			atomic_inc(newsk->sk_prot->sockets_allocated);
	}
out:
	return newsk;
}