1329 |
1329 |
#define ATTR_ATIME_SET (1 << 7)
|
1330 |
1330 |
#define ATTR_MTIME_SET (1 << 8)
|
1331 |
1331 |
|
1332 |
|
static void v9fs_setattr_post_truncate(V9fsState *s, V9fsSetattrState *vs,
|
1333 |
|
int err)
|
1334 |
|
{
|
1335 |
|
if (err == -1) {
|
1336 |
|
err = -errno;
|
1337 |
|
goto out;
|
1338 |
|
}
|
1339 |
|
err = vs->offset;
|
1340 |
|
|
1341 |
|
out:
|
1342 |
|
complete_pdu(s, vs->pdu, err);
|
1343 |
|
qemu_free(vs);
|
1344 |
|
}
|
1345 |
|
|
1346 |
|
static void v9fs_setattr_post_chown(V9fsState *s, V9fsSetattrState *vs, int err)
|
|
1332 |
static void v9fs_setattr(void *opaque)
|
1347 |
1333 |
{
|
1348 |
|
if (err == -1) {
|
1349 |
|
err = -errno;
|
1350 |
|
goto out;
|
1351 |
|
}
|
|
1334 |
int err = 0;
|
|
1335 |
int32_t fid;
|
|
1336 |
V9fsFidState *fidp;
|
|
1337 |
size_t offset = 7;
|
|
1338 |
V9fsIattr v9iattr;
|
|
1339 |
V9fsPDU *pdu = opaque;
|
|
1340 |
V9fsState *s = pdu->s;
|
1352 |
1341 |
|
1353 |
|
if (vs->v9iattr.valid & (ATTR_SIZE)) {
|
1354 |
|
err = v9fs_do_truncate(s, &vs->fidp->path, vs->v9iattr.size);
|
1355 |
|
}
|
1356 |
|
v9fs_setattr_post_truncate(s, vs, err);
|
1357 |
|
return;
|
|
1342 |
pdu_unmarshal(pdu, offset, "dI", &fid, &v9iattr);
|
1358 |
1343 |
|
1359 |
|
out:
|
1360 |
|
complete_pdu(s, vs->pdu, err);
|
1361 |
|
qemu_free(vs);
|
1362 |
|
}
|
1363 |
|
|
1364 |
|
static void v9fs_setattr_post_utimensat(V9fsState *s, V9fsSetattrState *vs,
|
1365 |
|
int err)
|
1366 |
|
{
|
1367 |
|
if (err == -1) {
|
1368 |
|
err = -errno;
|
|
1344 |
fidp = lookup_fid(s, fid);
|
|
1345 |
if (fidp == NULL) {
|
|
1346 |
err = -EINVAL;
|
1369 |
1347 |
goto out;
|
1370 |
1348 |
}
|
1371 |
|
|
1372 |
|
/* If the only valid entry in iattr is ctime we can call
|
1373 |
|
* chown(-1,-1) to update the ctime of the file
|
1374 |
|
*/
|
1375 |
|
if ((vs->v9iattr.valid & (ATTR_UID | ATTR_GID)) ||
|
1376 |
|
((vs->v9iattr.valid & ATTR_CTIME)
|
1377 |
|
&& !((vs->v9iattr.valid & ATTR_MASK) & ~ATTR_CTIME))) {
|
1378 |
|
if (!(vs->v9iattr.valid & ATTR_UID)) {
|
1379 |
|
vs->v9iattr.uid = -1;
|
1380 |
|
}
|
1381 |
|
if (!(vs->v9iattr.valid & ATTR_GID)) {
|
1382 |
|
vs->v9iattr.gid = -1;
|
|
1349 |
if (v9iattr.valid & ATTR_MODE) {
|
|
1350 |
err = v9fs_co_chmod(s, &fidp->path, v9iattr.mode);
|
|
1351 |
if (err < 0) {
|
|
1352 |
goto out;
|
1383 |
1353 |
}
|
1384 |
|
err = v9fs_do_chown(s, &vs->fidp->path, vs->v9iattr.uid,
|
1385 |
|
vs->v9iattr.gid);
|
1386 |
1354 |
}
|
1387 |
|
v9fs_setattr_post_chown(s, vs, err);
|
1388 |
|
return;
|
1389 |
|
|
1390 |
|
out:
|
1391 |
|
complete_pdu(s, vs->pdu, err);
|
1392 |
|
qemu_free(vs);
|
1393 |
|
}
|
1394 |
|
|
1395 |
|
static void v9fs_setattr_post_chmod(V9fsState *s, V9fsSetattrState *vs, int err)
|
1396 |
|
{
|
1397 |
|
if (err == -1) {
|
1398 |
|
err = -errno;
|
1399 |
|
goto out;
|
1400 |
|
}
|
1401 |
|
|
1402 |
|
if (vs->v9iattr.valid & (ATTR_ATIME | ATTR_MTIME)) {
|
|
1355 |
if (v9iattr.valid & (ATTR_ATIME | ATTR_MTIME)) {
|
1403 |
1356 |
struct timespec times[2];
|
1404 |
|
if (vs->v9iattr.valid & ATTR_ATIME) {
|
1405 |
|
if (vs->v9iattr.valid & ATTR_ATIME_SET) {
|
1406 |
|
times[0].tv_sec = vs->v9iattr.atime_sec;
|
1407 |
|
times[0].tv_nsec = vs->v9iattr.atime_nsec;
|
|
1357 |
if (v9iattr.valid & ATTR_ATIME) {
|
|
1358 |
if (v9iattr.valid & ATTR_ATIME_SET) {
|
|
1359 |
times[0].tv_sec = v9iattr.atime_sec;
|
|
1360 |
times[0].tv_nsec = v9iattr.atime_nsec;
|
1408 |
1361 |
} else {
|
1409 |
1362 |
times[0].tv_nsec = UTIME_NOW;
|
1410 |
1363 |
}
|
1411 |
1364 |
} else {
|
1412 |
1365 |
times[0].tv_nsec = UTIME_OMIT;
|
1413 |
1366 |
}
|
1414 |
|
|
1415 |
|
if (vs->v9iattr.valid & ATTR_MTIME) {
|
1416 |
|
if (vs->v9iattr.valid & ATTR_MTIME_SET) {
|
1417 |
|
times[1].tv_sec = vs->v9iattr.mtime_sec;
|
1418 |
|
times[1].tv_nsec = vs->v9iattr.mtime_nsec;
|
|
1367 |
if (v9iattr.valid & ATTR_MTIME) {
|
|
1368 |
if (v9iattr.valid & ATTR_MTIME_SET) {
|
|
1369 |
times[1].tv_sec = v9iattr.mtime_sec;
|
|
1370 |
times[1].tv_nsec = v9iattr.mtime_nsec;
|
1419 |
1371 |
} else {
|
1420 |
1372 |
times[1].tv_nsec = UTIME_NOW;
|
1421 |
1373 |
}
|
1422 |
1374 |
} else {
|
1423 |
1375 |
times[1].tv_nsec = UTIME_OMIT;
|
1424 |
1376 |
}
|
1425 |
|
err = v9fs_do_utimensat(s, &vs->fidp->path, times);
|
|
1377 |
err = v9fs_co_utimensat(s, &fidp->path, times);
|
|
1378 |
if (err < 0) {
|
|
1379 |
goto out;
|
|
1380 |
}
|
1426 |
1381 |
}
|
1427 |
|
v9fs_setattr_post_utimensat(s, vs, err);
|
1428 |
|
return;
|
1429 |
|
|
1430 |
|
out:
|
1431 |
|
complete_pdu(s, vs->pdu, err);
|
1432 |
|
qemu_free(vs);
|
1433 |
|
}
|
1434 |
|
|
1435 |
|
static void v9fs_setattr(void *opaque)
|
1436 |
|
{
|
1437 |
|
V9fsPDU *pdu = opaque;
|
1438 |
|
V9fsState *s = pdu->s;
|
1439 |
|
int32_t fid;
|
1440 |
|
V9fsSetattrState *vs;
|
1441 |
|
int err = 0;
|
1442 |
|
|
1443 |
|
vs = qemu_malloc(sizeof(*vs));
|
1444 |
|
vs->pdu = pdu;
|
1445 |
|
vs->offset = 7;
|
1446 |
|
|
1447 |
|
pdu_unmarshal(pdu, vs->offset, "dI", &fid, &vs->v9iattr);
|
1448 |
|
|
1449 |
|
vs->fidp = lookup_fid(s, fid);
|
1450 |
|
if (vs->fidp == NULL) {
|
1451 |
|
err = -EINVAL;
|
1452 |
|
goto out;
|
|
1382 |
/*
|
|
1383 |
* If the only valid entry in iattr is ctime we can call
|
|
1384 |
* chown(-1,-1) to update the ctime of the file
|
|
1385 |
*/
|
|
1386 |
if ((v9iattr.valid & (ATTR_UID | ATTR_GID)) ||
|
|
1387 |
((v9iattr.valid & ATTR_CTIME)
|
|
1388 |
&& !((v9iattr.valid & ATTR_MASK) & ~ATTR_CTIME))) {
|
|
1389 |
if (!(v9iattr.valid & ATTR_UID)) {
|
|
1390 |
v9iattr.uid = -1;
|
|
1391 |
}
|
|
1392 |
if (!(v9iattr.valid & ATTR_GID)) {
|
|
1393 |
v9iattr.gid = -1;
|
|
1394 |
}
|
|
1395 |
err = v9fs_co_chown(s, &fidp->path, v9iattr.uid,
|
|
1396 |
v9iattr.gid);
|
|
1397 |
if (err < 0) {
|
|
1398 |
goto out;
|
|
1399 |
}
|
1453 |
1400 |
}
|
1454 |
|
|
1455 |
|
if (vs->v9iattr.valid & ATTR_MODE) {
|
1456 |
|
err = v9fs_do_chmod(s, &vs->fidp->path, vs->v9iattr.mode);
|
|
1401 |
if (v9iattr.valid & (ATTR_SIZE)) {
|
|
1402 |
err = v9fs_co_truncate(s, &fidp->path, v9iattr.size);
|
|
1403 |
if (err < 0) {
|
|
1404 |
goto out;
|
|
1405 |
}
|
1457 |
1406 |
}
|
1458 |
|
|
1459 |
|
v9fs_setattr_post_chmod(s, vs, err);
|
1460 |
|
return;
|
1461 |
|
|
|
1407 |
err = offset;
|
1462 |
1408 |
out:
|
1463 |
|
complete_pdu(s, vs->pdu, err);
|
1464 |
|
qemu_free(vs);
|
|
1409 |
complete_pdu(s, pdu, err);
|
1465 |
1410 |
}
|
1466 |
1411 |
|
1467 |
1412 |
static void v9fs_walk_complete(V9fsState *s, V9fsWalkState *vs, int err)
|