Commit | Line | Data |
---|---|---|
1f327613 | 1 | // SPDX-License-Identifier: GPL-2.0-only |
147b31cf | 2 | /* |
147b31cf EVH |
3 | * This file contians vfs address (mmap) ops for 9P2000. |
4 | * | |
5 | * Copyright (C) 2005 by Eric Van Hensbergen <ericvh@gmail.com> | |
6 | * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> | |
147b31cf EVH |
7 | */ |
8 | ||
9 | #include <linux/module.h> | |
10 | #include <linux/errno.h> | |
11 | #include <linux/fs.h> | |
12 | #include <linux/file.h> | |
13 | #include <linux/stat.h> | |
14 | #include <linux/string.h> | |
147b31cf | 15 | #include <linux/pagemap.h> |
e8edc6e0 | 16 | #include <linux/sched.h> |
d7bdba1c | 17 | #include <linux/swap.h> |
e2e40f2c | 18 | #include <linux/uio.h> |
eb497943 | 19 | #include <linux/netfs.h> |
bd238fb4 LI |
20 | #include <net/9p/9p.h> |
21 | #include <net/9p/client.h> | |
80105ed2 | 22 | #include <trace/events/netfs.h> |
147b31cf | 23 | |
147b31cf | 24 | #include "v9fs.h" |
147b31cf | 25 | #include "v9fs_vfs.h" |
60e78d2c | 26 | #include "cache.h" |
7263cebe | 27 | #include "fid.h" |
147b31cf | 28 | |
5fb70e72 DH |
29 | /* |
30 | * Writeback calls this when it finds a folio that needs uploading. This isn't | |
31 | * called if writeback only has copy-to-cache to deal with. | |
32 | */ | |
33 | static void v9fs_begin_writeback(struct netfs_io_request *wreq) | |
34 | { | |
35 | struct p9_fid *fid; | |
36 | ||
37 | fid = v9fs_fid_find_inode(wreq->inode, true, INVALID_UID, true); | |
38 | if (!fid) { | |
39 | WARN_ONCE(1, "folio expected an open fid inode->i_ino=%lx\n", | |
40 | wreq->inode->i_ino); | |
41 | return; | |
42 | } | |
43 | ||
44 | wreq->wsize = fid->clnt->msize - P9_IOHDRSZ; | |
45 | if (fid->iounit) | |
46 | wreq->wsize = min(wreq->wsize, fid->iounit); | |
47 | wreq->netfs_priv = fid; | |
48 | wreq->io_streams[0].avail = true; | |
49 | } | |
50 | ||
51 | /* | |
52 | * Issue a subrequest to write to the server. | |
53 | */ | |
54 | static void v9fs_issue_write(struct netfs_io_subrequest *subreq) | |
55 | { | |
56 | struct p9_fid *fid = subreq->rreq->netfs_priv; | |
57 | int err, len; | |
58 | ||
59 | len = p9_client_write(fid, subreq->start, &subreq->io_iter, &err); | |
60 | netfs_write_subrequest_terminated(subreq, len ?: err, false); | |
61 | } | |
62 | ||
147b31cf | 63 | /** |
f18a3785 | 64 | * v9fs_issue_read - Issue a read from 9P |
eb497943 | 65 | * @subreq: The read to make |
147b31cf | 66 | */ |
f18a3785 | 67 | static void v9fs_issue_read(struct netfs_io_subrequest *subreq) |
147b31cf | 68 | { |
6a19114b | 69 | struct netfs_io_request *rreq = subreq->rreq; |
eb497943 | 70 | struct p9_fid *fid = rreq->netfs_priv; |
eb497943 | 71 | int total, err; |
e03abc0c | 72 | |
80105ed2 DH |
73 | total = p9_client_read(fid, subreq->start + subreq->transferred, |
74 | &subreq->io_iter, &err); | |
19d1c326 DM |
75 | |
76 | /* if we just extended the file size, any portion not in | |
77 | * cache won't be on server and is zeroes */ | |
78 | __set_bit(NETFS_SREQ_CLEAR_TAIL, &subreq->flags); | |
79 | ||
eb497943 DH |
80 | netfs_subreq_terminated(subreq, err ?: total, false); |
81 | } | |
60e78d2c | 82 | |
eb497943 | 83 | /** |
80105ed2 | 84 | * v9fs_init_request - Initialise a request |
eb497943 DH |
85 | * @rreq: The read request |
86 | * @file: The file being read from | |
87 | */ | |
2de16041 | 88 | static int v9fs_init_request(struct netfs_io_request *rreq, struct file *file) |
eb497943 | 89 | { |
80105ed2 DH |
90 | struct p9_fid *fid; |
91 | bool writing = (rreq->origin == NETFS_READ_FOR_WRITE || | |
80105ed2 | 92 | rreq->origin == NETFS_WRITETHROUGH || |
80105ed2 DH |
93 | rreq->origin == NETFS_UNBUFFERED_WRITE || |
94 | rreq->origin == NETFS_DIO_WRITE); | |
95 | ||
5fb70e72 DH |
96 | if (rreq->origin == NETFS_WRITEBACK) |
97 | return 0; /* We don't get the write handle until we find we | |
98 | * have actually dirty data and not just | |
99 | * copy-to-cache data. | |
100 | */ | |
5fb70e72 | 101 | |
80105ed2 DH |
102 | if (file) { |
103 | fid = file->private_data; | |
6c2c1e00 DH |
104 | if (!fid) |
105 | goto no_fid; | |
80105ed2 DH |
106 | p9_fid_get(fid); |
107 | } else { | |
108 | fid = v9fs_fid_find_inode(rreq->inode, writing, INVALID_UID, true); | |
6c2c1e00 DH |
109 | if (!fid) |
110 | goto no_fid; | |
80105ed2 | 111 | } |
b0017602 | 112 | |
5fb70e72 DH |
113 | rreq->wsize = fid->clnt->msize - P9_IOHDRSZ; |
114 | if (fid->iounit) | |
115 | rreq->wsize = min(rreq->wsize, fid->iounit); | |
116 | ||
b0017602 DM |
117 | /* we might need to read from a fid that was opened write-only |
118 | * for read-modify-write of page cache, use the writeback fid | |
119 | * for that */ | |
80105ed2 | 120 | WARN_ON(rreq->origin == NETFS_READ_FOR_WRITE && !(fid->mode & P9_ORDWR)); |
eb497943 | 121 | rreq->netfs_priv = fid; |
2de16041 | 122 | return 0; |
6c2c1e00 DH |
123 | |
124 | no_fid: | |
125 | WARN_ONCE(1, "folio expected an open fid inode->i_ino=%lx\n", | |
126 | rreq->inode->i_ino); | |
127 | return -EINVAL; | |
eb497943 | 128 | } |
147b31cf | 129 | |
eb497943 | 130 | /** |
40a81101 DH |
131 | * v9fs_free_request - Cleanup request initialized by v9fs_init_rreq |
132 | * @rreq: The I/O request to clean up | |
eb497943 | 133 | */ |
40a81101 | 134 | static void v9fs_free_request(struct netfs_io_request *rreq) |
eb497943 | 135 | { |
40a81101 | 136 | struct p9_fid *fid = rreq->netfs_priv; |
147b31cf | 137 | |
b48dbb99 | 138 | p9_fid_put(fid); |
eb497943 | 139 | } |
60e78d2c | 140 | |
bc899ee1 | 141 | const struct netfs_request_ops v9fs_req_ops = { |
6a19114b | 142 | .init_request = v9fs_init_request, |
40a81101 | 143 | .free_request = v9fs_free_request, |
f18a3785 | 144 | .issue_read = v9fs_issue_read, |
5fb70e72 DH |
145 | .begin_writeback = v9fs_begin_writeback, |
146 | .issue_write = v9fs_issue_write, | |
eb497943 DH |
147 | }; |
148 | ||
f5e54d6e | 149 | const struct address_space_operations v9fs_addr_operations = { |
80105ed2 DH |
150 | .read_folio = netfs_read_folio, |
151 | .readahead = netfs_readahead, | |
152 | .dirty_folio = netfs_dirty_folio, | |
153 | .release_folio = netfs_release_folio, | |
154 | .invalidate_folio = netfs_invalidate_folio, | |
80105ed2 DH |
155 | .direct_IO = noop_direct_IO, |
156 | .writepages = netfs_writepages, | |
147b31cf | 157 | }; |