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