]>
Commit | Line | Data |
---|---|---|
dcb9dbe3 | 1 | /* |
af8b38b0 | 2 | * 9p backend |
dcb9dbe3 AK |
3 | * |
4 | * Copyright IBM, Corp. 2011 | |
5 | * | |
6 | * Authors: | |
7 | * Aneesh Kumar K.V <[email protected]> | |
8 | * | |
9 | * This work is licensed under the terms of the GNU GPL, version 2. See | |
10 | * the COPYING file in the top-level directory. | |
11 | * | |
12 | */ | |
13 | ||
fbc04127 | 14 | #include "qemu/osdep.h" |
dcb9dbe3 | 15 | #include "fsdev/qemu-fsdev.h" |
1de7afc9 | 16 | #include "qemu/thread.h" |
10817bf0 | 17 | #include "qemu/coroutine.h" |
db725815 | 18 | #include "qemu/main-loop.h" |
fe52840c | 19 | #include "coth.h" |
dcb9dbe3 | 20 | |
5bdade66 GK |
21 | int coroutine_fn v9fs_co_readdir(V9fsPDU *pdu, V9fsFidState *fidp, |
22 | struct dirent **dent) | |
dcb9dbe3 AK |
23 | { |
24 | int err; | |
bccacf6c | 25 | V9fsState *s = pdu->s; |
dcb9dbe3 | 26 | |
bccacf6c AK |
27 | if (v9fs_request_cancelled(pdu)) { |
28 | return -EINTR; | |
29 | } | |
dcb9dbe3 AK |
30 | v9fs_co_run_in_worker( |
31 | { | |
635324e8 GK |
32 | struct dirent *entry; |
33 | ||
dcb9dbe3 | 34 | errno = 0; |
635324e8 GK |
35 | entry = s->ops->readdir(&s->ctx, &fidp->fs); |
36 | if (!entry && errno) { | |
dcb9dbe3 AK |
37 | err = -errno; |
38 | } else { | |
635324e8 | 39 | *dent = entry; |
dcb9dbe3 AK |
40 | err = 0; |
41 | } | |
42 | }); | |
43 | return err; | |
44 | } | |
45 | ||
bccacf6c | 46 | off_t v9fs_co_telldir(V9fsPDU *pdu, V9fsFidState *fidp) |
dcb9dbe3 AK |
47 | { |
48 | off_t err; | |
bccacf6c | 49 | V9fsState *s = pdu->s; |
dcb9dbe3 | 50 | |
bccacf6c AK |
51 | if (v9fs_request_cancelled(pdu)) { |
52 | return -EINTR; | |
53 | } | |
dcb9dbe3 AK |
54 | v9fs_co_run_in_worker( |
55 | { | |
cc720ddb | 56 | err = s->ops->telldir(&s->ctx, &fidp->fs); |
dcb9dbe3 AK |
57 | if (err < 0) { |
58 | err = -errno; | |
59 | } | |
60 | }); | |
61 | return err; | |
62 | } | |
63 | ||
5bdade66 GK |
64 | void coroutine_fn v9fs_co_seekdir(V9fsPDU *pdu, V9fsFidState *fidp, |
65 | off_t offset) | |
dcb9dbe3 | 66 | { |
bccacf6c AK |
67 | V9fsState *s = pdu->s; |
68 | if (v9fs_request_cancelled(pdu)) { | |
69 | return; | |
70 | } | |
dcb9dbe3 AK |
71 | v9fs_co_run_in_worker( |
72 | { | |
cc720ddb | 73 | s->ops->seekdir(&s->ctx, &fidp->fs, offset); |
dcb9dbe3 AK |
74 | }); |
75 | } | |
76 | ||
5bdade66 | 77 | void coroutine_fn v9fs_co_rewinddir(V9fsPDU *pdu, V9fsFidState *fidp) |
dcb9dbe3 | 78 | { |
bccacf6c AK |
79 | V9fsState *s = pdu->s; |
80 | if (v9fs_request_cancelled(pdu)) { | |
81 | return; | |
82 | } | |
dcb9dbe3 AK |
83 | v9fs_co_run_in_worker( |
84 | { | |
cc720ddb | 85 | s->ops->rewinddir(&s->ctx, &fidp->fs); |
dcb9dbe3 AK |
86 | }); |
87 | } | |
d0884642 | 88 | |
5bdade66 GK |
89 | int coroutine_fn v9fs_co_mkdir(V9fsPDU *pdu, V9fsFidState *fidp, |
90 | V9fsString *name, mode_t mode, uid_t uid, | |
91 | gid_t gid, struct stat *stbuf) | |
d0884642 VJ |
92 | { |
93 | int err; | |
94 | FsCred cred; | |
2289be19 | 95 | V9fsPath path; |
bccacf6c | 96 | V9fsState *s = pdu->s; |
d0884642 | 97 | |
bccacf6c | 98 | if (v9fs_request_cancelled(pdu)) { |
3a93113a | 99 | return -EINTR; |
bccacf6c | 100 | } |
d0884642 VJ |
101 | cred_init(&cred); |
102 | cred.fc_mode = mode; | |
103 | cred.fc_uid = uid; | |
104 | cred.fc_gid = gid; | |
532decb7 | 105 | v9fs_path_read_lock(s); |
d0884642 VJ |
106 | v9fs_co_run_in_worker( |
107 | { | |
2289be19 | 108 | err = s->ops->mkdir(&s->ctx, &fidp->path, name->data, &cred); |
d0884642 VJ |
109 | if (err < 0) { |
110 | err = -errno; | |
02cb7f3a | 111 | } else { |
2289be19 AK |
112 | v9fs_path_init(&path); |
113 | err = v9fs_name_to_path(s, &fidp->path, name->data, &path); | |
114 | if (!err) { | |
115 | err = s->ops->lstat(&s->ctx, &path, stbuf); | |
116 | if (err < 0) { | |
117 | err = -errno; | |
118 | } | |
02cb7f3a | 119 | } |
2289be19 | 120 | v9fs_path_free(&path); |
d0884642 VJ |
121 | } |
122 | }); | |
532decb7 | 123 | v9fs_path_unlock(s); |
d0884642 VJ |
124 | return err; |
125 | } | |
f6b7f0ab | 126 | |
5bdade66 | 127 | int coroutine_fn v9fs_co_opendir(V9fsPDU *pdu, V9fsFidState *fidp) |
f6b7f0ab AK |
128 | { |
129 | int err; | |
bccacf6c | 130 | V9fsState *s = pdu->s; |
f6b7f0ab | 131 | |
bccacf6c | 132 | if (v9fs_request_cancelled(pdu)) { |
3a93113a | 133 | return -EINTR; |
bccacf6c | 134 | } |
532decb7 | 135 | v9fs_path_read_lock(s); |
f6b7f0ab AK |
136 | v9fs_co_run_in_worker( |
137 | { | |
cc720ddb AK |
138 | err = s->ops->opendir(&s->ctx, &fidp->path, &fidp->fs); |
139 | if (err < 0) { | |
f6b7f0ab AK |
140 | err = -errno; |
141 | } else { | |
142 | err = 0; | |
143 | } | |
144 | }); | |
532decb7 | 145 | v9fs_path_unlock(s); |
95f65511 AK |
146 | if (!err) { |
147 | total_open_fd++; | |
148 | if (total_open_fd > open_fd_hw) { | |
bccacf6c | 149 | v9fs_reclaim_fd(pdu); |
95f65511 AK |
150 | } |
151 | } | |
f6b7f0ab AK |
152 | return err; |
153 | } | |
bed4352c | 154 | |
5bdade66 | 155 | int coroutine_fn v9fs_co_closedir(V9fsPDU *pdu, V9fsFidOpenState *fs) |
bed4352c AK |
156 | { |
157 | int err; | |
bccacf6c | 158 | V9fsState *s = pdu->s; |
bed4352c | 159 | |
bccacf6c | 160 | if (v9fs_request_cancelled(pdu)) { |
3a93113a | 161 | return -EINTR; |
bccacf6c | 162 | } |
bed4352c AK |
163 | v9fs_co_run_in_worker( |
164 | { | |
cc720ddb | 165 | err = s->ops->closedir(&s->ctx, fs); |
bed4352c AK |
166 | if (err < 0) { |
167 | err = -errno; | |
168 | } | |
169 | }); | |
95f65511 AK |
170 | if (!err) { |
171 | total_open_fd--; | |
172 | } | |
bed4352c AK |
173 | return err; |
174 | } |