]> git.proxmox.com Git - qemu.git/blame - hw/9pfs/cofs.c
hw/9pfs: Add fs driver specific details to fscontext
[qemu.git] / hw / 9pfs / cofs.c
CommitLineData
86e42d74
VJJ
1
2/*
3 * Virtio 9p backend
4 *
5 * Copyright IBM, Corp. 2011
6 *
7 * Authors:
8 * Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
9 *
10 * This work is licensed under the terms of the GNU GPL, version 2. See
11 * the COPYING file in the top-level directory.
12 *
13 */
14
15#include "fsdev/qemu-fsdev.h"
16#include "qemu-thread.h"
17#include "qemu-coroutine.h"
18#include "virtio-9p-coth.h"
19
2289be19 20int v9fs_co_readlink(V9fsState *s, V9fsPath *path, V9fsString *buf)
86e42d74
VJJ
21{
22 int err;
23 ssize_t len;
24
7267c094 25 buf->data = g_malloc(PATH_MAX);
532decb7 26 v9fs_path_read_lock(s);
86e42d74
VJJ
27 v9fs_co_run_in_worker(
28 {
2289be19 29 len = s->ops->readlink(&s->ctx, path,
86e42d74
VJJ
30 buf->data, PATH_MAX - 1);
31 if (len > -1) {
32 buf->size = len;
33 buf->data[len] = 0;
34 err = 0;
35 } else {
36 err = -errno;
37 }
38 });
532decb7 39 v9fs_path_unlock(s);
86e42d74 40 if (err) {
7267c094 41 g_free(buf->data);
86e42d74
VJJ
42 buf->data = NULL;
43 buf->size = 0;
44 }
45 return err;
46}
94840ff9 47
2289be19 48int v9fs_co_statfs(V9fsState *s, V9fsPath *path, struct statfs *stbuf)
94840ff9
AK
49{
50 int err;
51
532decb7 52 v9fs_path_read_lock(s);
94840ff9
AK
53 v9fs_co_run_in_worker(
54 {
2289be19 55 err = s->ops->statfs(&s->ctx, path, stbuf);
94840ff9
AK
56 if (err < 0) {
57 err = -errno;
58 }
59 });
532decb7 60 v9fs_path_unlock(s);
94840ff9
AK
61 return err;
62}
4011ead2 63
2289be19 64int v9fs_co_chmod(V9fsState *s, V9fsPath *path, mode_t mode)
4011ead2
AK
65{
66 int err;
67 FsCred cred;
68
69 cred_init(&cred);
70 cred.fc_mode = mode;
532decb7 71 v9fs_path_read_lock(s);
4011ead2
AK
72 v9fs_co_run_in_worker(
73 {
2289be19 74 err = s->ops->chmod(&s->ctx, path, &cred);
4011ead2
AK
75 if (err < 0) {
76 err = -errno;
77 }
78 });
532decb7 79 v9fs_path_unlock(s);
4011ead2
AK
80 return err;
81}
82
2289be19 83int v9fs_co_utimensat(V9fsState *s, V9fsPath *path,
4011ead2
AK
84 struct timespec times[2])
85{
86 int err;
87
532decb7 88 v9fs_path_read_lock(s);
4011ead2
AK
89 v9fs_co_run_in_worker(
90 {
2289be19 91 err = s->ops->utimensat(&s->ctx, path, times);
4011ead2
AK
92 if (err < 0) {
93 err = -errno;
94 }
95 });
532decb7 96 v9fs_path_unlock(s);
4011ead2
AK
97 return err;
98}
99
2289be19 100int v9fs_co_chown(V9fsState *s, V9fsPath *path, uid_t uid, gid_t gid)
4011ead2
AK
101{
102 int err;
103 FsCred cred;
104
105 cred_init(&cred);
106 cred.fc_uid = uid;
107 cred.fc_gid = gid;
532decb7 108 v9fs_path_read_lock(s);
4011ead2
AK
109 v9fs_co_run_in_worker(
110 {
2289be19 111 err = s->ops->chown(&s->ctx, path, &cred);
4011ead2
AK
112 if (err < 0) {
113 err = -errno;
114 }
115 });
532decb7 116 v9fs_path_unlock(s);
4011ead2
AK
117 return err;
118}
119
2289be19 120int v9fs_co_truncate(V9fsState *s, V9fsPath *path, off_t size)
4011ead2
AK
121{
122 int err;
123
532decb7 124 v9fs_path_read_lock(s);
4011ead2
AK
125 v9fs_co_run_in_worker(
126 {
2289be19 127 err = s->ops->truncate(&s->ctx, path, size);
4011ead2
AK
128 if (err < 0) {
129 err = -errno;
130 }
131 });
532decb7 132 v9fs_path_unlock(s);
4011ead2
AK
133 return err;
134}
00ace8c5 135
02cb7f3a
AK
136int v9fs_co_mknod(V9fsState *s, V9fsFidState *fidp, V9fsString *name, uid_t uid,
137 gid_t gid, dev_t dev, mode_t mode, struct stat *stbuf)
00ace8c5
AK
138{
139 int err;
2289be19 140 V9fsPath path;
00ace8c5
AK
141 FsCred cred;
142
143 cred_init(&cred);
144 cred.fc_uid = uid;
145 cred.fc_gid = gid;
146 cred.fc_mode = mode;
147 cred.fc_rdev = dev;
532decb7 148 v9fs_path_read_lock(s);
00ace8c5
AK
149 v9fs_co_run_in_worker(
150 {
2289be19 151 err = s->ops->mknod(&s->ctx, &fidp->path, name->data, &cred);
00ace8c5
AK
152 if (err < 0) {
153 err = -errno;
02cb7f3a 154 } else {
2289be19
AK
155 v9fs_path_init(&path);
156 err = v9fs_name_to_path(s, &fidp->path, name->data, &path);
157 if (!err) {
158 err = s->ops->lstat(&s->ctx, &path, stbuf);
159 if (err < 0) {
160 err = -errno;
161 }
02cb7f3a 162 }
2289be19 163 v9fs_path_free(&path);
00ace8c5
AK
164 }
165 });
532decb7 166 v9fs_path_unlock(s);
00ace8c5
AK
167 return err;
168}
b4b1537b 169
2289be19
AK
170/* Only works with path name based fid */
171int v9fs_co_remove(V9fsState *s, V9fsPath *path)
b4b1537b
VJ
172{
173 int err;
174
532decb7 175 v9fs_path_read_lock(s);
b4b1537b
VJ
176 v9fs_co_run_in_worker(
177 {
178 err = s->ops->remove(&s->ctx, path->data);
179 if (err < 0) {
180 err = -errno;
181 }
182 });
532decb7 183 v9fs_path_unlock(s);
b4b1537b
VJ
184 return err;
185}
2a487e05 186
2289be19
AK
187int v9fs_co_unlinkat(V9fsState *s, V9fsPath *path, V9fsString *name, int flags)
188{
189 int err;
190
532decb7 191 v9fs_path_read_lock(s);
2289be19
AK
192 v9fs_co_run_in_worker(
193 {
194 err = s->ops->unlinkat(&s->ctx, path, name->data, flags);
195 if (err < 0) {
196 err = -errno;
197 }
198 });
532decb7 199 v9fs_path_unlock(s);
2289be19
AK
200 return err;
201}
202
203/* Only work with path name based fid */
204int v9fs_co_rename(V9fsState *s, V9fsPath *oldpath, V9fsPath *newpath)
2a487e05
AK
205{
206 int err;
207
208 v9fs_co_run_in_worker(
209 {
210 err = s->ops->rename(&s->ctx, oldpath->data, newpath->data);
211 if (err < 0) {
212 err = -errno;
213 }
214 });
215 return err;
216}
02ac7a34 217
2289be19
AK
218int v9fs_co_renameat(V9fsState *s, V9fsPath *olddirpath, V9fsString *oldname,
219 V9fsPath *newdirpath, V9fsString *newname)
220{
221 int err;
222
223 v9fs_co_run_in_worker(
224 {
225 err = s->ops->renameat(&s->ctx, olddirpath, oldname->data,
226 newdirpath, newname->data);
227 if (err < 0) {
228 err = -errno;
229 }
230 });
231 return err;
232}
233
02cb7f3a
AK
234int v9fs_co_symlink(V9fsState *s, V9fsFidState *dfidp, V9fsString *name,
235 const char *oldpath, gid_t gid, struct stat *stbuf)
02ac7a34
VJ
236{
237 int err;
238 FsCred cred;
2289be19 239 V9fsPath path;
02cb7f3a 240
02ac7a34
VJ
241
242 cred_init(&cred);
02cb7f3a 243 cred.fc_uid = dfidp->uid;
02ac7a34
VJ
244 cred.fc_gid = gid;
245 cred.fc_mode = 0777;
532decb7 246 v9fs_path_read_lock(s);
02ac7a34
VJ
247 v9fs_co_run_in_worker(
248 {
2289be19
AK
249 err = s->ops->symlink(&s->ctx, oldpath, &dfidp->path,
250 name->data, &cred);
02ac7a34
VJ
251 if (err < 0) {
252 err = -errno;
02cb7f3a 253 } else {
2289be19
AK
254 v9fs_path_init(&path);
255 err = v9fs_name_to_path(s, &dfidp->path, name->data, &path);
256 if (!err) {
257 err = s->ops->lstat(&s->ctx, &path, stbuf);
258 if (err < 0) {
259 err = -errno;
260 }
02cb7f3a 261 }
2289be19 262 v9fs_path_free(&path);
02ac7a34
VJ
263 }
264 });
532decb7 265 v9fs_path_unlock(s);
2289be19
AK
266 return err;
267}
268
269/*
270 * For path name based fid we don't block. So we can
271 * directly call the fs driver ops.
272 */
273int v9fs_co_name_to_path(V9fsState *s, V9fsPath *dirpath,
274 const char *name, V9fsPath *path)
275{
276 int err;
532decb7
AK
277
278 if (s->ctx.flags & PATHNAME_FSCONTEXT) {
279 err = s->ops->name_to_path(&s->ctx, dirpath, name, path);
280 if (err < 0) {
281 err = -errno;
282 }
283 } else {
284 v9fs_co_run_in_worker(
285 {
286 err = s->ops->name_to_path(&s->ctx, dirpath, name, path);
287 if (err < 0) {
288 err = -errno;
289 }
290 });
2289be19 291 }
02ac7a34
VJ
292 return err;
293}