⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sock.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	sk->sk_state		=	TCP_CLOSE;	sk->sk_socket		=	sock;	sock_set_flag(sk, SOCK_ZAPPED);	if (sock) {		sk->sk_type	=	sock->type;		sk->sk_sleep	=	&sock->wait;		sock->sk	=	sk;	} else		sk->sk_sleep	=	NULL;	rwlock_init(&sk->sk_dst_lock);	rwlock_init(&sk->sk_callback_lock);	lockdep_set_class_and_name(&sk->sk_callback_lock,			af_callback_keys + sk->sk_family,			af_family_clock_key_strings[sk->sk_family]);	sk->sk_state_change	=	sock_def_wakeup;	sk->sk_data_ready	=	sock_def_readable;	sk->sk_write_space	=	sock_def_write_space;	sk->sk_error_report	=	sock_def_error_report;	sk->sk_destruct		=	sock_def_destruct;	sk->sk_sndmsg_page	=	NULL;	sk->sk_sndmsg_off	=	0;	sk->sk_peercred.pid 	=	0;	sk->sk_peercred.uid	=	-1;	sk->sk_peercred.gid	=	-1;	sk->sk_write_pending	=	0;	sk->sk_rcvlowat		=	1;	sk->sk_rcvtimeo		=	MAX_SCHEDULE_TIMEOUT;	sk->sk_sndtimeo		=	MAX_SCHEDULE_TIMEOUT;	sk->sk_stamp = ktime_set(-1L, -1L);	atomic_set(&sk->sk_refcnt, 1);}void fastcall lock_sock_nested(struct sock *sk, int subclass){	might_sleep();	spin_lock_bh(&sk->sk_lock.slock);	if (sk->sk_lock.owned)		__lock_sock(sk);	sk->sk_lock.owned = 1;	spin_unlock(&sk->sk_lock.slock);	/*	 * The sk_lock has mutex_lock() semantics here:	 */	mutex_acquire(&sk->sk_lock.dep_map, subclass, 0, _RET_IP_);	local_bh_enable();}EXPORT_SYMBOL(lock_sock_nested);void fastcall release_sock(struct sock *sk){	/*	 * The sk_lock has mutex_unlock() semantics:	 */	mutex_release(&sk->sk_lock.dep_map, 1, _RET_IP_);	spin_lock_bh(&sk->sk_lock.slock);	if (sk->sk_backlog.tail)		__release_sock(sk);	sk->sk_lock.owned = 0;	if (waitqueue_active(&sk->sk_lock.wq))		wake_up(&sk->sk_lock.wq);	spin_unlock_bh(&sk->sk_lock.slock);}EXPORT_SYMBOL(release_sock);int sock_get_timestamp(struct sock *sk, struct timeval __user *userstamp){	struct timeval tv;	if (!sock_flag(sk, SOCK_TIMESTAMP))		sock_enable_timestamp(sk);	tv = ktime_to_timeval(sk->sk_stamp);	if (tv.tv_sec == -1)		return -ENOENT;	if (tv.tv_sec == 0) {		sk->sk_stamp = ktime_get_real();		tv = ktime_to_timeval(sk->sk_stamp);	}	return copy_to_user(userstamp, &tv, sizeof(tv)) ? -EFAULT : 0;}EXPORT_SYMBOL(sock_get_timestamp);int sock_get_timestampns(struct sock *sk, struct timespec __user *userstamp){	struct timespec ts;	if (!sock_flag(sk, SOCK_TIMESTAMP))		sock_enable_timestamp(sk);	ts = ktime_to_timespec(sk->sk_stamp);	if (ts.tv_sec == -1)		return -ENOENT;	if (ts.tv_sec == 0) {		sk->sk_stamp = ktime_get_real();		ts = ktime_to_timespec(sk->sk_stamp);	}	return copy_to_user(userstamp, &ts, sizeof(ts)) ? -EFAULT : 0;}EXPORT_SYMBOL(sock_get_timestampns);void sock_enable_timestamp(struct sock *sk){	if (!sock_flag(sk, SOCK_TIMESTAMP)) {		sock_set_flag(sk, SOCK_TIMESTAMP);		net_enable_timestamp();	}}/* *	Get a socket option on an socket. * *	FIX: POSIX 1003.1g is very ambiguous here. It states that *	asynchronous errors should be reported by getsockopt. We assume *	this means if you specify SO_ERROR (otherwise whats the point of it). */int sock_common_getsockopt(struct socket *sock, int level, int optname,			   char __user *optval, int __user *optlen){	struct sock *sk = sock->sk;	return sk->sk_prot->getsockopt(sk, level, optname, optval, optlen);}EXPORT_SYMBOL(sock_common_getsockopt);#ifdef CONFIG_COMPATint compat_sock_common_getsockopt(struct socket *sock, int level, int optname,				  char __user *optval, int __user *optlen){	struct sock *sk = sock->sk;	if (sk->sk_prot->compat_getsockopt != NULL)		return sk->sk_prot->compat_getsockopt(sk, level, optname,						      optval, optlen);	return sk->sk_prot->getsockopt(sk, level, optname, optval, optlen);}EXPORT_SYMBOL(compat_sock_common_getsockopt);#endifint sock_common_recvmsg(struct kiocb *iocb, struct socket *sock,			struct msghdr *msg, size_t size, int flags){	struct sock *sk = sock->sk;	int addr_len = 0;	int err;	err = sk->sk_prot->recvmsg(iocb, sk, msg, size, flags & MSG_DONTWAIT,				   flags & ~MSG_DONTWAIT, &addr_len);	if (err >= 0)		msg->msg_namelen = addr_len;	return err;}EXPORT_SYMBOL(sock_common_recvmsg);/* *	Set socket options on an inet socket. */int sock_common_setsockopt(struct socket *sock, int level, int optname,			   char __user *optval, int optlen){	struct sock *sk = sock->sk;	return sk->sk_prot->setsockopt(sk, level, optname, optval, optlen);}EXPORT_SYMBOL(sock_common_setsockopt);#ifdef CONFIG_COMPATint compat_sock_common_setsockopt(struct socket *sock, int level, int optname,				  char __user *optval, int optlen){	struct sock *sk = sock->sk;	if (sk->sk_prot->compat_setsockopt != NULL)		return sk->sk_prot->compat_setsockopt(sk, level, optname,						      optval, optlen);	return sk->sk_prot->setsockopt(sk, level, optname, optval, optlen);}EXPORT_SYMBOL(compat_sock_common_setsockopt);#endifvoid sk_common_release(struct sock *sk){	if (sk->sk_prot->destroy)		sk->sk_prot->destroy(sk);	/*	 * Observation: when sock_common_release is called, processes have	 * no access to socket. But net still has.	 * Step one, detach it from networking:	 *	 * A. Remove from hash tables.	 */	sk->sk_prot->unhash(sk);	/*	 * In this point socket cannot receive new packets, but it is possible	 * that some packets are in flight because some CPU runs receiver and	 * did hash table lookup before we unhashed socket. They will achieve	 * receive queue and will be purged by socket destructor.	 *	 * Also we still have packets pending on receive queue and probably,	 * our own packets waiting in device queues. sock_destroy will drain	 * receive queue, but transmitted packets will delay socket destruction	 * until the last reference will be released.	 */	sock_orphan(sk);	xfrm_sk_free_policy(sk);	sk_refcnt_debug_release(sk);	sock_put(sk);}EXPORT_SYMBOL(sk_common_release);static DEFINE_RWLOCK(proto_list_lock);static LIST_HEAD(proto_list);#ifdef CONFIG_SMP/* * Define default functions to keep track of inuse sockets per protocol * Note that often used protocols use dedicated functions to get a speed increase. * (see DEFINE_PROTO_INUSE/REF_PROTO_INUSE) */static void inuse_add(struct proto *prot, int inc){	per_cpu_ptr(prot->inuse_ptr, smp_processor_id())[0] += inc;}static int inuse_get(const struct proto *prot){	int res = 0, cpu;	for_each_possible_cpu(cpu)		res += per_cpu_ptr(prot->inuse_ptr, cpu)[0];	return res;}static int inuse_init(struct proto *prot){	if (!prot->inuse_getval || !prot->inuse_add) {		prot->inuse_ptr = alloc_percpu(int);		if (prot->inuse_ptr == NULL)			return -ENOBUFS;		prot->inuse_getval = inuse_get;		prot->inuse_add = inuse_add;	}	return 0;}static void inuse_fini(struct proto *prot){	if (prot->inuse_ptr != NULL) {		free_percpu(prot->inuse_ptr);		prot->inuse_ptr = NULL;		prot->inuse_getval = NULL;		prot->inuse_add = NULL;	}}#elsestatic inline int inuse_init(struct proto *prot){	return 0;}static inline void inuse_fini(struct proto *prot){}#endifint proto_register(struct proto *prot, int alloc_slab){	char *request_sock_slab_name = NULL;	char *timewait_sock_slab_name;	if (inuse_init(prot))		goto out;	if (alloc_slab) {		prot->slab = kmem_cache_create(prot->name, prot->obj_size, 0,					       SLAB_HWCACHE_ALIGN, NULL);		if (prot->slab == NULL) {			printk(KERN_CRIT "%s: Can't create sock SLAB cache!\n",			       prot->name);			goto out_free_inuse;		}		if (prot->rsk_prot != NULL) {			static const char mask[] = "request_sock_%s";			request_sock_slab_name = kmalloc(strlen(prot->name) + sizeof(mask) - 1, GFP_KERNEL);			if (request_sock_slab_name == NULL)				goto out_free_sock_slab;			sprintf(request_sock_slab_name, mask, prot->name);			prot->rsk_prot->slab = kmem_cache_create(request_sock_slab_name,								 prot->rsk_prot->obj_size, 0,								 SLAB_HWCACHE_ALIGN, NULL);			if (prot->rsk_prot->slab == NULL) {				printk(KERN_CRIT "%s: Can't create request sock SLAB cache!\n",				       prot->name);				goto out_free_request_sock_slab_name;			}		}		if (prot->twsk_prot != NULL) {			static const char mask[] = "tw_sock_%s";			timewait_sock_slab_name = kmalloc(strlen(prot->name) + sizeof(mask) - 1, GFP_KERNEL);			if (timewait_sock_slab_name == NULL)				goto out_free_request_sock_slab;			sprintf(timewait_sock_slab_name, mask, prot->name);			prot->twsk_prot->twsk_slab =				kmem_cache_create(timewait_sock_slab_name,						  prot->twsk_prot->twsk_obj_size,						  0, SLAB_HWCACHE_ALIGN,						  NULL);			if (prot->twsk_prot->twsk_slab == NULL)				goto out_free_timewait_sock_slab_name;		}	}	write_lock(&proto_list_lock);	list_add(&prot->node, &proto_list);	write_unlock(&proto_list_lock);	return 0;out_free_timewait_sock_slab_name:	kfree(timewait_sock_slab_name);out_free_request_sock_slab:	if (prot->rsk_prot && prot->rsk_prot->slab) {		kmem_cache_destroy(prot->rsk_prot->slab);		prot->rsk_prot->slab = NULL;	}out_free_request_sock_slab_name:	kfree(request_sock_slab_name);out_free_sock_slab:	kmem_cache_destroy(prot->slab);	prot->slab = NULL;out_free_inuse:	inuse_fini(prot);out:	return -ENOBUFS;}EXPORT_SYMBOL(proto_register);void proto_unregister(struct proto *prot){	write_lock(&proto_list_lock);	list_del(&prot->node);	write_unlock(&proto_list_lock);	inuse_fini(prot);	if (prot->slab != NULL) {		kmem_cache_destroy(prot->slab);		prot->slab = NULL;	}	if (prot->rsk_prot != NULL && prot->rsk_prot->slab != NULL) {		const char *name = kmem_cache_name(prot->rsk_prot->slab);		kmem_cache_destroy(prot->rsk_prot->slab);		kfree(name);		prot->rsk_prot->slab = NULL;	}	if (prot->twsk_prot != NULL && prot->twsk_prot->twsk_slab != NULL) {		const char *name = kmem_cache_name(prot->twsk_prot->twsk_slab);		kmem_cache_destroy(prot->twsk_prot->twsk_slab);		kfree(name);		prot->twsk_prot->twsk_slab = NULL;	}}EXPORT_SYMBOL(proto_unregister);#ifdef CONFIG_PROC_FSstatic void *proto_seq_start(struct seq_file *seq, loff_t *pos){	read_lock(&proto_list_lock);	return seq_list_start_head(&proto_list, *pos);}static void *proto_seq_next(struct seq_file *seq, void *v, loff_t *pos){	return seq_list_next(v, &proto_list, pos);}static void proto_seq_stop(struct seq_file *seq, void *v){	read_unlock(&proto_list_lock);}static char proto_method_implemented(const void *method){	return method == NULL ? 'n' : 'y';}static void proto_seq_printf(struct seq_file *seq, struct proto *proto){	seq_printf(seq, "%-9s %4u %6d  %6d   %-3s %6u   %-3s  %-10s "			"%2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c\n",		   proto->name,		   proto->obj_size,		   proto->sockets_allocated != NULL ? atomic_read(proto->sockets_allocated) : -1,		   proto->memory_allocated != NULL ? atomic_read(proto->memory_allocated) : -1,		   proto->memory_pressure != NULL ? *proto->memory_pressure ? "yes" : "no" : "NI",		   proto->max_header,		   proto->slab == NULL ? "no" : "yes",		   module_name(proto->owner),		   proto_method_implemented(proto->close),		   proto_method_implemented(proto->connect),		   proto_method_implemented(proto->disconnect),		   proto_method_implemented(proto->accept),		   proto_method_implemented(proto->ioctl),		   proto_method_implemented(proto->init),		   proto_method_implemented(proto->destroy),		   proto_method_implemented(proto->shutdown),		   proto_method_implemented(proto->setsockopt),		   proto_method_implemented(proto->getsockopt),		   proto_method_implemented(proto->sendmsg),		   proto_method_implemented(proto->recvmsg),		   proto_method_implemented(proto->sendpage),		   proto_method_implemented(proto->bind),		   proto_method_implemented(proto->backlog_rcv),		   proto_method_implemented(proto->hash),		   proto_method_implemented(proto->unhash),		   proto_method_implemented(proto->get_port),		   proto_method_implemented(proto->enter_memory_pressure));}static int proto_seq_show(struct seq_file *seq, void *v){	if (v == &proto_list)		seq_printf(seq, "%-9s %-4s %-8s %-6s %-5s %-7s %-4s %-10s %s",			   "protocol",			   "size",			   "sockets",			   "memory",			   "press",			   "maxhdr",			   "slab",			   "module",			   "cl co di ac io in de sh ss gs se re sp bi br ha uh gp em\n");	else		proto_seq_printf(seq, list_entry(v, struct proto, node));	return 0;}static const struct seq_operations proto_seq_ops = {	.start  = proto_seq_start,	.next   = proto_seq_next,	.stop   = proto_seq_stop,	.show   = proto_seq_show,};static int proto_seq_open(struct inode *inode, struct file *file){	return seq_open(file, &proto_seq_ops);}static const struct file_operations proto_seq_fops = {	.owner		= THIS_MODULE,	.open		= proto_seq_open,	.read		= seq_read,	.llseek		= seq_lseek,	.release	= seq_release,};static int __init proto_init(void){	/* register /proc/net/protocols */	return proc_net_fops_create(&init_net, "protocols", S_IRUGO, &proto_seq_fops) == NULL ? -ENOBUFS : 0;}subsys_initcall(proto_init);#endif /* PROC_FS */EXPORT_SYMBOL(sk_alloc);EXPORT_SYMBOL(sk_free);EXPORT_SYMBOL(sk_send_sigurg);EXPORT_SYMBOL(sock_alloc_send_skb);EXPORT_SYMBOL(sock_init_data);EXPORT_SYMBOL(sock_kfree_s);EXPORT_SYMBOL(sock_kmalloc);EXPORT_SYMBOL(sock_no_accept);EXPORT_SYMBOL(sock_no_bind);EXPORT_SYMBOL(sock_no_connect);EXPORT_SYMBOL(sock_no_getname);EXPORT_SYMBOL(sock_no_getsockopt);EXPORT_SYMBOL(sock_no_ioctl);EXPORT_SYMBOL(sock_no_listen);EXPORT_SYMBOL(sock_no_mmap);EXPORT_SYMBOL(sock_no_poll);EXPORT_SYMBOL(sock_no_recvmsg);EXPORT_SYMBOL(sock_no_sendmsg);EXPORT_SYMBOL(sock_no_sendpage);EXPORT_SYMBOL(sock_no_setsockopt);EXPORT_SYMBOL(sock_no_shutdown);EXPORT_SYMBOL(sock_no_socketpair);EXPORT_SYMBOL(sock_rfree);EXPORT_SYMBOL(sock_setsockopt);EXPORT_SYMBOL(sock_wfree);EXPORT_SYMBOL(sock_wmalloc);EXPORT_SYMBOL(sock_i_uid);EXPORT_SYMBOL(sock_i_ino);EXPORT_SYMBOL(sysctl_optmem_max);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -