5 * Copyright IBM, Corp. 2011
8 * Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
10 * This work is licensed under the terms of the GNU GPL, version 2. See
11 * the COPYING file in the top-level directory.
15 #include "fsdev/qemu-fsdev.h"
16 #include "qemu/thread.h"
17 #include "block/coroutine.h"
18 #include "virtio-9p-coth.h"
20 int v9fs_co_st_gen(V9fsPDU
*pdu
, V9fsPath
*path
, mode_t st_mode
,
24 V9fsState
*s
= pdu
->s
;
26 if (v9fs_request_cancelled(pdu
)) {
29 if (s
->ctx
.exops
.get_st_gen
) {
30 v9fs_path_read_lock(s
);
31 v9fs_co_run_in_worker(
33 err
= s
->ctx
.exops
.get_st_gen(&s
->ctx
, path
, st_mode
,
41 /* The ioctl may not be supported depending on the path */
48 int v9fs_co_lstat(V9fsPDU
*pdu
, V9fsPath
*path
, struct stat
*stbuf
)
51 V9fsState
*s
= pdu
->s
;
53 if (v9fs_request_cancelled(pdu
)) {
56 v9fs_path_read_lock(s
);
57 v9fs_co_run_in_worker(
59 err
= s
->ops
->lstat(&s
->ctx
, path
, stbuf
);
68 int v9fs_co_fstat(V9fsPDU
*pdu
, V9fsFidState
*fidp
, struct stat
*stbuf
)
71 V9fsState
*s
= pdu
->s
;
73 if (v9fs_request_cancelled(pdu
)) {
76 v9fs_co_run_in_worker(
78 err
= s
->ops
->fstat(&s
->ctx
, fidp
->fid_type
, &fidp
->fs
, stbuf
);
84 * Some FS driver (local:mapped-file) can't support fetching attributes
85 * using file descriptor. Use Path name in that case.
87 if (err
== -EOPNOTSUPP
) {
88 err
= v9fs_co_lstat(pdu
, &fidp
->path
, stbuf
);
91 * fstat on an unlinked file. Work with partial results
92 * returned from s->ops->fstat
100 int v9fs_co_open(V9fsPDU
*pdu
, V9fsFidState
*fidp
, int flags
)
103 V9fsState
*s
= pdu
->s
;
105 if (v9fs_request_cancelled(pdu
)) {
108 v9fs_path_read_lock(s
);
109 v9fs_co_run_in_worker(
111 err
= s
->ops
->open(&s
->ctx
, &fidp
->path
, flags
, &fidp
->fs
);
121 if (total_open_fd
> open_fd_hw
) {
122 v9fs_reclaim_fd(pdu
);
128 int v9fs_co_open2(V9fsPDU
*pdu
, V9fsFidState
*fidp
, V9fsString
*name
, gid_t gid
,
129 int flags
, int mode
, struct stat
*stbuf
)
134 V9fsState
*s
= pdu
->s
;
136 if (v9fs_request_cancelled(pdu
)) {
140 cred
.fc_mode
= mode
& 07777;
141 cred
.fc_uid
= fidp
->uid
;
144 * Hold the directory fid lock so that directory path name
145 * don't change. Read lock is fine because this fid cannot
146 * be used by any other operation.
148 v9fs_path_read_lock(s
);
149 v9fs_co_run_in_worker(
151 err
= s
->ops
->open2(&s
->ctx
, &fidp
->path
,
152 name
->data
, flags
, &cred
, &fidp
->fs
);
156 v9fs_path_init(&path
);
157 err
= v9fs_name_to_path(s
, &fidp
->path
, name
->data
, &path
);
159 err
= s
->ops
->lstat(&s
->ctx
, &path
, stbuf
);
162 s
->ops
->close(&s
->ctx
, &fidp
->fs
);
164 v9fs_path_copy(&fidp
->path
, &path
);
167 s
->ops
->close(&s
->ctx
, &fidp
->fs
);
169 v9fs_path_free(&path
);
175 if (total_open_fd
> open_fd_hw
) {
176 v9fs_reclaim_fd(pdu
);
182 int v9fs_co_close(V9fsPDU
*pdu
, V9fsFidOpenState
*fs
)
185 V9fsState
*s
= pdu
->s
;
187 if (v9fs_request_cancelled(pdu
)) {
190 v9fs_co_run_in_worker(
192 err
= s
->ops
->close(&s
->ctx
, fs
);
203 int v9fs_co_fsync(V9fsPDU
*pdu
, V9fsFidState
*fidp
, int datasync
)
206 V9fsState
*s
= pdu
->s
;
208 if (v9fs_request_cancelled(pdu
)) {
211 v9fs_co_run_in_worker(
213 err
= s
->ops
->fsync(&s
->ctx
, fidp
->fid_type
, &fidp
->fs
, datasync
);
221 int v9fs_co_link(V9fsPDU
*pdu
, V9fsFidState
*oldfid
,
222 V9fsFidState
*newdirfid
, V9fsString
*name
)
225 V9fsState
*s
= pdu
->s
;
227 if (v9fs_request_cancelled(pdu
)) {
230 v9fs_path_read_lock(s
);
231 v9fs_co_run_in_worker(
233 err
= s
->ops
->link(&s
->ctx
, &oldfid
->path
,
234 &newdirfid
->path
, name
->data
);
243 int v9fs_co_pwritev(V9fsPDU
*pdu
, V9fsFidState
*fidp
,
244 struct iovec
*iov
, int iovcnt
, int64_t offset
)
247 V9fsState
*s
= pdu
->s
;
249 if (v9fs_request_cancelled(pdu
)) {
252 v9fs_co_run_in_worker(
254 err
= s
->ops
->pwritev(&s
->ctx
, &fidp
->fs
, iov
, iovcnt
, offset
);
262 int v9fs_co_preadv(V9fsPDU
*pdu
, V9fsFidState
*fidp
,
263 struct iovec
*iov
, int iovcnt
, int64_t offset
)
266 V9fsState
*s
= pdu
->s
;
268 if (v9fs_request_cancelled(pdu
)) {
271 v9fs_co_run_in_worker(
273 err
= s
->ops
->preadv(&s
->ctx
, &fidp
->fs
, iov
, iovcnt
, offset
);