blob: 65ad3298be9ce2e3b4a4f1ca1fd110cc74c8b02d [file] [log] [blame]
Aneesh Kumar K.Vdcb9dbe2011-05-18 15:42:42 -07001
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"
Paolo Bonzini1de7afc2012-12-17 18:20:00 +010016#include "qemu/thread.h"
Paolo Bonzini737e1502012-12-17 18:19:44 +010017#include "block/coroutine.h"
Aneesh Kumar K.Vdcb9dbe2011-05-18 15:42:42 -070018#include "virtio-9p-coth.h"
19
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +053020int v9fs_co_readdir_r(V9fsPDU *pdu, V9fsFidState *fidp, struct dirent *dent,
Harsh Prateek Bora5f524c12011-05-18 17:23:00 +053021 struct dirent **result)
Aneesh Kumar K.Vdcb9dbe2011-05-18 15:42:42 -070022{
23 int err;
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +053024 V9fsState *s = pdu->s;
Aneesh Kumar K.Vdcb9dbe2011-05-18 15:42:42 -070025
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +053026 if (v9fs_request_cancelled(pdu)) {
27 return -EINTR;
28 }
Aneesh Kumar K.Vdcb9dbe2011-05-18 15:42:42 -070029 v9fs_co_run_in_worker(
30 {
31 errno = 0;
Aneesh Kumar K.Vcc720dd2011-10-25 12:10:40 +053032 err = s->ops->readdir_r(&s->ctx, &fidp->fs, dent, result);
Harsh Prateek Bora5f524c12011-05-18 17:23:00 +053033 if (!*result && errno) {
Aneesh Kumar K.Vdcb9dbe2011-05-18 15:42:42 -070034 err = -errno;
35 } else {
36 err = 0;
37 }
38 });
39 return err;
40}
41
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +053042off_t v9fs_co_telldir(V9fsPDU *pdu, V9fsFidState *fidp)
Aneesh Kumar K.Vdcb9dbe2011-05-18 15:42:42 -070043{
44 off_t err;
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +053045 V9fsState *s = pdu->s;
Aneesh Kumar K.Vdcb9dbe2011-05-18 15:42:42 -070046
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +053047 if (v9fs_request_cancelled(pdu)) {
48 return -EINTR;
49 }
Aneesh Kumar K.Vdcb9dbe2011-05-18 15:42:42 -070050 v9fs_co_run_in_worker(
51 {
Aneesh Kumar K.Vcc720dd2011-10-25 12:10:40 +053052 err = s->ops->telldir(&s->ctx, &fidp->fs);
Aneesh Kumar K.Vdcb9dbe2011-05-18 15:42:42 -070053 if (err < 0) {
54 err = -errno;
55 }
56 });
57 return err;
58}
59
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +053060void v9fs_co_seekdir(V9fsPDU *pdu, V9fsFidState *fidp, off_t offset)
Aneesh Kumar K.Vdcb9dbe2011-05-18 15:42:42 -070061{
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +053062 V9fsState *s = pdu->s;
63 if (v9fs_request_cancelled(pdu)) {
64 return;
65 }
Aneesh Kumar K.Vdcb9dbe2011-05-18 15:42:42 -070066 v9fs_co_run_in_worker(
67 {
Aneesh Kumar K.Vcc720dd2011-10-25 12:10:40 +053068 s->ops->seekdir(&s->ctx, &fidp->fs, offset);
Aneesh Kumar K.Vdcb9dbe2011-05-18 15:42:42 -070069 });
70}
71
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +053072void v9fs_co_rewinddir(V9fsPDU *pdu, V9fsFidState *fidp)
Aneesh Kumar K.Vdcb9dbe2011-05-18 15:42:42 -070073{
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +053074 V9fsState *s = pdu->s;
75 if (v9fs_request_cancelled(pdu)) {
76 return;
77 }
Aneesh Kumar K.Vdcb9dbe2011-05-18 15:42:42 -070078 v9fs_co_run_in_worker(
79 {
Aneesh Kumar K.Vcc720dd2011-10-25 12:10:40 +053080 s->ops->rewinddir(&s->ctx, &fidp->fs);
Aneesh Kumar K.Vdcb9dbe2011-05-18 15:42:42 -070081 });
82}
Venkateswararao Jujjurid0884642011-08-08 23:44:24 +053083
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +053084int v9fs_co_mkdir(V9fsPDU *pdu, V9fsFidState *fidp, V9fsString *name,
Aneesh Kumar K.V02cb7f32011-05-24 15:10:56 +053085 mode_t mode, uid_t uid, gid_t gid, struct stat *stbuf)
Venkateswararao Jujjurid0884642011-08-08 23:44:24 +053086{
87 int err;
88 FsCred cred;
Aneesh Kumar K.V2289be12011-09-09 15:14:18 +053089 V9fsPath path;
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +053090 V9fsState *s = pdu->s;
Venkateswararao Jujjurid0884642011-08-08 23:44:24 +053091
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +053092 if (v9fs_request_cancelled(pdu)) {
Dong Xu Wang3a931132011-11-29 16:52:38 +080093 return -EINTR;
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +053094 }
Venkateswararao Jujjurid0884642011-08-08 23:44:24 +053095 cred_init(&cred);
96 cred.fc_mode = mode;
97 cred.fc_uid = uid;
98 cred.fc_gid = gid;
Aneesh Kumar K.V532decb2011-08-02 11:35:54 +053099 v9fs_path_read_lock(s);
Venkateswararao Jujjurid0884642011-08-08 23:44:24 +0530100 v9fs_co_run_in_worker(
101 {
Aneesh Kumar K.V2289be12011-09-09 15:14:18 +0530102 err = s->ops->mkdir(&s->ctx, &fidp->path, name->data, &cred);
Venkateswararao Jujjurid0884642011-08-08 23:44:24 +0530103 if (err < 0) {
104 err = -errno;
Aneesh Kumar K.V02cb7f32011-05-24 15:10:56 +0530105 } else {
Aneesh Kumar K.V2289be12011-09-09 15:14:18 +0530106 v9fs_path_init(&path);
107 err = v9fs_name_to_path(s, &fidp->path, name->data, &path);
108 if (!err) {
109 err = s->ops->lstat(&s->ctx, &path, stbuf);
110 if (err < 0) {
111 err = -errno;
112 }
Aneesh Kumar K.V02cb7f32011-05-24 15:10:56 +0530113 }
Aneesh Kumar K.V2289be12011-09-09 15:14:18 +0530114 v9fs_path_free(&path);
Venkateswararao Jujjurid0884642011-08-08 23:44:24 +0530115 }
116 });
Aneesh Kumar K.V532decb2011-08-02 11:35:54 +0530117 v9fs_path_unlock(s);
Venkateswararao Jujjurid0884642011-08-08 23:44:24 +0530118 return err;
119}
Aneesh Kumar K.Vf6b7f0a2011-05-07 18:12:42 +0530120
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +0530121int v9fs_co_opendir(V9fsPDU *pdu, V9fsFidState *fidp)
Aneesh Kumar K.Vf6b7f0a2011-05-07 18:12:42 +0530122{
123 int err;
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +0530124 V9fsState *s = pdu->s;
Aneesh Kumar K.Vf6b7f0a2011-05-07 18:12:42 +0530125
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +0530126 if (v9fs_request_cancelled(pdu)) {
Dong Xu Wang3a931132011-11-29 16:52:38 +0800127 return -EINTR;
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +0530128 }
Aneesh Kumar K.V532decb2011-08-02 11:35:54 +0530129 v9fs_path_read_lock(s);
Aneesh Kumar K.Vf6b7f0a2011-05-07 18:12:42 +0530130 v9fs_co_run_in_worker(
131 {
Aneesh Kumar K.Vcc720dd2011-10-25 12:10:40 +0530132 err = s->ops->opendir(&s->ctx, &fidp->path, &fidp->fs);
133 if (err < 0) {
Aneesh Kumar K.Vf6b7f0a2011-05-07 18:12:42 +0530134 err = -errno;
135 } else {
136 err = 0;
137 }
138 });
Aneesh Kumar K.V532decb2011-08-02 11:35:54 +0530139 v9fs_path_unlock(s);
Aneesh Kumar K.V95f65512011-05-18 17:08:34 +0530140 if (!err) {
141 total_open_fd++;
142 if (total_open_fd > open_fd_hw) {
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +0530143 v9fs_reclaim_fd(pdu);
Aneesh Kumar K.V95f65512011-05-18 17:08:34 +0530144 }
145 }
Aneesh Kumar K.Vf6b7f0a2011-05-07 18:12:42 +0530146 return err;
147}
Aneesh Kumar K.Vbed43522011-05-07 21:09:24 +0530148
Aneesh Kumar K.Vcc720dd2011-10-25 12:10:40 +0530149int v9fs_co_closedir(V9fsPDU *pdu, V9fsFidOpenState *fs)
Aneesh Kumar K.Vbed43522011-05-07 21:09:24 +0530150{
151 int err;
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +0530152 V9fsState *s = pdu->s;
Aneesh Kumar K.Vbed43522011-05-07 21:09:24 +0530153
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +0530154 if (v9fs_request_cancelled(pdu)) {
Dong Xu Wang3a931132011-11-29 16:52:38 +0800155 return -EINTR;
Aneesh Kumar K.Vbccacf62011-08-02 11:36:17 +0530156 }
Aneesh Kumar K.Vbed43522011-05-07 21:09:24 +0530157 v9fs_co_run_in_worker(
158 {
Aneesh Kumar K.Vcc720dd2011-10-25 12:10:40 +0530159 err = s->ops->closedir(&s->ctx, fs);
Aneesh Kumar K.Vbed43522011-05-07 21:09:24 +0530160 if (err < 0) {
161 err = -errno;
162 }
163 });
Aneesh Kumar K.V95f65512011-05-18 17:08:34 +0530164 if (!err) {
165 total_open_fd--;
166 }
Aneesh Kumar K.Vbed43522011-05-07 21:09:24 +0530167 return err;
168}