@@ -498,7 +498,7 @@ int btrfs_dirty_pages(struct btrfs_root *root, struct inode *inode,
498
498
loff_t isize = i_size_read (inode );
499
499
500
500
start_pos = pos & ~((u64 )root -> sectorsize - 1 );
501
- num_bytes = ALIGN (write_bytes + pos - start_pos , root -> sectorsize );
501
+ num_bytes = round_up (write_bytes + pos - start_pos , root -> sectorsize );
502
502
503
503
end_of_last_block = start_pos + num_bytes - 1 ;
504
504
err = btrfs_set_extent_delalloc (inode , start_pos , end_of_last_block ,
@@ -1379,16 +1379,19 @@ static noinline int prepare_pages(struct inode *inode, struct page **pages,
1379
1379
static noinline int
1380
1380
lock_and_cleanup_extent_if_need (struct inode * inode , struct page * * pages ,
1381
1381
size_t num_pages , loff_t pos ,
1382
+ size_t write_bytes ,
1382
1383
u64 * lockstart , u64 * lockend ,
1383
1384
struct extent_state * * cached_state )
1384
1385
{
1386
+ struct btrfs_root * root = BTRFS_I (inode )-> root ;
1385
1387
u64 start_pos ;
1386
1388
u64 last_pos ;
1387
1389
int i ;
1388
1390
int ret = 0 ;
1389
1391
1390
- start_pos = pos & ~((u64 )PAGE_CACHE_SIZE - 1 );
1391
- last_pos = start_pos + ((u64 )num_pages << PAGE_CACHE_SHIFT ) - 1 ;
1392
+ start_pos = round_down (pos , root -> sectorsize );
1393
+ last_pos = start_pos
1394
+ + round_up (pos + write_bytes - start_pos , root -> sectorsize ) - 1 ;
1392
1395
1393
1396
if (start_pos < inode -> i_size ) {
1394
1397
struct btrfs_ordered_extent * ordered ;
@@ -1503,6 +1506,7 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file,
1503
1506
1504
1507
while (iov_iter_count (i ) > 0 ) {
1505
1508
size_t offset = pos & (PAGE_CACHE_SIZE - 1 );
1509
+ size_t sector_offset ;
1506
1510
size_t write_bytes = min (iov_iter_count (i ),
1507
1511
nrptrs * (size_t )PAGE_CACHE_SIZE -
1508
1512
offset );
@@ -1511,6 +1515,8 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file,
1511
1515
size_t reserve_bytes ;
1512
1516
size_t dirty_pages ;
1513
1517
size_t copied ;
1518
+ size_t dirty_sectors ;
1519
+ size_t num_sectors ;
1514
1520
1515
1521
WARN_ON (num_pages > nrptrs );
1516
1522
@@ -1523,7 +1529,9 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file,
1523
1529
break ;
1524
1530
}
1525
1531
1526
- reserve_bytes = num_pages << PAGE_CACHE_SHIFT ;
1532
+ sector_offset = pos & (root -> sectorsize - 1 );
1533
+ reserve_bytes = round_up (write_bytes + sector_offset ,
1534
+ root -> sectorsize );
1527
1535
1528
1536
if (BTRFS_I (inode )-> flags & (BTRFS_INODE_NODATACOW |
1529
1537
BTRFS_INODE_PREALLOC )) {
@@ -1542,7 +1550,9 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file,
1542
1550
*/
1543
1551
num_pages = DIV_ROUND_UP (write_bytes + offset ,
1544
1552
PAGE_CACHE_SIZE );
1545
- reserve_bytes = num_pages << PAGE_CACHE_SHIFT ;
1553
+ reserve_bytes = round_up (write_bytes
1554
+ + sector_offset ,
1555
+ root -> sectorsize );
1546
1556
goto reserve_metadata ;
1547
1557
}
1548
1558
}
@@ -1576,8 +1586,8 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file,
1576
1586
break ;
1577
1587
1578
1588
ret = lock_and_cleanup_extent_if_need (inode , pages , num_pages ,
1579
- pos , & lockstart , & lockend ,
1580
- & cached_state );
1589
+ pos , write_bytes , & lockstart ,
1590
+ & lockend , & cached_state );
1581
1591
if (ret < 0 ) {
1582
1592
if (ret == - EAGAIN )
1583
1593
goto again ;
@@ -1612,9 +1622,16 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file,
1612
1622
* we still have an outstanding extent for the chunk we actually
1613
1623
* managed to copy.
1614
1624
*/
1615
- if (num_pages > dirty_pages ) {
1616
- release_bytes = (num_pages - dirty_pages ) <<
1617
- PAGE_CACHE_SHIFT ;
1625
+ num_sectors = BTRFS_BYTES_TO_BLKS (root -> fs_info ,
1626
+ reserve_bytes );
1627
+ dirty_sectors = round_up (copied + sector_offset ,
1628
+ root -> sectorsize );
1629
+ dirty_sectors = BTRFS_BYTES_TO_BLKS (root -> fs_info ,
1630
+ dirty_sectors );
1631
+
1632
+ if (num_sectors > dirty_sectors ) {
1633
+ release_bytes = (write_bytes - copied )
1634
+ & ~((u64 )root -> sectorsize - 1 );
1618
1635
if (copied > 0 ) {
1619
1636
spin_lock (& BTRFS_I (inode )-> lock );
1620
1637
BTRFS_I (inode )-> outstanding_extents ++ ;
@@ -1633,7 +1650,8 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file,
1633
1650
}
1634
1651
}
1635
1652
1636
- release_bytes = dirty_pages << PAGE_CACHE_SHIFT ;
1653
+ release_bytes = round_up (copied + sector_offset ,
1654
+ root -> sectorsize );
1637
1655
1638
1656
if (copied > 0 )
1639
1657
ret = btrfs_dirty_pages (root , inode , pages ,
@@ -1654,8 +1672,7 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file,
1654
1672
1655
1673
if (only_release_metadata && copied > 0 ) {
1656
1674
lockstart = round_down (pos , root -> sectorsize );
1657
- lockend = lockstart +
1658
- (dirty_pages << PAGE_CACHE_SHIFT ) - 1 ;
1675
+ lockend = round_up (pos + copied , root -> sectorsize ) - 1 ;
1659
1676
1660
1677
set_extent_bit (& BTRFS_I (inode )-> io_tree , lockstart ,
1661
1678
lockend , EXTENT_NORESERVE , NULL ,
0 commit comments