Esempio n. 1
0
struct p9_transport *p9_trans_create_tcp(const char *addr, int port)
{
	int err;
	struct p9_transport *trans;
	struct socket *csocket;
	struct sockaddr_in sin_server;

	csocket = NULL;
	trans = kmalloc(sizeof(struct p9_transport), GFP_KERNEL);
	if (!trans)
		return ERR_PTR(-ENOMEM);

	trans->write = p9_fd_write;
	trans->read = p9_fd_read;
	trans->close = p9_fd_close;
	trans->poll = p9_fd_poll;

	sin_server.sin_family = AF_INET;
	sin_server.sin_addr.s_addr = in_aton(addr);
	sin_server.sin_port = htons(port);
	sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &csocket);

	if (!csocket) {
		P9_EPRINTK(KERN_ERR, "p9_trans_tcp: problem creating socket\n");
		err = -EIO;
		goto error;
	}

	err = csocket->ops->connect(csocket,
				    (struct sockaddr *)&sin_server,
				    sizeof(struct sockaddr_in), 0);
	if (err < 0) {
		P9_EPRINTK(KERN_ERR,
			"p9_trans_tcp: problem connecting socket to %s\n",
			addr);
		goto error;
	}

	err = p9_socket_open(trans, csocket);
	if (err < 0)
		goto error;

	return trans;

error:
	if (csocket)
		sock_release(csocket);

	kfree(trans);
	return ERR_PTR(err);
}
Esempio n. 2
0
struct p9_transport *p9_trans_create_unix(const char *addr)
{
	int err;
	struct socket *csocket;
	struct sockaddr_un sun_server;
	struct p9_transport *trans;

	csocket = NULL;
	trans = kmalloc(sizeof(struct p9_transport), GFP_KERNEL);
	if (!trans)
		return ERR_PTR(-ENOMEM);

	trans->write = p9_fd_write;
	trans->read = p9_fd_read;
	trans->close = p9_fd_close;
	trans->poll = p9_fd_poll;

	if (strlen(addr) > UNIX_PATH_MAX) {
		P9_EPRINTK(KERN_ERR, "p9_trans_unix: address too long: %s\n",
			addr);
		err = -ENAMETOOLONG;
		goto error;
	}

	sun_server.sun_family = PF_UNIX;
	strcpy(sun_server.sun_path, addr);
	sock_create_kern(PF_UNIX, SOCK_STREAM, 0, &csocket);
	err = csocket->ops->connect(csocket, (struct sockaddr *)&sun_server,
			sizeof(struct sockaddr_un) - 1, 0);
	if (err < 0) {
		P9_EPRINTK(KERN_ERR,
			"p9_trans_unix: problem connecting socket: %s: %d\n",
			addr, err);
		goto error;
	}

	err = p9_socket_open(trans, csocket);
	if (err < 0)
		goto error;

	return trans;

error:
	if (csocket)
		sock_release(csocket);

	kfree(trans);
	return ERR_PTR(err);
}
Esempio n. 3
0
static int p9_socket_open(struct p9_transport *trans, struct socket *csocket)
{
	int fd, ret;

	csocket->sk->sk_allocation = GFP_NOIO;
	fd = sock_map_fd(csocket);
	if (fd < 0) {
		P9_EPRINTK(KERN_ERR, "p9_socket_open: failed to map fd\n");
		return fd;
	}

	ret = p9_fd_open(trans, fd, fd);
	if (ret < 0) {
		P9_EPRINTK(KERN_ERR, "p9_socket_open: failed to open fd\n");
		sockfd_put(csocket);
		return ret;
	}

	((struct p9_trans_fd *)trans->priv)->rd->f_flags |= O_NONBLOCK;

	return 0;
}
Esempio n. 4
0
static int buf_check_size(struct cbuf *buf, int len)
{
	if (buf->p + len > buf->ep) {
		if (buf->p < buf->ep) {
			P9_EPRINTK(KERN_ERR,
				"buffer overflow: want %d has %d\n", len,
				(int)(buf->ep - buf->p));
			dump_stack();
			buf->p = buf->ep + 1;
		}

		return 0;
	}

	return 1;
}
struct inode *v9fs_get_inode(struct super_block *sb, int mode, dev_t rdev)
{
	int err;
	struct inode *inode;
	struct v9fs_session_info *v9ses = sb->s_fs_info;

	P9_DPRINTK(P9_DEBUG_VFS, "super block: %p mode: %o\n", sb, mode);

