blob: 7cd6fce1ad3748db5b1a32585d163c07a92290d4 [file] [log] [blame]
Aneesh Kumar K.Vdcb9dbe2011-05-18 15:42:42 -07001/*
Greg Kurzaf8b38b2016-06-06 11:52:34 +02002 * 9p backend
Aneesh Kumar K.Vdcb9dbe2011-05-18 15:42:42 -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
Peter Maydellfbc04122016-01-26 18:17:10 +000014#include "qemu/osdep.h"
Aneesh Kumar K.Vdcb9dbe2011-05-18 15:42:42 -070015#include "fsdev/qemu-fsdev.h"
Paolo Bonzini1de7afc2012-12-17 18:20:00 +010016#include "qemu/thread.h"
Daniel P. Berrange10817bf2015-09-01 14:48:02 +010017#include "qemu/coroutine.h"
Wei Liufe528402015-11-18 17:57:30 +000018#include "coth.h"
Aneesh Kumar K.Vdcb9dbe2011-05-18 15:42:42 -070019
Greg Kurz5bdade62016-10-17 14:13:58 +020020int coroutine_fn v9fs_co_readdir(V9fsPDU *pdu, V9fsFidState *fidp,
21 struct dirent **dent)
Aneesh Kumar K.Vdcb9dbe2011-05-18 15:42:42 -070022{
23 int err;
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +053024 V9fsState *s = pdu->s;
Aneesh Kumar K.Vdcb9dbe2011-05-18 15:42:42 -070025
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +053026 if (v9fs_request_cancelled(pdu)) {
27 return -EINTR;
28 }
Aneesh Kumar K.Vdcb9dbe2011-05-18 15:42:42 -070029 v9fs_co_run_in_worker(
30 {
Greg Kurz635324e2016-06-06 11:52:34 +020031 struct dirent *entry;
32
Aneesh Kumar K.Vdcb9dbe2011-05-18 15:42:42 -070033 errno = 0;
Greg Kurz635324e2016-06-06 11:52:34 +020034 entry = s->ops->readdir(&s->ctx, &fidp->fs);
35 if (!entry && errno) {
Aneesh Kumar K.Vdcb9dbe2011-05-18 15:42:42 -070036 err = -errno;
37 } else {
Greg Kurz635324e2016-06-06 11:52:34 +020038 *dent = entry;
Aneesh Kumar K.Vdcb9dbe2011-05-18 15:42:42 -070039 err = 0;
40 }
41 });
42 return err;
43}
44
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +053045off_t v9fs_co_telldir(V9fsPDU *pdu, V9fsFidState *fidp)
Aneesh Kumar K.Vdcb9dbe2011-05-18 15:42:42 -070046{
47 off_t err;
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +053048 V9fsState *s = pdu->s;
Aneesh Kumar K.Vdcb9dbe2011-05-18 15:42:42 -070049
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +053050 if (v9fs_request_cancelled(pdu)) {
51 return -EINTR;
52 }
Aneesh Kumar K.Vdcb9dbe2011-05-18 15:42:42 -070053 v9fs_co_run_in_worker(
54 {
Aneesh Kumar K.Vcc720dd2011-10-25 12:10:40 +053055 err = s->ops->telldir(&s->ctx, &fidp->fs);
Aneesh Kumar K.Vdcb9dbe2011-05-18 15:42:42 -070056 if (err < 0) {
57 err = -errno;
58 }
59 });
60 return err;
61}
62
Greg Kurz5bdade62016-10-17 14:13:58 +020063void coroutine_fn v9fs_co_seekdir(V9fsPDU *pdu, V9fsFidState *fidp,
64 off_t offset)
Aneesh Kumar K.Vdcb9dbe2011-05-18 15:42:42 -070065{
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +053066 V9fsState *s = pdu->s;
67 if (v9fs_request_cancelled(pdu)) {
68 return;
69 }
Aneesh Kumar K.Vdcb9dbe2011-05-18 15:42:42 -070070 v9fs_co_run_in_worker(
71 {
Aneesh Kumar K.Vcc720dd2011-10-25 12:10:40 +053072 s->ops->seekdir(&s->ctx, &fidp->fs, offset);
Aneesh Kumar K.Vdcb9dbe2011-05-18 15:42:42 -070073 });
74}
75
Greg Kurz5bdade62016-10-17 14:13:58 +020076void coroutine_fn v9fs_co_rewinddir(V9fsPDU *pdu, V9fsFidState *fidp)
Aneesh Kumar K.Vdcb9dbe2011-05-18 15:42:42 -070077{
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +053078 V9fsState *s = pdu->s;
79 if (v9fs_request_cancelled(pdu)) {
80 return;
81 }
Aneesh Kumar K.Vdcb9dbe2011-05-18 15:42:42 -070082 v9fs_co_run_in_worker(
83 {
Aneesh Kumar K.Vcc720dd2011-10-25 12:10:40 +053084 s->ops->rewinddir(&s->ctx, &fidp->fs);
Aneesh Kumar K.Vdcb9dbe2011-05-18 15:42:42 -070085 });
86}
Venkateswararao Jujjurid0884642011-08-08 23:44:24 +053087
Greg Kurz5bdade62016-10-17 14:13:58 +020088int coroutine_fn v9fs_co_mkdir(V9fsPDU *pdu, V9fsFidState *fidp,
89 V9fsString *name, mode_t mode, uid_t uid,
90 gid_t gid, struct stat *stbuf)
Venkateswararao Jujjurid0884642011-08-08 23:44:24 +053091{
92 int err;
93 FsCred cred;
Aneesh Kumar K.V2289be12011-09-09 15:14:18 +053094 V9fsPath path;
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +053095 V9fsState *s = pdu->s;
Venkateswararao Jujjurid0884642011-08-08 23:44:24 +053096
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +053097 if (v9fs_request_cancelled(pdu)) {
Dong Xu Wang3a931132011-11-29 16:52:38 +080098 return -EINTR;
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +053099 }
Venkateswararao Jujjurid0884642011-08-08 23:44:24 +0530100 cred_init(&cred);
101 cred.fc_mode = mode;
102 cred.fc_uid = uid;
103 cred.fc_gid = gid;
Aneesh Kumar K.V532decb2011-08-02 11:35:54 +0530104 v9fs_path_read_lock(s);
Venkateswararao Jujjurid0884642011-08-08 23:44:24 +0530105 v9fs_co_run_in_worker(
106 {
Aneesh Kumar K.V2289be12011-09-09 15:14:18 +0530107 err = s->ops->mkdir(&s->ctx, &fidp->path, name->data, &cred);
Venkateswararao Jujjurid0884642011-08-08 23:44:24 +0530108 if (err < 0) {
109 err = -errno;
Aneesh Kumar K.V02cb7f32011-05-24 15:10:56 +0530110 } else {
Aneesh Kumar K.V2289be12011-09-09 15:14:18 +0530111 v9fs_path_init(&path);
112 err = v9fs_name_to_path(s, &fidp->path, name->data, &path);
113 if (!err) {
114 err = s->ops->lstat(&s->ctx, &path, stbuf);
115 if (err < 0) {
116 err = -errno;
117 }
Aneesh Kumar K.V02cb7f32011-05-24 15:10:56 +0530118 }
Aneesh Kumar K.V2289be12011-09-09 15:14:18 +0530119 v9fs_path_free(&path);
Venkateswararao Jujjurid0884642011-08-08 23:44:24 +0530120 }
121 });
Aneesh Kumar K.V532decb2011-08-02 11:35:54 +0530122 v9fs_path_unlock(s);
Venkateswararao Jujjurid0884642011-08-08 23:44:24 +0530123 return err;
124}
Aneesh Kumar K.Vf6b7f0a2011-05-07 18:12:42 +0530125
Greg Kurz5bdade62016-10-17 14:13:58 +0200126int coroutine_fn v9fs_co_opendir(V9fsPDU *pdu, V9fsFidState *fidp)
Aneesh Kumar K.Vf6b7f0a2011-05-07 18:12:42 +0530127{
128 int err;
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +0530129 V9fsState *s = pdu->s;
Aneesh Kumar K.Vf6b7f0a2011-05-07 18:12:42 +0530130
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +0530131 if (v9fs_request_cancelled(pdu)) {
Dong Xu Wang3a931132011-11-29 16:52:38 +0800132 return -EINTR;
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +0530133 }
Aneesh Kumar K.V532decb2011-08-02 11:35:54 +0530134 v9fs_path_read_lock(s);
Aneesh Kumar K.Vf6b7f0a2011-05-07 18:12:42 +0530135 v9fs_co_run_in_worker(
136 {
Aneesh Kumar K.Vcc720dd2011-10-25 12:10:40 +0530137 err = s->ops->opendir(&s->ctx, &fidp->path, &fidp->fs);
138 if (err < 0) {
Aneesh Kumar K.Vf6b7f0a2011-05-07 18:12:42 +0530139 err = -errno;
140 } else {
141 err = 0;
142 }
143 });
Aneesh Kumar K.V532decb2011-08-02 11:35:54 +0530144 v9fs_path_unlock(s);
Aneesh Kumar K.V95f65512011-05-18 17:08:34 +0530145 if (!err) {
146 total_open_fd++;
147 if (total_open_fd > open_fd_hw) {
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +0530148 v9fs_reclaim_fd(pdu);
Aneesh Kumar K.V95f65512011-05-18 17:08:34 +0530149 }
150 }
Aneesh Kumar K.Vf6b7f0a2011-05-07 18:12:42 +0530151 return err;
152}
Aneesh Kumar K.Vbed43522011-05-07 21:09:24 +0530153
Greg Kurz5bdade62016-10-17 14:13:58 +0200154int coroutine_fn v9fs_co_closedir(V9fsPDU *pdu, V9fsFidOpenState *fs)
Aneesh Kumar K.Vbed43522011-05-07 21:09:24 +0530155{
156 int err;
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +0530157 V9fsState *s = pdu->s;
Aneesh Kumar K.Vbed43522011-05-07 21:09:24 +0530158
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +0530159 if (v9fs_request_cancelled(pdu)) {
Dong Xu Wang3a931132011-11-29 16:52:38 +0800160 return -EINTR;
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +0530161 }
Aneesh Kumar K.Vbed43522011-05-07 21:09:24 +0530162 v9fs_co_run_in_worker(
163 {
Aneesh Kumar K.Vcc720dd2011-10-25 12:10:40 +0530164 err = s->ops->closedir(&s->ctx, fs);
Aneesh Kumar K.Vbed43522011-05-07 21:09:24 +0530165 if (err < 0) {
166 err = -errno;
167 }
168 });
Aneesh Kumar K.V95f65512011-05-18 17:08:34 +0530169 if (!err) {
170 total_open_fd--;
171 }
Aneesh Kumar K.Vbed43522011-05-07 21:09:24 +0530172 return err;
173}