Revision 65c05f9a hw/9pfs/virtio-9p.c

b/hw/9pfs/virtio-9p.c
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)

Also available in: Unified diff