xref: /qemu/hw/9pfs/codir.c (revision dd8151f4)
1dcb9dbe3SAneesh Kumar K.V /*
2af8b38b0SGreg Kurz  * 9p backend
3dcb9dbe3SAneesh Kumar K.V  *
4dcb9dbe3SAneesh Kumar K.V  * Copyright IBM, Corp. 2011
5dcb9dbe3SAneesh Kumar K.V  *
6dcb9dbe3SAneesh Kumar K.V  * Authors:
7dcb9dbe3SAneesh Kumar K.V  *  Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
8dcb9dbe3SAneesh Kumar K.V  *
9dcb9dbe3SAneesh Kumar K.V  * This work is licensed under the terms of the GNU GPL, version 2.  See
10dcb9dbe3SAneesh Kumar K.V  * the COPYING file in the top-level directory.
11dcb9dbe3SAneesh Kumar K.V  *
12dcb9dbe3SAneesh Kumar K.V  */
13dcb9dbe3SAneesh Kumar K.V 
14fbc04127SPeter Maydell #include "qemu/osdep.h"
15dcb9dbe3SAneesh Kumar K.V #include "fsdev/qemu-fsdev.h"
161de7afc9SPaolo Bonzini #include "qemu/thread.h"
1710817bf0SDaniel P. Berrange #include "qemu/coroutine.h"
18db725815SMarkus Armbruster #include "qemu/main-loop.h"
19fe52840cSWei Liu #include "coth.h"
20dcb9dbe3SAneesh Kumar K.V 
21*dd8151f4SChristian Schoenebeck /*
22*dd8151f4SChristian Schoenebeck  * Intended to be called from bottom-half (e.g. background I/O thread)
23*dd8151f4SChristian Schoenebeck  * context.
24*dd8151f4SChristian Schoenebeck  */
25*dd8151f4SChristian Schoenebeck static int do_readdir(V9fsPDU *pdu, V9fsFidState *fidp, struct dirent **dent)
26dcb9dbe3SAneesh Kumar K.V {
27*dd8151f4SChristian Schoenebeck     int err = 0;
28bccacf6cSAneesh Kumar K.V     V9fsState *s = pdu->s;
29635324e8SGreg Kurz     struct dirent *entry;
30635324e8SGreg Kurz 
31dcb9dbe3SAneesh Kumar K.V     errno = 0;
32635324e8SGreg Kurz     entry = s->ops->readdir(&s->ctx, &fidp->fs);
33635324e8SGreg Kurz     if (!entry && errno) {
34*dd8151f4SChristian Schoenebeck         *dent = NULL;
35dcb9dbe3SAneesh Kumar K.V         err = -errno;
36dcb9dbe3SAneesh Kumar K.V     } else {
37635324e8SGreg Kurz         *dent = entry;
38dcb9dbe3SAneesh Kumar K.V     }
39*dd8151f4SChristian Schoenebeck     return err;
40*dd8151f4SChristian Schoenebeck }
41*dd8151f4SChristian Schoenebeck 
42*dd8151f4SChristian Schoenebeck int coroutine_fn v9fs_co_readdir(V9fsPDU *pdu, V9fsFidState *fidp,
43*dd8151f4SChristian Schoenebeck                                  struct dirent **dent)
44*dd8151f4SChristian Schoenebeck {
45*dd8151f4SChristian Schoenebeck     int err;
46*dd8151f4SChristian Schoenebeck 
47*dd8151f4SChristian Schoenebeck     if (v9fs_request_cancelled(pdu)) {
48*dd8151f4SChristian Schoenebeck         return -EINTR;
49*dd8151f4SChristian Schoenebeck     }
50*dd8151f4SChristian Schoenebeck     v9fs_co_run_in_worker({
51*dd8151f4SChristian Schoenebeck         err = do_readdir(pdu, fidp, dent);
52dcb9dbe3SAneesh Kumar K.V     });
53dcb9dbe3SAneesh Kumar K.V     return err;
54dcb9dbe3SAneesh Kumar K.V }
55dcb9dbe3SAneesh Kumar K.V 
56bccacf6cSAneesh Kumar K.V off_t v9fs_co_telldir(V9fsPDU *pdu, V9fsFidState *fidp)
57dcb9dbe3SAneesh Kumar K.V {
58dcb9dbe3SAneesh Kumar K.V     off_t err;
59bccacf6cSAneesh Kumar K.V     V9fsState *s = pdu->s;
60dcb9dbe3SAneesh Kumar K.V 
61bccacf6cSAneesh Kumar K.V     if (v9fs_request_cancelled(pdu)) {
62bccacf6cSAneesh Kumar K.V         return -EINTR;
63bccacf6cSAneesh Kumar K.V     }
64dcb9dbe3SAneesh Kumar K.V     v9fs_co_run_in_worker(
65dcb9dbe3SAneesh Kumar K.V         {
66cc720ddbSAneesh Kumar K.V             err = s->ops->telldir(&s->ctx, &fidp->fs);
67dcb9dbe3SAneesh Kumar K.V             if (err < 0) {
68dcb9dbe3SAneesh Kumar K.V                 err = -errno;
69dcb9dbe3SAneesh Kumar K.V             }
70dcb9dbe3SAneesh Kumar K.V         });
71dcb9dbe3SAneesh Kumar K.V     return err;
72dcb9dbe3SAneesh Kumar K.V }
73dcb9dbe3SAneesh Kumar K.V 
745bdade66SGreg Kurz void coroutine_fn v9fs_co_seekdir(V9fsPDU *pdu, V9fsFidState *fidp,
755bdade66SGreg Kurz                                   off_t offset)
76dcb9dbe3SAneesh Kumar K.V {
77bccacf6cSAneesh Kumar K.V     V9fsState *s = pdu->s;
78bccacf6cSAneesh Kumar K.V     if (v9fs_request_cancelled(pdu)) {
79bccacf6cSAneesh Kumar K.V         return;
80bccacf6cSAneesh Kumar K.V     }
81dcb9dbe3SAneesh Kumar K.V     v9fs_co_run_in_worker(
82dcb9dbe3SAneesh Kumar K.V         {
83cc720ddbSAneesh Kumar K.V             s->ops->seekdir(&s->ctx, &fidp->fs, offset);
84dcb9dbe3SAneesh Kumar K.V         });
85dcb9dbe3SAneesh Kumar K.V }
86dcb9dbe3SAneesh Kumar K.V 
875bdade66SGreg Kurz void coroutine_fn v9fs_co_rewinddir(V9fsPDU *pdu, V9fsFidState *fidp)
88dcb9dbe3SAneesh Kumar K.V {
89bccacf6cSAneesh Kumar K.V     V9fsState *s = pdu->s;
90bccacf6cSAneesh Kumar K.V     if (v9fs_request_cancelled(pdu)) {
91bccacf6cSAneesh Kumar K.V         return;
92bccacf6cSAneesh Kumar K.V     }
93dcb9dbe3SAneesh Kumar K.V     v9fs_co_run_in_worker(
94dcb9dbe3SAneesh Kumar K.V         {
95cc720ddbSAneesh Kumar K.V             s->ops->rewinddir(&s->ctx, &fidp->fs);
96dcb9dbe3SAneesh Kumar K.V         });
97dcb9dbe3SAneesh Kumar K.V }
98d0884642SVenkateswararao Jujjuri 
995bdade66SGreg Kurz int coroutine_fn v9fs_co_mkdir(V9fsPDU *pdu, V9fsFidState *fidp,
1005bdade66SGreg Kurz                                V9fsString *name, mode_t mode, uid_t uid,
1015bdade66SGreg Kurz                                gid_t gid, struct stat *stbuf)
102d0884642SVenkateswararao Jujjuri {
103d0884642SVenkateswararao Jujjuri     int err;
104d0884642SVenkateswararao Jujjuri     FsCred cred;
1052289be19SAneesh Kumar K.V     V9fsPath path;
106bccacf6cSAneesh Kumar K.V     V9fsState *s = pdu->s;
107d0884642SVenkateswararao Jujjuri 
108bccacf6cSAneesh Kumar K.V     if (v9fs_request_cancelled(pdu)) {
1093a93113aSDong Xu Wang         return -EINTR;
110bccacf6cSAneesh Kumar K.V     }
111d0884642SVenkateswararao Jujjuri     cred_init(&cred);
112d0884642SVenkateswararao Jujjuri     cred.fc_mode = mode;
113d0884642SVenkateswararao Jujjuri     cred.fc_uid = uid;
114d0884642SVenkateswararao Jujjuri     cred.fc_gid = gid;
115532decb7SAneesh Kumar K.V     v9fs_path_read_lock(s);
116d0884642SVenkateswararao Jujjuri     v9fs_co_run_in_worker(
117d0884642SVenkateswararao Jujjuri         {
1182289be19SAneesh Kumar K.V             err = s->ops->mkdir(&s->ctx, &fidp->path, name->data,  &cred);
11902cb7f3aSAneesh Kumar K.V             if (err < 0) {
12002cb7f3aSAneesh Kumar K.V                 err = -errno;
12102cb7f3aSAneesh Kumar K.V             } else {
1222289be19SAneesh Kumar K.V                 v9fs_path_init(&path);
1232289be19SAneesh Kumar K.V                 err = v9fs_name_to_path(s, &fidp->path, name->data, &path);
1242289be19SAneesh Kumar K.V                 if (!err) {
1252289be19SAneesh Kumar K.V                     err = s->ops->lstat(&s->ctx, &path, stbuf);
126d0884642SVenkateswararao Jujjuri                     if (err < 0) {
127d0884642SVenkateswararao Jujjuri                         err = -errno;
128d0884642SVenkateswararao Jujjuri                     }
12902cb7f3aSAneesh Kumar K.V                 }
1302289be19SAneesh Kumar K.V                 v9fs_path_free(&path);
1312289be19SAneesh Kumar K.V             }
132d0884642SVenkateswararao Jujjuri         });
133532decb7SAneesh Kumar K.V     v9fs_path_unlock(s);
134d0884642SVenkateswararao Jujjuri     return err;
135d0884642SVenkateswararao Jujjuri }
136f6b7f0abSAneesh Kumar K.V 
1375bdade66SGreg Kurz int coroutine_fn v9fs_co_opendir(V9fsPDU *pdu, V9fsFidState *fidp)
138f6b7f0abSAneesh Kumar K.V {
139f6b7f0abSAneesh Kumar K.V     int err;
140bccacf6cSAneesh Kumar K.V     V9fsState *s = pdu->s;
141f6b7f0abSAneesh Kumar K.V 
142bccacf6cSAneesh Kumar K.V     if (v9fs_request_cancelled(pdu)) {
1433a93113aSDong Xu Wang         return -EINTR;
144bccacf6cSAneesh Kumar K.V     }
145532decb7SAneesh Kumar K.V     v9fs_path_read_lock(s);
146f6b7f0abSAneesh Kumar K.V     v9fs_co_run_in_worker(
147f6b7f0abSAneesh Kumar K.V         {
148cc720ddbSAneesh Kumar K.V             err = s->ops->opendir(&s->ctx, &fidp->path, &fidp->fs);
149cc720ddbSAneesh Kumar K.V             if (err < 0) {
150f6b7f0abSAneesh Kumar K.V                 err = -errno;
151f6b7f0abSAneesh Kumar K.V             } else {
152f6b7f0abSAneesh Kumar K.V                 err = 0;
153f6b7f0abSAneesh Kumar K.V             }
154f6b7f0abSAneesh Kumar K.V         });
155532decb7SAneesh Kumar K.V     v9fs_path_unlock(s);
15695f65511SAneesh Kumar K.V     if (!err) {
15795f65511SAneesh Kumar K.V         total_open_fd++;
15895f65511SAneesh Kumar K.V         if (total_open_fd > open_fd_hw) {
159bccacf6cSAneesh Kumar K.V             v9fs_reclaim_fd(pdu);
16095f65511SAneesh Kumar K.V         }
16195f65511SAneesh Kumar K.V     }
162f6b7f0abSAneesh Kumar K.V     return err;
163f6b7f0abSAneesh Kumar K.V }
164bed4352cSAneesh Kumar K.V 
1655bdade66SGreg Kurz int coroutine_fn v9fs_co_closedir(V9fsPDU *pdu, V9fsFidOpenState *fs)
166bed4352cSAneesh Kumar K.V {
167bed4352cSAneesh Kumar K.V     int err;
168bccacf6cSAneesh Kumar K.V     V9fsState *s = pdu->s;
169bed4352cSAneesh Kumar K.V 
170bccacf6cSAneesh Kumar K.V     if (v9fs_request_cancelled(pdu)) {
1713a93113aSDong Xu Wang         return -EINTR;
172bccacf6cSAneesh Kumar K.V     }
173bed4352cSAneesh Kumar K.V     v9fs_co_run_in_worker(
174bed4352cSAneesh Kumar K.V         {
175cc720ddbSAneesh Kumar K.V             err = s->ops->closedir(&s->ctx, fs);
176bed4352cSAneesh Kumar K.V             if (err < 0) {
177bed4352cSAneesh Kumar K.V                 err = -errno;
178bed4352cSAneesh Kumar K.V             }
179bed4352cSAneesh Kumar K.V         });
18095f65511SAneesh Kumar K.V     if (!err) {
18195f65511SAneesh Kumar K.V         total_open_fd--;
18295f65511SAneesh Kumar K.V     }
183bed4352cSAneesh Kumar K.V     return err;
184bed4352cSAneesh Kumar K.V }
185