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)
|