MCPcopy Create free account
hub / github.com/F-Stack/f-stack / send_reader_thread

Function send_reader_thread

freebsd/contrib/openzfs/module/zfs/dmu_send.c:1734–1897  ·  view source on GitHub ↗

* This thread is responsible for two things: First, it retrieves the correct * blkptr in the to ds if we need to send the data because of something from * the from thread. As a result of this, we're the first ones to discover that * some indirect blocks can be discarded because they're not holes. Second, * it issues prefetches for the data we need to send. */

Source from the content-addressed store, hash-verified

1732 * it issues prefetches for the data we need to send.
1733 */
1734static void
1735send_reader_thread(void *arg)
1736{
1737 struct send_reader_thread_arg *srta = arg;
1738 struct send_merge_thread_arg *smta = srta->smta;
1739 bqueue_t *inq = &smta->q;
1740 bqueue_t *outq = &srta->q;
1741 objset_t *os = smta->os;
1742 fstrans_cookie_t cookie = spl_fstrans_mark();
1743 struct send_range *range = bqueue_dequeue(inq);
1744 int err = 0;
1745
1746 /*
1747 * If the record we're analyzing is from a redaction bookmark from the
1748 * fromds, then we need to know whether or not it exists in the tods so
1749 * we know whether to create records for it or not. If it does, we need
1750 * the datablksz so we can generate an appropriate record for it.
1751 * Finally, if it isn't redacted, we need the blkptr so that we can send
1752 * a WRITE record containing the actual data.
1753 */
1754 uint64_t last_obj = UINT64_MAX;
1755 uint64_t last_obj_exists = B_TRUE;
1756 while (!range->eos_marker && !srta->cancel && smta->error == 0 &&
1757 err == 0) {
1758 switch (range->type) {
1759 case DATA:
1760 issue_data_read(srta, range);
1761 bqueue_enqueue(outq, range, range->sru.data.datablksz);
1762 range = get_next_range_nofree(inq, range);
1763 break;
1764 case HOLE:
1765 case OBJECT:
1766 case OBJECT_RANGE:
1767 case REDACT: // Redacted blocks must exist
1768 bqueue_enqueue(outq, range, sizeof (*range));
1769 range = get_next_range_nofree(inq, range);
1770 break;
1771 case PREVIOUSLY_REDACTED: {
1772 /*
1773 * This entry came from the "from bookmark" when
1774 * sending from a bookmark that has a redaction
1775 * list. We need to check if this object/blkid
1776 * exists in the target ("to") dataset, and if
1777 * not then we drop this entry. We also need
1778 * to fill in the block pointer so that we know
1779 * what to prefetch.
1780 *
1781 * To accomplish the above, we first cache whether or
1782 * not the last object we examined exists. If it
1783 * doesn't, we can drop this record. If it does, we hold
1784 * the dnode and use it to call dbuf_dnode_findbp. We do
1785 * this instead of dbuf_bookmark_findbp because we will
1786 * often operate on large ranges, and holding the dnode
1787 * once is more efficient.
1788 */
1789 boolean_t object_exists = B_TRUE;
1790 /*
1791 * If the data is redacted, we only care if it exists,

Callers

nothing calls this directly

Calls 15

bqueue_dequeueFunction · 0.85
issue_data_readFunction · 0.85
bqueue_enqueueFunction · 0.85
get_next_range_nofreeFunction · 0.85
dnode_holdFunction · 0.85
get_next_rangeFunction · 0.85
rw_enterFunction · 0.85
dnode_next_offsetFunction · 0.85
enqueue_rangeFunction · 0.85
dbuf_dnode_findbpFunction · 0.85
rw_exitFunction · 0.85
dnode_releFunction · 0.85

Tested by

no test coverage detected