示例#1
0
static void p9_xosclient_rerror(struct p9_req_t *req)
{
	struct p9_fcall *rcall;
	u16 tag;
	struct p9_xos_device *dev = (struct p9_xos_device *)req->aux;
	struct p9_xos_endpoint *ep = &dev->driver->ep[RD_EP];
	unsigned long flags;

	if (p9_parse_header(req->tc, &req->tc->size, &req->tc->id, &tag, 1))
		warning("Failed to decode header !");
	kfree(req->tc);
	spin_lock_irqsave(&dev->driver->ep_lock, flags);
	p9_xos_deque_push(ep->rqueue, a2n(req->tc->sdata - 8, ep), ep);
	nb_free_packets++;
	spin_unlock_irqrestore(&dev->driver->ep_lock, flags);

	rcall = kmalloc(sizeof(struct p9_fcall) + 32, GFP_KERNEL);
	p9pdu_reset(rcall);
	rcall->sdata = (u8 *) (rcall + sizeof(struct p9_fcall));
	p9pdu_writef(rcall, 0, "dbwT", 0, P9_RERROR, tag,
		     "9P destination service closed");
	p9pdu_finalize(rcall);

	req->rc = rcall;
	req->tc = NULL;

	spin_lock(&dev->lock);
	dev->ack_count += 1;
	spin_unlock(&dev->lock);

	p9_xos_add_write_request(req, 0);
}
int p9pdu_finalize(struct p9_client *clnt, struct p9_fcall *pdu)
{
	int size = pdu->size;
	int err;

	pdu->size = 0;
	err = p9pdu_writef(pdu, 0, "d", size);
	pdu->size = size;

	trace_9p_protocol_dump(clnt, pdu);
	p9_debug(P9_DEBUG_9P, ">>> size=%d type: %d tag: %d\n",
		 pdu->size, pdu->id, pdu->tag);

	return err;
}
示例#3
0
int p9pdu_finalize(struct p9_fcall *pdu)
{
    int size = pdu->size;
    int err;

    pdu->size = 0;
    err = p9pdu_writef(pdu, 0, "d", size);
    pdu->size = size;

#ifdef CONFIG_NET_9P_DEBUG
    if ((p9_debug_level & P9_DEBUG_PKT) == P9_DEBUG_PKT)
        p9pdu_dump(0, pdu);
#endif

    P9_DPRINTK(P9_DEBUG_9P, ">>> size=%d type: %d tag: %d\n", pdu->size,
               pdu->id, pdu->tag);

    return err;
}
示例#4
0
int p9pdu_prepare(struct p9_fcall *pdu, int16_t tag, int8_t type)
{
    return p9pdu_writef(pdu, 0, "dbw", 0, type, tag);
}
示例#5
0
int
p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt,
              va_list ap)
{
    const char *ptr;
    int errcode = 0;

    for (ptr = fmt; *ptr; ptr++) {
        switch (*ptr) {
        case 'b': {
            int8_t val = va_arg(ap, int);
            if (pdu_write(pdu, &val, sizeof(val)))
                errcode = -EFAULT;
        }
        break;
        case 'w': {
            __le16 val = cpu_to_le16(va_arg(ap, int));
            if (pdu_write(pdu, &val, sizeof(val)))
                errcode = -EFAULT;
        }
        break;
        case 'd': {
            __le32 val = cpu_to_le32(va_arg(ap, int32_t));
            if (pdu_write(pdu, &val, sizeof(val)))
                errcode = -EFAULT;
        }
        break;
        case 'q': {
            __le64 val = cpu_to_le64(va_arg(ap, int64_t));
            if (pdu_write(pdu, &val, sizeof(val)))
                errcode = -EFAULT;
        }
        break;
        case 's': {
            const char *sptr = va_arg(ap, const char *);
            int16_t len = 0;
            if (sptr)
                len = MIN(strlen(sptr), USHRT_MAX);

            errcode = p9pdu_writef(pdu, proto_version,
                                   "w", len);
            if (!errcode && pdu_write(pdu, sptr, len))
                errcode = -EFAULT;
        }
        break;
        case 'Q': {
            const struct p9_qid *qid =
                va_arg(ap, const struct p9_qid *);
            errcode =
                p9pdu_writef(pdu, proto_version, "bdq",
                             qid->type, qid->version,
                             qid->path);
        }
        break;
        case 'S': {
            const struct p9_wstat *stbuf =
                va_arg(ap, const struct p9_wstat *);
            errcode =
                p9pdu_writef(pdu, proto_version,
                             "wwdQdddqssss?sddd",
                             stbuf->size, stbuf->type,
                             stbuf->dev, &stbuf->qid,
                             stbuf->mode, stbuf->atime,
                             stbuf->mtime, stbuf->length,
                             stbuf->name, stbuf->uid,
                             stbuf->gid, stbuf->muid,
                             stbuf->extension, stbuf->n_uid,
                             stbuf->n_gid, stbuf->n_muid);
        }
        break;
        case 'D': {
            int32_t count = va_arg(ap, int32_t);
            const void *data = va_arg(ap, const void *);

            errcode = p9pdu_writef(pdu, proto_version, "d",
                                   count);
            if (!errcode && pdu_write(pdu, data, count))
                errcode = -EFAULT;
        }
        break;
        case 'U': {
            int32_t count = va_arg(ap, int32_t);
            const char __user *udata =
                va_arg(ap, const void __user *);
            errcode = p9pdu_writef(pdu, proto_version, "d",
                                   count);
            if (!errcode && pdu_write_u(pdu, udata, count))
                errcode = -EFAULT;
        }
        break;
        case 'T': {
            int16_t nwname = va_arg(ap, int);
            const char **wnames = va_arg(ap, const char **);

            errcode = p9pdu_writef(pdu, proto_version, "w",
                                   nwname);
            if (!errcode) {
                int i;

                for (i = 0; i < nwname; i++) {
                    errcode =
                        p9pdu_writef(pdu,
                                     proto_version,
                                     "s",
                                     wnames[i]);
                    if (errcode)
                        break;
                }
            }
        }
        break;
        case 'R': {
            int16_t nwqid = va_arg(ap, int);
            struct p9_qid *wqids =
                va_arg(ap, struct p9_qid *);

            errcode = p9pdu_writef(pdu, proto_version, "w",
                                   nwqid);
            if (!errcode) {
                int i;

                for (i = 0; i < nwqid; i++) {
                    errcode =
                        p9pdu_writef(pdu,
                                     proto_version,
                                     "Q",
                                     &wqids[i]);
                    if (errcode)
                        break;
                }
            }
        }
        break;
        case '?':
            if ((proto_version != p9_proto_2000u) &&
                    (proto_version != p9_proto_2000L))
                return 0;
            break;
        default:
            BUG();
            break;
        }

        if (errcode)
            break;
    }

    return errcode;
}