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