^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) * linux/fs/9p/trans_fd.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Fd transport layer. Includes deprecated socket layer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (C) 2006 by Russ Cox <rsc@swtch.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (C) 2004-2005 by Latchesar Ionkov <lucho@ionkov.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Copyright (C) 2004-2008 by Eric Van Hensbergen <ericvh@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Copyright (C) 1997-2002 by Ron Minnich <rminnich@sarnoff.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/in.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/net.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/ipv6.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/kthread.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/un.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/inet.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/idr.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/parser.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <net/9p/9p.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <net/9p/client.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <net/9p/transport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/syscalls.h> /* killme */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define P9_PORT 564
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define MAX_SOCK_BUF (64*1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define MAXPOLLWADDR 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) static struct p9_trans_module p9_tcp_trans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) static struct p9_trans_module p9_fd_trans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * struct p9_fd_opts - per-transport options
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * @rfd: file descriptor for reading (trans=fd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * @wfd: file descriptor for writing (trans=fd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * @port: port to connect to (trans=tcp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) struct p9_fd_opts {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) int rfd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) int wfd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) u16 port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) bool privport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * Option Parsing (code inspired by NFS code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * - a little lazy - parse all fd-transport options
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) /* Options that take integer arguments */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) Opt_port, Opt_rfdno, Opt_wfdno, Opt_err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) /* Options that take no arguments */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) Opt_privport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) static const match_table_t tokens = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) {Opt_port, "port=%u"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) {Opt_rfdno, "rfdno=%u"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) {Opt_wfdno, "wfdno=%u"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) {Opt_privport, "privport"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) {Opt_err, NULL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) Rworksched = 1, /* read work scheduled or running */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) Rpending = 2, /* can read */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) Wworksched = 4, /* write work scheduled or running */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) Wpending = 8, /* can write */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) struct p9_poll_wait {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) struct p9_conn *conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) wait_queue_entry_t wait;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) wait_queue_head_t *wait_addr;
^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) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * struct p9_conn - fd mux connection state information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * @mux_list: list link for mux to manage multiple connections (?)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * @client: reference to client instance for this connection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * @err: error state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * @req_list: accounting for requests which have been sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * @unsent_req_list: accounting for requests that haven't been sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * @req: current request being processed (if any)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * @tmp_buf: temporary buffer to read in header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * @rc: temporary fcall for reading current frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * @wpos: write position for current frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * @wsize: amount of data to write for current frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * @wbuf: current write buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * @poll_pending_link: pending links to be polled per conn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * @poll_wait: array of wait_q's for various worker threads
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * @pt: poll state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * @rq: current read work
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * @wq: current write work
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * @wsched: ????
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) struct p9_conn {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) struct list_head mux_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) struct p9_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct list_head req_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) struct list_head unsent_req_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) struct p9_req_t *rreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) struct p9_req_t *wreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) char tmp_buf[7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct p9_fcall rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) int wpos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) int wsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) char *wbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) struct list_head poll_pending_link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) struct p9_poll_wait poll_wait[MAXPOLLWADDR];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) poll_table pt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) struct work_struct rq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) struct work_struct wq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) unsigned long wsched;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * struct p9_trans_fd - transport state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * @rd: reference to file to read from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * @wr: reference of file to write to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * @conn: connection state reference
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) struct p9_trans_fd {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) struct file *rd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) struct file *wr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) struct p9_conn conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) static void p9_poll_workfn(struct work_struct *work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) static DEFINE_SPINLOCK(p9_poll_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) static LIST_HEAD(p9_poll_pending_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) static DECLARE_WORK(p9_poll_work, p9_poll_workfn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) static unsigned int p9_ipport_resv_min = P9_DEF_MIN_RESVPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) static unsigned int p9_ipport_resv_max = P9_DEF_MAX_RESVPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) static void p9_mux_poll_stop(struct p9_conn *m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) for (i = 0; i < ARRAY_SIZE(m->poll_wait); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) struct p9_poll_wait *pwait = &m->poll_wait[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) if (pwait->wait_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) remove_wait_queue(pwait->wait_addr, &pwait->wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) pwait->wait_addr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) spin_lock_irqsave(&p9_poll_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) list_del_init(&m->poll_pending_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) spin_unlock_irqrestore(&p9_poll_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) flush_work(&p9_poll_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) * p9_conn_cancel - cancel all pending requests with error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) * @m: mux data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) * @err: error code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) static void p9_conn_cancel(struct p9_conn *m, int err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) struct p9_req_t *req, *rtmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) LIST_HEAD(cancel_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) p9_debug(P9_DEBUG_ERROR, "mux %p err %d\n", m, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) spin_lock(&m->client->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) if (m->err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) spin_unlock(&m->client->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) m->err = err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) list_for_each_entry_safe(req, rtmp, &m->req_list, req_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) list_move(&req->req_list, &cancel_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) list_for_each_entry_safe(req, rtmp, &m->unsent_req_list, req_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) list_move(&req->req_list, &cancel_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) list_for_each_entry_safe(req, rtmp, &cancel_list, req_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) p9_debug(P9_DEBUG_ERROR, "call back req %p\n", req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) list_del(&req->req_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if (!req->t_err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) req->t_err = err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) p9_client_cb(m->client, req, REQ_STATUS_ERROR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) spin_unlock(&m->client->lock);
^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) static __poll_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) p9_fd_poll(struct p9_client *client, struct poll_table_struct *pt, int *err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) __poll_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) struct p9_trans_fd *ts = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if (client && client->status == Connected)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) ts = client->trans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) if (!ts) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) *err = -EREMOTEIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) return EPOLLERR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) ret = vfs_poll(ts->rd, pt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) if (ts->rd != ts->wr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) ret = (ret & ~EPOLLOUT) | (vfs_poll(ts->wr, pt) & ~EPOLLIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) * p9_fd_read- read from a fd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) * @client: client instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) * @v: buffer to receive data into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) * @len: size of receive buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) static int p9_fd_read(struct p9_client *client, void *v, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) struct p9_trans_fd *ts = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) loff_t pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) if (client && client->status != Disconnected)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) ts = client->trans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) if (!ts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) return -EREMOTEIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) if (!(ts->rd->f_flags & O_NONBLOCK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) p9_debug(P9_DEBUG_ERROR, "blocking read ...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) pos = ts->rd->f_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) ret = kernel_read(ts->rd, v, len, &pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) if (ret <= 0 && ret != -ERESTARTSYS && ret != -EAGAIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) client->status = Disconnected;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) * p9_read_work - called when there is some data to be read from a transport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) * @work: container of work to be done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) static void p9_read_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) __poll_t n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) struct p9_conn *m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) m = container_of(work, struct p9_conn, rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) if (m->err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) p9_debug(P9_DEBUG_TRANS, "start mux %p pos %zd\n", m, m->rc.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if (!m->rc.sdata) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) m->rc.sdata = m->tmp_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) m->rc.offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) m->rc.capacity = 7; /* start by reading header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) clear_bit(Rpending, &m->wsched);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) p9_debug(P9_DEBUG_TRANS, "read mux %p pos %zd size: %zd = %zd\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) m, m->rc.offset, m->rc.capacity,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) m->rc.capacity - m->rc.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) err = p9_fd_read(m->client, m->rc.sdata + m->rc.offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) m->rc.capacity - m->rc.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) p9_debug(P9_DEBUG_TRANS, "mux %p got %d bytes\n", m, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) if (err == -EAGAIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) goto end_clear;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) if (err <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) m->rc.offset += err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) /* header read in */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) if ((!m->rreq) && (m->rc.offset == m->rc.capacity)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) p9_debug(P9_DEBUG_TRANS, "got new header\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) /* Header size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) m->rc.size = 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) err = p9_parse_header(&m->rc, &m->rc.size, NULL, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) p9_debug(P9_DEBUG_ERROR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) "error parsing header: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) if (m->rc.size >= m->client->msize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) p9_debug(P9_DEBUG_ERROR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) "requested packet size too big: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) m->rc.size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) p9_debug(P9_DEBUG_TRANS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) "mux %p pkt: size: %d bytes tag: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) m, m->rc.size, m->rc.tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) m->rreq = p9_tag_lookup(m->client, m->rc.tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) if (!m->rreq || (m->rreq->status != REQ_STATUS_SENT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) p9_debug(P9_DEBUG_ERROR, "Unexpected packet tag %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) m->rc.tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) if (!m->rreq->rc.sdata) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) p9_debug(P9_DEBUG_ERROR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) "No recv fcall for tag %d (req %p), disconnecting!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) m->rc.tag, m->rreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) m->rreq = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) m->rc.sdata = m->rreq->rc.sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) memcpy(m->rc.sdata, m->tmp_buf, m->rc.capacity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) m->rc.capacity = m->rc.size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) /* packet is read in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) * not an else because some packets (like clunk) have no payload
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) if ((m->rreq) && (m->rc.offset == m->rc.capacity)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) p9_debug(P9_DEBUG_TRANS, "got new packet\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) m->rreq->rc.size = m->rc.offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) spin_lock(&m->client->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) if (m->rreq->status == REQ_STATUS_SENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) list_del(&m->rreq->req_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) p9_client_cb(m->client, m->rreq, REQ_STATUS_RCVD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) } else if (m->rreq->status == REQ_STATUS_FLSHD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) /* Ignore replies associated with a cancelled request. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) p9_debug(P9_DEBUG_TRANS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) "Ignore replies associated with a cancelled request\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) spin_unlock(&m->client->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) p9_debug(P9_DEBUG_ERROR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) "Request tag %d errored out while we were reading the reply\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) m->rc.tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) spin_unlock(&m->client->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) m->rc.sdata = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) m->rc.offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) m->rc.capacity = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) p9_req_put(m->rreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) m->rreq = NULL;
^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) end_clear:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) clear_bit(Rworksched, &m->wsched);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) if (!list_empty(&m->req_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) if (test_and_clear_bit(Rpending, &m->wsched))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) n = EPOLLIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) n = p9_fd_poll(m->client, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) if ((n & EPOLLIN) && !test_and_set_bit(Rworksched, &m->wsched)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) p9_debug(P9_DEBUG_TRANS, "sched read work %p\n", m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) schedule_work(&m->rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) p9_conn_cancel(m, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) clear_bit(Rworksched, &m->wsched);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) * p9_fd_write - write to a socket
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) * @client: client instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) * @v: buffer to send data from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) * @len: size of send buffer
^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) static int p9_fd_write(struct p9_client *client, void *v, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) struct p9_trans_fd *ts = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (client && client->status != Disconnected)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) ts = client->trans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) if (!ts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) return -EREMOTEIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) if (!(ts->wr->f_flags & O_NONBLOCK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) p9_debug(P9_DEBUG_ERROR, "blocking write ...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) ret = kernel_write(ts->wr, v, len, &ts->wr->f_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) if (ret <= 0 && ret != -ERESTARTSYS && ret != -EAGAIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) client->status = Disconnected;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) * p9_write_work - called when a transport can send some data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) * @work: container for work to be done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) static void p9_write_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) __poll_t n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) struct p9_conn *m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) struct p9_req_t *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) m = container_of(work, struct p9_conn, wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) if (m->err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) clear_bit(Wworksched, &m->wsched);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) if (!m->wsize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) spin_lock(&m->client->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) if (list_empty(&m->unsent_req_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) clear_bit(Wworksched, &m->wsched);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) spin_unlock(&m->client->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) req = list_entry(m->unsent_req_list.next, struct p9_req_t,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) req_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) req->status = REQ_STATUS_SENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) p9_debug(P9_DEBUG_TRANS, "move req %p\n", req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) list_move_tail(&req->req_list, &m->req_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) m->wbuf = req->tc.sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) m->wsize = req->tc.size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) m->wpos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) p9_req_get(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) m->wreq = req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) spin_unlock(&m->client->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) p9_debug(P9_DEBUG_TRANS, "mux %p pos %d size %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) m, m->wpos, m->wsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) clear_bit(Wpending, &m->wsched);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) err = p9_fd_write(m->client, m->wbuf + m->wpos, m->wsize - m->wpos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) p9_debug(P9_DEBUG_TRANS, "mux %p sent %d bytes\n", m, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) if (err == -EAGAIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) goto end_clear;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) else if (err == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) err = -EREMOTEIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) m->wpos += err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) if (m->wpos == m->wsize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) m->wpos = m->wsize = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) p9_req_put(m->wreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) m->wreq = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) end_clear:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) clear_bit(Wworksched, &m->wsched);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) if (m->wsize || !list_empty(&m->unsent_req_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) if (test_and_clear_bit(Wpending, &m->wsched))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) n = EPOLLOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) n = p9_fd_poll(m->client, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) if ((n & EPOLLOUT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) !test_and_set_bit(Wworksched, &m->wsched)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) p9_debug(P9_DEBUG_TRANS, "sched write work %p\n", m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) schedule_work(&m->wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) p9_conn_cancel(m, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) clear_bit(Wworksched, &m->wsched);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) static int p9_pollwake(wait_queue_entry_t *wait, unsigned int mode, int sync, void *key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) struct p9_poll_wait *pwait =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) container_of(wait, struct p9_poll_wait, wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) struct p9_conn *m = pwait->conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) spin_lock_irqsave(&p9_poll_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) if (list_empty(&m->poll_pending_link))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) list_add_tail(&m->poll_pending_link, &p9_poll_pending_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) spin_unlock_irqrestore(&p9_poll_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) schedule_work(&p9_poll_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) * p9_pollwait - add poll task to the wait queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) * @filp: file pointer being polled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) * @wait_address: wait_q to block on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) * @p: poll state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) * called by files poll operation to add v9fs-poll task to files wait queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) p9_pollwait(struct file *filp, wait_queue_head_t *wait_address, poll_table *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) struct p9_conn *m = container_of(p, struct p9_conn, pt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) struct p9_poll_wait *pwait = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) for (i = 0; i < ARRAY_SIZE(m->poll_wait); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) if (m->poll_wait[i].wait_addr == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) pwait = &m->poll_wait[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) if (!pwait) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) p9_debug(P9_DEBUG_ERROR, "not enough wait_address slots\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) pwait->conn = m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) pwait->wait_addr = wait_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) init_waitqueue_func_entry(&pwait->wait, p9_pollwake);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) add_wait_queue(wait_address, &pwait->wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) * p9_conn_create - initialize the per-session mux data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) * @client: client instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) * Note: Creates the polling task if this is the first session.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) static void p9_conn_create(struct p9_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) __poll_t n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) struct p9_trans_fd *ts = client->trans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) struct p9_conn *m = &ts->conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) p9_debug(P9_DEBUG_TRANS, "client %p msize %d\n", client, client->msize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) INIT_LIST_HEAD(&m->mux_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) m->client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) INIT_LIST_HEAD(&m->req_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) INIT_LIST_HEAD(&m->unsent_req_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) INIT_WORK(&m->rq, p9_read_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) INIT_WORK(&m->wq, p9_write_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) INIT_LIST_HEAD(&m->poll_pending_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) init_poll_funcptr(&m->pt, p9_pollwait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) n = p9_fd_poll(client, &m->pt, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) if (n & EPOLLIN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) p9_debug(P9_DEBUG_TRANS, "mux %p can read\n", m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) set_bit(Rpending, &m->wsched);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) if (n & EPOLLOUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) p9_debug(P9_DEBUG_TRANS, "mux %p can write\n", m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) set_bit(Wpending, &m->wsched);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) * p9_poll_mux - polls a mux and schedules read or write works if necessary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) * @m: connection to poll
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) static void p9_poll_mux(struct p9_conn *m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) __poll_t n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) int err = -ECONNRESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) if (m->err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) n = p9_fd_poll(m->client, NULL, &err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) if (n & (EPOLLERR | EPOLLHUP | EPOLLNVAL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) p9_debug(P9_DEBUG_TRANS, "error mux %p err %d\n", m, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) p9_conn_cancel(m, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) if (n & EPOLLIN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) set_bit(Rpending, &m->wsched);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) p9_debug(P9_DEBUG_TRANS, "mux %p can read\n", m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) if (!test_and_set_bit(Rworksched, &m->wsched)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) p9_debug(P9_DEBUG_TRANS, "sched read work %p\n", m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) schedule_work(&m->rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) if (n & EPOLLOUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) set_bit(Wpending, &m->wsched);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) p9_debug(P9_DEBUG_TRANS, "mux %p can write\n", m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) if ((m->wsize || !list_empty(&m->unsent_req_list)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) !test_and_set_bit(Wworksched, &m->wsched)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) p9_debug(P9_DEBUG_TRANS, "sched write work %p\n", m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) schedule_work(&m->wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) * p9_fd_request - send 9P request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) * The function can sleep until the request is scheduled for sending.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) * The function can be interrupted. Return from the function is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) * a guarantee that the request is sent successfully.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) * @client: client instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) * @req: request to be sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) static int p9_fd_request(struct p9_client *client, struct p9_req_t *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) __poll_t n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) struct p9_trans_fd *ts = client->trans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) struct p9_conn *m = &ts->conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) p9_debug(P9_DEBUG_TRANS, "mux %p task %p tcall %p id %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) m, current, &req->tc, req->tc.id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) if (m->err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) return m->err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) spin_lock(&client->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) req->status = REQ_STATUS_UNSENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) list_add_tail(&req->req_list, &m->unsent_req_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) spin_unlock(&client->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) if (test_and_clear_bit(Wpending, &m->wsched))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) n = EPOLLOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) n = p9_fd_poll(m->client, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) if (n & EPOLLOUT && !test_and_set_bit(Wworksched, &m->wsched))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) schedule_work(&m->wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) static int p9_fd_cancel(struct p9_client *client, struct p9_req_t *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) int ret = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) p9_debug(P9_DEBUG_TRANS, "client %p req %p\n", client, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) spin_lock(&client->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) if (req->status == REQ_STATUS_UNSENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) list_del(&req->req_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) req->status = REQ_STATUS_FLSHD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) p9_req_put(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) spin_unlock(&client->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) static int p9_fd_cancelled(struct p9_client *client, struct p9_req_t *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) p9_debug(P9_DEBUG_TRANS, "client %p req %p\n", client, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) spin_lock(&client->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) /* Ignore cancelled request if message has been received
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) * before lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) if (req->status == REQ_STATUS_RCVD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) spin_unlock(&client->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) /* we haven't received a response for oldreq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) * remove it from the list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) list_del(&req->req_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) req->status = REQ_STATUS_FLSHD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) spin_unlock(&client->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) p9_req_put(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) static int p9_fd_show_options(struct seq_file *m, struct p9_client *clnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) if (clnt->trans_mod == &p9_tcp_trans) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) if (clnt->trans_opts.tcp.port != P9_PORT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) seq_printf(m, ",port=%u", clnt->trans_opts.tcp.port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) } else if (clnt->trans_mod == &p9_fd_trans) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) if (clnt->trans_opts.fd.rfd != ~0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) seq_printf(m, ",rfd=%u", clnt->trans_opts.fd.rfd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) if (clnt->trans_opts.fd.wfd != ~0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) seq_printf(m, ",wfd=%u", clnt->trans_opts.fd.wfd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) * parse_opts - parse mount options into p9_fd_opts structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) * @params: options string passed from mount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) * @opts: fd transport-specific structure to parse options into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) * Returns 0 upon success, -ERRNO upon failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) static int parse_opts(char *params, struct p9_fd_opts *opts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) char *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) substring_t args[MAX_OPT_ARGS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) int option;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) char *options, *tmp_options;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) opts->port = P9_PORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) opts->rfd = ~0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) opts->wfd = ~0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) opts->privport = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) if (!params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) tmp_options = kstrdup(params, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) if (!tmp_options) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) p9_debug(P9_DEBUG_ERROR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) "failed to allocate copy of option string\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) options = tmp_options;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) while ((p = strsep(&options, ",")) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) int token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) if (!*p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) token = match_token(p, tokens, args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) if ((token != Opt_err) && (token != Opt_privport)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) r = match_int(&args[0], &option);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) if (r < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) p9_debug(P9_DEBUG_ERROR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) "integer field, but no integer?\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) switch (token) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) case Opt_port:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) opts->port = option;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) case Opt_rfdno:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) opts->rfd = option;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) case Opt_wfdno:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) opts->wfd = option;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) case Opt_privport:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) opts->privport = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) kfree(tmp_options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) static int p9_fd_open(struct p9_client *client, int rfd, int wfd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) struct p9_trans_fd *ts = kzalloc(sizeof(struct p9_trans_fd),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) if (!ts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) ts->rd = fget(rfd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) if (!ts->rd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) goto out_free_ts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) if (!(ts->rd->f_mode & FMODE_READ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) goto out_put_rd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) ts->wr = fget(wfd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) if (!ts->wr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) goto out_put_rd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) if (!(ts->wr->f_mode & FMODE_WRITE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) goto out_put_wr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) client->trans = ts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) client->status = Connected;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) out_put_wr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) fput(ts->wr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) out_put_rd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) fput(ts->rd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) out_free_ts:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) kfree(ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) static int p9_socket_open(struct p9_client *client, struct socket *csocket)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) struct p9_trans_fd *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) struct file *file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) p = kzalloc(sizeof(struct p9_trans_fd), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) csocket->sk->sk_allocation = GFP_NOIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) file = sock_alloc_file(csocket, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) if (IS_ERR(file)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) pr_err("%s (%d): failed to map fd\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) __func__, task_pid_nr(current));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) kfree(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) return PTR_ERR(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) get_file(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) p->wr = p->rd = file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) client->trans = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) client->status = Connected;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) p->rd->f_flags |= O_NONBLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) p9_conn_create(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) * p9_mux_destroy - cancels all pending requests of mux
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) * @m: mux to destroy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) static void p9_conn_destroy(struct p9_conn *m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) p9_debug(P9_DEBUG_TRANS, "mux %p prev %p next %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) m, m->mux_list.prev, m->mux_list.next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) p9_mux_poll_stop(m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) cancel_work_sync(&m->rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) if (m->rreq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) p9_req_put(m->rreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) m->rreq = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) cancel_work_sync(&m->wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) if (m->wreq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) p9_req_put(m->wreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) m->wreq = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) p9_conn_cancel(m, -ECONNRESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) m->client = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) * p9_fd_close - shutdown file descriptor transport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) * @client: client instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) static void p9_fd_close(struct p9_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) struct p9_trans_fd *ts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) if (!client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) ts = client->trans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) if (!ts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) client->status = Disconnected;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) p9_conn_destroy(&ts->conn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) if (ts->rd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) fput(ts->rd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) if (ts->wr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) fput(ts->wr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) kfree(ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) * stolen from NFS - maybe should be made a generic function?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) static inline int valid_ipaddr4(const char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) int rc, count, in[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) rc = sscanf(buf, "%d.%d.%d.%d", &in[0], &in[1], &in[2], &in[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) if (rc != 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) for (count = 0; count < 4; count++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) if (in[count] > 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) static int p9_bind_privport(struct socket *sock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) struct sockaddr_in cl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) int port, err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) memset(&cl, 0, sizeof(cl));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) cl.sin_family = AF_INET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) cl.sin_addr.s_addr = htonl(INADDR_ANY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) for (port = p9_ipport_resv_max; port >= p9_ipport_resv_min; port--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) cl.sin_port = htons((ushort)port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) err = kernel_bind(sock, (struct sockaddr *)&cl, sizeof(cl));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) if (err != -EADDRINUSE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) p9_fd_create_tcp(struct p9_client *client, const char *addr, char *args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) struct socket *csocket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) struct sockaddr_in sin_server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) struct p9_fd_opts opts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) err = parse_opts(args, &opts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) if (addr == NULL || valid_ipaddr4(addr) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) csocket = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) client->trans_opts.tcp.port = opts.port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) client->trans_opts.tcp.privport = opts.privport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) sin_server.sin_family = AF_INET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) sin_server.sin_addr.s_addr = in_aton(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) sin_server.sin_port = htons(opts.port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) err = __sock_create(current->nsproxy->net_ns, PF_INET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) SOCK_STREAM, IPPROTO_TCP, &csocket, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) pr_err("%s (%d): problem creating socket\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) __func__, task_pid_nr(current));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) if (opts.privport) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) err = p9_bind_privport(csocket);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) pr_err("%s (%d): problem binding to privport\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) __func__, task_pid_nr(current));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) sock_release(csocket);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) err = csocket->ops->connect(csocket,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) (struct sockaddr *)&sin_server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) sizeof(struct sockaddr_in), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) pr_err("%s (%d): problem connecting socket to %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) __func__, task_pid_nr(current), addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) sock_release(csocket);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) return p9_socket_open(client, csocket);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) p9_fd_create_unix(struct p9_client *client, const char *addr, char *args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) struct socket *csocket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) struct sockaddr_un sun_server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) csocket = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) if (!addr || !strlen(addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) if (strlen(addr) >= UNIX_PATH_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) pr_err("%s (%d): address too long: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) __func__, task_pid_nr(current), addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) return -ENAMETOOLONG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) sun_server.sun_family = PF_UNIX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) strcpy(sun_server.sun_path, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) err = __sock_create(current->nsproxy->net_ns, PF_UNIX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) SOCK_STREAM, 0, &csocket, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) pr_err("%s (%d): problem creating socket\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) __func__, task_pid_nr(current));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) err = csocket->ops->connect(csocket, (struct sockaddr *)&sun_server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) sizeof(struct sockaddr_un) - 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) pr_err("%s (%d): problem connecting socket: %s: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) __func__, task_pid_nr(current), addr, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) sock_release(csocket);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) return p9_socket_open(client, csocket);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) p9_fd_create(struct p9_client *client, const char *addr, char *args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) struct p9_fd_opts opts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) parse_opts(args, &opts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) client->trans_opts.fd.rfd = opts.rfd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) client->trans_opts.fd.wfd = opts.wfd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) if (opts.rfd == ~0 || opts.wfd == ~0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) pr_err("Insufficient options for proto=fd\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) return -ENOPROTOOPT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) err = p9_fd_open(client, opts.rfd, opts.wfd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) p9_conn_create(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) static struct p9_trans_module p9_tcp_trans = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) .name = "tcp",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) .maxsize = MAX_SOCK_BUF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) .def = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) .create = p9_fd_create_tcp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) .close = p9_fd_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) .request = p9_fd_request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) .cancel = p9_fd_cancel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) .cancelled = p9_fd_cancelled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) .show_options = p9_fd_show_options,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) static struct p9_trans_module p9_unix_trans = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) .name = "unix",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) .maxsize = MAX_SOCK_BUF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) .def = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) .create = p9_fd_create_unix,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) .close = p9_fd_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) .request = p9_fd_request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) .cancel = p9_fd_cancel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) .cancelled = p9_fd_cancelled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) .show_options = p9_fd_show_options,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) static struct p9_trans_module p9_fd_trans = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) .name = "fd",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) .maxsize = MAX_SOCK_BUF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) .def = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) .create = p9_fd_create,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) .close = p9_fd_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) .request = p9_fd_request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) .cancel = p9_fd_cancel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) .cancelled = p9_fd_cancelled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) .show_options = p9_fd_show_options,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) * p9_poll_workfn - poll worker thread
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) * @work: work queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) * polls all v9fs transports for new events and queues the appropriate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) * work to the work queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) static void p9_poll_workfn(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) p9_debug(P9_DEBUG_TRANS, "start %p\n", current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) spin_lock_irqsave(&p9_poll_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) while (!list_empty(&p9_poll_pending_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) struct p9_conn *conn = list_first_entry(&p9_poll_pending_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) struct p9_conn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) poll_pending_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) list_del_init(&conn->poll_pending_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) spin_unlock_irqrestore(&p9_poll_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) p9_poll_mux(conn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) spin_lock_irqsave(&p9_poll_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) spin_unlock_irqrestore(&p9_poll_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) p9_debug(P9_DEBUG_TRANS, "finish\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) int p9_trans_fd_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) v9fs_register_trans(&p9_tcp_trans);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) v9fs_register_trans(&p9_unix_trans);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) v9fs_register_trans(&p9_fd_trans);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) void p9_trans_fd_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) flush_work(&p9_poll_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) v9fs_unregister_trans(&p9_tcp_trans);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) v9fs_unregister_trans(&p9_unix_trans);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) v9fs_unregister_trans(&p9_fd_trans);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) }