Revision bb9e3216

b/hw/virtio-9p.c
580 580
    free_pdu(s, pdu);
581 581
}
582 582

  
583
static mode_t v9mode_to_mode(uint32_t mode, V9fsString *extension)
584
{
585
    mode_t ret;
586

  
587
    ret = mode & 0777;
588
    if (mode & P9_STAT_MODE_DIR) {
589
        ret |= S_IFDIR;
590
    }
591

  
592
    if (dotu) {
593
        if (mode & P9_STAT_MODE_SYMLINK) {
594
            ret |= S_IFLNK;
595
        }
596
        if (mode & P9_STAT_MODE_SOCKET) {
597
            ret |= S_IFSOCK;
598
        }
599
        if (mode & P9_STAT_MODE_NAMED_PIPE) {
600
            ret |= S_IFIFO;
601
        }
602
        if (mode & P9_STAT_MODE_DEVICE) {
603
            if (extension && extension->data[0] == 'c') {
604
                ret |= S_IFCHR;
605
            } else {
606
                ret |= S_IFBLK;
607
            }
608
        }
609
    }
610

  
611
    if (!(ret&~0777)) {
612
        ret |= S_IFREG;
613
    }
614

  
615
    if (mode & P9_STAT_MODE_SETUID) {
616
        ret |= S_ISUID;
617
    }
618
    if (mode & P9_STAT_MODE_SETGID) {
619
        ret |= S_ISGID;
620
    }
621
    if (mode & P9_STAT_MODE_SETVTX) {
622
        ret |= S_ISVTX;
623
    }
624

  
625
    return ret;
626
}
627

  
628
static int donttouch_stat(V9fsStat *stat)
629
{
630
    if (stat->type == -1 &&
631
        stat->dev == -1 &&
632
        stat->qid.type == -1 &&
633
        stat->qid.version == -1 &&
634
        stat->qid.path == -1 &&
635
        stat->mode == -1 &&
636
        stat->atime == -1 &&
637
        stat->mtime == -1 &&
638
        stat->length == -1 &&
639
        !stat->name.size &&
640
        !stat->uid.size &&
641
        !stat->gid.size &&
642
        !stat->muid.size &&
643
        stat->n_uid == -1 &&
644
        stat->n_gid == -1 &&
645
        stat->n_muid == -1) {
646
        return 1;
647
    }
648

  
649
    return 0;
650
}
651

  
652
static void v9fs_stat_free(V9fsStat *stat)
653
{
654
    v9fs_string_free(&stat->name);
655
    v9fs_string_free(&stat->uid);
656
    v9fs_string_free(&stat->gid);
657
    v9fs_string_free(&stat->muid);
658
    v9fs_string_free(&stat->extension);
659
}
660

  
661
static uint32_t stat_to_v9mode(const struct stat *stbuf)
662
{
663
    uint32_t mode;
664

  
665
    mode = stbuf->st_mode & 0777;
666
    if (S_ISDIR(stbuf->st_mode)) {
667
        mode |= P9_STAT_MODE_DIR;
668
    }
669

  
670
    if (dotu) {
671
        if (S_ISLNK(stbuf->st_mode)) {
672
            mode |= P9_STAT_MODE_SYMLINK;
673
        }
674

  
675
        if (S_ISSOCK(stbuf->st_mode)) {
676
            mode |= P9_STAT_MODE_SOCKET;
677
        }
678

  
679
        if (S_ISFIFO(stbuf->st_mode)) {
680
            mode |= P9_STAT_MODE_NAMED_PIPE;
681
        }
682

  
683
        if (S_ISBLK(stbuf->st_mode) || S_ISCHR(stbuf->st_mode)) {
684
            mode |= P9_STAT_MODE_DEVICE;
685
        }
686

  
687
        if (stbuf->st_mode & S_ISUID) {
688
            mode |= P9_STAT_MODE_SETUID;
689
        }
690

  
691
        if (stbuf->st_mode & S_ISGID) {
692
            mode |= P9_STAT_MODE_SETGID;
693
        }
694

  
695
        if (stbuf->st_mode & S_ISVTX) {
696
            mode |= P9_STAT_MODE_SETVTX;
697
        }
698
    }
699

  
700
    return mode;
701
}
702

  
703
static int stat_to_v9stat(V9fsState *s, V9fsString *name,
704
                            const struct stat *stbuf,
705
                            V9fsStat *v9stat)
706
{
707
    int err;
708
    const char *str;
709

  
710
    memset(v9stat, 0, sizeof(*v9stat));
711

  
712
    stat_to_qid(stbuf, &v9stat->qid);
713
    v9stat->mode = stat_to_v9mode(stbuf);
714
    v9stat->atime = stbuf->st_atime;
715
    v9stat->mtime = stbuf->st_mtime;
716
    v9stat->length = stbuf->st_size;
717

  
718
    v9fs_string_null(&v9stat->uid);
719
    v9fs_string_null(&v9stat->gid);
720
    v9fs_string_null(&v9stat->muid);
721

  
722
    if (dotu) {
723
        v9stat->n_uid = stbuf->st_uid;
724
        v9stat->n_gid = stbuf->st_gid;
725
        v9stat->n_muid = 0;
726

  
727
        v9fs_string_null(&v9stat->extension);
728

  
729
        if (v9stat->mode & P9_STAT_MODE_SYMLINK) {
730
            err = v9fs_do_readlink(s, name, &v9stat->extension);
731
            if (err == -1) {
732
                err = -errno;
733
                return err;
734
            }
735
            v9stat->extension.data[err] = 0;
736
            v9stat->extension.size = err;
737
        } else if (v9stat->mode & P9_STAT_MODE_DEVICE) {
738
            v9fs_string_sprintf(&v9stat->extension, "%c %u %u",
739
                    S_ISCHR(stbuf->st_mode) ? 'c' : 'b',
740
                    major(stbuf->st_rdev), minor(stbuf->st_rdev));
741
        } else if (S_ISDIR(stbuf->st_mode) || S_ISREG(stbuf->st_mode)) {
742
            v9fs_string_sprintf(&v9stat->extension, "%s %u",
743
                    "HARDLINKCOUNT", stbuf->st_nlink);
744
        }
745
    }
746

  
747
    str = strrchr(name->data, '/');
748
    if (str) {
749
        str += 1;
750
    } else {
751
        str = name->data;
752
    }
753

  
754
    v9fs_string_sprintf(&v9stat->name, "%s", str);
755

  
756
    v9stat->size = 61 +
757
        v9fs_string_size(&v9stat->name) +
758
        v9fs_string_size(&v9stat->uid) +
759
        v9fs_string_size(&v9stat->gid) +
760
        v9fs_string_size(&v9stat->muid) +
761
        v9fs_string_size(&v9stat->extension);
762
    return 0;
763
}
764

  
583 765
static void v9fs_dummy(V9fsState *s, V9fsPDU *pdu)
584 766
{
585 767
    /* Note: The following have been added to prevent GCC from complaining
......
600 782
    (void) alloc_fid;
601 783
    (void) free_fid;
602 784
    (void) fid_to_qid;
785
    (void) v9mode_to_mode;
786
    (void) donttouch_stat;
787
    (void) v9fs_stat_free;
788
    (void) stat_to_v9stat;
603 789
}
604 790

  
605 791
static void v9fs_version(V9fsState *s, V9fsPDU *pdu)

Also available in: Unified diff