diff options
| author | Peng Tao <tao.peng@primarydata.com> | 2015-06-23 07:52:02 -0400 |
|---|---|---|
| committer | Trond Myklebust <trond.myklebust@primarydata.com> | 2015-06-24 10:53:11 -0400 |
| commit | 27c430644369ccd9a2272492ba6d0e85e2e4800b (patch) | |
| tree | e4187a040a57810cd1c52a8e0f3be45c127b252c | |
| parent | ad4dc53e6496ba0b3c18aeda6f3367d9800b6ebf (diff) | |
pnfs/flexfiles: encode LAYOUTSTATS flexfiles specific data
Reviewed-by: Jeff Layton <jeff.layton@primarydata.com>
Signed-off-by: Peng Tao <tao.peng@primarydata.com>
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
| -rw-r--r-- | fs/nfs/flexfilelayout/flexfilelayout.c | 178 | ||||
| -rw-r--r-- | fs/nfs/flexfilelayout/flexfilelayout.h | 1 |
2 files changed, 177 insertions, 2 deletions
diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c index cd999af504d9..6bcb6d6c9dc3 100644 --- a/fs/nfs/flexfilelayout/flexfilelayout.c +++ b/fs/nfs/flexfilelayout/flexfilelayout.c | |||
| @@ -272,6 +272,7 @@ ff_layout_alloc_lseg(struct pnfs_layout_hdr *lh, | |||
| 272 | 272 | ||
| 273 | spin_lock_init(&fls->mirror_array[i]->lock); | 273 | spin_lock_init(&fls->mirror_array[i]->lock); |
| 274 | fls->mirror_array[i]->ds_count = ds_count; | 274 | fls->mirror_array[i]->ds_count = ds_count; |
| 275 | fls->mirror_array[i]->lseg = &fls->generic_hdr; | ||
| 275 | 276 | ||
| 276 | /* deviceid */ | 277 | /* deviceid */ |
| 277 | rc = decode_deviceid(&stream, &devid); | 278 | rc = decode_deviceid(&stream, &devid); |
| @@ -1660,6 +1661,161 @@ out: | |||
| 1660 | dprintk("%s: Return\n", __func__); | 1661 | dprintk("%s: Return\n", __func__); |
| 1661 | } | 1662 | } |
| 1662 | 1663 | ||
| 1664 | static int | ||
| 1665 | ff_layout_ntop4(const struct sockaddr *sap, char *buf, const size_t buflen) | ||
| 1666 | { | ||
| 1667 | const struct sockaddr_in *sin = (struct sockaddr_in *)sap; | ||
| 1668 | |||
| 1669 | return snprintf(buf, buflen, "%pI4", &sin->sin_addr); | ||
| 1670 | } | ||
| 1671 | |||
| 1672 | static size_t | ||
| 1673 | ff_layout_ntop6_noscopeid(const struct sockaddr *sap, char *buf, | ||
| 1674 | const int buflen) | ||
| 1675 | { | ||
| 1676 | const struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap; | ||
| 1677 | const struct in6_addr *addr = &sin6->sin6_addr; | ||
| 1678 | |||
| 1679 | /* | ||
| 1680 | * RFC 4291, Section 2.2.2 | ||
| 1681 | * | ||
| 1682 | * Shorthanded ANY address | ||
| 1683 | */ | ||
| 1684 | if (ipv6_addr_any(addr)) | ||
| 1685 | return snprintf(buf, buflen, "::"); | ||
| 1686 | |||
| 1687 | /* | ||
| 1688 | * RFC 4291, Section 2.2.2 | ||
| 1689 | * | ||
| 1690 | * Shorthanded loopback address | ||
| 1691 | */ | ||
| 1692 | if (ipv6_addr_loopback(addr)) | ||
| 1693 | return snprintf(buf, buflen, "::1"); | ||
| 1694 | |||
| 1695 | /* | ||
| 1696 | * RFC 4291, Section 2.2.3 | ||
| 1697 | * | ||
| 1698 | * Special presentation address format for mapped v4 | ||
| 1699 | * addresses. | ||
| 1700 | */ | ||
| 1701 | if (ipv6_addr_v4mapped(addr)) | ||
| 1702 | return snprintf(buf, buflen, "::ffff:%pI4", | ||
| 1703 | &addr->s6_addr32[3]); | ||
| 1704 | |||
| 1705 | /* | ||
| 1706 | * RFC 4291, Section 2.2.1 | ||
| 1707 | */ | ||
| 1708 | return snprintf(buf, buflen, "%pI6c", addr); | ||
| 1709 | } | ||
| 1710 | |||
| 1711 | /* Derived from rpc_sockaddr2uaddr */ | ||
| 1712 | static void | ||
| 1713 | ff_layout_encode_netaddr(struct xdr_stream *xdr, struct nfs4_pnfs_ds_addr *da) | ||
| 1714 | { | ||
| 1715 | struct sockaddr *sap = (struct sockaddr *)&da->da_addr; | ||
| 1716 | char portbuf[RPCBIND_MAXUADDRPLEN]; | ||
| 1717 | char addrbuf[RPCBIND_MAXUADDRLEN]; | ||
| 1718 | char *netid; | ||
| 1719 | unsigned short port; | ||
| 1720 | int len, netid_len; | ||
| 1721 | __be32 *p; | ||
| 1722 | |||
| 1723 | switch (sap->sa_family) { | ||
| 1724 | case AF_INET: | ||
| 1725 | if (ff_layout_ntop4(sap, addrbuf, sizeof(addrbuf)) == 0) | ||
| 1726 | return; | ||
| 1727 | port = ntohs(((struct sockaddr_in *)sap)->sin_port); | ||
| 1728 | netid = "tcp"; | ||
| 1729 | netid_len = 3; | ||
| 1730 | break; | ||
| 1731 | case AF_INET6: | ||
| 1732 | if (ff_layout_ntop6_noscopeid(sap, addrbuf, sizeof(addrbuf)) == 0) | ||
| 1733 | return; | ||
| 1734 | port = ntohs(((struct sockaddr_in6 *)sap)->sin6_port); | ||
| 1735 | netid = "tcp6"; | ||
| 1736 | netid_len = 4; | ||
| 1737 | break; | ||
| 1738 | default: | ||
| 1739 | /* we only support tcp and tcp6 */ | ||
| 1740 | WARN_ON_ONCE(1); | ||
| 1741 | return; | ||
| 1742 | } | ||
| 1743 | |||
| 1744 | snprintf(portbuf, sizeof(portbuf), ".%u.%u", port >> 8, port & 0xff); | ||
| 1745 | len = strlcat(addrbuf, portbuf, sizeof(addrbuf)); | ||
| 1746 | |||
| 1747 | p = xdr_reserve_space(xdr, 4 + netid_len); | ||
| 1748 | xdr_encode_opaque(p, netid, netid_len); | ||
| 1749 | |||
| 1750 | p = xdr_reserve_space(xdr, 4 + len); | ||
| 1751 | xdr_encode_opaque(p, addrbuf, len); | ||
| 1752 | } | ||
| 1753 | |||
| 1754 | static void | ||
| 1755 | ff_layout_encode_nfstime(struct xdr_stream *xdr, | ||
| 1756 | ktime_t t) | ||
| 1757 | { | ||
| 1758 | struct timespec64 ts; | ||
| 1759 | __be32 *p; | ||
| 1760 | |||
| 1761 | p = xdr_reserve_space(xdr, 12); | ||
| 1762 | ts = ktime_to_timespec64(t); | ||
| 1763 | p = xdr_encode_hyper(p, ts.tv_sec); | ||
| 1764 | *p++ = cpu_to_be32(ts.tv_nsec); | ||
| 1765 | } | ||
| 1766 | |||
| 1767 | static void | ||
| 1768 | ff_layout_encode_io_latency(struct xdr_stream *xdr, | ||
| 1769 | struct nfs4_ff_io_stat *stat) | ||
| 1770 | { | ||
| 1771 | __be32 *p; | ||
| 1772 | |||
| 1773 | p = xdr_reserve_space(xdr, 5 * 8); | ||
| 1774 | p = xdr_encode_hyper(p, stat->ops_requested); | ||
| 1775 | p = xdr_encode_hyper(p, stat->bytes_requested); | ||
| 1776 | p = xdr_encode_hyper(p, stat->ops_completed); | ||
| 1777 | p = xdr_encode_hyper(p, stat->bytes_completed); | ||
| 1778 | p = xdr_encode_hyper(p, stat->bytes_not_delivered); | ||
| 1779 | ff_layout_encode_nfstime(xdr, stat->total_busy_time); | ||
| 1780 | ff_layout_encode_nfstime(xdr, stat->aggregate_completion_time); | ||
| 1781 | } | ||
| 1782 | |||
| 1783 | static void | ||
| 1784 | ff_layout_encode_layoutstats(struct xdr_stream *xdr, | ||
| 1785 | struct nfs42_layoutstat_args *args, | ||
| 1786 | struct nfs42_layoutstat_devinfo *devinfo) | ||
| 1787 | { | ||
| 1788 | struct nfs4_ff_layout_mirror *mirror = devinfo->layout_private; | ||
| 1789 | struct nfs4_pnfs_ds_addr *da; | ||
| 1790 | struct nfs4_pnfs_ds *ds = mirror->mirror_ds->ds; | ||
| 1791 | struct nfs_fh *fh = &mirror->fh_versions[0]; | ||
| 1792 | __be32 *p, *start; | ||
| 1793 | |||
| 1794 | da = list_first_entry(&ds->ds_addrs, struct nfs4_pnfs_ds_addr, da_node); | ||
| 1795 | dprintk("%s: DS %s: encoding address %s\n", | ||
| 1796 | __func__, ds->ds_remotestr, da->da_remotestr); | ||
| 1797 | /* layoutupdate length */ | ||
| 1798 | start = xdr_reserve_space(xdr, 4); | ||
| 1799 | /* netaddr4 */ | ||
| 1800 | ff_layout_encode_netaddr(xdr, da); | ||
| 1801 | /* nfs_fh4 */ | ||
| 1802 | p = xdr_reserve_space(xdr, 4 + fh->size); | ||
| 1803 | xdr_encode_opaque(p, fh->data, fh->size); | ||
| 1804 | /* ff_io_latency4 read */ | ||
| 1805 | spin_lock(&mirror->lock); | ||
| 1806 | ff_layout_encode_io_latency(xdr, &mirror->read_stat.io_stat); | ||
| 1807 | /* ff_io_latency4 write */ | ||
| 1808 | ff_layout_encode_io_latency(xdr, &mirror->write_stat.io_stat); | ||
| 1809 | spin_unlock(&mirror->lock); | ||
| 1810 | /* nfstime4 */ | ||
| 1811 | ff_layout_encode_nfstime(xdr, ktime_sub(ktime_get(), mirror->start_time)); | ||
| 1812 | /* bool */ | ||
| 1813 | p = xdr_reserve_space(xdr, 4); | ||
| 1814 | *p = cpu_to_be32(false); | ||
| 1815 | |||
| 1816 | *start = cpu_to_be32((xdr->p - start - 1) * 4); | ||
| 1817 | } | ||
| 1818 | |||
| 1663 | static bool | 1819 | static bool |
| 1664 | ff_layout_mirror_prepare_stats(struct nfs42_layoutstat_args *args, | 1820 | ff_layout_mirror_prepare_stats(struct nfs42_layoutstat_args *args, |
| 1665 | struct pnfs_layout_segment *pls, | 1821 | struct pnfs_layout_segment *pls, |
| @@ -1674,6 +1830,8 @@ ff_layout_mirror_prepare_stats(struct nfs42_layoutstat_args *args, | |||
| 1674 | if (*dev_count >= dev_limit) | 1830 | if (*dev_count >= dev_limit) |
| 1675 | break; | 1831 | break; |
| 1676 | mirror = FF_LAYOUT_COMP(pls, i); | 1832 | mirror = FF_LAYOUT_COMP(pls, i); |
| 1833 | if (!mirror || !mirror->mirror_ds) | ||
| 1834 | continue; | ||
| 1677 | dev = FF_LAYOUT_DEVID_NODE(pls, i); | 1835 | dev = FF_LAYOUT_DEVID_NODE(pls, i); |
| 1678 | devinfo = &args->devinfo[*dev_count]; | 1836 | devinfo = &args->devinfo[*dev_count]; |
| 1679 | memcpy(&devinfo->dev_id, &dev->deviceid, NFS4_DEVICEID4_SIZE); | 1837 | memcpy(&devinfo->dev_id, &dev->deviceid, NFS4_DEVICEID4_SIZE); |
| @@ -1685,8 +1843,10 @@ ff_layout_mirror_prepare_stats(struct nfs42_layoutstat_args *args, | |||
| 1685 | devinfo->write_count = mirror->write_stat.io_stat.bytes_completed; | 1843 | devinfo->write_count = mirror->write_stat.io_stat.bytes_completed; |
| 1686 | devinfo->write_bytes = mirror->write_stat.io_stat.bytes_completed; | 1844 | devinfo->write_bytes = mirror->write_stat.io_stat.bytes_completed; |
| 1687 | devinfo->layout_type = LAYOUT_FLEX_FILES; | 1845 | devinfo->layout_type = LAYOUT_FLEX_FILES; |
| 1688 | devinfo->layoutstats_encode = NULL; | 1846 | devinfo->layoutstats_encode = ff_layout_encode_layoutstats; |
| 1689 | devinfo->layout_private = NULL; | 1847 | devinfo->layout_private = mirror; |
| 1848 | /* lseg refcount put in cleanup_layoutstats */ | ||
| 1849 | pnfs_get_lseg(pls); | ||
| 1690 | 1850 | ||
| 1691 | ++(*dev_count); | 1851 | ++(*dev_count); |
| 1692 | } | 1852 | } |
| @@ -1729,6 +1889,19 @@ ff_layout_prepare_layoutstats(struct nfs42_layoutstat_args *args) | |||
| 1729 | return 0; | 1889 | return 0; |
| 1730 | } | 1890 | } |
| 1731 | 1891 | ||
| 1892 | static void | ||
| 1893 | ff_layout_cleanup_layoutstats(struct nfs42_layoutstat_data *data) | ||
| 1894 | { | ||
| 1895 | struct nfs4_ff_layout_mirror *mirror; | ||
| 1896 | int i; | ||
| 1897 | |||
| 1898 | for (i = 0; i < data->args.num_dev; i++) { | ||
| 1899 | mirror = data->args.devinfo[i].layout_private; | ||
| 1900 | data->args.devinfo[i].layout_private = NULL; | ||
| 1901 | pnfs_put_lseg(mirror->lseg); | ||
| 1902 | } | ||
| 1903 | } | ||
| 1904 | |||
| 1732 | static struct pnfs_layoutdriver_type flexfilelayout_type = { | 1905 | static struct pnfs_layoutdriver_type flexfilelayout_type = { |
| 1733 | .id = LAYOUT_FLEX_FILES, | 1906 | .id = LAYOUT_FLEX_FILES, |
| 1734 | .name = "LAYOUT_FLEX_FILES", | 1907 | .name = "LAYOUT_FLEX_FILES", |
| @@ -1752,6 +1925,7 @@ static struct pnfs_layoutdriver_type flexfilelayout_type = { | |||
| 1752 | .encode_layoutreturn = ff_layout_encode_layoutreturn, | 1925 | .encode_layoutreturn = ff_layout_encode_layoutreturn, |
| 1753 | .sync = pnfs_nfs_generic_sync, | 1926 | .sync = pnfs_nfs_generic_sync, |
| 1754 | .prepare_layoutstats = ff_layout_prepare_layoutstats, | 1927 | .prepare_layoutstats = ff_layout_prepare_layoutstats, |
| 1928 | .cleanup_layoutstats = ff_layout_cleanup_layoutstats, | ||
| 1755 | }; | 1929 | }; |
| 1756 | 1930 | ||
| 1757 | static int __init nfs4flexfilelayout_init(void) | 1931 | static int __init nfs4flexfilelayout_init(void) |
diff --git a/fs/nfs/flexfilelayout/flexfilelayout.h b/fs/nfs/flexfilelayout/flexfilelayout.h index 0e7366f44d11..7e248874f46d 100644 --- a/fs/nfs/flexfilelayout/flexfilelayout.h +++ b/fs/nfs/flexfilelayout/flexfilelayout.h | |||
| @@ -75,6 +75,7 @@ struct nfs4_ff_layout_mirror { | |||
| 75 | struct nfs4_ff_layoutstat read_stat; | 75 | struct nfs4_ff_layoutstat read_stat; |
| 76 | struct nfs4_ff_layoutstat write_stat; | 76 | struct nfs4_ff_layoutstat write_stat; |
| 77 | ktime_t start_time; | 77 | ktime_t start_time; |
| 78 | struct pnfs_layout_segment *lseg; /* back pointer */ | ||
| 78 | }; | 79 | }; |
| 79 | 80 | ||
| 80 | struct nfs4_ff_layout_segment { | 81 | struct nfs4_ff_layout_segment { |
