xref: /openbmc/qemu/hw/9pfs/cofile.c (revision 1de7afc9)
1172198d4SAneesh Kumar K.V 
2172198d4SAneesh Kumar K.V /*
3172198d4SAneesh Kumar K.V  * Virtio 9p backend
4172198d4SAneesh Kumar K.V  *
5172198d4SAneesh Kumar K.V  * Copyright IBM, Corp. 2011
6172198d4SAneesh Kumar K.V  *
7172198d4SAneesh Kumar K.V  * Authors:
8172198d4SAneesh Kumar K.V  *  Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
9172198d4SAneesh Kumar K.V  *
10172198d4SAneesh Kumar K.V  * This work is licensed under the terms of the GNU GPL, version 2.  See
11172198d4SAneesh Kumar K.V  * the COPYING file in the top-level directory.
12172198d4SAneesh Kumar K.V  *
13172198d4SAneesh Kumar K.V  */
14172198d4SAneesh Kumar K.V 
15172198d4SAneesh Kumar K.V #include "fsdev/qemu-fsdev.h"
16*1de7afc9SPaolo Bonzini #include "qemu/thread.h"
17737e150eSPaolo Bonzini #include "block/coroutine.h"
18172198d4SAneesh Kumar K.V #include "virtio-9p-coth.h"
19172198d4SAneesh Kumar K.V 
20e06a765eSHarsh Prateek Bora int v9fs_co_st_gen(V9fsPDU *pdu, V9fsPath *path, mode_t st_mode,
21e06a765eSHarsh Prateek Bora                    V9fsStatDotl *v9stat)
22e06a765eSHarsh Prateek Bora {
23e06a765eSHarsh Prateek Bora     int err = 0;
24e06a765eSHarsh Prateek Bora     V9fsState *s = pdu->s;
25e06a765eSHarsh Prateek Bora 
26e06a765eSHarsh Prateek Bora     if (v9fs_request_cancelled(pdu)) {
27e06a765eSHarsh Prateek Bora         return -EINTR;
28e06a765eSHarsh Prateek Bora     }
29e06a765eSHarsh Prateek Bora     if (s->ctx.exops.get_st_gen) {
30e06a765eSHarsh Prateek Bora         v9fs_path_read_lock(s);
31e06a765eSHarsh Prateek Bora         v9fs_co_run_in_worker(
32e06a765eSHarsh Prateek Bora             {
33e06a765eSHarsh Prateek Bora                 err = s->ctx.exops.get_st_gen(&s->ctx, path, st_mode,
34e06a765eSHarsh Prateek Bora                                               &v9stat->st_gen);
35e06a765eSHarsh Prateek Bora                 if (err < 0) {
36e06a765eSHarsh Prateek Bora                     err = -errno;
37e06a765eSHarsh Prateek Bora                 }
38e06a765eSHarsh Prateek Bora             });
39e06a765eSHarsh Prateek Bora         v9fs_path_unlock(s);
40e06a765eSHarsh Prateek Bora     }
41e06a765eSHarsh Prateek Bora     return err;
42e06a765eSHarsh Prateek Bora }
43e06a765eSHarsh Prateek Bora 
44bccacf6cSAneesh Kumar K.V int v9fs_co_lstat(V9fsPDU *pdu, V9fsPath *path, struct stat *stbuf)
45172198d4SAneesh Kumar K.V {
46172198d4SAneesh Kumar K.V     int err;
47bccacf6cSAneesh Kumar K.V     V9fsState *s = pdu->s;
48172198d4SAneesh Kumar K.V 
49bccacf6cSAneesh Kumar K.V     if (v9fs_request_cancelled(pdu)) {
50bccacf6cSAneesh Kumar K.V         return -EINTR;
51bccacf6cSAneesh Kumar K.V     }
52532decb7SAneesh Kumar K.V     v9fs_path_read_lock(s);
53172198d4SAneesh Kumar K.V     v9fs_co_run_in_worker(
54172198d4SAneesh Kumar K.V         {
552289be19SAneesh Kumar K.V             err = s->ops->lstat(&s->ctx, path, stbuf);
56172198d4SAneesh Kumar K.V             if (err < 0) {
57172198d4SAneesh Kumar K.V                 err = -errno;
58172198d4SAneesh Kumar K.V             }
59172198d4SAneesh Kumar K.V         });
60532decb7SAneesh Kumar K.V     v9fs_path_unlock(s);
61172198d4SAneesh Kumar K.V     return err;
62172198d4SAneesh Kumar K.V }
6303feb1e1SAneesh Kumar K.V 
64cc720ddbSAneesh Kumar K.V int v9fs_co_fstat(V9fsPDU *pdu, V9fsFidState *fidp, struct stat *stbuf)
6503feb1e1SAneesh Kumar K.V {
6603feb1e1SAneesh Kumar K.V     int err;
67bccacf6cSAneesh Kumar K.V     V9fsState *s = pdu->s;
6803feb1e1SAneesh Kumar K.V 
69bccacf6cSAneesh Kumar K.V     if (v9fs_request_cancelled(pdu)) {
70bccacf6cSAneesh Kumar K.V         return -EINTR;
71bccacf6cSAneesh Kumar K.V     }
7203feb1e1SAneesh Kumar K.V     v9fs_co_run_in_worker(
7303feb1e1SAneesh Kumar K.V         {
748b888272SAneesh Kumar K.V             err = s->ops->fstat(&s->ctx, fidp->fid_type, &fidp->fs, stbuf);
7503feb1e1SAneesh Kumar K.V             if (err < 0) {
7603feb1e1SAneesh Kumar K.V                 err = -errno;
7703feb1e1SAneesh Kumar K.V             }
7803feb1e1SAneesh Kumar K.V         });
792c30dd74SAneesh Kumar K.V     /*
802c30dd74SAneesh Kumar K.V      * Some FS driver (local:mapped-file) can't support fetching attributes
812c30dd74SAneesh Kumar K.V      * using file descriptor. Use Path name in that case.
822c30dd74SAneesh Kumar K.V      */
832c30dd74SAneesh Kumar K.V     if (err == -EOPNOTSUPP) {
842c30dd74SAneesh Kumar K.V         err = v9fs_co_lstat(pdu, &fidp->path, stbuf);
852c30dd74SAneesh Kumar K.V         if (err == -ENOENT) {
862c30dd74SAneesh Kumar K.V             /*
872c30dd74SAneesh Kumar K.V              * fstat on an unlinked file. Work with partial results
882c30dd74SAneesh Kumar K.V              * returned from s->ops->fstat
892c30dd74SAneesh Kumar K.V              */
902c30dd74SAneesh Kumar K.V             err = 0;
912c30dd74SAneesh Kumar K.V         }
922c30dd74SAneesh Kumar K.V     }
9303feb1e1SAneesh Kumar K.V     return err;
9403feb1e1SAneesh Kumar K.V }
95f6b7f0abSAneesh Kumar K.V 
96bccacf6cSAneesh Kumar K.V int v9fs_co_open(V9fsPDU *pdu, V9fsFidState *fidp, int flags)
97f6b7f0abSAneesh Kumar K.V {
98f6b7f0abSAneesh Kumar K.V     int err;
99bccacf6cSAneesh Kumar K.V     V9fsState *s = pdu->s;
100f6b7f0abSAneesh Kumar K.V 
101bccacf6cSAneesh Kumar K.V     if (v9fs_request_cancelled(pdu)) {
102bccacf6cSAneesh Kumar K.V         return -EINTR;
103bccacf6cSAneesh Kumar K.V     }
104532decb7SAneesh Kumar K.V     v9fs_path_read_lock(s);
105f6b7f0abSAneesh Kumar K.V     v9fs_co_run_in_worker(
106f6b7f0abSAneesh Kumar K.V         {
107cc720ddbSAneesh Kumar K.V             err = s->ops->open(&s->ctx, &fidp->path, flags, &fidp->fs);
108cc720ddbSAneesh Kumar K.V             if (err == -1) {
109f6b7f0abSAneesh Kumar K.V                 err = -errno;
110f6b7f0abSAneesh Kumar K.V             } else {
111f6b7f0abSAneesh Kumar K.V                 err = 0;
112f6b7f0abSAneesh Kumar K.V             }
113f6b7f0abSAneesh Kumar K.V         });
114532decb7SAneesh Kumar K.V     v9fs_path_unlock(s);
1157a462745SAneesh Kumar K.V     if (!err) {
1167a462745SAneesh Kumar K.V         total_open_fd++;
1177a462745SAneesh Kumar K.V         if (total_open_fd > open_fd_hw) {
118bccacf6cSAneesh Kumar K.V             v9fs_reclaim_fd(pdu);
1197a462745SAneesh Kumar K.V         }
1207a462745SAneesh Kumar K.V     }
121f6b7f0abSAneesh Kumar K.V     return err;
122f6b7f0abSAneesh Kumar K.V }
123e4de4232SVenkateswararao Jujjuri 
124bccacf6cSAneesh Kumar K.V int v9fs_co_open2(V9fsPDU *pdu, V9fsFidState *fidp, V9fsString *name, gid_t gid,
12502cb7f3aSAneesh Kumar K.V                   int flags, int mode, struct stat *stbuf)
126e4de4232SVenkateswararao Jujjuri {
127e4de4232SVenkateswararao Jujjuri     int err;
128e4de4232SVenkateswararao Jujjuri     FsCred cred;
1292289be19SAneesh Kumar K.V     V9fsPath path;
130bccacf6cSAneesh Kumar K.V     V9fsState *s = pdu->s;
1312289be19SAneesh Kumar K.V 
132bccacf6cSAneesh Kumar K.V     if (v9fs_request_cancelled(pdu)) {
133bccacf6cSAneesh Kumar K.V         return -EINTR;
134bccacf6cSAneesh Kumar K.V     }
135e4de4232SVenkateswararao Jujjuri     cred_init(&cred);
136e4de4232SVenkateswararao Jujjuri     cred.fc_mode = mode & 07777;
137e4de4232SVenkateswararao Jujjuri     cred.fc_uid = fidp->uid;
138e4de4232SVenkateswararao Jujjuri     cred.fc_gid = gid;
13902cb7f3aSAneesh Kumar K.V     /*
14002cb7f3aSAneesh Kumar K.V      * Hold the directory fid lock so that directory path name
14102cb7f3aSAneesh Kumar K.V      * don't change. Read lock is fine because this fid cannot
14202cb7f3aSAneesh Kumar K.V      * be used by any other operation.
14302cb7f3aSAneesh Kumar K.V      */
144532decb7SAneesh Kumar K.V     v9fs_path_read_lock(s);
145e4de4232SVenkateswararao Jujjuri     v9fs_co_run_in_worker(
146e4de4232SVenkateswararao Jujjuri         {
147cc720ddbSAneesh Kumar K.V             err = s->ops->open2(&s->ctx, &fidp->path,
148cc720ddbSAneesh Kumar K.V                                 name->data, flags, &cred, &fidp->fs);
149cc720ddbSAneesh Kumar K.V             if (err < 0) {
150e4de4232SVenkateswararao Jujjuri                 err = -errno;
15102cb7f3aSAneesh Kumar K.V             } else {
1522289be19SAneesh Kumar K.V                 v9fs_path_init(&path);
1532289be19SAneesh Kumar K.V                 err = v9fs_name_to_path(s, &fidp->path, name->data, &path);
1542289be19SAneesh Kumar K.V                 if (!err) {
1552289be19SAneesh Kumar K.V                     err = s->ops->lstat(&s->ctx, &path, stbuf);
15602cb7f3aSAneesh Kumar K.V                     if (err < 0) {
15702cb7f3aSAneesh Kumar K.V                         err = -errno;
158cc720ddbSAneesh Kumar K.V                         s->ops->close(&s->ctx, &fidp->fs);
15902cb7f3aSAneesh Kumar K.V                     } else {
1602289be19SAneesh Kumar K.V                         v9fs_path_copy(&fidp->path, &path);
16102cb7f3aSAneesh Kumar K.V                     }
1622289be19SAneesh Kumar K.V                 } else {
163cc720ddbSAneesh Kumar K.V                     s->ops->close(&s->ctx, &fidp->fs);
1642289be19SAneesh Kumar K.V                 }
1652289be19SAneesh Kumar K.V                 v9fs_path_free(&path);
166e4de4232SVenkateswararao Jujjuri             }
167e4de4232SVenkateswararao Jujjuri         });
168532decb7SAneesh Kumar K.V     v9fs_path_unlock(s);
1697a462745SAneesh Kumar K.V     if (!err) {
1707a462745SAneesh Kumar K.V         total_open_fd++;
1717a462745SAneesh Kumar K.V         if (total_open_fd > open_fd_hw) {
172bccacf6cSAneesh Kumar K.V             v9fs_reclaim_fd(pdu);
1737a462745SAneesh Kumar K.V         }
1747a462745SAneesh Kumar K.V     }
175e4de4232SVenkateswararao Jujjuri     return err;
176e4de4232SVenkateswararao Jujjuri }
177bed4352cSAneesh Kumar K.V 
178cc720ddbSAneesh Kumar K.V int v9fs_co_close(V9fsPDU *pdu, V9fsFidOpenState *fs)
179bed4352cSAneesh Kumar K.V {
180bed4352cSAneesh Kumar K.V     int err;
181bccacf6cSAneesh Kumar K.V     V9fsState *s = pdu->s;
182bed4352cSAneesh Kumar K.V 
183bccacf6cSAneesh Kumar K.V     if (v9fs_request_cancelled(pdu)) {
184bccacf6cSAneesh Kumar K.V         return -EINTR;
185bccacf6cSAneesh Kumar K.V     }
186bed4352cSAneesh Kumar K.V     v9fs_co_run_in_worker(
187bed4352cSAneesh Kumar K.V         {
188cc720ddbSAneesh Kumar K.V             err = s->ops->close(&s->ctx, fs);
189bed4352cSAneesh Kumar K.V             if (err < 0) {
190bed4352cSAneesh Kumar K.V                 err = -errno;
191bed4352cSAneesh Kumar K.V             }
192bed4352cSAneesh Kumar K.V         });
1937a462745SAneesh Kumar K.V     if (!err) {
1947a462745SAneesh Kumar K.V         total_open_fd--;
1957a462745SAneesh Kumar K.V     }
196bed4352cSAneesh Kumar K.V     return err;
197bed4352cSAneesh Kumar K.V }
1984743d1f5SAneesh Kumar K.V 
199bccacf6cSAneesh Kumar K.V int v9fs_co_fsync(V9fsPDU *pdu, V9fsFidState *fidp, int datasync)
2004743d1f5SAneesh Kumar K.V {
201cc720ddbSAneesh Kumar K.V     int err;
202bccacf6cSAneesh Kumar K.V     V9fsState *s = pdu->s;
2034743d1f5SAneesh Kumar K.V 
204bccacf6cSAneesh Kumar K.V     if (v9fs_request_cancelled(pdu)) {
205bccacf6cSAneesh Kumar K.V         return -EINTR;
206bccacf6cSAneesh Kumar K.V     }
2074743d1f5SAneesh Kumar K.V     v9fs_co_run_in_worker(
2084743d1f5SAneesh Kumar K.V         {
2098b888272SAneesh Kumar K.V             err = s->ops->fsync(&s->ctx, fidp->fid_type, &fidp->fs, datasync);
2104743d1f5SAneesh Kumar K.V             if (err < 0) {
2114743d1f5SAneesh Kumar K.V                 err = -errno;
2124743d1f5SAneesh Kumar K.V             }
2134743d1f5SAneesh Kumar K.V         });
2144743d1f5SAneesh Kumar K.V     return err;
2154743d1f5SAneesh Kumar K.V }
216c6c069b0SVenkateswararao Jujjuri 
217bccacf6cSAneesh Kumar K.V int v9fs_co_link(V9fsPDU *pdu, V9fsFidState *oldfid,
2182289be19SAneesh Kumar K.V                  V9fsFidState *newdirfid, V9fsString *name)
219c6c069b0SVenkateswararao Jujjuri {
220c6c069b0SVenkateswararao Jujjuri     int err;
221bccacf6cSAneesh Kumar K.V     V9fsState *s = pdu->s;
222c6c069b0SVenkateswararao Jujjuri 
223bccacf6cSAneesh Kumar K.V     if (v9fs_request_cancelled(pdu)) {
224bccacf6cSAneesh Kumar K.V         return -EINTR;
225bccacf6cSAneesh Kumar K.V     }
226532decb7SAneesh Kumar K.V     v9fs_path_read_lock(s);
227c6c069b0SVenkateswararao Jujjuri     v9fs_co_run_in_worker(
228c6c069b0SVenkateswararao Jujjuri         {
2292289be19SAneesh Kumar K.V             err = s->ops->link(&s->ctx, &oldfid->path,
2302289be19SAneesh Kumar K.V                                &newdirfid->path, name->data);
231c6c069b0SVenkateswararao Jujjuri             if (err < 0) {
232c6c069b0SVenkateswararao Jujjuri                 err = -errno;
233c6c069b0SVenkateswararao Jujjuri             }
234c6c069b0SVenkateswararao Jujjuri         });
235532decb7SAneesh Kumar K.V     v9fs_path_unlock(s);
236c6c069b0SVenkateswararao Jujjuri     return err;
237c6c069b0SVenkateswararao Jujjuri }
238f6b3c976SAneesh Kumar K.V 
239bccacf6cSAneesh Kumar K.V int v9fs_co_pwritev(V9fsPDU *pdu, V9fsFidState *fidp,
240f6b3c976SAneesh Kumar K.V                     struct iovec *iov, int iovcnt, int64_t offset)
241f6b3c976SAneesh Kumar K.V {
242cc720ddbSAneesh Kumar K.V     int err;
243bccacf6cSAneesh Kumar K.V     V9fsState *s = pdu->s;
244f6b3c976SAneesh Kumar K.V 
245bccacf6cSAneesh Kumar K.V     if (v9fs_request_cancelled(pdu)) {
246bccacf6cSAneesh Kumar K.V         return -EINTR;
247bccacf6cSAneesh Kumar K.V     }
248f6b3c976SAneesh Kumar K.V     v9fs_co_run_in_worker(
249f6b3c976SAneesh Kumar K.V         {
250cc720ddbSAneesh Kumar K.V             err = s->ops->pwritev(&s->ctx, &fidp->fs, iov, iovcnt, offset);
251f6b3c976SAneesh Kumar K.V             if (err < 0) {
252f6b3c976SAneesh Kumar K.V                 err = -errno;
253f6b3c976SAneesh Kumar K.V             }
254f6b3c976SAneesh Kumar K.V         });
255f6b3c976SAneesh Kumar K.V     return err;
256f6b3c976SAneesh Kumar K.V }
2577eafdcc9SAneesh Kumar K.V 
258bccacf6cSAneesh Kumar K.V int v9fs_co_preadv(V9fsPDU *pdu, V9fsFidState *fidp,
2597eafdcc9SAneesh Kumar K.V                    struct iovec *iov, int iovcnt, int64_t offset)
2607eafdcc9SAneesh Kumar K.V {
261cc720ddbSAneesh Kumar K.V     int err;
262bccacf6cSAneesh Kumar K.V     V9fsState *s = pdu->s;
2637eafdcc9SAneesh Kumar K.V 
264bccacf6cSAneesh Kumar K.V     if (v9fs_request_cancelled(pdu)) {
265bccacf6cSAneesh Kumar K.V         return -EINTR;
266bccacf6cSAneesh Kumar K.V     }
2677eafdcc9SAneesh Kumar K.V     v9fs_co_run_in_worker(
2687eafdcc9SAneesh Kumar K.V         {
269cc720ddbSAneesh Kumar K.V             err = s->ops->preadv(&s->ctx, &fidp->fs, iov, iovcnt, offset);
2707eafdcc9SAneesh Kumar K.V             if (err < 0) {
2717eafdcc9SAneesh Kumar K.V                 err = -errno;
2727eafdcc9SAneesh Kumar K.V             }
2737eafdcc9SAneesh Kumar K.V         });
2747eafdcc9SAneesh Kumar K.V     return err;
2757eafdcc9SAneesh Kumar K.V }
276