Example #1
0
/* 根据文件描述符来查找struct socket */
static inline struct socket *sockfd_lookup(int fd, struct file **pfile)
{
  struct file *file;

  if (fd < 0 || fd >= NR_OPEN || !(file = current->filp[fd])) return(NULL);
  if (pfile) *pfile = file;
  return(socki_lookup(file->f_inode));
}
Example #2
0
int
sock_fcntl(struct file *filp, unsigned int cmd, unsigned long arg)
{
  struct socket *sock;

  sock = socki_lookup (filp->f_inode);
  if (sock != NULL && sock->ops != NULL && sock->ops->fcntl != NULL)
				return(sock->ops->fcntl(sock, cmd, arg));
  return(-EINVAL);
}
Example #3
0
/* 向socket文件中写数据 */
static int sock_write(struct inode *inode, struct file *file, char *ubuf, int size)
{
  struct socket *sock;

  DPRINTF((net_debug, "NET: sock_write: buf=0x%x, size=%d\n", ubuf, size));
  if (!(sock = socki_lookup(inode))) {
	printk("NET: sock_write: can't find socket for inode!\n");
	return(-EBADF);
  }
  if (sock->flags & SO_ACCEPTCON) return(-EINVAL);
  return(sock->ops->write(sock, ubuf, size,(file->f_flags & O_NONBLOCK)));
}
Example #4
0
int
sock_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
	   unsigned int arg)
{
	struct socket *sock;

	PRINTK("sock_ioctl: inode=0x%x cmd=0x%x arg=%d\n", inode, cmd, arg);
	if (!(sock = socki_lookup(inode))) {
		printk("sock_ioctl: can't find socket for inode!\n");
		return -EBADF;
	}
	return sock->ops->ioctl(sock, cmd, arg);
}
Example #5
0
int
sock_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
	   unsigned long arg)
{
  struct socket *sock;

  DPRINTF((net_debug, "NET: sock_ioctl: inode=0x%x cmd=0x%x arg=%d\n",
							inode, cmd, arg));
  if (!(sock = socki_lookup(inode))) {
	printk("NET: sock_ioctl: can't find socket for inode!\n");
	return(-EBADF);
  }
  return(sock->ops->ioctl(sock, cmd, arg));
}
Example #6
0
static int
sock_read(struct inode *inode, struct file *file, char *ubuf, int size)
{
	struct socket *sock;

	PRINTK("sock_read: buf=0x%x, size=%d\n", ubuf, size);
	if (!(sock = socki_lookup(inode))) {
		printk("sock_read: can't find socket for inode!\n");
		return -EBADF;
	}
	if (sock->flags & SO_ACCEPTCON)
		return -EINVAL;
	return sock->ops->read(sock, ubuf, size, (file->f_flags & O_NONBLOCK));
}
Example #7
0
/* 关闭socket文件 */
void sock_close(struct inode *inode, struct file *file)
{
  struct socket *sock;

  DPRINTF((net_debug, "NET: sock_close: inode=0x%x (cnt=%d)\n",
						inode, inode->i_count));

  /* It's possible the inode is NULL if we're closing an unfinished socket. */
  if (!inode) return;
  if (!(sock = socki_lookup(inode))) {
	printk("NET: sock_close: can't find socket for inode!\n");
	return;
  }
  /* 将socket释放 */
  sock_release(sock);
}
Example #8
0
static int sock_select(struct inode *inode, struct file *file, int sel_type, select_table * wait)
{
  struct socket *sock;

  DPRINTF((net_debug, "NET: sock_select: inode = 0x%x, kind = %s\n", inode,
       (sel_type == SEL_IN) ? "in" :
       (sel_type == SEL_OUT) ? "out" : "ex"));
  if (!(sock = socki_lookup(inode))) {
	printk("NET: sock_select: can't find socket for inode!\n");
	return(0);
  }

  /* We can't return errors to select, so its either yes or no. */
  if (sock->ops && sock->ops->select)
	return(sock->ops->select(sock, sel_type, wait));
  return(0);
}
Example #9
0
void
sock_close(struct inode *inode, struct file *file)
{
	struct socket *sock;

	PRINTK("sock_close: inode=0x%x (cnt=%d)\n", inode, inode->i_count);
	/*
	 * it's possible the inode is NULL if we're closing an unfinished
	 * socket.
	 */
	if (!inode)
		return;
	if (!(sock = socki_lookup(inode))) {
		printk("sock_close: can't find socket for inode!\n");
		return;
	}
	sock_release(sock);
}
Example #10
0
static struct socket *sockfd_lookup(int fd, int *err)
{
	struct file *file;
	struct inode *inode;
	struct socket *sock;

	if (!(file = fget(fd))) {
		*err = -EBADF;
		return NULL;
	}

	inode = file->f_dentry->d_inode;
	if (!inode->i_sock || !(sock = socki_lookup(inode))) {
		*err = -ENOTSOCK;
		fput(file);
		return NULL;
	}

	if (sock->file != file) {
		printk(KERN_ERR "socki_lookup: socket file changed!\n");
		sock->file = file;
	}
	return sock;
}
Example #11
0
static int do_nfs_rpc_call(struct nfs_server *server, int *start, int *end, int size)
{
	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;
	/* JEJB/JSP 2/7/94
	 * This is for a 4 byte recv of the xid only */
	int recv_xid;

	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) {
			  /* JEJB/JSP 2/7/94
			   * This is useful to see if the system is
			   * hanging */
			  printk("NFS max timeout reached on %s\n",
				 server_name);
			  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;
		/* JEJB/JSP 2/7/94
		 * Get the xid from the next packet using a peek, so keep it
		 * on the recv queue.  If it is wrong, it will be some reply
		 * we don't now need, so discard it */
		result = sock->ops->recvfrom(sock, (void *)&recv_xid,
					     sizeof(recv_xid), 1, MSG_PEEK,
					     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 (recv_xid == xid) {
			if (major_timeout_seen)
				printk("NFS server %s OK\n", server_name);
			break;
		}
		/* JEJB/JSP 2/7/94
		 * we have xid mismatch, so discard the packet and start
		 * again.  What a hack! but I can't call recvfrom with
		 * a null buffer yet. */
		(void)sock->ops->recvfrom(sock, (void *)&recv_xid,
					  sizeof(recv_xid), 1, 0, NULL,
					  &addrlen);
#if 0
		printk("nfs_rpc_call: XID mismatch\n");
#endif
		goto re_select;
	}
	/* JEJB/JSP 2/7/94
	 *
	 * we have the correct xid, so read into the correct place and
	 * return it
	 *
	 */
	result=sock->ops->recvfrom(sock, (void *)start, 
				  size + 1024, 1, 0, NULL,
			/* Here is NFS_SLACK_SPACE..., hack */
				  &addrlen);
	if (result < addrlen) {
		printk("NFS: just caught a too small read memory size..., email to NET channel\n");
		printk("NFS: result=%d,addrlen=%d\n", result, addrlen);
		result = -EIO;
	}
	current->blocked = old_mask;
	set_fs(fs);
	return result;
}