Revision 5e94c103 hw/virtio-9p.c
b/hw/virtio-9p.c | ||
---|---|---|
253 | 253 |
return s->ops->fsync(&s->ctx, fd); |
254 | 254 |
} |
255 | 255 |
|
256 |
static int v9fs_do_statfs(V9fsState *s, V9fsString *path, struct statfs *stbuf) |
|
257 |
{ |
|
258 |
return s->ops->statfs(&s->ctx, path->data, stbuf); |
|
259 |
} |
|
260 |
|
|
256 | 261 |
static void v9fs_string_init(V9fsString *str) |
257 | 262 |
{ |
258 | 263 |
str->data = NULL; |
... | ... | |
1019 | 1024 |
|
1020 | 1025 |
static void v9fs_version(V9fsState *s, V9fsPDU *pdu) |
1021 | 1026 |
{ |
1022 |
int32_t msize; |
|
1023 | 1027 |
V9fsString version; |
1024 | 1028 |
size_t offset = 7; |
1025 | 1029 |
|
1026 |
pdu_unmarshal(pdu, offset, "ds", &msize, &version); |
|
1030 |
pdu_unmarshal(pdu, offset, "ds", &s->msize, &version);
|
|
1027 | 1031 |
|
1028 | 1032 |
if (!strcmp(version.data, "9P2000.u")) { |
1029 | 1033 |
s->proto_version = V9FS_PROTO_2000U; |
... | ... | |
1033 | 1037 |
v9fs_string_sprintf(&version, "unknown"); |
1034 | 1038 |
} |
1035 | 1039 |
|
1036 |
offset += pdu_marshal(pdu, offset, "ds", msize, &version); |
|
1040 |
offset += pdu_marshal(pdu, offset, "ds", s->msize, &version);
|
|
1037 | 1041 |
complete_pdu(s, pdu, offset); |
1038 | 1042 |
|
1039 | 1043 |
v9fs_string_free(&version); |
... | ... | |
1288 | 1292 |
v9fs_walk_complete(s, vs, err); |
1289 | 1293 |
} |
1290 | 1294 |
|
1295 |
static int32_t get_iounit(V9fsState *s, V9fsString *name) |
|
1296 |
{ |
|
1297 |
struct statfs stbuf; |
|
1298 |
int32_t iounit = 0; |
|
1299 |
|
|
1300 |
/* |
|
1301 |
* iounit should be multiples of f_bsize (host filesystem block size |
|
1302 |
* and as well as less than (client msize - P9_IOHDRSZ)) |
|
1303 |
*/ |
|
1304 |
if (!v9fs_do_statfs(s, name, &stbuf)) { |
|
1305 |
iounit = stbuf.f_bsize; |
|
1306 |
iounit *= (s->msize - P9_IOHDRSZ)/stbuf.f_bsize; |
|
1307 |
} |
|
1308 |
|
|
1309 |
if (!iounit) { |
|
1310 |
iounit = s->msize - P9_IOHDRSZ; |
|
1311 |
} |
|
1312 |
return iounit; |
|
1313 |
} |
|
1314 |
|
|
1291 | 1315 |
static void v9fs_open_post_opendir(V9fsState *s, V9fsOpenState *vs, int err) |
1292 | 1316 |
{ |
1293 | 1317 |
if (vs->fidp->dir == NULL) { |
... | ... | |
1303 | 1327 |
|
1304 | 1328 |
} |
1305 | 1329 |
|
1330 |
static void v9fs_open_post_getiounit(V9fsState *s, V9fsOpenState *vs) |
|
1331 |
{ |
|
1332 |
int err; |
|
1333 |
vs->offset += pdu_marshal(vs->pdu, vs->offset, "Qd", &vs->qid, vs->iounit); |
|
1334 |
err = vs->offset; |
|
1335 |
complete_pdu(s, vs->pdu, err); |
|
1336 |
qemu_free(vs); |
|
1337 |
} |
|
1338 |
|
|
1306 | 1339 |
static void v9fs_open_post_open(V9fsState *s, V9fsOpenState *vs, int err) |
1307 | 1340 |
{ |
1308 | 1341 |
if (vs->fidp->fd == -1) { |
... | ... | |
1310 | 1343 |
goto out; |
1311 | 1344 |
} |
1312 | 1345 |
|
1313 |
vs->offset += pdu_marshal(vs->pdu, vs->offset, "Qd", &vs->qid, 0); |
|
1314 |
err = vs->offset; |
|
1346 |
vs->iounit = get_iounit(s, &vs->fidp->path); |
|
1347 |
v9fs_open_post_getiounit(s, vs); |
|
1348 |
return; |
|
1315 | 1349 |
out: |
1316 | 1350 |
complete_pdu(s, vs->pdu, err); |
1317 | 1351 |
qemu_free(vs); |
... | ... | |
1794 | 1828 |
qemu_free(vs); |
1795 | 1829 |
} |
1796 | 1830 |
|
1797 |
static void v9fs_post_create(V9fsState *s, V9fsCreateState *vs, int err)
|
|
1831 |
static void v9fs_create_post_getiounit(V9fsState *s, V9fsCreateState *vs)
|
|
1798 | 1832 |
{ |
1799 |
if (err == 0) {
|
|
1800 |
v9fs_string_copy(&vs->fidp->path, &vs->fullname);
|
|
1801 |
stat_to_qid(&vs->stbuf, &vs->qid);
|
|
1833 |
int err;
|
|
1834 |
v9fs_string_copy(&vs->fidp->path, &vs->fullname); |
|
1835 |
stat_to_qid(&vs->stbuf, &vs->qid); |
|
1802 | 1836 |
|
1803 |
vs->offset += pdu_marshal(vs->pdu, vs->offset, "Qd", &vs->qid, 0); |
|
1837 |
vs->offset += pdu_marshal(vs->pdu, vs->offset, "Qd", &vs->qid, vs->iounit); |
|
1838 |
err = vs->offset; |
|
1804 | 1839 |
|
1805 |
err = vs->offset; |
|
1840 |
complete_pdu(s, vs->pdu, err); |
|
1841 |
v9fs_string_free(&vs->name); |
|
1842 |
v9fs_string_free(&vs->extension); |
|
1843 |
v9fs_string_free(&vs->fullname); |
|
1844 |
qemu_free(vs); |
|
1845 |
} |
|
1846 |
|
|
1847 |
static void v9fs_post_create(V9fsState *s, V9fsCreateState *vs, int err) |
|
1848 |
{ |
|
1849 |
if (err == 0) { |
|
1850 |
vs->iounit = get_iounit(s, &vs->fidp->path); |
|
1851 |
v9fs_create_post_getiounit(s, vs); |
|
1852 |
return; |
|
1806 | 1853 |
} |
1807 | 1854 |
|
1808 | 1855 |
complete_pdu(s, vs->pdu, err); |
... | ... | |
2266 | 2313 |
qemu_free(vs); |
2267 | 2314 |
} |
2268 | 2315 |
|
2269 |
static int v9fs_do_statfs(V9fsState *s, V9fsString *path, struct statfs *stbuf) |
|
2270 |
{ |
|
2271 |
return s->ops->statfs(&s->ctx, path->data, stbuf); |
|
2272 |
} |
|
2273 |
|
|
2274 | 2316 |
static void v9fs_statfs_post_statfs(V9fsState *s, V9fsStatfsState *vs, int err) |
2275 | 2317 |
{ |
2318 |
int32_t bsize_factor; |
|
2319 |
|
|
2276 | 2320 |
if (err) { |
2277 | 2321 |
err = -errno; |
2278 | 2322 |
goto out; |
2279 | 2323 |
} |
2280 | 2324 |
|
2325 |
/* |
|
2326 |
* compute bsize factor based on host file system block size |
|
2327 |
* and client msize |
|
2328 |
*/ |
|
2329 |
bsize_factor = (s->msize - P9_IOHDRSZ)/vs->stbuf.f_bsize; |
|
2330 |
if (!bsize_factor) { |
|
2331 |
bsize_factor = 1; |
|
2332 |
} |
|
2281 | 2333 |
vs->v9statfs.f_type = vs->stbuf.f_type; |
2282 | 2334 |
vs->v9statfs.f_bsize = vs->stbuf.f_bsize; |
2283 |
vs->v9statfs.f_blocks = vs->stbuf.f_blocks; |
|
2284 |
vs->v9statfs.f_bfree = vs->stbuf.f_bfree; |
|
2285 |
vs->v9statfs.f_bavail = vs->stbuf.f_bavail; |
|
2335 |
vs->v9statfs.f_bsize *= bsize_factor; |
|
2336 |
/* |
|
2337 |
* f_bsize is adjusted(multiplied) by bsize factor, so we need to |
|
2338 |
* adjust(divide) the number of blocks, free blocks and available |
|
2339 |
* blocks by bsize factor |
|
2340 |
*/ |
|
2341 |
vs->v9statfs.f_blocks = vs->stbuf.f_blocks/bsize_factor; |
|
2342 |
vs->v9statfs.f_bfree = vs->stbuf.f_bfree/bsize_factor; |
|
2343 |
vs->v9statfs.f_bavail = vs->stbuf.f_bavail/bsize_factor; |
|
2286 | 2344 |
vs->v9statfs.f_files = vs->stbuf.f_files; |
2287 | 2345 |
vs->v9statfs.f_ffree = vs->stbuf.f_ffree; |
2288 | 2346 |
vs->v9statfs.fsid_val = (unsigned int) vs->stbuf.f_fsid.__val[0] | |
Also available in: Unified diff