^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/clnt.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * 9P Client
^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) * Copyright (C) 2007 by Latchesar Ionkov <lucho@ionkov.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^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/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/poll.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/idr.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/sched/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/uio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <net/9p/9p.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/parser.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <net/9p/client.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <net/9p/transport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include "protocol.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define CREATE_TRACE_POINTS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <trace/events/9p.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * Client Option Parsing (code inspired by NFS code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * - a little lazy - parse all client options
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) Opt_msize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) Opt_trans,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) Opt_legacy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) Opt_version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) Opt_err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) static const match_table_t tokens = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) {Opt_msize, "msize=%u"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) {Opt_legacy, "noextend"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) {Opt_trans, "trans=%s"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) {Opt_version, "version=%s"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) {Opt_err, NULL},
^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) inline int p9_is_proto_dotl(struct p9_client *clnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) return clnt->proto_version == p9_proto_2000L;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) EXPORT_SYMBOL(p9_is_proto_dotl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) inline int p9_is_proto_dotu(struct p9_client *clnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) return clnt->proto_version == p9_proto_2000u;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) EXPORT_SYMBOL(p9_is_proto_dotu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) int p9_show_client_options(struct seq_file *m, struct p9_client *clnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) if (clnt->msize != 8192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) seq_printf(m, ",msize=%u", clnt->msize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) seq_printf(m, ",trans=%s", clnt->trans_mod->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) switch (clnt->proto_version) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) case p9_proto_legacy:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) seq_puts(m, ",noextend");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) case p9_proto_2000u:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) seq_puts(m, ",version=9p2000.u");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) case p9_proto_2000L:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) /* Default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) if (clnt->trans_mod->show_options)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) return clnt->trans_mod->show_options(m, clnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) EXPORT_SYMBOL(p9_show_client_options);
^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) * Some error codes are taken directly from the server replies,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * make sure they are valid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) static int safe_errno(int err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) if ((err > 0) || (err < -MAX_ERRNO)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) p9_debug(P9_DEBUG_ERROR, "Invalid error code %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) return -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /* Interpret mount option for protocol version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) static int get_protocol_version(char *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) int version = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (!strcmp(s, "9p2000")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) version = p9_proto_legacy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) p9_debug(P9_DEBUG_9P, "Protocol version: Legacy\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) } else if (!strcmp(s, "9p2000.u")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) version = p9_proto_2000u;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) p9_debug(P9_DEBUG_9P, "Protocol version: 9P2000.u\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) } else if (!strcmp(s, "9p2000.L")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) version = p9_proto_2000L;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) p9_debug(P9_DEBUG_9P, "Protocol version: 9P2000.L\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) pr_info("Unknown protocol version %s\n", s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) return version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * parse_options - parse mount options into client structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * @opts: options string passed from mount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * @clnt: existing v9fs client information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * Return 0 upon success, -ERRNO upon failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) static int parse_opts(char *opts, struct p9_client *clnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) char *options, *tmp_options;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) char *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) substring_t args[MAX_OPT_ARGS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) int option;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) char *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) clnt->proto_version = p9_proto_2000L;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) clnt->msize = 8192;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) if (!opts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) tmp_options = kstrdup(opts, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) if (!tmp_options) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) p9_debug(P9_DEBUG_ERROR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) "failed to allocate copy of option string\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) options = tmp_options;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) while ((p = strsep(&options, ",")) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) int token, r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (!*p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) token = match_token(p, tokens, args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) switch (token) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) case Opt_msize:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) r = match_int(&args[0], &option);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (r < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) p9_debug(P9_DEBUG_ERROR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) "integer field, but no integer?\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) ret = r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) if (option < 4096) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) p9_debug(P9_DEBUG_ERROR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) "msize should be at least 4k\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) clnt->msize = option;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) case Opt_trans:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) s = match_strdup(&args[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) if (!s) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) p9_debug(P9_DEBUG_ERROR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) "problem allocating copy of trans arg\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) goto free_and_return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) v9fs_put_trans(clnt->trans_mod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) clnt->trans_mod = v9fs_get_trans_by_name(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) if (clnt->trans_mod == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) pr_info("Could not find request transport: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) kfree(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) case Opt_legacy:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) clnt->proto_version = p9_proto_legacy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) case Opt_version:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) s = match_strdup(&args[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) if (!s) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) p9_debug(P9_DEBUG_ERROR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) "problem allocating copy of version arg\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) goto free_and_return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) r = get_protocol_version(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) if (r < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) ret = r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) clnt->proto_version = r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) kfree(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) free_and_return:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) v9fs_put_trans(clnt->trans_mod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) kfree(tmp_options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) static int p9_fcall_init(struct p9_client *c, struct p9_fcall *fc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) int alloc_msize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) if (likely(c->fcall_cache) && alloc_msize == c->msize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) fc->sdata = kmem_cache_alloc(c->fcall_cache, GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) fc->cache = c->fcall_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) fc->sdata = kmalloc(alloc_msize, GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) fc->cache = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) if (!fc->sdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) fc->capacity = alloc_msize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) void p9_fcall_fini(struct p9_fcall *fc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) /* sdata can be NULL for interrupted requests in trans_rdma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) * and kmem_cache_free does not do NULL-check for us
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) if (unlikely(!fc->sdata))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) if (fc->cache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) kmem_cache_free(fc->cache, fc->sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) kfree(fc->sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) EXPORT_SYMBOL(p9_fcall_fini);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) static struct kmem_cache *p9_req_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) * p9_req_alloc - Allocate a new request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) * @c: Client session.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) * @type: Transaction type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) * @max_size: Maximum packet size for this request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) * Context: Process context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) * Return: Pointer to new request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) static struct p9_req_t *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) p9_tag_alloc(struct p9_client *c, int8_t type, unsigned int max_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) struct p9_req_t *req = kmem_cache_alloc(p9_req_cache, GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) int alloc_msize = min(c->msize, max_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) int tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) if (!req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) if (p9_fcall_init(c, &req->tc, alloc_msize))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) goto free_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) if (p9_fcall_init(c, &req->rc, alloc_msize))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) p9pdu_reset(&req->tc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) p9pdu_reset(&req->rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) req->t_err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) req->status = REQ_STATUS_ALLOC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) init_waitqueue_head(&req->wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) INIT_LIST_HEAD(&req->req_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) idr_preload(GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) spin_lock_irq(&c->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) if (type == P9_TVERSION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) tag = idr_alloc(&c->reqs, req, P9_NOTAG, P9_NOTAG + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) GFP_NOWAIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) tag = idr_alloc(&c->reqs, req, 0, P9_NOTAG, GFP_NOWAIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) req->tc.tag = tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) spin_unlock_irq(&c->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) idr_preload_end();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) if (tag < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) /* Init ref to two because in the general case there is one ref
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) * that is put asynchronously by a writer thread, one ref
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) * temporarily given by p9_tag_lookup and put by p9_client_cb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) * in the recv thread, and one ref put by p9_tag_remove in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) * main thread. The only exception is virtio that does not use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) * p9_tag_lookup but does not have a writer thread either
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) * (the write happens synchronously in the request/zc_request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) * callback), so p9_client_cb eats the second ref there
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) * as the pointer is duplicated directly by virtqueue_add_sgs()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) refcount_set(&req->refcount.refcount, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) return req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) p9_fcall_fini(&req->tc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) p9_fcall_fini(&req->rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) free_req:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) kmem_cache_free(p9_req_cache, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) * p9_tag_lookup - Look up a request by tag.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) * @c: Client session.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) * @tag: Transaction ID.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) * Context: Any context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) * Return: A request, or %NULL if there is no request with that tag.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) struct p9_req_t *p9_tag_lookup(struct p9_client *c, u16 tag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) struct p9_req_t *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) again:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) req = idr_find(&c->reqs, tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (req) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) /* We have to be careful with the req found under rcu_read_lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) * Thanks to SLAB_TYPESAFE_BY_RCU we can safely try to get the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) * ref again without corrupting other data, then check again
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) * that the tag matches once we have the ref
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) if (!p9_req_try_get(req))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) goto again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) if (req->tc.tag != tag) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) p9_req_put(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) goto again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) return req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) EXPORT_SYMBOL(p9_tag_lookup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) * p9_tag_remove - Remove a tag.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) * @c: Client session.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) * @r: Request of reference.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) * Context: Any context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) static int p9_tag_remove(struct p9_client *c, struct p9_req_t *r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) u16 tag = r->tc.tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) p9_debug(P9_DEBUG_MUX, "clnt %p req %p tag: %d\n", c, r, tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) spin_lock_irqsave(&c->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) idr_remove(&c->reqs, tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) spin_unlock_irqrestore(&c->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) return p9_req_put(r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) static void p9_req_free(struct kref *ref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) struct p9_req_t *r = container_of(ref, struct p9_req_t, refcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) p9_fcall_fini(&r->tc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) p9_fcall_fini(&r->rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) kmem_cache_free(p9_req_cache, r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) int p9_req_put(struct p9_req_t *r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) return kref_put(&r->refcount, p9_req_free);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) EXPORT_SYMBOL(p9_req_put);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) * p9_tag_cleanup - cleans up tags structure and reclaims resources
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) * @c: v9fs client struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) * This frees resources associated with the tags structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) static void p9_tag_cleanup(struct p9_client *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) struct p9_req_t *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) idr_for_each_entry(&c->reqs, req, id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) pr_info("Tag %d still in use\n", id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) if (p9_tag_remove(c, req) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) pr_warn("Packet with tag %d has still references",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) req->tc.tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) * p9_client_cb - call back from transport to client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) * c: client state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) * req: request received
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) void p9_client_cb(struct p9_client *c, struct p9_req_t *req, int status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) p9_debug(P9_DEBUG_MUX, " tag %d\n", req->tc.tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) * This barrier is needed to make sure any change made to req before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) * the status change is visible to another thread
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) smp_wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) req->status = status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) wake_up(&req->wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) p9_debug(P9_DEBUG_MUX, "wakeup: %d\n", req->tc.tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) p9_req_put(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) EXPORT_SYMBOL(p9_client_cb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) * p9_parse_header - parse header arguments out of a packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) * @pdu: packet to parse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) * @size: size of packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) * @type: type of request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) * @tag: tag of packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) * @rewind: set if we need to rewind offset afterwards
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) p9_parse_header(struct p9_fcall *pdu, int32_t *size, int8_t *type, int16_t *tag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) int rewind)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) int8_t r_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) int16_t r_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) int32_t r_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) int offset = pdu->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) pdu->offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) err = p9pdu_readf(pdu, 0, "dbw", &r_size, &r_type, &r_tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) goto rewind_and_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) if (type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) *type = r_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) if (tag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) *tag = r_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) if (size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) *size = r_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) if (pdu->size != r_size || r_size < 7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) goto rewind_and_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) pdu->id = r_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) pdu->tag = r_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) p9_debug(P9_DEBUG_9P, "<<< size=%d type: %d tag: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) pdu->size, pdu->id, pdu->tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) rewind_and_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) if (rewind)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) pdu->offset = offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) EXPORT_SYMBOL(p9_parse_header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) * p9_check_errors - check 9p packet for error return and process it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) * @c: current client instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) * @req: request to parse and check for error conditions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) * returns error code if one is discovered, otherwise returns 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) * this will have to be more complicated if we have multiple
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) * error packet types
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) static int p9_check_errors(struct p9_client *c, struct p9_req_t *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) int8_t type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) int ecode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) err = p9_parse_header(&req->rc, NULL, &type, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) if (req->rc.size >= c->msize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) p9_debug(P9_DEBUG_ERROR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) "requested packet size too big: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) req->rc.size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) * dump the response from server
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) * This should be after check errors which poplulate pdu_fcall.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) trace_9p_protocol_dump(c, &req->rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) p9_debug(P9_DEBUG_ERROR, "couldn't parse header %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) if (type != P9_RERROR && type != P9_RLERROR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) if (!p9_is_proto_dotl(c)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) char *ename;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) err = p9pdu_readf(&req->rc, c->proto_version, "s?d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) &ename, &ecode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) if (p9_is_proto_dotu(c) && ecode < 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) err = -ecode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) if (!err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) err = p9_errstr2errno(ename, strlen(ename));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) p9_debug(P9_DEBUG_9P, "<<< RERROR (%d) %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) -ecode, ename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) kfree(ename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) err = p9pdu_readf(&req->rc, c->proto_version, "d", &ecode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) err = -ecode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) p9_debug(P9_DEBUG_9P, "<<< RLERROR (%d)\n", -ecode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) p9_debug(P9_DEBUG_ERROR, "couldn't parse error%d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) * p9_check_zc_errors - check 9p packet for error return and process it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) * @c: current client instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) * @req: request to parse and check for error conditions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) * @in_hdrlen: Size of response protocol buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) * returns error code if one is discovered, otherwise returns 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) * this will have to be more complicated if we have multiple
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) * error packet types
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) static int p9_check_zc_errors(struct p9_client *c, struct p9_req_t *req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) struct iov_iter *uidata, int in_hdrlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) int ecode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) int8_t type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) char *ename = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) err = p9_parse_header(&req->rc, NULL, &type, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) * dump the response from server
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) * This should be after parse_header which poplulate pdu_fcall.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) trace_9p_protocol_dump(c, &req->rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) p9_debug(P9_DEBUG_ERROR, "couldn't parse header %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) if (type != P9_RERROR && type != P9_RLERROR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) if (!p9_is_proto_dotl(c)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) /* Error is reported in string format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) /* 7 = header size for RERROR; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) int inline_len = in_hdrlen - 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) len = req->rc.size - req->rc.offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) if (len > (P9_ZC_HDR_SZ - 7)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) ename = &req->rc.sdata[req->rc.offset];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) if (len > inline_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) /* We have error in external buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) if (!copy_from_iter_full(ename + inline_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) len - inline_len, uidata)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) ename = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) err = p9pdu_readf(&req->rc, c->proto_version, "s?d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) &ename, &ecode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) if (p9_is_proto_dotu(c) && ecode < 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) err = -ecode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) if (!err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) err = p9_errstr2errno(ename, strlen(ename));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) p9_debug(P9_DEBUG_9P, "<<< RERROR (%d) %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) -ecode, ename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) kfree(ename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) err = p9pdu_readf(&req->rc, c->proto_version, "d", &ecode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) err = -ecode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) p9_debug(P9_DEBUG_9P, "<<< RLERROR (%d)\n", -ecode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) p9_debug(P9_DEBUG_ERROR, "couldn't parse error%d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) static struct p9_req_t *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) * p9_client_flush - flush (cancel) a request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) * @c: client state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) * @oldreq: request to cancel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) * This sents a flush for a particular request and links
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) * the flush request to the original request. The current
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) * code only supports a single flush request although the protocol
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) * allows for multiple flush requests to be sent for a single request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) static int p9_client_flush(struct p9_client *c, struct p9_req_t *oldreq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) struct p9_req_t *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) int16_t oldtag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) err = p9_parse_header(&oldreq->tc, NULL, NULL, &oldtag, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) p9_debug(P9_DEBUG_9P, ">>> TFLUSH tag %d\n", oldtag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) req = p9_client_rpc(c, P9_TFLUSH, "w", oldtag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) if (IS_ERR(req))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) return PTR_ERR(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) * if we haven't received a response for oldreq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) * remove it from the list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) if (oldreq->status == REQ_STATUS_SENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) if (c->trans_mod->cancelled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) c->trans_mod->cancelled(c, oldreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) p9_tag_remove(c, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) static struct p9_req_t *p9_client_prepare_req(struct p9_client *c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) int8_t type, int req_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) const char *fmt, va_list ap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) struct p9_req_t *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) p9_debug(P9_DEBUG_MUX, "client %p op %d\n", c, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) /* we allow for any status other than disconnected */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) if (c->status == Disconnected)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) return ERR_PTR(-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) /* if status is begin_disconnected we allow only clunk request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) if ((c->status == BeginDisconnect) && (type != P9_TCLUNK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) return ERR_PTR(-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) req = p9_tag_alloc(c, type, req_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) if (IS_ERR(req))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) return req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) /* marshall the data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) p9pdu_prepare(&req->tc, req->tc.tag, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) err = p9pdu_vwritef(&req->tc, c->proto_version, fmt, ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) goto reterr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) p9pdu_finalize(c, &req->tc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) trace_9p_client_req(c, type, req->tc.tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) return req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) reterr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) p9_tag_remove(c, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) /* We have to put also the 2nd reference as it won't be used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) p9_req_put(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) return ERR_PTR(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) * p9_client_rpc - issue a request and wait for a response
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) * @c: client session
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) * @type: type of request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) * @fmt: protocol format string (see protocol.c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) * Returns request structure (which client must free using p9_tag_remove)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) static struct p9_req_t *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) va_list ap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) int sigpending, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) struct p9_req_t *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) va_start(ap, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) req = p9_client_prepare_req(c, type, c->msize, fmt, ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) va_end(ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) if (IS_ERR(req))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) return req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) if (signal_pending(current)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) sigpending = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) clear_thread_flag(TIF_SIGPENDING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) sigpending = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) err = c->trans_mod->request(c, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) /* write won't happen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) p9_req_put(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) if (err != -ERESTARTSYS && err != -EFAULT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) c->status = Disconnected;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) goto recalc_sigpending;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) again:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) /* Wait for the response */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) err = wait_event_killable(req->wq, req->status >= REQ_STATUS_RCVD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) * Make sure our req is coherent with regard to updates in other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) * threads - echoes to wmb() in the callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) smp_rmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) if ((err == -ERESTARTSYS) && (c->status == Connected)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) && (type == P9_TFLUSH)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) sigpending = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) clear_thread_flag(TIF_SIGPENDING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) goto again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) if (req->status == REQ_STATUS_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) p9_debug(P9_DEBUG_ERROR, "req_status error %d\n", req->t_err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) err = req->t_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) if ((err == -ERESTARTSYS) && (c->status == Connected)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) p9_debug(P9_DEBUG_MUX, "flushing\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) sigpending = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) clear_thread_flag(TIF_SIGPENDING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) if (c->trans_mod->cancel(c, req))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) p9_client_flush(c, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) /* if we received the response anyway, don't signal error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) if (req->status == REQ_STATUS_RCVD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) recalc_sigpending:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) if (sigpending) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) spin_lock_irqsave(¤t->sighand->siglock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) recalc_sigpending();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) spin_unlock_irqrestore(¤t->sighand->siglock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) goto reterr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) err = p9_check_errors(c, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) trace_9p_client_res(c, type, req->rc.tag, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) return req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) reterr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) p9_tag_remove(c, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) return ERR_PTR(safe_errno(err));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) * p9_client_zc_rpc - issue a request and wait for a response
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) * @c: client session
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) * @type: type of request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) * @uidata: destination for zero copy read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) * @uodata: source for zero copy write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) * @inlen: read buffer size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) * @olen: write buffer size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) * @in_hdrlen: reader header size, This is the size of response protocol data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) * @fmt: protocol format string (see protocol.c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) * Returns request structure (which client must free using p9_tag_remove)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) static struct p9_req_t *p9_client_zc_rpc(struct p9_client *c, int8_t type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) struct iov_iter *uidata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) struct iov_iter *uodata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) int inlen, int olen, int in_hdrlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) const char *fmt, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) va_list ap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) int sigpending, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) struct p9_req_t *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) va_start(ap, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) * We allocate a inline protocol data of only 4k bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) * The actual content is passed in zero-copy fashion.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) req = p9_client_prepare_req(c, type, P9_ZC_HDR_SZ, fmt, ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) va_end(ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) if (IS_ERR(req))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) return req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) if (signal_pending(current)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) sigpending = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) clear_thread_flag(TIF_SIGPENDING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) sigpending = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) err = c->trans_mod->zc_request(c, req, uidata, uodata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) inlen, olen, in_hdrlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) if (err == -EIO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) c->status = Disconnected;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) if (err != -ERESTARTSYS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) goto recalc_sigpending;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) if (req->status == REQ_STATUS_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) p9_debug(P9_DEBUG_ERROR, "req_status error %d\n", req->t_err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) err = req->t_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) if ((err == -ERESTARTSYS) && (c->status == Connected)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) p9_debug(P9_DEBUG_MUX, "flushing\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) sigpending = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) clear_thread_flag(TIF_SIGPENDING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) if (c->trans_mod->cancel(c, req))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) p9_client_flush(c, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) /* if we received the response anyway, don't signal error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) if (req->status == REQ_STATUS_RCVD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) recalc_sigpending:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) if (sigpending) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) spin_lock_irqsave(¤t->sighand->siglock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) recalc_sigpending();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) spin_unlock_irqrestore(¤t->sighand->siglock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) goto reterr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) err = p9_check_zc_errors(c, req, uidata, in_hdrlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) trace_9p_client_res(c, type, req->rc.tag, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) return req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) reterr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) p9_tag_remove(c, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) return ERR_PTR(safe_errno(err));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) static struct p9_fid *p9_fid_create(struct p9_client *clnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) struct p9_fid *fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) p9_debug(P9_DEBUG_FID, "clnt %p\n", clnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) fid = kmalloc(sizeof(struct p9_fid), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) if (!fid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) memset(&fid->qid, 0, sizeof(struct p9_qid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) fid->mode = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) fid->uid = current_fsuid();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) fid->clnt = clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) fid->rdir = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) fid->fid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) idr_preload(GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) spin_lock_irq(&clnt->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) ret = idr_alloc_u32(&clnt->fids, fid, &fid->fid, P9_NOFID - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) GFP_NOWAIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) spin_unlock_irq(&clnt->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) idr_preload_end();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) return fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) kfree(fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) static void p9_fid_destroy(struct p9_fid *fid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) struct p9_client *clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) p9_debug(P9_DEBUG_FID, "fid %d\n", fid->fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) clnt = fid->clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) spin_lock_irqsave(&clnt->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) idr_remove(&clnt->fids, fid->fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) spin_unlock_irqrestore(&clnt->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) kfree(fid->rdir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) kfree(fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) static int p9_client_version(struct p9_client *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) struct p9_req_t *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) char *version = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) int msize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) p9_debug(P9_DEBUG_9P, ">>> TVERSION msize %d protocol %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) c->msize, c->proto_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) switch (c->proto_version) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) case p9_proto_2000L:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) req = p9_client_rpc(c, P9_TVERSION, "ds",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) c->msize, "9P2000.L");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) case p9_proto_2000u:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) req = p9_client_rpc(c, P9_TVERSION, "ds",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) c->msize, "9P2000.u");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) case p9_proto_legacy:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) req = p9_client_rpc(c, P9_TVERSION, "ds",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) c->msize, "9P2000");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) if (IS_ERR(req))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) return PTR_ERR(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) err = p9pdu_readf(&req->rc, c->proto_version, "ds", &msize, &version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) p9_debug(P9_DEBUG_9P, "version error %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) trace_9p_protocol_dump(c, &req->rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) p9_debug(P9_DEBUG_9P, "<<< RVERSION msize %d %s\n", msize, version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) if (!strncmp(version, "9P2000.L", 8))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) c->proto_version = p9_proto_2000L;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) else if (!strncmp(version, "9P2000.u", 8))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) c->proto_version = p9_proto_2000u;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) else if (!strncmp(version, "9P2000", 6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) c->proto_version = p9_proto_legacy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) p9_debug(P9_DEBUG_ERROR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) "server returned an unknown version: %s\n", version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) err = -EREMOTEIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) if (msize < 4096) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) p9_debug(P9_DEBUG_ERROR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) "server returned a msize < 4096: %d\n", msize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) err = -EREMOTEIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) if (msize < c->msize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) c->msize = msize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) kfree(version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) p9_tag_remove(c, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) struct p9_client *p9_client_create(const char *dev_name, char *options)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) struct p9_client *clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) char *client_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) clnt = kmalloc(sizeof(struct p9_client), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) if (!clnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) clnt->trans_mod = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) clnt->trans = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) clnt->fcall_cache = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) client_id = utsname()->nodename;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) memcpy(clnt->name, client_id, strlen(client_id) + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) spin_lock_init(&clnt->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) idr_init(&clnt->fids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) idr_init(&clnt->reqs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) err = parse_opts(options, clnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) goto free_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) if (!clnt->trans_mod)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) clnt->trans_mod = v9fs_get_default_trans();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) if (clnt->trans_mod == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) err = -EPROTONOSUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) p9_debug(P9_DEBUG_ERROR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) "No transport defined or default transport\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) goto free_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) p9_debug(P9_DEBUG_MUX, "clnt %p trans %p msize %d protocol %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) clnt, clnt->trans_mod, clnt->msize, clnt->proto_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) err = clnt->trans_mod->create(clnt, dev_name, options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) goto put_trans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) if (clnt->msize > clnt->trans_mod->maxsize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) clnt->msize = clnt->trans_mod->maxsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) if (clnt->msize < 4096) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) p9_debug(P9_DEBUG_ERROR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) "Please specify a msize of at least 4k\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) goto close_trans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) err = p9_client_version(clnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) goto close_trans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) /* P9_HDRSZ + 4 is the smallest packet header we can have that is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) * followed by data accessed from userspace by read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) clnt->fcall_cache =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) kmem_cache_create_usercopy("9p-fcall-cache", clnt->msize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 0, 0, P9_HDRSZ + 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) clnt->msize - (P9_HDRSZ + 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) return clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) close_trans:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) clnt->trans_mod->close(clnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) put_trans:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) v9fs_put_trans(clnt->trans_mod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) free_client:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) kfree(clnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) return ERR_PTR(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) EXPORT_SYMBOL(p9_client_create);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) void p9_client_destroy(struct p9_client *clnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) struct p9_fid *fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) p9_debug(P9_DEBUG_MUX, "clnt %p\n", clnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) if (clnt->trans_mod)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) clnt->trans_mod->close(clnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) v9fs_put_trans(clnt->trans_mod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) idr_for_each_entry(&clnt->fids, fid, id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) pr_info("Found fid %d not clunked\n", fid->fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) p9_fid_destroy(fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) p9_tag_cleanup(clnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) kmem_cache_destroy(clnt->fcall_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) kfree(clnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) EXPORT_SYMBOL(p9_client_destroy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) void p9_client_disconnect(struct p9_client *clnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) p9_debug(P9_DEBUG_9P, "clnt %p\n", clnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) clnt->status = Disconnected;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) EXPORT_SYMBOL(p9_client_disconnect);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) void p9_client_begin_disconnect(struct p9_client *clnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) p9_debug(P9_DEBUG_9P, "clnt %p\n", clnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) clnt->status = BeginDisconnect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) EXPORT_SYMBOL(p9_client_begin_disconnect);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) const char *uname, kuid_t n_uname, const char *aname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) struct p9_req_t *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) struct p9_fid *fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) struct p9_qid qid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) p9_debug(P9_DEBUG_9P, ">>> TATTACH afid %d uname %s aname %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) afid ? afid->fid : -1, uname, aname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) fid = p9_fid_create(clnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) if (!fid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) fid->uid = n_uname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) req = p9_client_rpc(clnt, P9_TATTACH, "ddss?u", fid->fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) afid ? afid->fid : P9_NOFID, uname, aname, n_uname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) if (IS_ERR(req)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) err = PTR_ERR(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) err = p9pdu_readf(&req->rc, clnt->proto_version, "Q", &qid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) trace_9p_protocol_dump(clnt, &req->rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) p9_tag_remove(clnt, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) p9_debug(P9_DEBUG_9P, "<<< RATTACH qid %x.%llx.%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) qid.type, (unsigned long long)qid.path, qid.version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) memmove(&fid->qid, &qid, sizeof(struct p9_qid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) p9_tag_remove(clnt, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) return fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) if (fid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) p9_fid_destroy(fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) return ERR_PTR(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) EXPORT_SYMBOL(p9_client_attach);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) struct p9_fid *p9_client_walk(struct p9_fid *oldfid, uint16_t nwname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) const unsigned char * const *wnames, int clone)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) struct p9_client *clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) struct p9_fid *fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) struct p9_qid *wqids;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) struct p9_req_t *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) uint16_t nwqids, count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) wqids = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) clnt = oldfid->clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) if (clone) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) fid = p9_fid_create(clnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) if (!fid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) fid->uid = oldfid->uid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) fid = oldfid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) p9_debug(P9_DEBUG_9P, ">>> TWALK fids %d,%d nwname %ud wname[0] %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) oldfid->fid, fid->fid, nwname, wnames ? wnames[0] : NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) req = p9_client_rpc(clnt, P9_TWALK, "ddT", oldfid->fid, fid->fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) nwname, wnames);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) if (IS_ERR(req)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) err = PTR_ERR(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) err = p9pdu_readf(&req->rc, clnt->proto_version, "R", &nwqids, &wqids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) trace_9p_protocol_dump(clnt, &req->rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) p9_tag_remove(clnt, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) goto clunk_fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) p9_tag_remove(clnt, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) p9_debug(P9_DEBUG_9P, "<<< RWALK nwqid %d:\n", nwqids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) if (nwqids != nwname) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) err = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) goto clunk_fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) for (count = 0; count < nwqids; count++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) p9_debug(P9_DEBUG_9P, "<<< [%d] %x.%llx.%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) count, wqids[count].type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) (unsigned long long)wqids[count].path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) wqids[count].version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) if (nwname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) memmove(&fid->qid, &wqids[nwqids - 1], sizeof(struct p9_qid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) fid->qid = oldfid->qid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) kfree(wqids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) return fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) clunk_fid:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) kfree(wqids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) p9_client_clunk(fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) fid = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) if (fid && (fid != oldfid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) p9_fid_destroy(fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) return ERR_PTR(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) EXPORT_SYMBOL(p9_client_walk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) int p9_client_open(struct p9_fid *fid, int mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) struct p9_client *clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) struct p9_req_t *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) struct p9_qid qid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) int iounit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) clnt = fid->clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) p9_debug(P9_DEBUG_9P, ">>> %s fid %d mode %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) p9_is_proto_dotl(clnt) ? "TLOPEN" : "TOPEN", fid->fid, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) if (fid->mode != -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) if (p9_is_proto_dotl(clnt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) req = p9_client_rpc(clnt, P9_TLOPEN, "dd", fid->fid, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) req = p9_client_rpc(clnt, P9_TOPEN, "db", fid->fid, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) if (IS_ERR(req)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) err = PTR_ERR(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) err = p9pdu_readf(&req->rc, clnt->proto_version, "Qd", &qid, &iounit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) trace_9p_protocol_dump(clnt, &req->rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) goto free_and_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) p9_debug(P9_DEBUG_9P, "<<< %s qid %x.%llx.%x iounit %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) p9_is_proto_dotl(clnt) ? "RLOPEN" : "ROPEN", qid.type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) (unsigned long long)qid.path, qid.version, iounit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) fid->mode = mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) fid->iounit = iounit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) free_and_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) p9_tag_remove(clnt, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) EXPORT_SYMBOL(p9_client_open);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) int p9_client_create_dotl(struct p9_fid *ofid, const char *name, u32 flags, u32 mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) kgid_t gid, struct p9_qid *qid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) struct p9_client *clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) struct p9_req_t *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) int iounit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) p9_debug(P9_DEBUG_9P,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) ">>> TLCREATE fid %d name %s flags %d mode %d gid %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) ofid->fid, name, flags, mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) from_kgid(&init_user_ns, gid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) clnt = ofid->clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) if (ofid->mode != -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) req = p9_client_rpc(clnt, P9_TLCREATE, "dsddg", ofid->fid, name, flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) mode, gid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) if (IS_ERR(req)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) err = PTR_ERR(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) err = p9pdu_readf(&req->rc, clnt->proto_version, "Qd", qid, &iounit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) trace_9p_protocol_dump(clnt, &req->rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) goto free_and_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) p9_debug(P9_DEBUG_9P, "<<< RLCREATE qid %x.%llx.%x iounit %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) qid->type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) (unsigned long long)qid->path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) qid->version, iounit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) ofid->mode = mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) ofid->iounit = iounit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) free_and_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) p9_tag_remove(clnt, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) EXPORT_SYMBOL(p9_client_create_dotl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) int p9_client_fcreate(struct p9_fid *fid, const char *name, u32 perm, int mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) char *extension)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) struct p9_client *clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) struct p9_req_t *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) struct p9_qid qid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) int iounit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) p9_debug(P9_DEBUG_9P, ">>> TCREATE fid %d name %s perm %d mode %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) fid->fid, name, perm, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) clnt = fid->clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) if (fid->mode != -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) req = p9_client_rpc(clnt, P9_TCREATE, "dsdb?s", fid->fid, name, perm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) mode, extension);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) if (IS_ERR(req)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) err = PTR_ERR(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) err = p9pdu_readf(&req->rc, clnt->proto_version, "Qd", &qid, &iounit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) trace_9p_protocol_dump(clnt, &req->rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) goto free_and_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) p9_debug(P9_DEBUG_9P, "<<< RCREATE qid %x.%llx.%x iounit %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) qid.type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) (unsigned long long)qid.path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) qid.version, iounit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) fid->mode = mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) fid->iounit = iounit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) free_and_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) p9_tag_remove(clnt, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) EXPORT_SYMBOL(p9_client_fcreate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) int p9_client_symlink(struct p9_fid *dfid, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) const char *symtgt, kgid_t gid, struct p9_qid *qid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) struct p9_client *clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) struct p9_req_t *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) p9_debug(P9_DEBUG_9P, ">>> TSYMLINK dfid %d name %s symtgt %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) dfid->fid, name, symtgt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) clnt = dfid->clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) req = p9_client_rpc(clnt, P9_TSYMLINK, "dssg", dfid->fid, name, symtgt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) gid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) if (IS_ERR(req)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) err = PTR_ERR(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) err = p9pdu_readf(&req->rc, clnt->proto_version, "Q", qid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) trace_9p_protocol_dump(clnt, &req->rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) goto free_and_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) p9_debug(P9_DEBUG_9P, "<<< RSYMLINK qid %x.%llx.%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) qid->type, (unsigned long long)qid->path, qid->version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) free_and_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) p9_tag_remove(clnt, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) EXPORT_SYMBOL(p9_client_symlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) int p9_client_link(struct p9_fid *dfid, struct p9_fid *oldfid, const char *newname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) struct p9_client *clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) struct p9_req_t *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) p9_debug(P9_DEBUG_9P, ">>> TLINK dfid %d oldfid %d newname %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) dfid->fid, oldfid->fid, newname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) clnt = dfid->clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) req = p9_client_rpc(clnt, P9_TLINK, "dds", dfid->fid, oldfid->fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) newname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) if (IS_ERR(req))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) return PTR_ERR(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) p9_debug(P9_DEBUG_9P, "<<< RLINK\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) p9_tag_remove(clnt, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) EXPORT_SYMBOL(p9_client_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) int p9_client_fsync(struct p9_fid *fid, int datasync)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) struct p9_client *clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) struct p9_req_t *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) p9_debug(P9_DEBUG_9P, ">>> TFSYNC fid %d datasync:%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) fid->fid, datasync);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) clnt = fid->clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) req = p9_client_rpc(clnt, P9_TFSYNC, "dd", fid->fid, datasync);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) if (IS_ERR(req)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) err = PTR_ERR(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) p9_debug(P9_DEBUG_9P, "<<< RFSYNC fid %d\n", fid->fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) p9_tag_remove(clnt, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) EXPORT_SYMBOL(p9_client_fsync);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) int p9_client_clunk(struct p9_fid *fid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) struct p9_client *clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) struct p9_req_t *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) int retries = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) if (!fid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) pr_warn("%s (%d): Trying to clunk with NULL fid\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) __func__, task_pid_nr(current));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) dump_stack();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) again:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) p9_debug(P9_DEBUG_9P, ">>> TCLUNK fid %d (try %d)\n", fid->fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) retries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) clnt = fid->clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) req = p9_client_rpc(clnt, P9_TCLUNK, "d", fid->fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) if (IS_ERR(req)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) err = PTR_ERR(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) p9_debug(P9_DEBUG_9P, "<<< RCLUNK fid %d\n", fid->fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) p9_tag_remove(clnt, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) * Fid is not valid even after a failed clunk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) * If interrupted, retry once then give up and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) * leak fid until umount.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) if (err == -ERESTARTSYS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) if (retries++ == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) goto again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) p9_fid_destroy(fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) EXPORT_SYMBOL(p9_client_clunk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) int p9_client_remove(struct p9_fid *fid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) struct p9_client *clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) struct p9_req_t *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) p9_debug(P9_DEBUG_9P, ">>> TREMOVE fid %d\n", fid->fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) clnt = fid->clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) req = p9_client_rpc(clnt, P9_TREMOVE, "d", fid->fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) if (IS_ERR(req)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) err = PTR_ERR(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) p9_debug(P9_DEBUG_9P, "<<< RREMOVE fid %d\n", fid->fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) p9_tag_remove(clnt, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) if (err == -ERESTARTSYS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) p9_client_clunk(fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) p9_fid_destroy(fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) EXPORT_SYMBOL(p9_client_remove);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) int p9_client_unlinkat(struct p9_fid *dfid, const char *name, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) struct p9_req_t *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) struct p9_client *clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) p9_debug(P9_DEBUG_9P, ">>> TUNLINKAT fid %d %s %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) dfid->fid, name, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) clnt = dfid->clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) req = p9_client_rpc(clnt, P9_TUNLINKAT, "dsd", dfid->fid, name, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) if (IS_ERR(req)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) err = PTR_ERR(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) p9_debug(P9_DEBUG_9P, "<<< RUNLINKAT fid %d %s\n", dfid->fid, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) p9_tag_remove(clnt, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) EXPORT_SYMBOL(p9_client_unlinkat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) p9_client_read(struct p9_fid *fid, u64 offset, struct iov_iter *to, int *err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) int total = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) *err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) while (iov_iter_count(to)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) count = p9_client_read_once(fid, offset, to, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) if (!count || *err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) offset += count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) total += count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) return total;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) EXPORT_SYMBOL(p9_client_read);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) p9_client_read_once(struct p9_fid *fid, u64 offset, struct iov_iter *to,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) int *err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) struct p9_client *clnt = fid->clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) struct p9_req_t *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) int count = iov_iter_count(to);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) int rsize, non_zc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) char *dataptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) *err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) p9_debug(P9_DEBUG_9P, ">>> TREAD fid %d offset %llu %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) fid->fid, (unsigned long long) offset, (int)iov_iter_count(to));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) rsize = fid->iounit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) if (!rsize || rsize > clnt->msize - P9_IOHDRSZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) rsize = clnt->msize - P9_IOHDRSZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) if (count < rsize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) rsize = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) /* Don't bother zerocopy for small IO (< 1024) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) if (clnt->trans_mod->zc_request && rsize > 1024) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) /* response header len is 11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) * PDU Header(7) + IO Size (4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) req = p9_client_zc_rpc(clnt, P9_TREAD, to, NULL, rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) 0, 11, "dqd", fid->fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) offset, rsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) non_zc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) req = p9_client_rpc(clnt, P9_TREAD, "dqd", fid->fid, offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) rsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) if (IS_ERR(req)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) *err = PTR_ERR(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) *err = p9pdu_readf(&req->rc, clnt->proto_version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) "D", &count, &dataptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) if (*err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) trace_9p_protocol_dump(clnt, &req->rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) p9_tag_remove(clnt, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) if (rsize < count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) pr_err("bogus RREAD count (%d > %d)\n", count, rsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) count = rsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) p9_debug(P9_DEBUG_9P, "<<< RREAD count %d\n", count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) if (non_zc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) int n = copy_to_iter(dataptr, count, to);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) if (n != count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) *err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) p9_tag_remove(clnt, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) return n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) iov_iter_advance(to, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) p9_tag_remove(clnt, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) EXPORT_SYMBOL(p9_client_read_once);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) p9_client_write(struct p9_fid *fid, u64 offset, struct iov_iter *from, int *err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) struct p9_client *clnt = fid->clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) struct p9_req_t *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) int total = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) *err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) p9_debug(P9_DEBUG_9P, ">>> TWRITE fid %d offset %llu count %zd\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) fid->fid, (unsigned long long) offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) iov_iter_count(from));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) while (iov_iter_count(from)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) int count = iov_iter_count(from);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) int rsize = fid->iounit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) if (!rsize || rsize > clnt->msize-P9_IOHDRSZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) rsize = clnt->msize - P9_IOHDRSZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) if (count < rsize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) rsize = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) /* Don't bother zerocopy for small IO (< 1024) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) if (clnt->trans_mod->zc_request && rsize > 1024) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) req = p9_client_zc_rpc(clnt, P9_TWRITE, NULL, from, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) rsize, P9_ZC_HDR_SZ, "dqd",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) fid->fid, offset, rsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) req = p9_client_rpc(clnt, P9_TWRITE, "dqV", fid->fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) offset, rsize, from);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) if (IS_ERR(req)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) *err = PTR_ERR(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) *err = p9pdu_readf(&req->rc, clnt->proto_version, "d", &count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) if (*err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) trace_9p_protocol_dump(clnt, &req->rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) p9_tag_remove(clnt, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) if (rsize < count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) pr_err("bogus RWRITE count (%d > %d)\n", count, rsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) count = rsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) p9_debug(P9_DEBUG_9P, "<<< RWRITE count %d\n", count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) p9_tag_remove(clnt, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) iov_iter_advance(from, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) total += count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) offset += count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) return total;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) EXPORT_SYMBOL(p9_client_write);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) struct p9_wstat *p9_client_stat(struct p9_fid *fid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) struct p9_client *clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) struct p9_wstat *ret = kmalloc(sizeof(struct p9_wstat), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) struct p9_req_t *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) u16 ignored;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) p9_debug(P9_DEBUG_9P, ">>> TSTAT fid %d\n", fid->fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) clnt = fid->clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) req = p9_client_rpc(clnt, P9_TSTAT, "d", fid->fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) if (IS_ERR(req)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) err = PTR_ERR(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) err = p9pdu_readf(&req->rc, clnt->proto_version, "wS", &ignored, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) trace_9p_protocol_dump(clnt, &req->rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) p9_tag_remove(clnt, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) p9_debug(P9_DEBUG_9P,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) "<<< RSTAT sz=%x type=%x dev=%x qid=%x.%llx.%x\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) "<<< mode=%8.8x atime=%8.8x mtime=%8.8x length=%llx\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) "<<< name=%s uid=%s gid=%s muid=%s extension=(%s)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) "<<< uid=%d gid=%d n_muid=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) ret->size, ret->type, ret->dev, ret->qid.type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) (unsigned long long)ret->qid.path, ret->qid.version, ret->mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) ret->atime, ret->mtime, (unsigned long long)ret->length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) ret->name, ret->uid, ret->gid, ret->muid, ret->extension,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) from_kuid(&init_user_ns, ret->n_uid),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) from_kgid(&init_user_ns, ret->n_gid),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) from_kuid(&init_user_ns, ret->n_muid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) p9_tag_remove(clnt, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) kfree(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) return ERR_PTR(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) EXPORT_SYMBOL(p9_client_stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) struct p9_stat_dotl *p9_client_getattr_dotl(struct p9_fid *fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) u64 request_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) struct p9_client *clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) struct p9_stat_dotl *ret = kmalloc(sizeof(struct p9_stat_dotl),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) struct p9_req_t *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) p9_debug(P9_DEBUG_9P, ">>> TGETATTR fid %d, request_mask %lld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) fid->fid, request_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) clnt = fid->clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) req = p9_client_rpc(clnt, P9_TGETATTR, "dq", fid->fid, request_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) if (IS_ERR(req)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) err = PTR_ERR(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) err = p9pdu_readf(&req->rc, clnt->proto_version, "A", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) trace_9p_protocol_dump(clnt, &req->rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) p9_tag_remove(clnt, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) p9_debug(P9_DEBUG_9P,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) "<<< RGETATTR st_result_mask=%lld\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) "<<< qid=%x.%llx.%x\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) "<<< st_mode=%8.8x st_nlink=%llu\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) "<<< st_uid=%d st_gid=%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) "<<< st_rdev=%llx st_size=%llx st_blksize=%llu st_blocks=%llu\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) "<<< st_atime_sec=%lld st_atime_nsec=%lld\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) "<<< st_mtime_sec=%lld st_mtime_nsec=%lld\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) "<<< st_ctime_sec=%lld st_ctime_nsec=%lld\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) "<<< st_btime_sec=%lld st_btime_nsec=%lld\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) "<<< st_gen=%lld st_data_version=%lld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) ret->st_result_mask, ret->qid.type, ret->qid.path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) ret->qid.version, ret->st_mode, ret->st_nlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) from_kuid(&init_user_ns, ret->st_uid),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) from_kgid(&init_user_ns, ret->st_gid),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) ret->st_rdev, ret->st_size, ret->st_blksize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) ret->st_blocks, ret->st_atime_sec, ret->st_atime_nsec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) ret->st_mtime_sec, ret->st_mtime_nsec, ret->st_ctime_sec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) ret->st_ctime_nsec, ret->st_btime_sec, ret->st_btime_nsec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) ret->st_gen, ret->st_data_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) p9_tag_remove(clnt, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) kfree(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) return ERR_PTR(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) EXPORT_SYMBOL(p9_client_getattr_dotl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) static int p9_client_statsize(struct p9_wstat *wst, int proto_version)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) /* NOTE: size shouldn't include its own length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) /* size[2] type[2] dev[4] qid[13] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) /* mode[4] atime[4] mtime[4] length[8]*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) /* name[s] uid[s] gid[s] muid[s] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) ret = 2+4+13+4+4+4+8+2+2+2+2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) if (wst->name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) ret += strlen(wst->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) if (wst->uid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) ret += strlen(wst->uid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) if (wst->gid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) ret += strlen(wst->gid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) if (wst->muid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) ret += strlen(wst->muid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) if ((proto_version == p9_proto_2000u) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) (proto_version == p9_proto_2000L)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) ret += 2+4+4+4; /* extension[s] n_uid[4] n_gid[4] n_muid[4] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) if (wst->extension)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) ret += strlen(wst->extension);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) int p9_client_wstat(struct p9_fid *fid, struct p9_wstat *wst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) struct p9_req_t *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) struct p9_client *clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) clnt = fid->clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) wst->size = p9_client_statsize(wst, clnt->proto_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) p9_debug(P9_DEBUG_9P, ">>> TWSTAT fid %d\n", fid->fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) p9_debug(P9_DEBUG_9P,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) " sz=%x type=%x dev=%x qid=%x.%llx.%x\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) " mode=%8.8x atime=%8.8x mtime=%8.8x length=%llx\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) " name=%s uid=%s gid=%s muid=%s extension=(%s)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) " uid=%d gid=%d n_muid=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) wst->size, wst->type, wst->dev, wst->qid.type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) (unsigned long long)wst->qid.path, wst->qid.version, wst->mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) wst->atime, wst->mtime, (unsigned long long)wst->length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) wst->name, wst->uid, wst->gid, wst->muid, wst->extension,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) from_kuid(&init_user_ns, wst->n_uid),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) from_kgid(&init_user_ns, wst->n_gid),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) from_kuid(&init_user_ns, wst->n_muid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) req = p9_client_rpc(clnt, P9_TWSTAT, "dwS", fid->fid, wst->size+2, wst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) if (IS_ERR(req)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) err = PTR_ERR(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) p9_debug(P9_DEBUG_9P, "<<< RWSTAT fid %d\n", fid->fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) p9_tag_remove(clnt, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) EXPORT_SYMBOL(p9_client_wstat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) int p9_client_setattr(struct p9_fid *fid, struct p9_iattr_dotl *p9attr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) struct p9_req_t *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) struct p9_client *clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) clnt = fid->clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) p9_debug(P9_DEBUG_9P, ">>> TSETATTR fid %d\n", fid->fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) p9_debug(P9_DEBUG_9P,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) " valid=%x mode=%x uid=%d gid=%d size=%lld\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) " atime_sec=%lld atime_nsec=%lld\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) " mtime_sec=%lld mtime_nsec=%lld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) p9attr->valid, p9attr->mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) from_kuid(&init_user_ns, p9attr->uid),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) from_kgid(&init_user_ns, p9attr->gid),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) p9attr->size, p9attr->atime_sec, p9attr->atime_nsec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) p9attr->mtime_sec, p9attr->mtime_nsec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) req = p9_client_rpc(clnt, P9_TSETATTR, "dI", fid->fid, p9attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) if (IS_ERR(req)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) err = PTR_ERR(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) p9_debug(P9_DEBUG_9P, "<<< RSETATTR fid %d\n", fid->fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) p9_tag_remove(clnt, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) EXPORT_SYMBOL(p9_client_setattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) int p9_client_statfs(struct p9_fid *fid, struct p9_rstatfs *sb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) struct p9_req_t *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) struct p9_client *clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) clnt = fid->clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) p9_debug(P9_DEBUG_9P, ">>> TSTATFS fid %d\n", fid->fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) req = p9_client_rpc(clnt, P9_TSTATFS, "d", fid->fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) if (IS_ERR(req)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) err = PTR_ERR(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) err = p9pdu_readf(&req->rc, clnt->proto_version, "ddqqqqqqd", &sb->type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) &sb->bsize, &sb->blocks, &sb->bfree, &sb->bavail,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) &sb->files, &sb->ffree, &sb->fsid, &sb->namelen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) trace_9p_protocol_dump(clnt, &req->rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) p9_tag_remove(clnt, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) p9_debug(P9_DEBUG_9P, "<<< RSTATFS fid %d type 0x%lx bsize %ld "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) "blocks %llu bfree %llu bavail %llu files %llu ffree %llu "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) "fsid %llu namelen %ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) fid->fid, (long unsigned int)sb->type, (long int)sb->bsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) sb->blocks, sb->bfree, sb->bavail, sb->files, sb->ffree,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) sb->fsid, (long int)sb->namelen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) p9_tag_remove(clnt, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) EXPORT_SYMBOL(p9_client_statfs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) int p9_client_rename(struct p9_fid *fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) struct p9_fid *newdirfid, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) struct p9_req_t *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) struct p9_client *clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) clnt = fid->clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) p9_debug(P9_DEBUG_9P, ">>> TRENAME fid %d newdirfid %d name %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) fid->fid, newdirfid->fid, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) req = p9_client_rpc(clnt, P9_TRENAME, "dds", fid->fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) newdirfid->fid, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) if (IS_ERR(req)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) err = PTR_ERR(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) p9_debug(P9_DEBUG_9P, "<<< RRENAME fid %d\n", fid->fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) p9_tag_remove(clnt, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) EXPORT_SYMBOL(p9_client_rename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) int p9_client_renameat(struct p9_fid *olddirfid, const char *old_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) struct p9_fid *newdirfid, const char *new_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) struct p9_req_t *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) struct p9_client *clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) clnt = olddirfid->clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) p9_debug(P9_DEBUG_9P, ">>> TRENAMEAT olddirfid %d old name %s"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) " newdirfid %d new name %s\n", olddirfid->fid, old_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) newdirfid->fid, new_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) req = p9_client_rpc(clnt, P9_TRENAMEAT, "dsds", olddirfid->fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) old_name, newdirfid->fid, new_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) if (IS_ERR(req)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) err = PTR_ERR(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) p9_debug(P9_DEBUG_9P, "<<< RRENAMEAT newdirfid %d new name %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) newdirfid->fid, new_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) p9_tag_remove(clnt, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) EXPORT_SYMBOL(p9_client_renameat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) * An xattrwalk without @attr_name gives the fid for the lisxattr namespace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) struct p9_fid *p9_client_xattrwalk(struct p9_fid *file_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) const char *attr_name, u64 *attr_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) struct p9_req_t *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) struct p9_client *clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) struct p9_fid *attr_fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) clnt = file_fid->clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) attr_fid = p9_fid_create(clnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) if (!attr_fid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) p9_debug(P9_DEBUG_9P,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) ">>> TXATTRWALK file_fid %d, attr_fid %d name %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) file_fid->fid, attr_fid->fid, attr_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) req = p9_client_rpc(clnt, P9_TXATTRWALK, "dds",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) file_fid->fid, attr_fid->fid, attr_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) if (IS_ERR(req)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) err = PTR_ERR(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) err = p9pdu_readf(&req->rc, clnt->proto_version, "q", attr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) trace_9p_protocol_dump(clnt, &req->rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) p9_tag_remove(clnt, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) goto clunk_fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) p9_tag_remove(clnt, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) p9_debug(P9_DEBUG_9P, "<<< RXATTRWALK fid %d size %llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) attr_fid->fid, *attr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) return attr_fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) clunk_fid:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) p9_client_clunk(attr_fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) attr_fid = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) if (attr_fid && (attr_fid != file_fid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) p9_fid_destroy(attr_fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) return ERR_PTR(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) EXPORT_SYMBOL_GPL(p9_client_xattrwalk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) int p9_client_xattrcreate(struct p9_fid *fid, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) u64 attr_size, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) struct p9_req_t *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) struct p9_client *clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) p9_debug(P9_DEBUG_9P,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) ">>> TXATTRCREATE fid %d name %s size %lld flag %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) fid->fid, name, (long long)attr_size, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) clnt = fid->clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) req = p9_client_rpc(clnt, P9_TXATTRCREATE, "dsqd",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) fid->fid, name, attr_size, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) if (IS_ERR(req)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) err = PTR_ERR(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) p9_debug(P9_DEBUG_9P, "<<< RXATTRCREATE fid %d\n", fid->fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) p9_tag_remove(clnt, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) EXPORT_SYMBOL_GPL(p9_client_xattrcreate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) int err, rsize, non_zc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) struct p9_client *clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) struct p9_req_t *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) char *dataptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) struct kvec kv = {.iov_base = data, .iov_len = count};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) struct iov_iter to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) iov_iter_kvec(&to, READ, &kv, 1, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) p9_debug(P9_DEBUG_9P, ">>> TREADDIR fid %d offset %llu count %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) fid->fid, (unsigned long long) offset, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) clnt = fid->clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) rsize = fid->iounit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) if (!rsize || rsize > clnt->msize-P9_READDIRHDRSZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) rsize = clnt->msize - P9_READDIRHDRSZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) if (count < rsize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) rsize = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) /* Don't bother zerocopy for small IO (< 1024) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) if (clnt->trans_mod->zc_request && rsize > 1024) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) * response header len is 11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) * PDU Header(7) + IO Size (4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) req = p9_client_zc_rpc(clnt, P9_TREADDIR, &to, NULL, rsize, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) 11, "dqd", fid->fid, offset, rsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) non_zc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) req = p9_client_rpc(clnt, P9_TREADDIR, "dqd", fid->fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) offset, rsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) if (IS_ERR(req)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) err = PTR_ERR(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) err = p9pdu_readf(&req->rc, clnt->proto_version, "D", &count, &dataptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) trace_9p_protocol_dump(clnt, &req->rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) goto free_and_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) if (rsize < count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) pr_err("bogus RREADDIR count (%d > %d)\n", count, rsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) count = rsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) p9_debug(P9_DEBUG_9P, "<<< RREADDIR count %d\n", count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) if (non_zc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) memmove(data, dataptr, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) p9_tag_remove(clnt, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) free_and_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) p9_tag_remove(clnt, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) EXPORT_SYMBOL(p9_client_readdir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) int p9_client_mknod_dotl(struct p9_fid *fid, const char *name, int mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) dev_t rdev, kgid_t gid, struct p9_qid *qid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) struct p9_client *clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) struct p9_req_t *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) clnt = fid->clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) p9_debug(P9_DEBUG_9P, ">>> TMKNOD fid %d name %s mode %d major %d "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) "minor %d\n", fid->fid, name, mode, MAJOR(rdev), MINOR(rdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) req = p9_client_rpc(clnt, P9_TMKNOD, "dsdddg", fid->fid, name, mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) MAJOR(rdev), MINOR(rdev), gid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) if (IS_ERR(req))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) return PTR_ERR(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) err = p9pdu_readf(&req->rc, clnt->proto_version, "Q", qid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) trace_9p_protocol_dump(clnt, &req->rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) p9_debug(P9_DEBUG_9P, "<<< RMKNOD qid %x.%llx.%x\n", qid->type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) (unsigned long long)qid->path, qid->version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) p9_tag_remove(clnt, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) EXPORT_SYMBOL(p9_client_mknod_dotl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) int p9_client_mkdir_dotl(struct p9_fid *fid, const char *name, int mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) kgid_t gid, struct p9_qid *qid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) struct p9_client *clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) struct p9_req_t *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) clnt = fid->clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) p9_debug(P9_DEBUG_9P, ">>> TMKDIR fid %d name %s mode %d gid %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) fid->fid, name, mode, from_kgid(&init_user_ns, gid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) req = p9_client_rpc(clnt, P9_TMKDIR, "dsdg", fid->fid, name, mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) gid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) if (IS_ERR(req))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) return PTR_ERR(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) err = p9pdu_readf(&req->rc, clnt->proto_version, "Q", qid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) trace_9p_protocol_dump(clnt, &req->rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) p9_debug(P9_DEBUG_9P, "<<< RMKDIR qid %x.%llx.%x\n", qid->type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) (unsigned long long)qid->path, qid->version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) p9_tag_remove(clnt, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) EXPORT_SYMBOL(p9_client_mkdir_dotl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) int p9_client_lock_dotl(struct p9_fid *fid, struct p9_flock *flock, u8 *status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) struct p9_client *clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) struct p9_req_t *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) clnt = fid->clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) p9_debug(P9_DEBUG_9P, ">>> TLOCK fid %d type %i flags %d "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) "start %lld length %lld proc_id %d client_id %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) fid->fid, flock->type, flock->flags, flock->start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) flock->length, flock->proc_id, flock->client_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) req = p9_client_rpc(clnt, P9_TLOCK, "dbdqqds", fid->fid, flock->type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) flock->flags, flock->start, flock->length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) flock->proc_id, flock->client_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) if (IS_ERR(req))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) return PTR_ERR(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) err = p9pdu_readf(&req->rc, clnt->proto_version, "b", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) trace_9p_protocol_dump(clnt, &req->rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) p9_debug(P9_DEBUG_9P, "<<< RLOCK status %i\n", *status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) p9_tag_remove(clnt, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) EXPORT_SYMBOL(p9_client_lock_dotl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) int p9_client_getlock_dotl(struct p9_fid *fid, struct p9_getlock *glock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) struct p9_client *clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) struct p9_req_t *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) clnt = fid->clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) p9_debug(P9_DEBUG_9P, ">>> TGETLOCK fid %d, type %i start %lld "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) "length %lld proc_id %d client_id %s\n", fid->fid, glock->type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) glock->start, glock->length, glock->proc_id, glock->client_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) req = p9_client_rpc(clnt, P9_TGETLOCK, "dbqqds", fid->fid, glock->type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) glock->start, glock->length, glock->proc_id, glock->client_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) if (IS_ERR(req))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) return PTR_ERR(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) err = p9pdu_readf(&req->rc, clnt->proto_version, "bqqds", &glock->type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) &glock->start, &glock->length, &glock->proc_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) &glock->client_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) trace_9p_protocol_dump(clnt, &req->rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) p9_debug(P9_DEBUG_9P, "<<< RGETLOCK type %i start %lld length %lld "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) "proc_id %d client_id %s\n", glock->type, glock->start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) glock->length, glock->proc_id, glock->client_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) p9_tag_remove(clnt, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) EXPORT_SYMBOL(p9_client_getlock_dotl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) int p9_client_readlink(struct p9_fid *fid, char **target)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) struct p9_client *clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) struct p9_req_t *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) clnt = fid->clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) p9_debug(P9_DEBUG_9P, ">>> TREADLINK fid %d\n", fid->fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) req = p9_client_rpc(clnt, P9_TREADLINK, "d", fid->fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) if (IS_ERR(req))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) return PTR_ERR(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) err = p9pdu_readf(&req->rc, clnt->proto_version, "s", target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) trace_9p_protocol_dump(clnt, &req->rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) p9_debug(P9_DEBUG_9P, "<<< RREADLINK target %s\n", *target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) p9_tag_remove(clnt, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) EXPORT_SYMBOL(p9_client_readlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) int __init p9_client_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) p9_req_cache = KMEM_CACHE(p9_req_t, SLAB_TYPESAFE_BY_RCU);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) return p9_req_cache ? 0 : -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) void __exit p9_client_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) kmem_cache_destroy(p9_req_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) }