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 "qemu/osdep.h"
16 #include "fsdev/qemu-fsdev.h"
17 #include "qemu/thread.h"
18 #include "qemu/coroutine.h"
21 int v9fs_co_st_gen(V9fsPDU *pdu, V9fsPath *path, mode_t st_mode,
25 V9fsState *s = pdu->s;
27 if (v9fs_request_cancelled(pdu)) {
30 if (s->ctx.exops.get_st_gen) {
31 v9fs_path_read_lock(s);
32 v9fs_co_run_in_worker(
34 err = s->ctx.exops.get_st_gen(&s->ctx, path, st_mode,
45 int v9fs_co_lstat(V9fsPDU *pdu, V9fsPath *path, struct stat *stbuf)
48 V9fsState *s = pdu->s;
50 if (v9fs_request_cancelled(pdu)) {
53 v9fs_path_read_lock(s);
54 v9fs_co_run_in_worker(
56 err = s->ops->lstat(&s->ctx, path, stbuf);
65 int v9fs_co_fstat(V9fsPDU *pdu, V9fsFidState *fidp, struct stat *stbuf)
68 V9fsState *s = pdu->s;
70 if (v9fs_request_cancelled(pdu)) {
73 v9fs_co_run_in_worker(
75 err = s->ops->fstat(&s->ctx, fidp->fid_type, &fidp->fs, stbuf);
81 * Some FS driver (local:mapped-file) can't support fetching attributes
82 * using file descriptor. Use Path name in that case.
84 if (err == -EOPNOTSUPP) {
85 err = v9fs_co_lstat(pdu, &fidp->path, stbuf);
88 * fstat on an unlinked file. Work with partial results
89 * returned from s->ops->fstat
97 int v9fs_co_open(V9fsPDU *pdu, V9fsFidState *fidp, int flags)
100 V9fsState *s = pdu->s;
102 if (v9fs_request_cancelled(pdu)) {
105 v9fs_path_read_lock(s);
106 v9fs_co_run_in_worker(
108 err = s->ops->open(&s->ctx, &fidp->path, flags, &fidp->fs);
118 if (total_open_fd > open_fd_hw) {
119 v9fs_reclaim_fd(pdu);
125 int v9fs_co_open2(V9fsPDU *pdu, V9fsFidState *fidp, V9fsString *name, gid_t gid,
126 int flags, int mode, struct stat *stbuf)
131 V9fsState *s = pdu->s;
133 if (v9fs_request_cancelled(pdu)) {
137 cred.fc_mode = mode & 07777;
138 cred.fc_uid = fidp->uid;
141 * Hold the directory fid lock so that directory path name
142 * don't change. Read lock is fine because this fid cannot
143 * be used by any other operation.
145 v9fs_path_read_lock(s);
146 v9fs_co_run_in_worker(
148 err = s->ops->open2(&s->ctx, &fidp->path,
149 name->data, flags, &cred, &fidp->fs);
153 v9fs_path_init(&path);
154 err = v9fs_name_to_path(s, &fidp->path, name->data, &path);
156 err = s->ops->lstat(&s->ctx, &path, stbuf);
159 s->ops->close(&s->ctx, &fidp->fs);
161 v9fs_path_copy(&fidp->path, &path);
164 s->ops->close(&s->ctx, &fidp->fs);
166 v9fs_path_free(&path);
172 if (total_open_fd > open_fd_hw) {
173 v9fs_reclaim_fd(pdu);
179 int v9fs_co_close(V9fsPDU *pdu, V9fsFidOpenState *fs)
182 V9fsState *s = pdu->s;
184 if (v9fs_request_cancelled(pdu)) {
187 v9fs_co_run_in_worker(
189 err = s->ops->close(&s->ctx, fs);
200 int v9fs_co_fsync(V9fsPDU *pdu, V9fsFidState *fidp, int datasync)
203 V9fsState *s = pdu->s;
205 if (v9fs_request_cancelled(pdu)) {
208 v9fs_co_run_in_worker(
210 err = s->ops->fsync(&s->ctx, fidp->fid_type, &fidp->fs, datasync);
218 int v9fs_co_link(V9fsPDU *pdu, V9fsFidState *oldfid,
219 V9fsFidState *newdirfid, V9fsString *name)
222 V9fsState *s = pdu->s;
224 if (v9fs_request_cancelled(pdu)) {
227 v9fs_path_read_lock(s);
228 v9fs_co_run_in_worker(
230 err = s->ops->link(&s->ctx, &oldfid->path,
231 &newdirfid->path, name->data);
240 int v9fs_co_pwritev(V9fsPDU *pdu, V9fsFidState *fidp,
241 struct iovec *iov, int iovcnt, int64_t offset)
244 V9fsState *s = pdu->s;
246 if (v9fs_request_cancelled(pdu)) {
249 v9fs_co_run_in_worker(
251 err = s->ops->pwritev(&s->ctx, &fidp->fs, iov, iovcnt, offset);
259 int v9fs_co_preadv(V9fsPDU *pdu, V9fsFidState *fidp,
260 struct iovec *iov, int iovcnt, int64_t offset)
263 V9fsState *s = pdu->s;
265 if (v9fs_request_cancelled(pdu)) {
268 v9fs_co_run_in_worker(
270 err = s->ops->preadv(&s->ctx, &fidp->fs, iov, iovcnt, offset);