Merge remote-tracking branch 'aneesh/for-upstream-3' into staging
[sdk/emulator/qemu.git] / hw / 9pfs / cofile.c
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
20 int v9fs_co_lstat(V9fsState *s, V9fsString *path, struct stat *stbuf)
21 {
22     int err;
23
24     v9fs_co_run_in_worker(
25         {
26             err = s->ops->lstat(&s->ctx, path->data, stbuf);
27             if (err < 0) {
28                 err = -errno;
29             }
30         });
31     return err;
32 }
33
34 int v9fs_co_fstat(V9fsState *s, int fd, struct stat *stbuf)
35 {
36     int err;
37
38     v9fs_co_run_in_worker(
39         {
40             err = s->ops->fstat(&s->ctx, fd, stbuf);
41             if (err < 0) {
42                 err = -errno;
43             }
44         });
45     return err;
46 }
47
48 int v9fs_co_open(V9fsState *s, V9fsFidState *fidp, int flags)
49 {
50     int err;
51
52     v9fs_co_run_in_worker(
53         {
54             fidp->fs.fd = s->ops->open(&s->ctx, fidp->path.data, flags);
55             if (fidp->fs.fd == -1) {
56                 err = -errno;
57             } else {
58                 err = 0;
59             }
60         });
61     if (!err) {
62         total_open_fd++;
63         if (total_open_fd > open_fd_hw) {
64             v9fs_reclaim_fd(s);
65         }
66     }
67     return err;
68 }
69
70 int v9fs_co_open2(V9fsState *s, V9fsFidState *fidp, char *fullname, gid_t gid,
71                   int flags, int mode)
72 {
73     int err;
74     FsCred cred;
75
76     cred_init(&cred);
77     cred.fc_mode = mode & 07777;
78     cred.fc_uid = fidp->uid;
79     cred.fc_gid = gid;
80     v9fs_co_run_in_worker(
81         {
82             fidp->fs.fd = s->ops->open2(&s->ctx, fullname, flags, &cred);
83             err = 0;
84             if (fidp->fs.fd == -1) {
85                 err = -errno;
86             }
87         });
88     if (!err) {
89         total_open_fd++;
90         if (total_open_fd > open_fd_hw) {
91             v9fs_reclaim_fd(s);
92         }
93     }
94     return err;
95 }
96
97 int v9fs_co_close(V9fsState *s, int fd)
98 {
99     int err;
100
101     v9fs_co_run_in_worker(
102         {
103             err = s->ops->close(&s->ctx, fd);
104             if (err < 0) {
105                 err = -errno;
106             }
107         });
108     if (!err) {
109         total_open_fd--;
110     }
111     return err;
112 }
113
114 int v9fs_co_fsync(V9fsState *s, V9fsFidState *fidp, int datasync)
115 {
116     int fd;
117     int err;
118
119     fd = fidp->fs.fd;
120     v9fs_co_run_in_worker(
121         {
122             err = s->ops->fsync(&s->ctx, fd, datasync);
123             if (err < 0) {
124                 err = -errno;
125             }
126         });
127     return err;
128 }
129
130 int v9fs_co_link(V9fsState *s, V9fsString *oldpath, V9fsString *newpath)
131 {
132     int err;
133
134     v9fs_co_run_in_worker(
135         {
136             err = s->ops->link(&s->ctx, oldpath->data, newpath->data);
137             if (err < 0) {
138                 err = -errno;
139             }
140         });
141     return err;
142 }
143
144 int v9fs_co_pwritev(V9fsState *s, V9fsFidState *fidp,
145                     struct iovec *iov, int iovcnt, int64_t offset)
146 {
147     int fd;
148     int err;
149
150     fd = fidp->fs.fd;
151     v9fs_co_run_in_worker(
152         {
153             err = s->ops->pwritev(&s->ctx, fd, iov, iovcnt, offset);
154             if (err < 0) {
155                 err = -errno;
156             }
157         });
158     return err;
159 }
160
161 int v9fs_co_preadv(V9fsState *s, V9fsFidState *fidp,
162                    struct iovec *iov, int iovcnt, int64_t offset)
163 {
164     int fd;
165     int err;
166
167     fd = fidp->fs.fd;
168     v9fs_co_run_in_worker(
169         {
170             err = s->ops->preadv(&s->ctx, fd, iov, iovcnt, offset);
171             if (err < 0) {
172                 err = -errno;
173             }
174         });
175     return err;
176 }