static size_t pdu_marshal(V9fsPDU *pdu, size_t offset, const char *fmt, ...)

{

    size_t old_offset = offset;

    va_list ap;

    int i;



    va_start(ap, fmt);

    for (i = 0; fmt[i]; i++) {

        switch (fmt[i]) {

        case 'b': {

            uint8_t val = va_arg(ap, int);

            offset += pdu_pack(pdu, offset, &val, sizeof(val));

            break;

        }

        case 'w': {

            uint16_t val;

            cpu_to_le16w(&val, va_arg(ap, int));

            offset += pdu_pack(pdu, offset, &val, sizeof(val));

            break;

        }

        case 'd': {

            uint32_t val;

            cpu_to_le32w(&val, va_arg(ap, uint32_t));

            offset += pdu_pack(pdu, offset, &val, sizeof(val));

            break;

        }

        case 'q': {

            uint64_t val;

            cpu_to_le64w(&val, va_arg(ap, uint64_t));

            offset += pdu_pack(pdu, offset, &val, sizeof(val));

            break;

        }

        case 'v': {

            struct iovec *iov = va_arg(ap, struct iovec *);

            int *iovcnt = va_arg(ap, int *);

            *iovcnt = pdu_copy_sg(pdu, offset, 1, iov);

            break;

        }

        case 's': {

            V9fsString *str = va_arg(ap, V9fsString *);

            offset += pdu_marshal(pdu, offset, "w", str->size);

            offset += pdu_pack(pdu, offset, str->data, str->size);

            break;

        }

        case 'Q': {

            V9fsQID *qidp = va_arg(ap, V9fsQID *);

            offset += pdu_marshal(pdu, offset, "bdq",

                        qidp->type, qidp->version, qidp->path);

            break;

        }

        case 'S': {

            V9fsStat *statp = va_arg(ap, V9fsStat *);

            offset += pdu_marshal(pdu, offset, "wwdQdddqsssssddd",

                        statp->size, statp->type, statp->dev,

                        &statp->qid, statp->mode, statp->atime,

                        statp->mtime, statp->length, &statp->name,

                        &statp->uid, &statp->gid, &statp->muid,

                        &statp->extension, statp->n_uid,

                        statp->n_gid, statp->n_muid);

            break;

        }

        case 'A': {

            V9fsStatDotl *statp = va_arg(ap, V9fsStatDotl *);

            offset += pdu_marshal(pdu, offset, "qQdddqqqqqqqqqqqqqqq",

                        statp->st_result_mask,

                        &statp->qid, statp->st_mode,

                        statp->st_uid, statp->st_gid,

                        statp->st_nlink, statp->st_rdev,

                        statp->st_size, statp->st_blksize, statp->st_blocks,

                        statp->st_atime_sec, statp->st_atime_nsec,

                        statp->st_mtime_sec, statp->st_mtime_nsec,

                        statp->st_ctime_sec, statp->st_ctime_nsec,

                        statp->st_btime_sec, statp->st_btime_nsec,

                        statp->st_gen, statp->st_data_version);

            break;

        }

        default:

            break;

        }

    }

    va_end(ap);



    return offset - old_offset;

}
