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