]> git.proxmox.com Git - qemu.git/blame - hw/9pfs/cofs.c
hw/9pfs: Use read-write lock for protecting fid path.
[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
20int v9fs_co_readlink(V9fsState *s, V9fsString *path, V9fsString *buf)
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
VJJ
28 v9fs_co_run_in_worker(
29 {
30 len = s->ops->readlink(&s->ctx, path->data,
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
VJJ
43 buf->data = NULL;
44 buf->size = 0;
45 }
46 return err;
47}
94840ff9
AK
48
49int v9fs_co_statfs(V9fsState *s, V9fsString *path, struct statfs *stbuf)
50{
51 int err;
52
02cb7f3a 53 qemu_co_rwlock_rdlock(&s->rename_lock);
94840ff9
AK
54 v9fs_co_run_in_worker(
55 {
56 err = s->ops->statfs(&s->ctx, path->data, stbuf);
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
AK
64
65int v9fs_co_chmod(V9fsState *s, V9fsString *path, mode_t mode)
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 {
75 err = s->ops->chmod(&s->ctx, path->data, &cred);
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
84int v9fs_co_utimensat(V9fsState *s, V9fsString *path,
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 {
92 err = s->ops->utimensat(&s->ctx, path->data, times);
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
101int v9fs_co_chown(V9fsState *s, V9fsString *path, uid_t uid, gid_t gid)
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 {
112 err = s->ops->chown(&s->ctx, path->data, &cred);
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
121int v9fs_co_truncate(V9fsState *s, V9fsString *path, off_t size)
122{
123 int err;
124
02cb7f3a 125 qemu_co_rwlock_rdlock(&s->rename_lock);
4011ead2
AK
126 v9fs_co_run_in_worker(
127 {
128 err = s->ops->truncate(&s->ctx, path->data, size);
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;
141 FsCred cred;
02cb7f3a 142 V9fsString fullname;
00ace8c5
AK
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
AK
149 v9fs_string_init(&fullname);
150 qemu_co_rwlock_rdlock(&s->rename_lock);
151 v9fs_string_sprintf(&fullname, "%s/%s", fidp->path.data, name->data);
00ace8c5
AK
152 v9fs_co_run_in_worker(
153 {
02cb7f3a 154 err = s->ops->mknod(&s->ctx, fullname.data, &cred);
00ace8c5
AK
155 if (err < 0) {
156 err = -errno;
02cb7f3a
AK
157 } else {
158 err = s->ops->lstat(&s->ctx, fullname.data, stbuf);
159 if (err < 0) {
160 err = -errno;
161 }
00ace8c5
AK
162 }
163 });
02cb7f3a
AK
164 qemu_co_rwlock_unlock(&s->rename_lock);
165 v9fs_string_free(&fullname);
00ace8c5
AK
166 return err;
167}
b4b1537b
VJ
168
169int v9fs_co_remove(V9fsState *s, V9fsString *path)
170{
171 int err;
172
02cb7f3a 173 qemu_co_rwlock_rdlock(&s->rename_lock);
b4b1537b
VJ
174 v9fs_co_run_in_worker(
175 {
176 err = s->ops->remove(&s->ctx, path->data);
177 if (err < 0) {
178 err = -errno;
179 }
180 });
02cb7f3a 181 qemu_co_rwlock_unlock(&s->rename_lock);
b4b1537b
VJ
182 return err;
183}
2a487e05
AK
184
185int v9fs_co_rename(V9fsState *s, V9fsString *oldpath, V9fsString *newpath)
186{
187 int err;
188
189 v9fs_co_run_in_worker(
190 {
191 err = s->ops->rename(&s->ctx, oldpath->data, newpath->data);
192 if (err < 0) {
193 err = -errno;
194 }
195 });
196 return err;
197}
02ac7a34 198
02cb7f3a
AK
199int v9fs_co_symlink(V9fsState *s, V9fsFidState *dfidp, V9fsString *name,
200 const char *oldpath, gid_t gid, struct stat *stbuf)
02ac7a34
VJ
201{
202 int err;
203 FsCred cred;
02cb7f3a
AK
204 V9fsString fullname;
205
02ac7a34
VJ
206
207 cred_init(&cred);
02cb7f3a 208 cred.fc_uid = dfidp->uid;
02ac7a34
VJ
209 cred.fc_gid = gid;
210 cred.fc_mode = 0777;
02cb7f3a
AK
211 v9fs_string_init(&fullname);
212 qemu_co_rwlock_rdlock(&s->rename_lock);
213 v9fs_string_sprintf(&fullname, "%s/%s", dfidp->path.data, name->data);
02ac7a34
VJ
214 v9fs_co_run_in_worker(
215 {
02cb7f3a 216 err = s->ops->symlink(&s->ctx, oldpath, fullname.data, &cred);
02ac7a34
VJ
217 if (err < 0) {
218 err = -errno;
02cb7f3a
AK
219 } else {
220 err = s->ops->lstat(&s->ctx, fullname.data, stbuf);
221 if (err < 0) {
222 err = -errno;
223 }
02ac7a34
VJ
224 }
225 });
02cb7f3a
AK
226 qemu_co_rwlock_unlock(&s->rename_lock);
227 v9fs_string_free(&fullname);
02ac7a34
VJ
228 return err;
229}