Pull xen block driver fixes from Jens Axboe: "A few small bug fixes for xen-blk{front,back} that have been sitting over my vacation" * 'for-linus' of git://git.kernel.dk/linux-block: xen-blkback: replace work_pending with work_busy in purge_persistent_gnt() xen-blkfront: don't add indirect pages to list when !feature_persistent xen-blkfront: introduce blkfront_gather_backend_features()
Unified · Split
| @@ -369,8 +369,8 @@ static void purge_persistent_gnt(struct xen_blkif *blkif) · 368 unmodified lines | ||
| 369 | 369 | return; |
| 370 | 370 | } |
| 371 | 371 | |
| 372 | − if (work_pending(&blkif->persistent_purge_work)) { | |
| 373 | − pr_alert_ratelimited("Scheduled work from previous purge is still pending, cannot purge list\n"); | |
| 372 | + if (work_busy(&blkif->persistent_purge_work)) { | |
| 373 | + pr_alert_ratelimited("Scheduled work from previous purge is still busy, cannot purge list\n"); | |
| 374 | 374 | return; |
| 375 | 375 | } |
| 376 | 376 | |
| @@ -179,6 +179,7 @@ static DEFINE_SPINLOCK(minor_lock); · 178 unmodified lines | ||
| 179 | 179 | ((_segs + SEGS_PER_INDIRECT_FRAME - 1)/SEGS_PER_INDIRECT_FRAME) |
| 180 | 180 | |
| 181 | 181 | static int blkfront_setup_indirect(struct blkfront_info *info); |
| 182 | +static int blkfront_gather_backend_features(struct blkfront_info *info); | |
| 182 | 183 | |
| 183 | 184 | static int get_id_from_freelist(struct blkfront_info *info) |
| 184 | 185 | { |
| @@ -1128,8 +1129,10 @@ static void blkif_completion(struct blk_shadow *s, struct blkfront_info *info, · 943 unmodified lines | ||
| 1128 | 1129 | * Add the used indirect page back to the list of |
| 1129 | 1130 | * available pages for indirect grefs. |
| 1130 | 1131 | */ |
| 1131 | − indirect_page = pfn_to_page(s->indirect_grants[i]->pfn); | |
| 1132 | − list_add(&indirect_page->lru, &info->indirect_pages); | |
| 1132 | + if (!info->feature_persistent) { | |
| 1133 | + indirect_page = pfn_to_page(s->indirect_grants[i]->pfn); | |
| 1134 | + list_add(&indirect_page->lru, &info->indirect_pages); | |
| 1135 | + } | |
| 1133 | 1136 | s->indirect_grants[i]->gref = GRANT_INVALID_REF; |
| 1134 | 1137 | list_add_tail(&s->indirect_grants[i]->node, &info->grants); |
| 1135 | 1138 | } |
| @@ -1519,7 +1522,7 @@ static int blkif_recover(struct blkfront_info *info) · 383 unmodified lines | ||
| 1519 | 1522 | info->shadow_free = info->ring.req_prod_pvt; |
| 1520 | 1523 | info->shadow[BLK_RING_SIZE(info)-1].req.u.rw.id = 0x0fffffff; |
| 1521 | 1524 | |
| 1522 | − rc = blkfront_setup_indirect(info); | |
| 1525 | + rc = blkfront_gather_backend_features(info); | |
| 1523 | 1526 | if (rc) { |
| 1524 | 1527 | kfree(copy); |
| 1525 | 1528 | return rc; |
| @@ -1720,20 +1723,13 @@ static void blkfront_setup_discard(struct blkfront_info *info) · 194 unmodified lines | ||
| 1720 | 1723 | |
| 1721 | 1724 | static int blkfront_setup_indirect(struct blkfront_info *info) |
| 1722 | 1725 | { |
| 1723 | − unsigned int indirect_segments, segs; | |
| 1726 | + unsigned int segs; | |
| 1724 | 1727 | int err, i; |
| 1725 | 1728 | |
| 1726 | − err = xenbus_gather(XBT_NIL, info->xbdev->otherend, | |
| 1727 | − "feature-max-indirect-segments", "%u", &indirect_segments, | |
| 1728 | − NULL); | |
| 1729 | − if (err) { | |
| 1730 | − info->max_indirect_segments = 0; | |
| 1729 | + if (info->max_indirect_segments == 0) | |
| 1731 | 1730 | segs = BLKIF_MAX_SEGMENTS_PER_REQUEST; |
| 1732 | − } else { | |
| 1733 | − info->max_indirect_segments = min(indirect_segments, | |
| 1734 | − xen_blkif_max_segments); | |
| 1731 | + else | |
| 1735 | 1732 | segs = info->max_indirect_segments; |
| 1736 | − } | |
| 1737 | 1733 | |
| 1738 | 1734 | err = fill_grant_buffer(info, (segs + INDIRECT_GREFS(segs)) * BLK_RING_SIZE(info)); |
| 1739 | 1735 | if (err) |
| @@ -1796,6 +1792,68 @@ out_of_memory: · 56 unmodified lines | ||
| 1796 | 1792 | return -ENOMEM; |
| 1797 | 1793 | } |
| 1798 | 1794 | |
| 1795 | +/* | |
| 1796 | + * Gather all backend feature-* | |
| 1797 | + */ | |
| 1798 | +static int blkfront_gather_backend_features(struct blkfront_info *info) | |
| 1799 | +{ | |
| 1800 | + int err; | |
| 1801 | + int barrier, flush, discard, persistent; | |
| 1802 | + unsigned int indirect_segments; | |
| 1803 | + | |
| 1804 | + info->feature_flush = 0; | |
| 1805 | + | |
| 1806 | + err = xenbus_gather(XBT_NIL, info->xbdev->otherend, | |
| 1807 | + "feature-barrier", "%d", &barrier, | |
| 1808 | + NULL); | |
| 1809 | + | |
| 1810 | + /* | |
| 1811 | + * If there's no "feature-barrier" defined, then it means | |
| 1812 | + * we're dealing with a very old backend which writes | |
| 1813 | + * synchronously; nothing to do. | |
| 1814 | + * | |
| 1815 | + * If there are barriers, then we use flush. | |
| 1816 | + */ | |
| 1817 | + if (!err && barrier) | |
| 1818 | + info->feature_flush = REQ_FLUSH | REQ_FUA; | |
| 1819 | + /* | |
| 1820 | + * And if there is "feature-flush-cache" use that above | |
| 1821 | + * barriers. | |
| 1822 | + */ | |
| 1823 | + err = xenbus_gather(XBT_NIL, info->xbdev->otherend, | |
| 1824 | + "feature-flush-cache", "%d", &flush, | |
| 1825 | + NULL); | |
| 1826 | + | |
| 1827 | + if (!err && flush) | |
| 1828 | + info->feature_flush = REQ_FLUSH; | |
| 1829 | + | |
| 1830 | + err = xenbus_gather(XBT_NIL, info->xbdev->otherend, | |
| 1831 | + "feature-discard", "%d", &discard, | |
| 1832 | + NULL); | |
| 1833 | + | |
| 1834 | + if (!err && discard) | |
| 1835 | + blkfront_setup_discard(info); | |
| 1836 | + | |
| 1837 | + err = xenbus_gather(XBT_NIL, info->xbdev->otherend, | |
| 1838 | + "feature-persistent", "%u", &persistent, | |
| 1839 | + NULL); | |
| 1840 | + if (err) | |
| 1841 | + info->feature_persistent = 0; | |
| 1842 | + else | |
| 1843 | + info->feature_persistent = persistent; | |
| 1844 | + | |
| 1845 | + err = xenbus_gather(XBT_NIL, info->xbdev->otherend, | |
| 1846 | + "feature-max-indirect-segments", "%u", &indirect_segments, | |
| 1847 | + NULL); | |
| 1848 | + if (err) | |
| 1849 | + info->max_indirect_segments = 0; | |
| 1850 | + else | |
| 1851 | + info->max_indirect_segments = min(indirect_segments, | |
| 1852 | + xen_blkif_max_segments); | |
| 1853 | + | |
| 1854 | + return blkfront_setup_indirect(info); | |
| 1855 | +} | |
| 1856 | + | |
| 1799 | 1857 | /* |
| 1800 | 1858 | * Invoked when the backend is finally 'ready' (and has told produced |
| 1801 | 1859 | * the details about the physical device - #sectors, size, etc). |
| @@ -1807,7 +1865,6 @@ static void blkfront_connect(struct blkfront_info *info) · 5 unmodified lines | ||
| 1807 | 1865 | unsigned int physical_sector_size; |
| 1808 | 1866 | unsigned int binfo; |
| 1809 | 1867 | int err; |
| 1810 | − int barrier, flush, discard, persistent; | |
| 1811 | 1868 | |
| 1812 | 1869 | switch (info->connected) { |
| 1813 | 1870 | case BLKIF_STATE_CONNECTED: |
| @@ -1864,48 +1921,7 @@ static void blkfront_connect(struct blkfront_info *info) · 50 unmodified lines | ||
| 1864 | 1921 | if (err != 1) |
| 1865 | 1922 | physical_sector_size = sector_size; |
| 1866 | 1923 | |
| 1867 | − info->feature_flush = 0; | |
| 1868 | − | |
| 1869 | − err = xenbus_gather(XBT_NIL, info->xbdev->otherend, | |
| 1870 | − "feature-barrier", "%d", &barrier, | |
| 1871 | − NULL); | |
| 1872 | − | |
| 1873 | − /* | |
| 1874 | − * If there's no "feature-barrier" defined, then it means | |
| 1875 | − * we're dealing with a very old backend which writes | |
| 1876 | − * synchronously; nothing to do. | |
| 1877 | − * | |
| 1878 | − * If there are barriers, then we use flush. | |
| 1879 | − */ | |
| 1880 | − if (!err && barrier) | |
| 1881 | − info->feature_flush = REQ_FLUSH | REQ_FUA; | |
| 1882 | − /* | |
| 1883 | − * And if there is "feature-flush-cache" use that above | |
| 1884 | − * barriers. | |
| 1885 | − */ | |
| 1886 | − err = xenbus_gather(XBT_NIL, info->xbdev->otherend, | |
| 1887 | − "feature-flush-cache", "%d", &flush, | |
| 1888 | − NULL); | |
| 1889 | − | |
| 1890 | − if (!err && flush) | |
| 1891 | − info->feature_flush = REQ_FLUSH; | |
| 1892 | − | |
| 1893 | − err = xenbus_gather(XBT_NIL, info->xbdev->otherend, | |
| 1894 | − "feature-discard", "%d", &discard, | |
| 1895 | − NULL); | |
| 1896 | − | |
| 1897 | − if (!err && discard) | |
| 1898 | − blkfront_setup_discard(info); | |
| 1899 | − | |
| 1900 | − err = xenbus_gather(XBT_NIL, info->xbdev->otherend, | |
| 1901 | − "feature-persistent", "%u", &persistent, | |
| 1902 | − NULL); | |
| 1903 | − if (err) | |
| 1904 | − info->feature_persistent = 0; | |
| 1905 | − else | |
| 1906 | − info->feature_persistent = persistent; | |
| 1907 | − | |
| 1908 | − err = blkfront_setup_indirect(info); | |
| 1924 | + err = blkfront_gather_backend_features(info); | |
| 1909 | 1925 | if (err) { |
| 1910 | 1926 | xenbus_dev_fatal(info->xbdev, err, "setup_indirect at %s", |
| 1911 | 1927 | info->xbdev->otherend); |