xref: /qemu/hw/9pfs/codir.c (revision fbc04127)
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 
15*fbc04127SPeter Maydell #include "qemu/osdep.h"
16dcb9dbe3SAneesh Kumar K.V #include "fsdev/qemu-fsdev.h"
171de7afc9SPaolo Bonzini #include "qemu/thread.h"
1810817bf0SDaniel P. Berrange #include "qemu/coroutine.h"
19fe52840cSWei Liu #include "coth.h"
20dcb9dbe3SAneesh Kumar K.V 
21bccacf6cSAneesh Kumar K.V int v9fs_co_readdir_r(V9fsPDU *pdu, V9fsFidState *fidp, struct dirent *dent,
225f524c1eSHarsh Prateek Bora                       struct dirent **result)
23dcb9dbe3SAneesh Kumar K.V {
24dcb9dbe3SAneesh Kumar K.V     int err;
25bccacf6cSAneesh Kumar K.V     V9fsState *s = pdu->s;
26dcb9dbe3SAneesh Kumar K.V 
27bccacf6cSAneesh Kumar K.V     if (v9fs_request_cancelled(pdu)) {
28bccacf6cSAneesh Kumar K.V         return -EINTR;
29bccacf6cSAneesh Kumar K.V     }
30dcb9dbe3SAneesh Kumar K.V     v9fs_co_run_in_worker(
31dcb9dbe3SAneesh Kumar K.V         {
32dcb9dbe3SAneesh Kumar K.V             errno = 0;
33cc720ddbSAneesh Kumar K.V             err = s->ops->readdir_r(&s->ctx, &fidp->fs, dent, result);
345f524c1eSHarsh Prateek Bora             if (!*result && errno) {
35dcb9dbe3SAneesh Kumar K.V                 err = -errno;
36dcb9dbe3SAneesh Kumar K.V             } else {
37dcb9dbe3SAneesh Kumar K.V                 err = 0;
38dcb9dbe3SAneesh Kumar K.V             }
39dcb9dbe3SAneesh Kumar K.V         });
40dcb9dbe3SAneesh Kumar K.V     return err;
41dcb9dbe3SAneesh Kumar K.V }
42dcb9dbe3SAneesh Kumar K.V 
43bccacf6cSAneesh Kumar K.V off_t v9fs_co_telldir(V9fsPDU *pdu, V9fsFidState *fidp)
44dcb9dbe3SAneesh Kumar K.V {
45dcb9dbe3SAneesh Kumar K.V     off_t err;
46bccacf6cSAneesh Kumar K.V     V9fsState *s = pdu->s;
47dcb9dbe3SAneesh Kumar K.V 
48bccacf6cSAneesh Kumar K.V     if (v9fs_request_cancelled(pdu)) {
49bccacf6cSAneesh Kumar K.V         return -EINTR;
50bccacf6cSAneesh Kumar K.V     }
51dcb9dbe3SAneesh Kumar K.V     v9fs_co_run_in_worker(
52dcb9dbe3SAneesh Kumar K.V         {
53cc720ddbSAneesh Kumar K.V             err = s->ops->telldir(&s->ctx, &fidp->fs);
54dcb9dbe3SAneesh Kumar K.V             if (err < 0) {
55dcb9dbe3SAneesh Kumar K.V                 err = -errno;
56dcb9dbe3SAneesh Kumar K.V             }
57dcb9dbe3SAneesh Kumar K.V         });
58dcb9dbe3SAneesh Kumar K.V     return err;
59dcb9dbe3SAneesh Kumar K.V }
60dcb9dbe3SAneesh Kumar K.V 
61bccacf6cSAneesh Kumar K.V void v9fs_co_seekdir(V9fsPDU *pdu, V9fsFidState *fidp, off_t offset)
62dcb9dbe3SAneesh Kumar K.V {
63bccacf6cSAneesh Kumar K.V     V9fsState *s = pdu->s;
64bccacf6cSAneesh Kumar K.V     if (v9fs_request_cancelled(pdu)) {
65bccacf6cSAneesh Kumar K.V         return;
66bccacf6cSAneesh Kumar K.V     }
67dcb9dbe3SAneesh Kumar K.V     v9fs_co_run_in_worker(
68dcb9dbe3SAneesh Kumar K.V         {
69cc720ddbSAneesh Kumar K.V             s->ops->seekdir(&s->ctx, &fidp->fs, offset);
70dcb9dbe3SAneesh Kumar K.V         });
71dcb9dbe3SAneesh Kumar K.V }
72dcb9dbe3SAneesh Kumar K.V 
73bccacf6cSAneesh Kumar K.V void v9fs_co_rewinddir(V9fsPDU *pdu, V9fsFidState *fidp)
74dcb9dbe3SAneesh Kumar K.V {
75bccacf6cSAneesh Kumar K.V     V9fsState *s = pdu->s;
76bccacf6cSAneesh Kumar K.V     if (v9fs_request_cancelled(pdu)) {
77bccacf6cSAneesh Kumar K.V         return;
78bccacf6cSAneesh Kumar K.V     }
79dcb9dbe3SAneesh Kumar K.V     v9fs_co_run_in_worker(
80dcb9dbe3SAneesh Kumar K.V         {
81cc720ddbSAneesh Kumar K.V             s->ops->rewinddir(&s->ctx, &fidp->fs);
82dcb9dbe3SAneesh Kumar K.V         });
83dcb9dbe3SAneesh Kumar K.V }
84d0884642SVenkateswararao Jujjuri 
85bccacf6cSAneesh Kumar K.V int v9fs_co_mkdir(V9fsPDU *pdu, V9fsFidState *fidp, V9fsString *name,
8602cb7f3aSAneesh Kumar K.V                   mode_t mode, uid_t uid, gid_t gid, struct stat *stbuf)
87d0884642SVenkateswararao Jujjuri {
88d0884642SVenkateswararao Jujjuri     int err;
89d0884642SVenkateswararao Jujjuri     FsCred cred;
902289be19SAneesh Kumar K.V     V9fsPath path;
91bccacf6cSAneesh Kumar K.V     V9fsState *s = pdu->s;
92d0884642SVenkateswararao Jujjuri 
93bccacf6cSAneesh Kumar K.V     if (v9fs_request_cancelled(pdu)) {
943a93113aSDong Xu Wang         return -EINTR;
95bccacf6cSAneesh Kumar K.V     }
96d0884642SVenkateswararao Jujjuri     cred_init(&cred);
97d0884642SVenkateswararao Jujjuri     cred.fc_mode = mode;
98d0884642SVenkateswararao Jujjuri     cred.fc_uid = uid;
99d0884642SVenkateswararao Jujjuri     cred.fc_gid = gid;
100532decb7SAneesh Kumar K.V     v9fs_path_read_lock(s);
101d0884642SVenkateswararao Jujjuri     v9fs_co_run_in_worker(
102d0884642SVenkateswararao Jujjuri         {
1032289be19SAneesh Kumar K.V             err = s->ops->mkdir(&s->ctx, &fidp->path, name->data,  &cred);
10402cb7f3aSAneesh Kumar K.V             if (err < 0) {
10502cb7f3aSAneesh Kumar K.V                 err = -errno;
10602cb7f3aSAneesh Kumar K.V             } else {
1072289be19SAneesh Kumar K.V                 v9fs_path_init(&path);
1082289be19SAneesh Kumar K.V                 err = v9fs_name_to_path(s, &fidp->path, name->data, &path);
1092289be19SAneesh Kumar K.V                 if (!err) {
1102289be19SAneesh Kumar K.V                     err = s->ops->lstat(&s->ctx, &path, stbuf);
111d0884642SVenkateswararao Jujjuri                     if (err < 0) {
112d0884642SVenkateswararao Jujjuri                         err = -errno;
113d0884642SVenkateswararao Jujjuri                     }
11402cb7f3aSAneesh Kumar K.V                 }
1152289be19SAneesh Kumar K.V                 v9fs_path_free(&path);
1162289be19SAneesh Kumar K.V             }
117d0884642SVenkateswararao Jujjuri         });
118532decb7SAneesh Kumar K.V     v9fs_path_unlock(s);
119d0884642SVenkateswararao Jujjuri     return err;
120d0884642SVenkateswararao Jujjuri }
121f6b7f0abSAneesh Kumar K.V 
122bccacf6cSAneesh Kumar K.V int v9fs_co_opendir(V9fsPDU *pdu, V9fsFidState *fidp)
123f6b7f0abSAneesh Kumar K.V {
124f6b7f0abSAneesh Kumar K.V     int err;
125bccacf6cSAneesh Kumar K.V     V9fsState *s = pdu->s;
126f6b7f0abSAneesh Kumar K.V 
127bccacf6cSAneesh Kumar K.V     if (v9fs_request_cancelled(pdu)) {
1283a93113aSDong Xu Wang         return -EINTR;
129bccacf6cSAneesh Kumar K.V     }
130532decb7SAneesh Kumar K.V     v9fs_path_read_lock(s);
131f6b7f0abSAneesh Kumar K.V     v9fs_co_run_in_worker(
132f6b7f0abSAneesh Kumar K.V         {
133cc720ddbSAneesh Kumar K.V             err = s->ops->opendir(&s->ctx, &fidp->path, &fidp->fs);
134cc720ddbSAneesh Kumar K.V             if (err < 0) {
135f6b7f0abSAneesh Kumar K.V                 err = -errno;
136f6b7f0abSAneesh Kumar K.V             } else {
137f6b7f0abSAneesh Kumar K.V                 err = 0;
138f6b7f0abSAneesh Kumar K.V             }
139f6b7f0abSAneesh Kumar K.V         });
140532decb7SAneesh Kumar K.V     v9fs_path_unlock(s);
14195f65511SAneesh Kumar K.V     if (!err) {
14295f65511SAneesh Kumar K.V         total_open_fd++;
14395f65511SAneesh Kumar K.V         if (total_open_fd > open_fd_hw) {
144bccacf6cSAneesh Kumar K.V             v9fs_reclaim_fd(pdu);
14595f65511SAneesh Kumar K.V         }
14695f65511SAneesh Kumar K.V     }
147f6b7f0abSAneesh Kumar K.V     return err;
148f6b7f0abSAneesh Kumar K.V }
149bed4352cSAneesh Kumar K.V 
150cc720ddbSAneesh Kumar K.V int v9fs_co_closedir(V9fsPDU *pdu, V9fsFidOpenState *fs)
151bed4352cSAneesh Kumar K.V {
152bed4352cSAneesh Kumar K.V     int err;
153bccacf6cSAneesh Kumar K.V     V9fsState *s = pdu->s;
154bed4352cSAneesh Kumar K.V 
155bccacf6cSAneesh Kumar K.V     if (v9fs_request_cancelled(pdu)) {
1563a93113aSDong Xu Wang         return -EINTR;
157bccacf6cSAneesh Kumar K.V     }
158bed4352cSAneesh Kumar K.V     v9fs_co_run_in_worker(
159bed4352cSAneesh Kumar K.V         {
160cc720ddbSAneesh Kumar K.V             err = s->ops->closedir(&s->ctx, fs);
161bed4352cSAneesh Kumar K.V             if (err < 0) {
162bed4352cSAneesh Kumar K.V                 err = -errno;
163bed4352cSAneesh Kumar K.V             }
164bed4352cSAneesh Kumar K.V         });
16595f65511SAneesh Kumar K.V     if (!err) {
16695f65511SAneesh Kumar K.V         total_open_fd--;
16795f65511SAneesh Kumar K.V     }
168bed4352cSAneesh Kumar K.V     return err;
169bed4352cSAneesh Kumar K.V }
170