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