9p.c (1a6ed33cc56997479bbe5b48337ff8da44585bd4) | 9p.c (f3fe4a2d92bb4ee5b599b8b1eb781b2ae68af36c) |
---|---|
1/* 2 * Virtio 9p backend 3 * 4 * Copyright IBM, Corp. 2010 5 * 6 * Authors: 7 * Anthony Liguori <aliguori@us.ibm.com> 8 * --- 565 unchanged lines hidden (view full) --- 574 P9_STAT_MODE_SOCKET) 575 576/* creative abuse of tb_hash_func7, which is based on xxhash */ 577static uint32_t qpp_hash(QppEntry e) 578{ 579 return qemu_xxhash7(e.ino_prefix, e.dev, 0, 0, 0); 580} 581 | 1/* 2 * Virtio 9p backend 3 * 4 * Copyright IBM, Corp. 2010 5 * 6 * Authors: 7 * Anthony Liguori <aliguori@us.ibm.com> 8 * --- 565 unchanged lines hidden (view full) --- 574 P9_STAT_MODE_SOCKET) 575 576/* creative abuse of tb_hash_func7, which is based on xxhash */ 577static uint32_t qpp_hash(QppEntry e) 578{ 579 return qemu_xxhash7(e.ino_prefix, e.dev, 0, 0, 0); 580} 581 |
582static uint32_t qpf_hash(QpfEntry e) 583{ 584 return qemu_xxhash7(e.ino, e.dev, 0, 0, 0); 585} 586 |
|
582static bool qpp_lookup_func(const void *obj, const void *userp) 583{ 584 const QppEntry *e1 = obj, *e2 = userp; 585 return e1->dev == e2->dev && e1->ino_prefix == e2->ino_prefix; 586} 587 | 587static bool qpp_lookup_func(const void *obj, const void *userp) 588{ 589 const QppEntry *e1 = obj, *e2 = userp; 590 return e1->dev == e2->dev && e1->ino_prefix == e2->ino_prefix; 591} 592 |
588static void qpp_table_remove(void *p, uint32_t h, void *up) | 593static bool qpf_lookup_func(const void *obj, const void *userp) |
589{ | 594{ |
595 const QpfEntry *e1 = obj, *e2 = userp; 596 return e1->dev == e2->dev && e1->ino == e2->ino; 597} 598 599static void qp_table_remove(void *p, uint32_t h, void *up) 600{ |
|
590 g_free(p); 591} 592 | 601 g_free(p); 602} 603 |
593static void qpp_table_destroy(struct qht *ht) | 604static void qp_table_destroy(struct qht *ht) |
594{ 595 if (!ht || !ht->map) { 596 return; 597 } | 605{ 606 if (!ht || !ht->map) { 607 return; 608 } |
598 qht_iter(ht, qpp_table_remove, NULL); | 609 qht_iter(ht, qp_table_remove, NULL); |
599 qht_destroy(ht); 600} 601 602static void qpp_table_init(struct qht *ht) 603{ 604 qht_init(ht, qpp_lookup_func, 1, QHT_MODE_AUTO_RESIZE); 605} 606 | 610 qht_destroy(ht); 611} 612 613static void qpp_table_init(struct qht *ht) 614{ 615 qht_init(ht, qpp_lookup_func, 1, QHT_MODE_AUTO_RESIZE); 616} 617 |
618static void qpf_table_init(struct qht *ht) 619{ 620 qht_init(ht, qpf_lookup_func, 1 << 16, QHT_MODE_AUTO_RESIZE); 621} 622 623static int qid_path_fullmap(V9fsPDU *pdu, const struct stat *stbuf, 624 uint64_t *path) 625{ 626 QpfEntry lookup = { 627 .dev = stbuf->st_dev, 628 .ino = stbuf->st_ino 629 }, *val; 630 uint32_t hash = qpf_hash(lookup); 631 632 /* most users won't need the fullmap, so init the table lazily */ 633 if (!pdu->s->qpf_table.map) { 634 qpf_table_init(&pdu->s->qpf_table); 635 } 636 637 val = qht_lookup(&pdu->s->qpf_table, &lookup, hash); 638 639 if (!val) { 640 if (pdu->s->qp_fullpath_next == 0) { 641 /* no more files can be mapped :'( */ 642 error_report_once( 643 "9p: No more prefixes available for remapping inodes from " 644 "host to guest." 645 ); 646 return -ENFILE; 647 } 648 649 val = g_malloc0(sizeof(QppEntry)); 650 *val = lookup; 651 652 /* new unique inode and device combo */ 653 val->path = pdu->s->qp_fullpath_next++; 654 pdu->s->qp_fullpath_next &= QPATH_INO_MASK; 655 qht_insert(&pdu->s->qpf_table, val, hash, NULL); 656 } 657 658 *path = val->path; 659 return 0; 660} 661 |
|
607/* 608 * stat_to_qid needs to map inode number (64 bits) and device id (32 bits) 609 * to a unique QID path (64 bits). To avoid having to map and keep track 610 * of up to 2^64 objects, we map only the 16 highest bits of the inode plus 611 * the device id to the 16 highest bits of the QID path. The 48 lowest bits 612 * of the QID path equal to the lowest bits of the inode number. 613 * 614 * This takes advantage of the fact that inode number are usually not --- 9 unchanged lines hidden (view full) --- 624 }, *val; 625 uint32_t hash = qpp_hash(lookup); 626 627 val = qht_lookup(&pdu->s->qpp_table, &lookup, hash); 628 629 if (!val) { 630 if (pdu->s->qp_prefix_next == 0) { 631 /* we ran out of prefixes */ | 662/* 663 * stat_to_qid needs to map inode number (64 bits) and device id (32 bits) 664 * to a unique QID path (64 bits). To avoid having to map and keep track 665 * of up to 2^64 objects, we map only the 16 highest bits of the inode plus 666 * the device id to the 16 highest bits of the QID path. The 48 lowest bits 667 * of the QID path equal to the lowest bits of the inode number. 668 * 669 * This takes advantage of the fact that inode number are usually not --- 9 unchanged lines hidden (view full) --- 679 }, *val; 680 uint32_t hash = qpp_hash(lookup); 681 682 val = qht_lookup(&pdu->s->qpp_table, &lookup, hash); 683 684 if (!val) { 685 if (pdu->s->qp_prefix_next == 0) { 686 /* we ran out of prefixes */ |
632 error_report_once( 633 "9p: No more prefixes available for remapping inodes from " 634 "host to guest." | 687 warn_report_once( 688 "9p: Potential degraded performance of inode remapping" |
635 ); 636 return -ENFILE; 637 } 638 639 val = g_malloc0(sizeof(QppEntry)); 640 *val = lookup; 641 642 /* new unique inode prefix and device combo */ --- 8 unchanged lines hidden (view full) --- 651static int stat_to_qid(V9fsPDU *pdu, const struct stat *stbuf, V9fsQID *qidp) 652{ 653 int err; 654 size_t size; 655 656 if (pdu->s->ctx.export_flags & V9FS_REMAP_INODES) { 657 /* map inode+device to qid path (fast path) */ 658 err = qid_path_prefixmap(pdu, stbuf, &qidp->path); | 689 ); 690 return -ENFILE; 691 } 692 693 val = g_malloc0(sizeof(QppEntry)); 694 *val = lookup; 695 696 /* new unique inode prefix and device combo */ --- 8 unchanged lines hidden (view full) --- 705static int stat_to_qid(V9fsPDU *pdu, const struct stat *stbuf, V9fsQID *qidp) 706{ 707 int err; 708 size_t size; 709 710 if (pdu->s->ctx.export_flags & V9FS_REMAP_INODES) { 711 /* map inode+device to qid path (fast path) */ 712 err = qid_path_prefixmap(pdu, stbuf, &qidp->path); |
713 if (err == -ENFILE) { 714 /* fast path didn't work, fall back to full map */ 715 err = qid_path_fullmap(pdu, stbuf, &qidp->path); 716 } |
|
659 if (err) { 660 return err; 661 } 662 } else { 663 if (pdu->s->dev_id != stbuf->st_dev) { 664 if (pdu->s->ctx.export_flags & V9FS_FORBID_MULTIDEVS) { 665 error_report_once( 666 "9p: Multiple devices detected in same VirtFS export. " --- 3148 unchanged lines hidden (view full) --- 3815 error_setg(errp, "share path %s is not a directory", fse->path); 3816 goto out; 3817 } 3818 3819 s->dev_id = stat.st_dev; 3820 3821 qpp_table_init(&s->qpp_table); 3822 s->qp_prefix_next = 1; /* reserve 0 to detect overflow */ | 717 if (err) { 718 return err; 719 } 720 } else { 721 if (pdu->s->dev_id != stbuf->st_dev) { 722 if (pdu->s->ctx.export_flags & V9FS_FORBID_MULTIDEVS) { 723 error_report_once( 724 "9p: Multiple devices detected in same VirtFS export. " --- 3148 unchanged lines hidden (view full) --- 3873 error_setg(errp, "share path %s is not a directory", fse->path); 3874 goto out; 3875 } 3876 3877 s->dev_id = stat.st_dev; 3878 3879 qpp_table_init(&s->qpp_table); 3880 s->qp_prefix_next = 1; /* reserve 0 to detect overflow */ |
3881 s->qp_fullpath_next = 1; |
|
3823 3824 s->ctx.fst = &fse->fst; 3825 fsdev_throttle_init(s->ctx.fst); 3826 3827 rc = 0; 3828out: 3829 if (rc) { 3830 v9fs_device_unrealize_common(s, NULL); --- 6 unchanged lines hidden (view full) --- 3837{ 3838 if (s->ops && s->ops->cleanup) { 3839 s->ops->cleanup(&s->ctx); 3840 } 3841 if (s->ctx.fst) { 3842 fsdev_throttle_cleanup(s->ctx.fst); 3843 } 3844 g_free(s->tag); | 3882 3883 s->ctx.fst = &fse->fst; 3884 fsdev_throttle_init(s->ctx.fst); 3885 3886 rc = 0; 3887out: 3888 if (rc) { 3889 v9fs_device_unrealize_common(s, NULL); --- 6 unchanged lines hidden (view full) --- 3896{ 3897 if (s->ops && s->ops->cleanup) { 3898 s->ops->cleanup(&s->ctx); 3899 } 3900 if (s->ctx.fst) { 3901 fsdev_throttle_cleanup(s->ctx.fst); 3902 } 3903 g_free(s->tag); |
3845 qpp_table_destroy(&s->qpp_table); | 3904 qp_table_destroy(&s->qpp_table); 3905 qp_table_destroy(&s->qpf_table); |
3846 g_free(s->ctx.fs_root); 3847} 3848 3849typedef struct VirtfsCoResetData { 3850 V9fsPDU pdu; 3851 bool done; 3852} VirtfsCoResetData; 3853 --- 35 unchanged lines hidden --- | 3906 g_free(s->ctx.fs_root); 3907} 3908 3909typedef struct VirtfsCoResetData { 3910 V9fsPDU pdu; 3911 bool done; 3912} VirtfsCoResetData; 3913 --- 35 unchanged lines hidden --- |