]>
Commit | Line | Data |
---|---|---|
172198d4 AK |
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 | ||
e06a765e HPB |
20 | int v9fs_co_st_gen(V9fsPDU *pdu, V9fsPath *path, mode_t st_mode, |
21 | V9fsStatDotl *v9stat) | |
22 | { | |
23 | int err = 0; | |
24 | V9fsState *s = pdu->s; | |
25 | ||
26 | if (v9fs_request_cancelled(pdu)) { | |
27 | return -EINTR; | |
28 | } | |
29 | if (s->ctx.exops.get_st_gen) { | |
30 | v9fs_path_read_lock(s); | |
31 | v9fs_co_run_in_worker( | |
32 | { | |
33 | err = s->ctx.exops.get_st_gen(&s->ctx, path, st_mode, | |
34 | &v9stat->st_gen); | |
35 | if (err < 0) { | |
36 | err = -errno; | |
37 | } | |
38 | }); | |
39 | v9fs_path_unlock(s); | |
40 | } | |
41 | return err; | |
42 | } | |
43 | ||
bccacf6c | 44 | int v9fs_co_lstat(V9fsPDU *pdu, V9fsPath *path, struct stat *stbuf) |
172198d4 AK |
45 | { |
46 | int err; | |
bccacf6c | 47 | V9fsState *s = pdu->s; |
172198d4 | 48 | |
bccacf6c AK |
49 | if (v9fs_request_cancelled(pdu)) { |
50 | return -EINTR; | |
51 | } | |
532decb7 | 52 | v9fs_path_read_lock(s); |
172198d4 AK |
53 | v9fs_co_run_in_worker( |
54 | { | |
2289be19 | 55 | err = s->ops->lstat(&s->ctx, path, stbuf); |
172198d4 AK |
56 | if (err < 0) { |
57 | err = -errno; | |
58 | } | |
59 | }); | |
532decb7 | 60 | v9fs_path_unlock(s); |
172198d4 AK |
61 | return err; |
62 | } | |
03feb1e1 | 63 | |
cc720ddb | 64 | int v9fs_co_fstat(V9fsPDU *pdu, V9fsFidState *fidp, struct stat *stbuf) |
03feb1e1 AK |
65 | { |
66 | int err; | |
bccacf6c | 67 | V9fsState *s = pdu->s; |
03feb1e1 | 68 | |
bccacf6c AK |
69 | if (v9fs_request_cancelled(pdu)) { |
70 | return -EINTR; | |
71 | } | |
03feb1e1 AK |
72 | v9fs_co_run_in_worker( |
73 | { | |
cc720ddb | 74 | err = s->ops->fstat(&s->ctx, &fidp->fs, stbuf); |
03feb1e1 AK |
75 | if (err < 0) { |
76 | err = -errno; | |
77 | } | |
78 | }); | |
79 | return err; | |
80 | } | |
f6b7f0ab | 81 | |
bccacf6c | 82 | int v9fs_co_open(V9fsPDU *pdu, V9fsFidState *fidp, int flags) |
f6b7f0ab AK |
83 | { |
84 | int err; | |
bccacf6c | 85 | V9fsState *s = pdu->s; |
f6b7f0ab | 86 | |
bccacf6c AK |
87 | if (v9fs_request_cancelled(pdu)) { |
88 | return -EINTR; | |
89 | } | |
532decb7 | 90 | v9fs_path_read_lock(s); |
f6b7f0ab AK |
91 | v9fs_co_run_in_worker( |
92 | { | |
cc720ddb AK |
93 | err = s->ops->open(&s->ctx, &fidp->path, flags, &fidp->fs); |
94 | if (err == -1) { | |
f6b7f0ab AK |
95 | err = -errno; |
96 | } else { | |
97 | err = 0; | |
98 | } | |
99 | }); | |
532decb7 | 100 | v9fs_path_unlock(s); |
7a462745 AK |
101 | if (!err) { |
102 | total_open_fd++; | |
103 | if (total_open_fd > open_fd_hw) { | |
bccacf6c | 104 | v9fs_reclaim_fd(pdu); |
7a462745 AK |
105 | } |
106 | } | |
f6b7f0ab AK |
107 | return err; |
108 | } | |
e4de4232 | 109 | |
bccacf6c | 110 | int v9fs_co_open2(V9fsPDU *pdu, V9fsFidState *fidp, V9fsString *name, gid_t gid, |
02cb7f3a | 111 | int flags, int mode, struct stat *stbuf) |
e4de4232 VJ |
112 | { |
113 | int err; | |
114 | FsCred cred; | |
2289be19 | 115 | V9fsPath path; |
bccacf6c | 116 | V9fsState *s = pdu->s; |
2289be19 | 117 | |
bccacf6c AK |
118 | if (v9fs_request_cancelled(pdu)) { |
119 | return -EINTR; | |
120 | } | |
e4de4232 VJ |
121 | cred_init(&cred); |
122 | cred.fc_mode = mode & 07777; | |
123 | cred.fc_uid = fidp->uid; | |
124 | cred.fc_gid = gid; | |
02cb7f3a AK |
125 | /* |
126 | * Hold the directory fid lock so that directory path name | |
127 | * don't change. Read lock is fine because this fid cannot | |
128 | * be used by any other operation. | |
129 | */ | |
532decb7 | 130 | v9fs_path_read_lock(s); |
e4de4232 VJ |
131 | v9fs_co_run_in_worker( |
132 | { | |
cc720ddb AK |
133 | err = s->ops->open2(&s->ctx, &fidp->path, |
134 | name->data, flags, &cred, &fidp->fs); | |
135 | if (err < 0) { | |
e4de4232 | 136 | err = -errno; |
02cb7f3a | 137 | } else { |
2289be19 AK |
138 | v9fs_path_init(&path); |
139 | err = v9fs_name_to_path(s, &fidp->path, name->data, &path); | |
140 | if (!err) { | |
141 | err = s->ops->lstat(&s->ctx, &path, stbuf); | |
142 | if (err < 0) { | |
143 | err = -errno; | |
cc720ddb | 144 | s->ops->close(&s->ctx, &fidp->fs); |
2289be19 AK |
145 | } else { |
146 | v9fs_path_copy(&fidp->path, &path); | |
147 | } | |
02cb7f3a | 148 | } else { |
cc720ddb | 149 | s->ops->close(&s->ctx, &fidp->fs); |
02cb7f3a | 150 | } |
2289be19 | 151 | v9fs_path_free(&path); |
e4de4232 VJ |
152 | } |
153 | }); | |
532decb7 | 154 | v9fs_path_unlock(s); |
7a462745 AK |
155 | if (!err) { |
156 | total_open_fd++; | |
157 | if (total_open_fd > open_fd_hw) { | |
bccacf6c | 158 | v9fs_reclaim_fd(pdu); |
7a462745 AK |
159 | } |
160 | } | |
e4de4232 VJ |
161 | return err; |
162 | } | |
bed4352c | 163 | |
cc720ddb | 164 | int v9fs_co_close(V9fsPDU *pdu, V9fsFidOpenState *fs) |
bed4352c | 165 | { |
bed4352c | 166 | int err; |
bccacf6c | 167 | V9fsState *s = pdu->s; |
bed4352c | 168 | |
bccacf6c AK |
169 | if (v9fs_request_cancelled(pdu)) { |
170 | return -EINTR; | |
171 | } | |
bed4352c AK |
172 | v9fs_co_run_in_worker( |
173 | { | |
cc720ddb | 174 | err = s->ops->close(&s->ctx, fs); |
bed4352c AK |
175 | if (err < 0) { |
176 | err = -errno; | |
177 | } | |
178 | }); | |
7a462745 AK |
179 | if (!err) { |
180 | total_open_fd--; | |
181 | } | |
bed4352c AK |
182 | return err; |
183 | } | |
4743d1f5 | 184 | |
bccacf6c | 185 | int v9fs_co_fsync(V9fsPDU *pdu, V9fsFidState *fidp, int datasync) |
4743d1f5 | 186 | { |
cc720ddb | 187 | int err; |
bccacf6c | 188 | V9fsState *s = pdu->s; |
4743d1f5 | 189 | |
bccacf6c AK |
190 | if (v9fs_request_cancelled(pdu)) { |
191 | return -EINTR; | |
192 | } | |
4743d1f5 AK |
193 | v9fs_co_run_in_worker( |
194 | { | |
cc720ddb | 195 | err = s->ops->fsync(&s->ctx, &fidp->fs, datasync); |
4743d1f5 AK |
196 | if (err < 0) { |
197 | err = -errno; | |
198 | } | |
199 | }); | |
200 | return err; | |
201 | } | |
c6c069b0 | 202 | |
bccacf6c | 203 | int v9fs_co_link(V9fsPDU *pdu, V9fsFidState *oldfid, |
2289be19 | 204 | V9fsFidState *newdirfid, V9fsString *name) |
c6c069b0 VJ |
205 | { |
206 | int err; | |
bccacf6c | 207 | V9fsState *s = pdu->s; |
c6c069b0 | 208 | |
bccacf6c AK |
209 | if (v9fs_request_cancelled(pdu)) { |
210 | return -EINTR; | |
211 | } | |
532decb7 | 212 | v9fs_path_read_lock(s); |
c6c069b0 VJ |
213 | v9fs_co_run_in_worker( |
214 | { | |
2289be19 AK |
215 | err = s->ops->link(&s->ctx, &oldfid->path, |
216 | &newdirfid->path, name->data); | |
c6c069b0 VJ |
217 | if (err < 0) { |
218 | err = -errno; | |
219 | } | |
220 | }); | |
532decb7 | 221 | v9fs_path_unlock(s); |
c6c069b0 VJ |
222 | return err; |
223 | } | |
f6b3c976 | 224 | |
bccacf6c | 225 | int v9fs_co_pwritev(V9fsPDU *pdu, V9fsFidState *fidp, |
f6b3c976 AK |
226 | struct iovec *iov, int iovcnt, int64_t offset) |
227 | { | |
cc720ddb | 228 | int err; |
bccacf6c | 229 | V9fsState *s = pdu->s; |
f6b3c976 | 230 | |
bccacf6c AK |
231 | if (v9fs_request_cancelled(pdu)) { |
232 | return -EINTR; | |
233 | } | |
f6b3c976 AK |
234 | v9fs_co_run_in_worker( |
235 | { | |
cc720ddb | 236 | err = s->ops->pwritev(&s->ctx, &fidp->fs, iov, iovcnt, offset); |
f6b3c976 AK |
237 | if (err < 0) { |
238 | err = -errno; | |
239 | } | |
240 | }); | |
241 | return err; | |
242 | } | |
7eafdcc9 | 243 | |
bccacf6c | 244 | int v9fs_co_preadv(V9fsPDU *pdu, V9fsFidState *fidp, |
7eafdcc9 AK |
245 | struct iovec *iov, int iovcnt, int64_t offset) |
246 | { | |
cc720ddb | 247 | int err; |
bccacf6c | 248 | V9fsState *s = pdu->s; |
7eafdcc9 | 249 | |
bccacf6c AK |
250 | if (v9fs_request_cancelled(pdu)) { |
251 | return -EINTR; | |
252 | } | |
7eafdcc9 AK |
253 | v9fs_co_run_in_worker( |
254 | { | |
cc720ddb | 255 | err = s->ops->preadv(&s->ctx, &fidp->fs, iov, iovcnt, offset); |
7eafdcc9 AK |
256 | if (err < 0) { |
257 | err = -errno; | |
258 | } | |
259 | }); | |
260 | return err; | |
261 | } |