	inode = new_inode(sb);
	if (!inode) {
		P9_EPRINTK(KERN_WARNING, "Problem allocating inode\n");
		return ERR_PTR(-ENOMEM);
	}
	err = v9fs_init_inode(v9ses, inode, mode, rdev);
	if (err) {
		iput(inode);
		return ERR_PTR(err);
	}
	return inode;
}
Esempio n. 6
0
static int p9_size_wstat(struct p9_wstat *wstat, int dotu)
{
	int size = 0;

	if (wstat == NULL) {
		P9_EPRINTK(KERN_ERR, "p9_size_stat: got a NULL stat pointer\n");
		return 0;
	}

	size =			/* 2 + *//* size[2] */
	    2 +			/* type[2] */
	    4 +			/* dev[4] */
	    1 +			/* qid.type[1] */
	    4 +			/* qid.vers[4] */
	    8 +			/* qid.path[8] */
	    4 +			/* mode[4] */
	    4 +			/* atime[4] */
	    4 +			/* mtime[4] */
	    8 +			/* length[8] */
	    8;			/* minimum sum of string lengths */

	if (wstat->name)
		size += strlen(wstat->name);
	if (wstat->uid)
		size += strlen(wstat->uid);
	if (wstat->gid)
		size += strlen(wstat->gid);
	if (wstat->muid)
		size += strlen(wstat->muid);

	if (dotu) {
		size += 4 +	/* n_uid[4] */
		    4 +		/* n_gid[4] */
		    4 +		/* n_muid[4] */
		    2;		/* string length of extension[4] */
		if (wstat->extension)
			size += strlen(wstat->extension);
	}

	return size;
}
Esempio n. 7
0
int
p9_deserialize_fcall(void *buf, u32 buflen, struct p9_fcall *rcall,
		       int dotu)
{

	struct cbuf buffer;
	struct cbuf *bufp = &buffer;
	int i = 0;

	buf_init(bufp, buf, buflen);

	rcall->size = buf_get_int32(bufp);
	rcall->id = buf_get_int8(bufp);
	rcall->tag = buf_get_int16(bufp);

	P9_DPRINTK(P9_DEBUG_CONV, "size %d id %d tag %d\n", rcall->size,
							rcall->id, rcall->tag);

	switch (rcall->id) {
	default:
		P9_EPRINTK(KERN_ERR, "unknown message type: %d\n", rcall->id);
		return -EPROTO;
	case P9_RVERSION:
		rcall->params.rversion.msize = buf_get_int32(bufp);
		buf_get_str(bufp, &rcall->params.rversion.version);
		break;
	case P9_RFLUSH:
		break;
	case P9_RATTACH:
		rcall->params.rattach.qid.type = buf_get_int8(bufp);
		rcall->params.rattach.qid.version = buf_get_int32(bufp);
		rcall->params.rattach.qid.path = buf_get_int64(bufp);
		break;
	case P9_RWALK:
		rcall->params.rwalk.nwqid = buf_get_int16(bufp);
		if (rcall->params.rwalk.nwqid > P9_MAXWELEM) {
			P9_EPRINTK(KERN_ERR,
					"Rwalk with more than %d qids: %d\n",
					P9_MAXWELEM, rcall->params.rwalk.nwqid);
			return -EPROTO;
		}

		for (i = 0; i < rcall->params.rwalk.nwqid; i++)
			buf_get_qid(bufp, &rcall->params.rwalk.wqids[i]);
		break;
	case P9_ROPEN:
		buf_get_qid(bufp, &rcall->params.ropen.qid);
		rcall->params.ropen.iounit = buf_get_int32(bufp);
		break;
	case P9_RCREATE:
		buf_get_qid(bufp, &rcall->params.rcreate.qid);
		rcall->params.rcreate.iounit = buf_get_int32(bufp);
		break;
	case P9_RREAD:
		rcall->params.rread.count = buf_get_int32(bufp);
		rcall->params.rread.data = bufp->p;
		buf_check_size(bufp, rcall->params.rread.count);
		break;
	case P9_RWRITE:
		rcall->params.rwrite.count = buf_get_int32(bufp);
		break;
	case P9_RCLUNK:
		break;
	case P9_RREMOVE:
		break;
	case P9_RSTAT:
		buf_get_int16(bufp);
		buf_get_stat(bufp, &rcall->params.rstat.stat, dotu);
		break;
	case P9_RWSTAT:
		break;
	case P9_RERROR:
		buf_get_str(bufp, &rcall->params.rerror.error);
		if (dotu)
			rcall->params.rerror.errno = buf_get_int16(bufp);
		break;
	}

	if (buf_check_overflow(bufp)) {
		P9_DPRINTK(P9_DEBUG_ERROR, "buffer overflow\n");
		return -EIO;
	}

	return bufp->p - bufp->sp;
}