blob: 20f93a90e75fc7cde8d2e4c64fca326777798fb3 [file] [log] [blame]
Aneesh Kumar K.V172198d2011-05-18 16:04:13 -07001/*
Greg Kurzaf8b38b2016-06-06 11:52:34 +02002 * 9p backend
Aneesh Kumar K.V172198d2011-05-18 16:04:13 -07003 *
4 * Copyright IBM, Corp. 2011
5 *
6 * Authors:
7 * Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
8 *
9 * This work is licensed under the terms of the GNU GPL, version 2. See
10 * the COPYING file in the top-level directory.
11 *
12 */
13
Christian Schoenebeck6f569082021-05-06 15:12:23 +020014/*
15 * Not so fast! You might want to read the 9p developer docs first:
16 * https://wiki.qemu.org/Documentation/9p
17 */
18
Peter Maydellfbc04122016-01-26 18:17:10 +000019#include "qemu/osdep.h"
Aneesh Kumar K.V172198d2011-05-18 16:04:13 -070020#include "fsdev/qemu-fsdev.h"
Paolo Bonzini1de7afc2012-12-17 18:20:00 +010021#include "qemu/thread.h"
Daniel P. Berrange10817bf2015-09-01 14:48:02 +010022#include "qemu/coroutine.h"
Markus Armbrusterdb725812019-08-12 07:23:50 +020023#include "qemu/main-loop.h"
Wei Liufe528402015-11-18 17:57:30 +000024#include "coth.h"
Aneesh Kumar K.V172198d2011-05-18 16:04:13 -070025
Greg Kurz5bdade62016-10-17 14:13:58 +020026int coroutine_fn v9fs_co_st_gen(V9fsPDU *pdu, V9fsPath *path, mode_t st_mode,
27 V9fsStatDotl *v9stat)
Harsh Prateek Borae06a7652011-10-12 19:11:25 +053028{
29 int err = 0;
30 V9fsState *s = pdu->s;
31
32 if (v9fs_request_cancelled(pdu)) {
33 return -EINTR;
34 }
35 if (s->ctx.exops.get_st_gen) {
36 v9fs_path_read_lock(s);
37 v9fs_co_run_in_worker(
38 {
39 err = s->ctx.exops.get_st_gen(&s->ctx, path, st_mode,
40 &v9stat->st_gen);
41 if (err < 0) {
42 err = -errno;
43 }
44 });
45 v9fs_path_unlock(s);
46 }
47 return err;
48}
49
Greg Kurz5bdade62016-10-17 14:13:58 +020050int coroutine_fn v9fs_co_lstat(V9fsPDU *pdu, V9fsPath *path, struct stat *stbuf)
Aneesh Kumar K.V172198d2011-05-18 16:04:13 -070051{
52 int err;
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +053053 V9fsState *s = pdu->s;
Aneesh Kumar K.V172198d2011-05-18 16:04:13 -070054
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +053055 if (v9fs_request_cancelled(pdu)) {
56 return -EINTR;
57 }
Aneesh Kumar K.V532decb2011-08-02 11:35:54 +053058 v9fs_path_read_lock(s);
Aneesh Kumar K.V172198d2011-05-18 16:04:13 -070059 v9fs_co_run_in_worker(
60 {
Aneesh Kumar K.V2289be12011-09-09 15:14:18 +053061 err = s->ops->lstat(&s->ctx, path, stbuf);
Aneesh Kumar K.V172198d2011-05-18 16:04:13 -070062 if (err < 0) {
63 err = -errno;
64 }
65 });
Aneesh Kumar K.V532decb2011-08-02 11:35:54 +053066 v9fs_path_unlock(s);
Aneesh Kumar K.V172198d2011-05-18 16:04:13 -070067 return err;
68}
Aneesh Kumar K.V03feb1e2011-08-22 09:14:04 +053069
Greg Kurz5bdade62016-10-17 14:13:58 +020070int coroutine_fn v9fs_co_fstat(V9fsPDU *pdu, V9fsFidState *fidp,
71 struct stat *stbuf)
Aneesh Kumar K.V03feb1e2011-08-22 09:14:04 +053072{
73 int err;
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +053074 V9fsState *s = pdu->s;
Aneesh Kumar K.V03feb1e2011-08-22 09:14:04 +053075
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +053076 if (v9fs_request_cancelled(pdu)) {
77 return -EINTR;
78 }
Aneesh Kumar K.V03feb1e2011-08-22 09:14:04 +053079 v9fs_co_run_in_worker(
80 {
Aneesh Kumar K.V8b888272011-12-04 22:35:28 +053081 err = s->ops->fstat(&s->ctx, fidp->fid_type, &fidp->fs, stbuf);
Aneesh Kumar K.V03feb1e2011-08-22 09:14:04 +053082 if (err < 0) {
83 err = -errno;
84 }
85 });
Aneesh Kumar K.V2c30dd72012-01-19 12:21:11 +053086 /*
87 * Some FS driver (local:mapped-file) can't support fetching attributes
88 * using file descriptor. Use Path name in that case.
89 */
90 if (err == -EOPNOTSUPP) {
91 err = v9fs_co_lstat(pdu, &fidp->path, stbuf);
92 if (err == -ENOENT) {
93 /*
94 * fstat on an unlinked file. Work with partial results
95 * returned from s->ops->fstat
96 */
97 err = 0;
98 }
99 }
Aneesh Kumar K.V03feb1e2011-08-22 09:14:04 +0530100 return err;
101}
Aneesh Kumar K.Vf6b7f0a2011-05-07 18:12:42 +0530102
Greg Kurz5bdade62016-10-17 14:13:58 +0200103int coroutine_fn v9fs_co_open(V9fsPDU *pdu, V9fsFidState *fidp, int flags)
Aneesh Kumar K.Vf6b7f0a2011-05-07 18:12:42 +0530104{
105 int err;
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +0530106 V9fsState *s = pdu->s;
Aneesh Kumar K.Vf6b7f0a2011-05-07 18:12:42 +0530107
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +0530108 if (v9fs_request_cancelled(pdu)) {
109 return -EINTR;
110 }
Aneesh Kumar K.V532decb2011-08-02 11:35:54 +0530111 v9fs_path_read_lock(s);
Aneesh Kumar K.Vf6b7f0a2011-05-07 18:12:42 +0530112 v9fs_co_run_in_worker(
113 {
Aneesh Kumar K.Vcc720dd2011-10-25 12:10:40 +0530114 err = s->ops->open(&s->ctx, &fidp->path, flags, &fidp->fs);
115 if (err == -1) {
Aneesh Kumar K.Vf6b7f0a2011-05-07 18:12:42 +0530116 err = -errno;
117 } else {
118 err = 0;
119 }
120 });
Aneesh Kumar K.V532decb2011-08-02 11:35:54 +0530121 v9fs_path_unlock(s);
Aneesh Kumar K.V7a462742011-05-18 15:40:57 +0530122 if (!err) {
123 total_open_fd++;
124 if (total_open_fd > open_fd_hw) {
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +0530125 v9fs_reclaim_fd(pdu);
Aneesh Kumar K.V7a462742011-05-18 15:40:57 +0530126 }
127 }
Aneesh Kumar K.Vf6b7f0a2011-05-07 18:12:42 +0530128 return err;
129}
Venkateswararao Jujjurie4de4232011-08-08 23:52:33 +0530130
Greg Kurz5bdade62016-10-17 14:13:58 +0200131int coroutine_fn v9fs_co_open2(V9fsPDU *pdu, V9fsFidState *fidp,
132 V9fsString *name, gid_t gid, int flags, int mode,
133 struct stat *stbuf)
Venkateswararao Jujjurie4de4232011-08-08 23:52:33 +0530134{
135 int err;
136 FsCred cred;
Aneesh Kumar K.V2289be12011-09-09 15:14:18 +0530137 V9fsPath path;
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +0530138 V9fsState *s = pdu->s;
Aneesh Kumar K.V2289be12011-09-09 15:14:18 +0530139
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +0530140 if (v9fs_request_cancelled(pdu)) {
141 return -EINTR;
142 }
Venkateswararao Jujjurie4de4232011-08-08 23:52:33 +0530143 cred_init(&cred);
144 cred.fc_mode = mode & 07777;
145 cred.fc_uid = fidp->uid;
146 cred.fc_gid = gid;
Aneesh Kumar K.V02cb7f32011-05-24 15:10:56 +0530147 /*
148 * Hold the directory fid lock so that directory path name
Greg Kurz5b76ef52018-11-07 01:00:04 +0100149 * don't change. Take the write lock to be sure this fid
150 * cannot be used by another operation.
Aneesh Kumar K.V02cb7f32011-05-24 15:10:56 +0530151 */
Greg Kurz5b76ef52018-11-07 01:00:04 +0100152 v9fs_path_write_lock(s);
Venkateswararao Jujjurie4de4232011-08-08 23:52:33 +0530153 v9fs_co_run_in_worker(
154 {
Aneesh Kumar K.Vcc720dd2011-10-25 12:10:40 +0530155 err = s->ops->open2(&s->ctx, &fidp->path,
156 name->data, flags, &cred, &fidp->fs);
157 if (err < 0) {
Venkateswararao Jujjurie4de4232011-08-08 23:52:33 +0530158 err = -errno;
Aneesh Kumar K.V02cb7f32011-05-24 15:10:56 +0530159 } else {
Aneesh Kumar K.V2289be12011-09-09 15:14:18 +0530160 v9fs_path_init(&path);
161 err = v9fs_name_to_path(s, &fidp->path, name->data, &path);
162 if (!err) {
163 err = s->ops->lstat(&s->ctx, &path, stbuf);
164 if (err < 0) {
165 err = -errno;
Aneesh Kumar K.Vcc720dd2011-10-25 12:10:40 +0530166 s->ops->close(&s->ctx, &fidp->fs);
Aneesh Kumar K.V2289be12011-09-09 15:14:18 +0530167 } else {
168 v9fs_path_copy(&fidp->path, &path);
169 }
Aneesh Kumar K.V02cb7f32011-05-24 15:10:56 +0530170 } else {
Aneesh Kumar K.Vcc720dd2011-10-25 12:10:40 +0530171 s->ops->close(&s->ctx, &fidp->fs);
Aneesh Kumar K.V02cb7f32011-05-24 15:10:56 +0530172 }
Aneesh Kumar K.V2289be12011-09-09 15:14:18 +0530173 v9fs_path_free(&path);
Venkateswararao Jujjurie4de4232011-08-08 23:52:33 +0530174 }
175 });
Aneesh Kumar K.V532decb2011-08-02 11:35:54 +0530176 v9fs_path_unlock(s);
Aneesh Kumar K.V7a462742011-05-18 15:40:57 +0530177 if (!err) {
178 total_open_fd++;
179 if (total_open_fd > open_fd_hw) {
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +0530180 v9fs_reclaim_fd(pdu);
Aneesh Kumar K.V7a462742011-05-18 15:40:57 +0530181 }
182 }
Venkateswararao Jujjurie4de4232011-08-08 23:52:33 +0530183 return err;
184}
Aneesh Kumar K.Vbed43522011-05-07 21:09:24 +0530185
Greg Kurz5bdade62016-10-17 14:13:58 +0200186int coroutine_fn v9fs_co_close(V9fsPDU *pdu, V9fsFidOpenState *fs)
Aneesh Kumar K.Vbed43522011-05-07 21:09:24 +0530187{
Aneesh Kumar K.Vbed43522011-05-07 21:09:24 +0530188 int err;
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +0530189 V9fsState *s = pdu->s;
Aneesh Kumar K.Vbed43522011-05-07 21:09:24 +0530190
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +0530191 if (v9fs_request_cancelled(pdu)) {
192 return -EINTR;
193 }
Aneesh Kumar K.Vbed43522011-05-07 21:09:24 +0530194 v9fs_co_run_in_worker(
195 {
Aneesh Kumar K.Vcc720dd2011-10-25 12:10:40 +0530196 err = s->ops->close(&s->ctx, fs);
Aneesh Kumar K.Vbed43522011-05-07 21:09:24 +0530197 if (err < 0) {
198 err = -errno;
199 }
200 });
Aneesh Kumar K.V7a462742011-05-18 15:40:57 +0530201 if (!err) {
202 total_open_fd--;
203 }
Aneesh Kumar K.Vbed43522011-05-07 21:09:24 +0530204 return err;
205}
Aneesh Kumar K.V4743d1f2011-05-07 21:29:32 +0530206
Greg Kurz5bdade62016-10-17 14:13:58 +0200207int coroutine_fn v9fs_co_fsync(V9fsPDU *pdu, V9fsFidState *fidp, int datasync)
Aneesh Kumar K.V4743d1f2011-05-07 21:29:32 +0530208{
Aneesh Kumar K.Vcc720dd2011-10-25 12:10:40 +0530209 int err;
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +0530210 V9fsState *s = pdu->s;
Aneesh Kumar K.V4743d1f2011-05-07 21:29:32 +0530211
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +0530212 if (v9fs_request_cancelled(pdu)) {
213 return -EINTR;
214 }
Aneesh Kumar K.V4743d1f2011-05-07 21:29:32 +0530215 v9fs_co_run_in_worker(
216 {
Aneesh Kumar K.V8b888272011-12-04 22:35:28 +0530217 err = s->ops->fsync(&s->ctx, fidp->fid_type, &fidp->fs, datasync);
Aneesh Kumar K.V4743d1f2011-05-07 21:29:32 +0530218 if (err < 0) {
219 err = -errno;
220 }
221 });
222 return err;
223}
Venkateswararao Jujjuric6c069b2011-08-09 00:01:22 +0530224
Greg Kurz5bdade62016-10-17 14:13:58 +0200225int coroutine_fn v9fs_co_link(V9fsPDU *pdu, V9fsFidState *oldfid,
226 V9fsFidState *newdirfid, V9fsString *name)
Venkateswararao Jujjuric6c069b2011-08-09 00:01:22 +0530227{
228 int err;
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +0530229 V9fsState *s = pdu->s;
Venkateswararao Jujjuric6c069b2011-08-09 00:01:22 +0530230
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +0530231 if (v9fs_request_cancelled(pdu)) {
232 return -EINTR;
233 }
Aneesh Kumar K.V532decb2011-08-02 11:35:54 +0530234 v9fs_path_read_lock(s);
Venkateswararao Jujjuric6c069b2011-08-09 00:01:22 +0530235 v9fs_co_run_in_worker(
236 {
Aneesh Kumar K.V2289be12011-09-09 15:14:18 +0530237 err = s->ops->link(&s->ctx, &oldfid->path,
238 &newdirfid->path, name->data);
Venkateswararao Jujjuric6c069b2011-08-09 00:01:22 +0530239 if (err < 0) {
240 err = -errno;
241 }
242 });
Aneesh Kumar K.V532decb2011-08-02 11:35:54 +0530243 v9fs_path_unlock(s);
Venkateswararao Jujjuric6c069b2011-08-09 00:01:22 +0530244 return err;
245}
Aneesh Kumar K.Vf6b3c972011-05-08 12:36:59 +0530246
Greg Kurz5bdade62016-10-17 14:13:58 +0200247int coroutine_fn v9fs_co_pwritev(V9fsPDU *pdu, V9fsFidState *fidp,
248 struct iovec *iov, int iovcnt, int64_t offset)
Aneesh Kumar K.Vf6b3c972011-05-08 12:36:59 +0530249{
Aneesh Kumar K.Vcc720dd2011-10-25 12:10:40 +0530250 int err;
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +0530251 V9fsState *s = pdu->s;
Aneesh Kumar K.Vf6b3c972011-05-08 12:36:59 +0530252
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +0530253 if (v9fs_request_cancelled(pdu)) {
254 return -EINTR;
255 }
Pradeep Jagadeeshb8bbdb82017-02-28 10:31:46 +0100256 fsdev_co_throttle_request(s->ctx.fst, true, iov, iovcnt);
Aneesh Kumar K.Vf6b3c972011-05-08 12:36:59 +0530257 v9fs_co_run_in_worker(
258 {
Aneesh Kumar K.Vcc720dd2011-10-25 12:10:40 +0530259 err = s->ops->pwritev(&s->ctx, &fidp->fs, iov, iovcnt, offset);
Aneesh Kumar K.Vf6b3c972011-05-08 12:36:59 +0530260 if (err < 0) {
261 err = -errno;
262 }
263 });
264 return err;
265}
Aneesh Kumar K.V7eafdcc2011-05-08 15:16:22 +0530266
Greg Kurz5bdade62016-10-17 14:13:58 +0200267int coroutine_fn v9fs_co_preadv(V9fsPDU *pdu, V9fsFidState *fidp,
268 struct iovec *iov, int iovcnt, int64_t offset)
Aneesh Kumar K.V7eafdcc2011-05-08 15:16:22 +0530269{
Aneesh Kumar K.Vcc720dd2011-10-25 12:10:40 +0530270 int err;
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +0530271 V9fsState *s = pdu->s;
Aneesh Kumar K.V7eafdcc2011-05-08 15:16:22 +0530272
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +0530273 if (v9fs_request_cancelled(pdu)) {
274 return -EINTR;
275 }
Pradeep Jagadeeshb8bbdb82017-02-28 10:31:46 +0100276 fsdev_co_throttle_request(s->ctx.fst, false, iov, iovcnt);
Aneesh Kumar K.V7eafdcc2011-05-08 15:16:22 +0530277 v9fs_co_run_in_worker(
278 {
Aneesh Kumar K.Vcc720dd2011-10-25 12:10:40 +0530279 err = s->ops->preadv(&s->ctx, &fidp->fs, iov, iovcnt, offset);
Aneesh Kumar K.V7eafdcc2011-05-08 15:16:22 +0530280 if (err < 0) {
281 err = -errno;
282 }
283 });
284 return err;
285}