aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeng Tao <tao.peng@primarydata.com>2015-06-23 07:52:02 -0400
committerTrond Myklebust <trond.myklebust@primarydata.com>2015-06-24 10:53:11 -0400
commit27c430644369ccd9a2272492ba6d0e85e2e4800b (patch)
treee4187a040a57810cd1c52a8e0f3be45c127b252c
parentad4dc53e6496ba0b3c18aeda6f3367d9800b6ebf (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.c178
-rw-r--r--fs/nfs/flexfilelayout/flexfilelayout.h1
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
1664static int
1665ff_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
1672static size_t
1673ff_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 */
1712static void
1713ff_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
1754static void
1755ff_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
1767static void
1768ff_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
1783static void
1784ff_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
1663static bool 1819static bool
1664ff_layout_mirror_prepare_stats(struct nfs42_layoutstat_args *args, 1820ff_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
1892static void
1893ff_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
1732static struct pnfs_layoutdriver_type flexfilelayout_type = { 1905static 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
1757static int __init nfs4flexfilelayout_init(void) 1931static 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
80struct nfs4_ff_layout_segment { 81struct nfs4_ff_layout_segment {