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

📄 sock.c

📁 LINUX1.0内核源代码,学习LINUX编程的一定要看。
💻 C
字号:
/* *  linux/fs/nfs/sock.c * *  Copyright (C) 1992, 1993  Rick Sladkey * *  low-level nfs remote procedure call interface */#include <linux/config.h>#include <linux/sched.h>#include <linux/nfs_fs.h>#include <linux/errno.h>#include <linux/socket.h>#include <linux/fcntl.h>#include <asm/segment.h>#include <linux/in.h>#include <linux/net.h>extern struct socket *socki_lookup(struct inode *inode);#define _S(nr) (1<<((nr)-1))/* * We violate some modularity principles here by poking around * in some socket internals.  Besides having to call socket * functions from kernel-space instead of user space, the socket * interface does not lend itself well to being cleanly called * without a file descriptor.  Since the nfs calls can run on * behalf of any process, the superblock maintains a file pointer * to the server socket. */static int do_nfs_rpc_call(struct nfs_server *server, int *start, int *end){	struct file *file;	struct inode *inode;	struct socket *sock;	unsigned short fs;	int result;	int xid;	int len;	select_table wait_table;	struct select_table_entry entry;	int (*select) (struct inode *, struct file *, int, select_table *);	int init_timeout, max_timeout;	int timeout;	int retrans;	int major_timeout_seen;	char *server_name;	int n;	int addrlen;	unsigned long old_mask;	xid = start[0];	len = ((char *) end) - ((char *) start);	file = server->file;	inode = file->f_inode;	select = file->f_op->select;	sock = socki_lookup(inode);	if (!sock) {		printk("nfs_rpc_call: socki_lookup failed\n");		return -EBADF;	}	init_timeout = server->timeo;	max_timeout = NFS_MAX_RPC_TIMEOUT*HZ/10;	retrans = server->retrans;	major_timeout_seen = 0;	server_name = server->hostname;	old_mask = current->blocked;	current->blocked |= ~(_S(SIGKILL)#if 0		| _S(SIGSTOP)#endif		| ((server->flags & NFS_MOUNT_INTR)		? ((current->sigaction[SIGINT - 1].sa_handler == SIG_DFL			? _S(SIGINT) : 0)		| (current->sigaction[SIGQUIT - 1].sa_handler == SIG_DFL			? _S(SIGQUIT) : 0))		: 0));	fs = get_fs();	set_fs(get_ds());	for (n = 0, timeout = init_timeout; ; n++, timeout <<= 1) {		result = sock->ops->send(sock, (void *) start, len, 0, 0);		if (result < 0) {			printk("nfs_rpc_call: send error = %d\n", result);			break;		}	re_select:		wait_table.nr = 0;		wait_table.entry = &entry;		current->state = TASK_INTERRUPTIBLE;		if (!select(inode, file, SEL_IN, &wait_table)		    && !select(inode, file, SEL_IN, NULL)) {			if (timeout > max_timeout)				timeout = max_timeout;			current->timeout = jiffies + timeout;			schedule();			remove_wait_queue(entry.wait_address, &entry.wait);			current->state = TASK_RUNNING;			if (current->signal & ~current->blocked) {				current->timeout = 0;				result = -ERESTARTSYS;				break;			}			if (!current->timeout) {				if (n < retrans)					continue;				if (server->flags & NFS_MOUNT_SOFT) {					printk("NFS server %s not responding, "						"timed out\n", server_name);					result = -EIO;					break;				}				n = 0;				timeout = init_timeout;				init_timeout <<= 1;				if (!major_timeout_seen) {					printk("NFS server %s not responding, "						"still trying\n", server_name);				}				major_timeout_seen = 1;				continue;			}			else				current->timeout = 0;		}		else if (wait_table.nr)			remove_wait_queue(entry.wait_address, &entry.wait);		current->state = TASK_RUNNING;		addrlen = 0;		result = sock->ops->recvfrom(sock, (void *) start, PAGE_SIZE, 1, 0,			NULL, &addrlen);		if (result < 0) {			if (result == -EAGAIN) {#if 0				printk("nfs_rpc_call: bad select ready\n");#endif				goto re_select;			}			if (result == -ECONNREFUSED) {#if 0				printk("nfs_rpc_call: server playing coy\n");#endif				goto re_select;			}			if (result != -ERESTARTSYS) {				printk("nfs_rpc_call: recv error = %d\n",					-result);			}			break;		}		if (*start == xid) {			if (major_timeout_seen)				printk("NFS server %s OK\n", server_name);			break;		}#if 0		printk("nfs_rpc_call: XID mismatch\n");#endif	}	current->blocked = old_mask;	set_fs(fs);	return result;}/* * For now we lock out other simulaneous nfs calls for the same filesytem * because we are single-threaded and don't want to get mismatched * RPC replies. */int nfs_rpc_call(struct nfs_server *server, int *start, int *end){	int result;	while (server->lock)		sleep_on(&server->wait);	server->lock = 1;	result = do_nfs_rpc_call(server, start, end);	server->lock = 0;	wake_up(&server->wait);	return result;}

⌨️ 快捷键说明

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