* Note: if this fails, the caller will clean up any records left on the * rwa->write_batch list. */
| 1860 | * rwa->write_batch list. |
| 1861 | */ |
| 1862 | static int |
| 1863 | flush_write_batch_impl(struct receive_writer_arg *rwa) |
| 1864 | { |
| 1865 | dnode_t *dn; |
| 1866 | int err; |
| 1867 | |
| 1868 | if (dnode_hold(rwa->os, rwa->last_object, FTAG, &dn) != 0) |
| 1869 | return (SET_ERROR(EINVAL)); |
| 1870 | |
| 1871 | struct receive_record_arg *last_rrd = list_tail(&rwa->write_batch); |
| 1872 | struct drr_write *last_drrw = &last_rrd->header.drr_u.drr_write; |
| 1873 | |
| 1874 | struct receive_record_arg *first_rrd = list_head(&rwa->write_batch); |
| 1875 | struct drr_write *first_drrw = &first_rrd->header.drr_u.drr_write; |
| 1876 | |
| 1877 | ASSERT3U(rwa->last_object, ==, last_drrw->drr_object); |
| 1878 | ASSERT3U(rwa->last_offset, ==, last_drrw->drr_offset); |
| 1879 | |
| 1880 | dmu_tx_t *tx = dmu_tx_create(rwa->os); |
| 1881 | dmu_tx_hold_write_by_dnode(tx, dn, first_drrw->drr_offset, |
| 1882 | last_drrw->drr_offset - first_drrw->drr_offset + |
| 1883 | last_drrw->drr_logical_size); |
| 1884 | err = dmu_tx_assign(tx, TXG_WAIT); |
| 1885 | if (err != 0) { |
| 1886 | dmu_tx_abort(tx); |
| 1887 | dnode_rele(dn, FTAG); |
| 1888 | return (err); |
| 1889 | } |
| 1890 | |
| 1891 | struct receive_record_arg *rrd; |
| 1892 | while ((rrd = list_head(&rwa->write_batch)) != NULL) { |
| 1893 | struct drr_write *drrw = &rrd->header.drr_u.drr_write; |
| 1894 | abd_t *abd = rrd->abd; |
| 1895 | |
| 1896 | ASSERT3U(drrw->drr_object, ==, rwa->last_object); |
| 1897 | |
| 1898 | if (drrw->drr_logical_size != dn->dn_datablksz) { |
| 1899 | /* |
| 1900 | * The WRITE record is larger than the object's block |
| 1901 | * size. We must be receiving an incremental |
| 1902 | * large-block stream into a dataset that previously did |
| 1903 | * a non-large-block receive. Lightweight writes must |
| 1904 | * be exactly one block, so we need to decompress the |
| 1905 | * data (if compressed) and do a normal dmu_write(). |
| 1906 | */ |
| 1907 | ASSERT3U(drrw->drr_logical_size, >, dn->dn_datablksz); |
| 1908 | if (DRR_WRITE_COMPRESSED(drrw)) { |
| 1909 | abd_t *decomp_abd = |
| 1910 | abd_alloc_linear(drrw->drr_logical_size, |
| 1911 | B_FALSE); |
| 1912 | |
| 1913 | err = zio_decompress_data( |
| 1914 | drrw->drr_compressiontype, |
| 1915 | abd, abd_to_buf(decomp_abd), |
| 1916 | abd_get_size(abd), |
| 1917 | abd_get_size(decomp_abd), NULL); |
| 1918 | |
| 1919 | if (err == 0) { |
no test coverage detected