^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * net/9p/protocol.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * 9P Protocol Support Code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (C) 2008 by Eric Van Hensbergen <ericvh@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Base on code from Anthony Liguori <aliguori@us.ibm.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Copyright (C) 2008 by IBM, Corp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/stddef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/uio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <net/9p/9p.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <net/9p/client.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "protocol.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <trace/events/9p.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) p9pdu_writef(struct p9_fcall *pdu, int proto_version, const char *fmt, ...);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) void p9stat_free(struct p9_wstat *stbuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) kfree(stbuf->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) stbuf->name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) kfree(stbuf->uid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) stbuf->uid = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) kfree(stbuf->gid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) stbuf->gid = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) kfree(stbuf->muid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) stbuf->muid = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) kfree(stbuf->extension);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) stbuf->extension = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) EXPORT_SYMBOL(p9stat_free);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) size_t pdu_read(struct p9_fcall *pdu, void *data, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) size_t len = min(pdu->size - pdu->offset, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) memcpy(data, &pdu->sdata[pdu->offset], len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) pdu->offset += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) return size - len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) static size_t pdu_write(struct p9_fcall *pdu, const void *data, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) size_t len = min(pdu->capacity - pdu->size, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) memcpy(&pdu->sdata[pdu->size], data, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) pdu->size += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) return size - len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) static size_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) pdu_write_u(struct p9_fcall *pdu, struct iov_iter *from, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) size_t len = min(pdu->capacity - pdu->size, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) struct iov_iter i = *from;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) if (!copy_from_iter_full(&pdu->sdata[pdu->size], len, &i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) pdu->size += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) return size - len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) b - int8_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) w - int16_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) d - int32_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) q - int64_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) s - string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) u - numeric uid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) g - numeric gid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) S - stat
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) Q - qid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) D - data blob (int32_t size followed by void *, results are not freed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) T - array of strings (int16_t count, followed by strings)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) R - array of qids (int16_t count, followed by qids)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) A - stat for 9p2000.L (p9_stat_dotl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) ? - if optional = 1, continue parsing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) p9pdu_vreadf(struct p9_fcall *pdu, int proto_version, const char *fmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) va_list ap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) const char *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) int errcode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) for (ptr = fmt; *ptr; ptr++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) switch (*ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) case 'b':{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) int8_t *val = va_arg(ap, int8_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) if (pdu_read(pdu, val, sizeof(*val))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) errcode = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) case 'w':{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) int16_t *val = va_arg(ap, int16_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) __le16 le_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) if (pdu_read(pdu, &le_val, sizeof(le_val))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) errcode = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) *val = le16_to_cpu(le_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) case 'd':{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) int32_t *val = va_arg(ap, int32_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) __le32 le_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) if (pdu_read(pdu, &le_val, sizeof(le_val))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) errcode = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) *val = le32_to_cpu(le_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) case 'q':{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) int64_t *val = va_arg(ap, int64_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) __le64 le_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if (pdu_read(pdu, &le_val, sizeof(le_val))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) errcode = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) *val = le64_to_cpu(le_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) case 's':{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) char **sptr = va_arg(ap, char **);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) uint16_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) errcode = p9pdu_readf(pdu, proto_version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) "w", &len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) if (errcode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) *sptr = kmalloc(len + 1, GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) if (*sptr == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) errcode = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) if (pdu_read(pdu, *sptr, len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) errcode = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) kfree(*sptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) *sptr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) (*sptr)[len] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) case 'u': {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) kuid_t *uid = va_arg(ap, kuid_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) __le32 le_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (pdu_read(pdu, &le_val, sizeof(le_val))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) errcode = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) *uid = make_kuid(&init_user_ns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) le32_to_cpu(le_val));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) } break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) case 'g': {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) kgid_t *gid = va_arg(ap, kgid_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) __le32 le_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) if (pdu_read(pdu, &le_val, sizeof(le_val))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) errcode = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) *gid = make_kgid(&init_user_ns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) le32_to_cpu(le_val));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) } break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) case 'Q':{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) struct p9_qid *qid =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) va_arg(ap, struct p9_qid *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) errcode = p9pdu_readf(pdu, proto_version, "bdq",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) &qid->type, &qid->version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) &qid->path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) case 'S':{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) struct p9_wstat *stbuf =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) va_arg(ap, struct p9_wstat *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) memset(stbuf, 0, sizeof(struct p9_wstat));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) stbuf->n_uid = stbuf->n_muid = INVALID_UID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) stbuf->n_gid = INVALID_GID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) errcode =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) p9pdu_readf(pdu, proto_version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) "wwdQdddqssss?sugu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) &stbuf->size, &stbuf->type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) &stbuf->dev, &stbuf->qid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) &stbuf->mode, &stbuf->atime,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) &stbuf->mtime, &stbuf->length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) &stbuf->name, &stbuf->uid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) &stbuf->gid, &stbuf->muid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) &stbuf->extension,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) &stbuf->n_uid, &stbuf->n_gid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) &stbuf->n_muid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) if (errcode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) p9stat_free(stbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) case 'D':{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) uint32_t *count = va_arg(ap, uint32_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) void **data = va_arg(ap, void **);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) errcode =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) p9pdu_readf(pdu, proto_version, "d", count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) if (!errcode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) *count =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) min_t(uint32_t, *count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) pdu->size - pdu->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) *data = &pdu->sdata[pdu->offset];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) case 'T':{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) uint16_t *nwname = va_arg(ap, uint16_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) char ***wnames = va_arg(ap, char ***);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) errcode = p9pdu_readf(pdu, proto_version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) "w", nwname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) if (!errcode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) *wnames =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) kmalloc_array(*nwname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) sizeof(char *),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) if (!*wnames)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) errcode = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) if (!errcode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) for (i = 0; i < *nwname; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) errcode =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) p9pdu_readf(pdu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) proto_version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) "s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) &(*wnames)[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) if (errcode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) if (errcode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) if (*wnames) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) for (i = 0; i < *nwname; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) kfree((*wnames)[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) kfree(*wnames);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) *wnames = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) case 'R':{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) uint16_t *nwqid = va_arg(ap, uint16_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) struct p9_qid **wqids =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) va_arg(ap, struct p9_qid **);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) *wqids = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) errcode =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) p9pdu_readf(pdu, proto_version, "w", nwqid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) if (!errcode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) *wqids =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) kmalloc_array(*nwqid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) sizeof(struct p9_qid),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) if (*wqids == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) errcode = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) if (!errcode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) for (i = 0; i < *nwqid; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) errcode =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) p9pdu_readf(pdu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) proto_version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) "Q",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) &(*wqids)[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) if (errcode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) if (errcode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) kfree(*wqids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) *wqids = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) case 'A': {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) struct p9_stat_dotl *stbuf =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) va_arg(ap, struct p9_stat_dotl *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) memset(stbuf, 0, sizeof(struct p9_stat_dotl));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) errcode =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) p9pdu_readf(pdu, proto_version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) "qQdugqqqqqqqqqqqqqqq",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) &stbuf->st_result_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) &stbuf->qid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) &stbuf->st_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) &stbuf->st_uid, &stbuf->st_gid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) &stbuf->st_nlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) &stbuf->st_rdev, &stbuf->st_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) &stbuf->st_blksize, &stbuf->st_blocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) &stbuf->st_atime_sec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) &stbuf->st_atime_nsec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) &stbuf->st_mtime_sec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) &stbuf->st_mtime_nsec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) &stbuf->st_ctime_sec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) &stbuf->st_ctime_nsec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) &stbuf->st_btime_sec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) &stbuf->st_btime_nsec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) &stbuf->st_gen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) &stbuf->st_data_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) case '?':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) if ((proto_version != p9_proto_2000u) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) (proto_version != p9_proto_2000L))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (errcode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) return errcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) va_list ap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) const char *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) int errcode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) for (ptr = fmt; *ptr; ptr++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) switch (*ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) case 'b':{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) int8_t val = va_arg(ap, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) if (pdu_write(pdu, &val, sizeof(val)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) errcode = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) case 'w':{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) __le16 val = cpu_to_le16(va_arg(ap, int));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) if (pdu_write(pdu, &val, sizeof(val)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) errcode = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) case 'd':{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) __le32 val = cpu_to_le32(va_arg(ap, int32_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) if (pdu_write(pdu, &val, sizeof(val)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) errcode = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) case 'q':{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) __le64 val = cpu_to_le64(va_arg(ap, int64_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) if (pdu_write(pdu, &val, sizeof(val)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) errcode = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) case 's':{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) const char *sptr = va_arg(ap, const char *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) uint16_t len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) if (sptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) len = min_t(size_t, strlen(sptr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) USHRT_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) errcode = p9pdu_writef(pdu, proto_version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) "w", len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) if (!errcode && pdu_write(pdu, sptr, len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) errcode = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) case 'u': {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) kuid_t uid = va_arg(ap, kuid_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) __le32 val = cpu_to_le32(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) from_kuid(&init_user_ns, uid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) if (pdu_write(pdu, &val, sizeof(val)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) errcode = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) } break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) case 'g': {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) kgid_t gid = va_arg(ap, kgid_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) __le32 val = cpu_to_le32(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) from_kgid(&init_user_ns, gid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) if (pdu_write(pdu, &val, sizeof(val)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) errcode = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) } break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) case 'Q':{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) const struct p9_qid *qid =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) va_arg(ap, const struct p9_qid *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) errcode =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) p9pdu_writef(pdu, proto_version, "bdq",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) qid->type, qid->version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) qid->path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) } break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) case 'S':{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) const struct p9_wstat *stbuf =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) va_arg(ap, const struct p9_wstat *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) errcode =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) p9pdu_writef(pdu, proto_version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) "wwdQdddqssss?sugu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) stbuf->size, stbuf->type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) stbuf->dev, &stbuf->qid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) stbuf->mode, stbuf->atime,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) stbuf->mtime, stbuf->length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) stbuf->name, stbuf->uid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) stbuf->gid, stbuf->muid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) stbuf->extension, stbuf->n_uid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) stbuf->n_gid, stbuf->n_muid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) } break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) case 'V':{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) uint32_t count = va_arg(ap, uint32_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) struct iov_iter *from =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) va_arg(ap, struct iov_iter *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) errcode = p9pdu_writef(pdu, proto_version, "d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) if (!errcode && pdu_write_u(pdu, from, count))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) errcode = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) case 'T':{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) uint16_t nwname = va_arg(ap, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) const char **wnames = va_arg(ap, const char **);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) errcode = p9pdu_writef(pdu, proto_version, "w",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) nwname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) if (!errcode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) for (i = 0; i < nwname; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) errcode =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) p9pdu_writef(pdu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) proto_version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) "s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) wnames[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) if (errcode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) case 'R':{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) uint16_t nwqid = va_arg(ap, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) struct p9_qid *wqids =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) va_arg(ap, struct p9_qid *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) errcode = p9pdu_writef(pdu, proto_version, "w",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) nwqid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) if (!errcode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) for (i = 0; i < nwqid; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) errcode =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) p9pdu_writef(pdu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) proto_version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) "Q",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) &wqids[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) if (errcode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) case 'I':{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) struct p9_iattr_dotl *p9attr = va_arg(ap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) struct p9_iattr_dotl *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) errcode = p9pdu_writef(pdu, proto_version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) "ddugqqqqq",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) p9attr->valid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) p9attr->mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) p9attr->uid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) p9attr->gid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) p9attr->size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) p9attr->atime_sec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) p9attr->atime_nsec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) p9attr->mtime_sec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) p9attr->mtime_nsec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) case '?':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) if ((proto_version != p9_proto_2000u) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) (proto_version != p9_proto_2000L))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) if (errcode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) return errcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) int p9pdu_readf(struct p9_fcall *pdu, int proto_version, const char *fmt, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) va_list ap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) va_start(ap, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) ret = p9pdu_vreadf(pdu, proto_version, fmt, ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) va_end(ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) p9pdu_writef(struct p9_fcall *pdu, int proto_version, const char *fmt, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) va_list ap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) va_start(ap, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) ret = p9pdu_vwritef(pdu, proto_version, fmt, ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) va_end(ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) int p9stat_read(struct p9_client *clnt, char *buf, int len, struct p9_wstat *st)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) struct p9_fcall fake_pdu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) fake_pdu.size = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) fake_pdu.capacity = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) fake_pdu.sdata = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) fake_pdu.offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) ret = p9pdu_readf(&fake_pdu, clnt->proto_version, "S", st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) p9_debug(P9_DEBUG_9P, "<<< p9stat_read failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) trace_9p_protocol_dump(clnt, &fake_pdu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) return fake_pdu.offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) EXPORT_SYMBOL(p9stat_read);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) int p9pdu_prepare(struct p9_fcall *pdu, int16_t tag, int8_t type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) pdu->id = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) return p9pdu_writef(pdu, 0, "dbw", 0, type, tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) int p9pdu_finalize(struct p9_client *clnt, struct p9_fcall *pdu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) int size = pdu->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) pdu->size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) err = p9pdu_writef(pdu, 0, "d", size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) pdu->size = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) trace_9p_protocol_dump(clnt, pdu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) p9_debug(P9_DEBUG_9P, ">>> size=%d type: %d tag: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) pdu->size, pdu->id, pdu->tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) void p9pdu_reset(struct p9_fcall *pdu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) pdu->offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) pdu->size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) int p9dirent_read(struct p9_client *clnt, char *buf, int len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) struct p9_dirent *dirent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) struct p9_fcall fake_pdu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) char *nameptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) fake_pdu.size = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) fake_pdu.capacity = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) fake_pdu.sdata = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) fake_pdu.offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) ret = p9pdu_readf(&fake_pdu, clnt->proto_version, "Qqbs", &dirent->qid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) &dirent->d_off, &dirent->d_type, &nameptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) p9_debug(P9_DEBUG_9P, "<<< p9dirent_read failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) trace_9p_protocol_dump(clnt, &fake_pdu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) ret = strscpy(dirent->d_name, nameptr, sizeof(dirent->d_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) p9_debug(P9_DEBUG_ERROR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) "On the wire dirent name too long: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) nameptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) kfree(nameptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) kfree(nameptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) return fake_pdu.offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) EXPORT_SYMBOL(p9dirent_read);