Revision a6568fe2 hw/virtio-9p.c
b/hw/virtio-9p.c | ||
---|---|---|
56 | 56 |
return s->ops->closedir(&s->ctx, dir); |
57 | 57 |
} |
58 | 58 |
|
59 |
static int v9fs_do_open(V9fsState *s, V9fsString *path, int flags) |
|
60 |
{ |
|
61 |
return s->ops->open(&s->ctx, path->data, flags); |
|
62 |
} |
|
63 |
|
|
64 |
static DIR *v9fs_do_opendir(V9fsState *s, V9fsString *path) |
|
65 |
{ |
|
66 |
return s->ops->opendir(&s->ctx, path->data); |
|
67 |
} |
|
68 |
|
|
59 | 69 |
static void v9fs_string_init(V9fsString *str) |
60 | 70 |
{ |
61 | 71 |
str->data = NULL; |
... | ... | |
1129 | 1139 |
v9fs_walk_complete(s, vs, err); |
1130 | 1140 |
} |
1131 | 1141 |
|
1132 |
static void v9fs_clunk(V9fsState *s, V9fsPDU *pdu) |
|
1142 |
typedef struct V9fsOpenState { |
|
1143 |
V9fsPDU *pdu; |
|
1144 |
size_t offset; |
|
1145 |
int8_t mode; |
|
1146 |
V9fsFidState *fidp; |
|
1147 |
V9fsQID qid; |
|
1148 |
struct stat stbuf; |
|
1149 |
|
|
1150 |
} V9fsOpenState; |
|
1151 |
|
|
1152 |
enum { |
|
1153 |
Oread = 0x00, |
|
1154 |
Owrite = 0x01, |
|
1155 |
Ordwr = 0x02, |
|
1156 |
Oexec = 0x03, |
|
1157 |
Oexcl = 0x04, |
|
1158 |
Otrunc = 0x10, |
|
1159 |
Orexec = 0x20, |
|
1160 |
Orclose = 0x40, |
|
1161 |
Oappend = 0x80, |
|
1162 |
}; |
|
1163 |
|
|
1164 |
static int omode_to_uflags(int8_t mode) |
|
1133 | 1165 |
{ |
1134 |
if (debug_9p_pdu) { |
|
1135 |
pprint_pdu(pdu); |
|
1166 |
int ret = 0; |
|
1167 |
|
|
1168 |
switch (mode & 3) { |
|
1169 |
case Oread: |
|
1170 |
ret = O_RDONLY; |
|
1171 |
break; |
|
1172 |
case Ordwr: |
|
1173 |
ret = O_RDWR; |
|
1174 |
break; |
|
1175 |
case Owrite: |
|
1176 |
ret = O_WRONLY; |
|
1177 |
break; |
|
1178 |
case Oexec: |
|
1179 |
ret = O_RDONLY; |
|
1180 |
break; |
|
1136 | 1181 |
} |
1182 |
|
|
1183 |
if (mode & Otrunc) { |
|
1184 |
ret |= O_TRUNC; |
|
1185 |
} |
|
1186 |
|
|
1187 |
if (mode & Oappend) { |
|
1188 |
ret |= O_APPEND; |
|
1189 |
} |
|
1190 |
|
|
1191 |
if (mode & Oexcl) { |
|
1192 |
ret |= O_EXCL; |
|
1193 |
} |
|
1194 |
|
|
1195 |
return ret; |
|
1196 |
} |
|
1197 |
|
|
1198 |
static void v9fs_open_post_opendir(V9fsState *s, V9fsOpenState *vs, int err) |
|
1199 |
{ |
|
1200 |
if (vs->fidp->dir == NULL) { |
|
1201 |
err = -errno; |
|
1202 |
goto out; |
|
1203 |
} |
|
1204 |
|
|
1205 |
vs->offset += pdu_marshal(vs->pdu, vs->offset, "Qd", &vs->qid, 0); |
|
1206 |
err = vs->offset; |
|
1207 |
out: |
|
1208 |
complete_pdu(s, vs->pdu, err); |
|
1209 |
qemu_free(vs); |
|
1210 |
|
|
1211 |
} |
|
1212 |
|
|
1213 |
static void v9fs_open_post_open(V9fsState *s, V9fsOpenState *vs, int err) |
|
1214 |
{ |
|
1215 |
if (vs->fidp->fd == -1) { |
|
1216 |
err = -errno; |
|
1217 |
goto out; |
|
1218 |
} |
|
1219 |
|
|
1220 |
vs->offset += pdu_marshal(vs->pdu, vs->offset, "Qd", &vs->qid, 0); |
|
1221 |
err = vs->offset; |
|
1222 |
out: |
|
1223 |
complete_pdu(s, vs->pdu, err); |
|
1224 |
qemu_free(vs); |
|
1225 |
} |
|
1226 |
|
|
1227 |
static void v9fs_open_post_lstat(V9fsState *s, V9fsOpenState *vs, int err) |
|
1228 |
{ |
|
1229 |
if (err) { |
|
1230 |
err = -errno; |
|
1231 |
goto out; |
|
1232 |
} |
|
1233 |
|
|
1234 |
stat_to_qid(&vs->stbuf, &vs->qid); |
|
1235 |
|
|
1236 |
if (S_ISDIR(vs->stbuf.st_mode)) { |
|
1237 |
vs->fidp->dir = v9fs_do_opendir(s, &vs->fidp->path); |
|
1238 |
v9fs_open_post_opendir(s, vs, err); |
|
1239 |
} else { |
|
1240 |
vs->fidp->fd = v9fs_do_open(s, &vs->fidp->path, |
|
1241 |
omode_to_uflags(vs->mode)); |
|
1242 |
v9fs_open_post_open(s, vs, err); |
|
1243 |
} |
|
1244 |
return; |
|
1245 |
out: |
|
1246 |
complete_pdu(s, vs->pdu, err); |
|
1247 |
qemu_free(vs); |
|
1137 | 1248 |
} |
1138 | 1249 |
|
1139 | 1250 |
static void v9fs_open(V9fsState *s, V9fsPDU *pdu) |
1140 |
{ if (debug_9p_pdu) { |
|
1251 |
{ |
|
1252 |
int32_t fid; |
|
1253 |
V9fsOpenState *vs; |
|
1254 |
ssize_t err = 0; |
|
1255 |
|
|
1256 |
|
|
1257 |
vs = qemu_malloc(sizeof(*vs)); |
|
1258 |
vs->pdu = pdu; |
|
1259 |
vs->offset = 7; |
|
1260 |
|
|
1261 |
pdu_unmarshal(vs->pdu, vs->offset, "db", &fid, &vs->mode); |
|
1262 |
|
|
1263 |
vs->fidp = lookup_fid(s, fid); |
|
1264 |
if (vs->fidp == NULL) { |
|
1265 |
err = -ENOENT; |
|
1266 |
goto out; |
|
1267 |
} |
|
1268 |
|
|
1269 |
BUG_ON(vs->fidp->fd != -1); |
|
1270 |
BUG_ON(vs->fidp->dir); |
|
1271 |
|
|
1272 |
err = v9fs_do_lstat(s, &vs->fidp->path, &vs->stbuf); |
|
1273 |
|
|
1274 |
v9fs_open_post_lstat(s, vs, err); |
|
1275 |
return; |
|
1276 |
out: |
|
1277 |
complete_pdu(s, pdu, err); |
|
1278 |
qemu_free(vs); |
|
1279 |
} |
|
1280 |
|
|
1281 |
static void v9fs_clunk(V9fsState *s, V9fsPDU *pdu) |
|
1282 |
{ |
|
1283 |
if (debug_9p_pdu) { |
|
1141 | 1284 |
pprint_pdu(pdu); |
1142 |
}
|
|
1285 |
} |
|
1143 | 1286 |
} |
1144 | 1287 |
|
1145 | 1288 |
static void v9fs_read(V9fsState *s, V9fsPDU *pdu) |
Also available in: Unified diff