xref: /openbmc/qemu/hw/9pfs/codir.c (revision 10817bf0)
1dcb9dbe3SAneesh Kumar K.V 
2dcb9dbe3SAneesh Kumar K.V /*
3dcb9dbe3SAneesh Kumar K.V  * Virtio 9p backend
4dcb9dbe3SAneesh Kumar K.V  *
5dcb9dbe3SAneesh Kumar K.V  * Copyright IBM, Corp. 2011
6dcb9dbe3SAneesh Kumar K.V  *
7dcb9dbe3SAneesh Kumar K.V  * Authors:
8dcb9dbe3SAneesh Kumar K.V  *  Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
9dcb9dbe3SAneesh Kumar K.V  *
10dcb9dbe3SAneesh Kumar K.V  * This work is licensed under the terms of the GNU GPL, version 2.  See
11dcb9dbe3SAneesh Kumar K.V  * the COPYING file in the top-level directory.
12dcb9dbe3SAneesh Kumar K.V  *
13dcb9dbe3SAneesh Kumar K.V  */
14dcb9dbe3SAneesh Kumar K.V 
15dcb9dbe3SAneesh Kumar K.V #include "fsdev/qemu-fsdev.h"
161de7afc9SPaolo Bonzini #include "qemu/thread.h"
17*10817bf0SDaniel P. Berrange #include "qemu/coroutine.h"
18dcb9dbe3SAneesh Kumar K.V #include "virtio-9p-coth.h"
19dcb9dbe3SAneesh Kumar K.V 
20bccacf6cSAneesh Kumar K.V int v9fs_co_readdir_r(V9fsPDU *pdu, V9fsFidState *fidp, struct dirent *dent,
215f524c1eSHarsh Prateek Bora                       struct dirent **result)
22dcb9dbe3SAneesh Kumar K.V {
23dcb9dbe3SAneesh Kumar K.V     int err;
24bccacf6cSAneesh Kumar K.V     V9fsState *s = pdu->s;
25dcb9dbe3SAneesh Kumar K.V 
26bccacf6cSAneesh Kumar K.V     if (v9fs_request_cancelled(pdu)) {
27bccacf6cSAneesh Kumar K.V         return -EINTR;
28bccacf6cSAneesh Kumar K.V     }
29dcb9dbe3SAneesh Kumar K.V     v9fs_co_run_in_worker(
30dcb9dbe3SAneesh Kumar K.V         {
31dcb9dbe3SAneesh Kumar K.V             errno = 0;
32cc720ddbSAneesh Kumar K.V             err = s->ops->readdir_r(&s->ctx, &fidp->fs, dent, result);
335f524c1eSHarsh Prateek Bora             if (!*result && errno) {
34dcb9dbe3SAneesh Kumar K.V                 err = -errno;
35dcb9dbe3SAneesh Kumar K.V             } else {
36dcb9dbe3SAneesh Kumar K.V                 err = 0;
37dcb9dbe3SAneesh Kumar K.V             }
38dcb9dbe3SAneesh Kumar K.V         });
39dcb9dbe3SAneesh Kumar K.V     return err;
40dcb9dbe3SAneesh Kumar K.V }
41dcb9dbe3SAneesh Kumar K.V 
42bccacf6cSAneesh Kumar K.V off_t v9fs_co_telldir(V9fsPDU *pdu, V9fsFidState *fidp)
43dcb9dbe3SAneesh Kumar K.V {
44dcb9dbe3SAneesh Kumar K.V     off_t err;
45bccacf6cSAneesh Kumar K.V     V9fsState *s = pdu->s;
46dcb9dbe3SAneesh Kumar K.V 
47bccacf6cSAneesh Kumar K.V     if (v9fs_request_cancelled(pdu)) {
48bccacf6cSAneesh Kumar K.V         return -EINTR;
49bccacf6cSAneesh Kumar K.V     }
50dcb9dbe3SAneesh Kumar K.V     v9fs_co_run_in_worker(
51dcb9dbe3SAneesh Kumar K.V         {
52cc720ddbSAneesh Kumar K.V             err = s->ops->telldir(&s->ctx, &fidp->fs);
53dcb9dbe3SAneesh Kumar K.V             if (err < 0) {
54dcb9dbe3SAneesh Kumar K.V                 err = -errno;
55dcb9dbe3SAneesh Kumar K.V             }
56dcb9dbe3SAneesh Kumar K.V         });
57dcb9dbe3SAneesh Kumar K.V     return err;
58dcb9dbe3SAneesh Kumar K.V }
59dcb9dbe3SAneesh Kumar K.V 
60bccacf6cSAneesh Kumar K.V void v9fs_co_seekdir(V9fsPDU *pdu, V9fsFidState *fidp, off_t offset)
61dcb9dbe3SAneesh Kumar K.V {
62bccacf6cSAneesh Kumar K.V     V9fsState *s = pdu->s;
63bccacf6cSAneesh Kumar K.V     if (v9fs_request_cancelled(pdu)) {
64bccacf6cSAneesh Kumar K.V         return;
65bccacf6cSAneesh Kumar K.V     }
66dcb9dbe3SAneesh Kumar K.V     v9fs_co_run_in_worker(
67dcb9dbe3SAneesh Kumar K.V         {
68cc720ddbSAneesh Kumar K.V             s->ops->seekdir(&s->ctx, &fidp->fs, offset);
69dcb9dbe3SAneesh Kumar K.V         });
70dcb9dbe3SAneesh Kumar K.V }
71dcb9dbe3SAneesh Kumar K.V 
72bccacf6cSAneesh Kumar K.V void v9fs_co_rewinddir(V9fsPDU *pdu, V9fsFidState *fidp)
73dcb9dbe3SAneesh Kumar K.V {
74bccacf6cSAneesh Kumar K.V     V9fsState *s = pdu->s;
75bccacf6cSAneesh Kumar K.V     if (v9fs_request_cancelled(pdu)) {
76bccacf6cSAneesh Kumar K.V         return;
77bccacf6cSAneesh Kumar K.V     }
78dcb9dbe3SAneesh Kumar K.V     v9fs_co_run_in_worker(
79dcb9dbe3SAneesh Kumar K.V         {
80cc720ddbSAneesh Kumar K.V             s->ops->rewinddir(&s->ctx, &fidp->fs);
81dcb9dbe3SAneesh Kumar K.V         });
82dcb9dbe3SAneesh Kumar K.V }
83d0884642SVenkateswararao Jujjuri 
84bccacf6cSAneesh Kumar K.V int v9fs_co_mkdir(V9fsPDU *pdu, V9fsFidState *fidp, V9fsString *name,
8502cb7f3aSAneesh Kumar K.V                   mode_t mode, uid_t uid, gid_t gid, struct stat *stbuf)
86d0884642SVenkateswararao Jujjuri {
87d0884642SVenkateswararao Jujjuri     int err;
88d0884642SVenkateswararao Jujjuri     FsCred cred;
892289be19SAneesh Kumar K.V     V9fsPath path;
90bccacf6cSAneesh Kumar K.V     V9fsState *s = pdu->s;
91d0884642SVenkateswararao Jujjuri 
92bccacf6cSAneesh Kumar K.V     if (v9fs_request_cancelled(pdu)) {
933a93113aSDong Xu Wang         return -EINTR;
94bccacf6cSAneesh Kumar K.V     }
95d0884642SVenkateswararao Jujjuri     cred_init(&cred);
96d0884642SVenkateswararao Jujjuri     cred.fc_mode = mode;
97d0884642SVenkateswararao Jujjuri     cred.fc_uid = uid;
98d0884642SVenkateswararao Jujjuri     cred.fc_gid = gid;
99532decb7SAneesh Kumar K.V     v9fs_path_read_lock(s);
100d0884642SVenkateswararao Jujjuri     v9fs_co_run_in_worker(
101d0884642SVenkateswararao Jujjuri         {
1022289be19SAneesh Kumar K.V             err = s->ops->mkdir(&s->ctx, &fidp->path, name->data,  &cred);
10302cb7f3aSAneesh Kumar K.V             if (err < 0) {
10402cb7f3aSAneesh Kumar K.V                 err = -errno;
10502cb7f3aSAneesh Kumar K.V             } else {
1062289be19SAneesh Kumar K.V                 v9fs_path_init(&path);
1072289be19SAneesh Kumar K.V                 err = v9fs_name_to_path(s, &fidp->path, name->data, &path);
1082289be19SAneesh Kumar K.V                 if (!err) {
1092289be19SAneesh Kumar K.V                     err = s->ops->lstat(&s->ctx, &path, stbuf);
110d0884642SVenkateswararao Jujjuri                     if (err < 0) {
111d0884642SVenkateswararao Jujjuri                         err = -errno;
112d0884642SVenkateswararao Jujjuri                     }
11302cb7f3aSAneesh Kumar K.V                 }
1142289be19SAneesh Kumar K.V                 v9fs_path_free(&path);
1152289be19SAneesh Kumar K.V             }
116d0884642SVenkateswararao Jujjuri         });
117532decb7SAneesh Kumar K.V     v9fs_path_unlock(s);
118d0884642SVenkateswararao Jujjuri     return err;
119d0884642SVenkateswararao Jujjuri }
120f6b7f0abSAneesh Kumar K.V 
121bccacf6cSAneesh Kumar K.V int v9fs_co_opendir(V9fsPDU *pdu, V9fsFidState *fidp)
122f6b7f0abSAneesh Kumar K.V {
123f6b7f0abSAneesh Kumar K.V     int err;
124bccacf6cSAneesh Kumar K.V     V9fsState *s = pdu->s;
125f6b7f0abSAneesh Kumar K.V 
126bccacf6cSAneesh Kumar K.V     if (v9fs_request_cancelled(pdu)) {
1273a93113aSDong Xu Wang         return -EINTR;
128bccacf6cSAneesh Kumar K.V     }
129532decb7SAneesh Kumar K.V     v9fs_path_read_lock(s);
130f6b7f0abSAneesh Kumar K.V     v9fs_co_run_in_worker(
131f6b7f0abSAneesh Kumar K.V         {
132cc720ddbSAneesh Kumar K.V             err = s->ops->opendir(&s->ctx, &fidp->path, &fidp->fs);
133cc720ddbSAneesh Kumar K.V             if (err < 0) {
134f6b7f0abSAneesh Kumar K.V                 err = -errno;
135f6b7f0abSAneesh Kumar K.V             } else {
136f6b7f0abSAneesh Kumar K.V                 err = 0;
137f6b7f0abSAneesh Kumar K.V             }
138f6b7f0abSAneesh Kumar K.V         });
139532decb7SAneesh Kumar K.V     v9fs_path_unlock(s);
14095f65511SAneesh Kumar K.V     if (!err) {
14195f65511SAneesh Kumar K.V         total_open_fd++;
14295f65511SAneesh Kumar K.V         if (total_open_fd > open_fd_hw) {
143bccacf6cSAneesh Kumar K.V             v9fs_reclaim_fd(pdu);
14495f65511SAneesh Kumar K.V         }
14595f65511SAneesh Kumar K.V     }
146f6b7f0abSAneesh Kumar K.V     return err;
147f6b7f0abSAneesh Kumar K.V }
148bed4352cSAneesh Kumar K.V 
149cc720ddbSAneesh Kumar K.V int v9fs_co_closedir(V9fsPDU *pdu, V9fsFidOpenState *fs)
150bed4352cSAneesh Kumar K.V {
151bed4352cSAneesh Kumar K.V     int err;
152bccacf6cSAneesh Kumar K.V     V9fsState *s = pdu->s;
153bed4352cSAneesh Kumar K.V 
154bccacf6cSAneesh Kumar K.V     if (v9fs_request_cancelled(pdu)) {
1553a93113aSDong Xu Wang         return -EINTR;
156bccacf6cSAneesh Kumar K.V     }
157bed4352cSAneesh Kumar K.V     v9fs_co_run_in_worker(
158bed4352cSAneesh Kumar K.V         {
159cc720ddbSAneesh Kumar K.V             err = s->ops->closedir(&s->ctx, fs);
160bed4352cSAneesh Kumar K.V             if (err < 0) {
161bed4352cSAneesh Kumar K.V                 err = -errno;
162bed4352cSAneesh Kumar K.V             }
163bed4352cSAneesh Kumar K.V         });
16495f65511SAneesh Kumar K.V     if (!err) {
16595f65511SAneesh Kumar K.V         total_open_fd--;
16695f65511SAneesh Kumar K.V     }
167bed4352cSAneesh Kumar K.V     return err;
168bed4352cSAneesh Kumar K.V }
169