Skip to content

Commit 810a763

Browse files
committed
Fix partial uiomove size handling
- ensure loops process the same dbuf until all bytes are moved - update loop variables using amount actually copied - fix indentation Signed-off-by: Codex <[email protected]>
1 parent 1af41fd commit 810a763

File tree

1 file changed

+46
-39
lines changed

1 file changed

+46
-39
lines changed

module/zfs/dmu.c

Lines changed: 46 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1417,26 +1417,30 @@ dmu_read_uio_dnode(dnode_t *dn, zfs_uio_t *uio, uint64_t size)
14171417
err = dmu_buf_hold_array_by_dnode(dn, zfs_uio_offset(uio), size,
14181418
TRUE, FTAG, &numbufs, &dbp, 0);
14191419
if (err)
1420-
return (err);
1420+
return (err);
14211421

1422-
for (i = 0; i < numbufs; i++) {
1423-
uint64_t tocpy;
1424-
int64_t bufoff;
1425-
dmu_buf_t *db = dbp[i];
1422+
for (i = 0; i < numbufs && size > 0; ) {
1423+
uint64_t tocpy;
1424+
int64_t bufoff;
1425+
dmu_buf_t *db = dbp[i];
14261426

1427-
ASSERT(size > 0);
1427+
bufoff = zfs_uio_offset(uio) - db->db_offset;
1428+
tocpy = MIN(db->db_size - bufoff, size);
14281429

1429-
bufoff = zfs_uio_offset(uio) - db->db_offset;
1430-
tocpy = MIN(db->db_size - bufoff, size);
1430+
ASSERT(db->db_data != NULL);
14311431

1432-
ASSERT(db->db_data != NULL);
1433-
err = zfs_uio_fault_move((char *)db->db_data + bufoff, tocpy,
1434-
UIO_READ, uio);
1432+
uint64_t resid_before = uio->uio_resid;
1433+
err = zfs_uio_fault_move((char *)db->db_data + bufoff,
1434+
tocpy, UIO_READ, uio);
1435+
uint64_t moved = resid_before - uio->uio_resid;
14351436

1436-
if (err)
1437-
break;
1437+
size -= moved;
14381438

1439-
size -= tocpy;
1439+
if (err || moved == 0)
1440+
break;
1441+
1442+
if (bufoff + moved >= db->db_size)
1443+
i++;
14401444
}
14411445
dmu_buf_rele_array(dbp, numbufs, FTAG);
14421446

@@ -1536,41 +1540,44 @@ dmu_write_uio_dnode(dnode_t *dn, zfs_uio_t *uio, uint64_t size, dmu_tx_t *tx)
15361540
if (err)
15371541
return (err);
15381542

1539-
for (int i = 0; i < numbufs; i++) {
1540-
uint64_t tocpy;
1541-
int64_t bufoff;
1542-
dmu_buf_t *db = dbp[i];
1543+
for (int i = 0; i < numbufs && write_size > 0; ) {
1544+
uint64_t tocpy;
1545+
int64_t bufoff;
1546+
dmu_buf_t *db = dbp[i];
15431547

1544-
ASSERT(write_size > 0);
1548+
offset_t off = zfs_uio_offset(uio);
1549+
bufoff = off - db->db_offset;
1550+
tocpy = MIN(db->db_size - bufoff, write_size);
15451551

1546-
offset_t off = zfs_uio_offset(uio);
1547-
bufoff = off - db->db_offset;
1548-
tocpy = MIN(db->db_size - bufoff, write_size);
1552+
ASSERT(i == 0 || i == numbufs-1 || tocpy == db->db_size);
15491553

1550-
ASSERT(i == 0 || i == numbufs-1 || tocpy == db->db_size);
1554+
if (tocpy == db->db_size)
1555+
dmu_buf_will_fill(db, tx, B_TRUE);
1556+
else
1557+
dmu_buf_will_dirty(db, tx);
15511558

1552-
if (tocpy == db->db_size)
1553-
dmu_buf_will_fill(db, tx, B_TRUE);
1554-
else
1555-
dmu_buf_will_dirty(db, tx);
1559+
ASSERT(db->db_data != NULL);
1560+
uint64_t resid_before = uio->uio_resid;
1561+
err = zfs_uio_fault_move((char *)db->db_data + bufoff,
1562+
tocpy, UIO_WRITE, uio);
1563+
uint64_t moved = resid_before - uio->uio_resid;
15561564

1557-
ASSERT(db->db_data != NULL);
1558-
err = zfs_uio_fault_move((char *)db->db_data + bufoff,
1559-
tocpy, UIO_WRITE, uio);
1565+
if (tocpy == db->db_size && dmu_buf_fill_done(db, tx, err)) {
1566+
/* The fill was reverted. Undo any uio progress. */
1567+
zfs_uio_advance(uio, off - zfs_uio_offset(uio));
1568+
}
15601569

1561-
if (tocpy == db->db_size && dmu_buf_fill_done(db, tx, err)) {
1562-
/* The fill was reverted. Undo any uio progress. */
1563-
zfs_uio_advance(uio, off - zfs_uio_offset(uio));
1564-
}
1570+
if (err || moved == 0)
1571+
break;
15651572

1566-
if (err)
1567-
break;
1573+
write_size -= moved;
1574+
size -= moved;
15681575

1569-
write_size -= tocpy;
1570-
size -= tocpy;
1576+
if (bufoff + moved >= db->db_size)
1577+
i++;
15711578
}
15721579

1573-
IMPLY(err == 0, write_size == 0);
1580+
IMPLY(err == 0, write_size == 0);
15741581

15751582
dmu_buf_rele_array(dbp, numbufs, FTAG);
15761583

0 commit comments

Comments
 (0)