diff options
| -rw-r--r-- | fs/ext4/ext4.h | 1 | ||||
| -rw-r--r-- | fs/ext4/inode.c | 108 |
2 files changed, 67 insertions, 42 deletions
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 303e41cf7b14..6c7924d9e358 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h | |||
| @@ -1044,7 +1044,6 @@ extern void ext4_mb_update_group_info(struct ext4_group_info *grp, | |||
| 1044 | 1044 | ||
| 1045 | 1045 | ||
| 1046 | /* inode.c */ | 1046 | /* inode.c */ |
| 1047 | void ext4_da_release_space(struct inode *inode, int used, int to_free); | ||
| 1048 | int ext4_forget(handle_t *handle, int is_metadata, struct inode *inode, | 1047 | int ext4_forget(handle_t *handle, int is_metadata, struct inode *inode, |
| 1049 | struct buffer_head *bh, ext4_fsblk_t blocknr); | 1048 | struct buffer_head *bh, ext4_fsblk_t blocknr); |
| 1050 | struct buffer_head *ext4_getblk(handle_t *, struct inode *, | 1049 | struct buffer_head *ext4_getblk(handle_t *, struct inode *, |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 2697eaf0368f..85a862c9c4cc 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
| @@ -980,6 +980,67 @@ out: | |||
| 980 | return err; | 980 | return err; |
| 981 | } | 981 | } |
| 982 | 982 | ||
| 983 | /* | ||
| 984 | * Calculate the number of metadata blocks need to reserve | ||
| 985 | * to allocate @blocks for non extent file based file | ||
| 986 | */ | ||
| 987 | static int ext4_indirect_calc_metadata_amount(struct inode *inode, int blocks) | ||
| 988 | { | ||
| 989 | int icap = EXT4_ADDR_PER_BLOCK(inode->i_sb); | ||
| 990 | int ind_blks, dind_blks, tind_blks; | ||
| 991 | |||
| 992 | /* number of new indirect blocks needed */ | ||
| 993 | ind_blks = (blocks + icap - 1) / icap; | ||
| 994 | |||
| 995 | dind_blks = (ind_blks + icap - 1) / icap; | ||
| 996 | |||
| 997 | tind_blks = 1; | ||
| 998 | |||
| 999 | return ind_blks + dind_blks + tind_blks; | ||
| 1000 | } | ||
| 1001 | |||
| 1002 | /* | ||
| 1003 | * Calculate the number of metadata blocks need to reserve | ||
| 1004 | * to allocate given number of blocks | ||
| 1005 | */ | ||
| 1006 | static int ext4_calc_metadata_amount(struct inode *inode, int blocks) | ||
| 1007 | { | ||
| 1008 | if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) | ||
| 1009 | return ext4_ext_calc_metadata_amount(inode, blocks); | ||
| 1010 | |||
| 1011 | return ext4_indirect_calc_metadata_amount(inode, blocks); | ||
| 1012 | } | ||
| 1013 | |||
| 1014 | static void ext4_da_update_reserve_space(struct inode *inode, int used) | ||
| 1015 | { | ||
| 1016 | struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); | ||
| 1017 | int total, mdb, mdb_free; | ||
| 1018 | |||
| 1019 | spin_lock(&EXT4_I(inode)->i_block_reservation_lock); | ||
| 1020 | /* recalculate the number of metablocks still need to be reserved */ | ||
| 1021 | total = EXT4_I(inode)->i_reserved_data_blocks - used; | ||
| 1022 | mdb = ext4_calc_metadata_amount(inode, total); | ||
| 1023 | |||
| 1024 | /* figure out how many metablocks to release */ | ||
| 1025 | BUG_ON(mdb > EXT4_I(inode)->i_reserved_meta_blocks); | ||
| 1026 | mdb_free = EXT4_I(inode)->i_reserved_meta_blocks - mdb; | ||
| 1027 | |||
| 1028 | /* Account for allocated meta_blocks */ | ||
| 1029 | mdb_free -= EXT4_I(inode)->i_allocated_meta_blocks; | ||
| 1030 | |||
| 1031 | /* update fs free blocks counter for truncate case */ | ||
| 1032 | percpu_counter_add(&sbi->s_freeblocks_counter, mdb_free); | ||
| 1033 | |||
| 1034 | /* update per-inode reservations */ | ||
| 1035 | BUG_ON(used > EXT4_I(inode)->i_reserved_data_blocks); | ||
| 1036 | EXT4_I(inode)->i_reserved_data_blocks -= used; | ||
| 1037 | |||
| 1038 | BUG_ON(mdb > EXT4_I(inode)->i_reserved_meta_blocks); | ||
| 1039 | EXT4_I(inode)->i_reserved_meta_blocks = mdb; | ||
| 1040 | EXT4_I(inode)->i_allocated_meta_blocks = 0; | ||
| 1041 | spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); | ||
| 1042 | } | ||
| 1043 | |||
| 983 | /* Maximum number of blocks we map for direct IO at once. */ | 1044 | /* Maximum number of blocks we map for direct IO at once. */ |
| 984 | #define DIO_MAX_BLOCKS 4096 | 1045 | #define DIO_MAX_BLOCKS 4096 |
| 985 | /* | 1046 | /* |
| @@ -1097,7 +1158,7 @@ int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block, | |||
| 1097 | * which were deferred till now | 1158 | * which were deferred till now |
| 1098 | */ | 1159 | */ |
| 1099 | if ((retval > 0) && buffer_delay(bh)) | 1160 | if ((retval > 0) && buffer_delay(bh)) |
| 1100 | ext4_da_release_space(inode, retval, 0); | 1161 | ext4_da_update_reserve_space(inode, retval); |
| 1101 | } | 1162 | } |
| 1102 | 1163 | ||
| 1103 | up_write((&EXT4_I(inode)->i_data_sem)); | 1164 | up_write((&EXT4_I(inode)->i_data_sem)); |
| @@ -1465,36 +1526,6 @@ static int ext4_journalled_write_end(struct file *file, | |||
| 1465 | 1526 | ||
| 1466 | return ret ? ret : copied; | 1527 | return ret ? ret : copied; |
| 1467 | } | 1528 | } |
| 1468 | /* | ||
| 1469 | * Calculate the number of metadata blocks need to reserve | ||
| 1470 | * to allocate @blocks for non extent file based file | ||
| 1471 | */ | ||
| 1472 | static int ext4_indirect_calc_metadata_amount(struct inode *inode, int blocks) | ||
| 1473 | { | ||
| 1474 | int icap = EXT4_ADDR_PER_BLOCK(inode->i_sb); | ||
| 1475 | int ind_blks, dind_blks, tind_blks; | ||
| 1476 | |||
| 1477 | /* number of new indirect blocks needed */ | ||
| 1478 | ind_blks = (blocks + icap - 1) / icap; | ||
| 1479 | |||
| 1480 | dind_blks = (ind_blks + icap - 1) / icap; | ||
| 1481 | |||
| 1482 | tind_blks = 1; | ||
| 1483 | |||
| 1484 | return ind_blks + dind_blks + tind_blks; | ||
| 1485 | } | ||
| 1486 | |||
| 1487 | /* | ||
| 1488 | * Calculate the number of metadata blocks need to reserve | ||
| 1489 | * to allocate given number of blocks | ||
| 1490 | */ | ||
| 1491 | static int ext4_calc_metadata_amount(struct inode *inode, int blocks) | ||
| 1492 | { | ||
| 1493 | if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) | ||
| 1494 | return ext4_ext_calc_metadata_amount(inode, blocks); | ||
| 1495 | |||
| 1496 | return ext4_indirect_calc_metadata_amount(inode, blocks); | ||
| 1497 | } | ||
| 1498 | 1529 | ||
| 1499 | static int ext4_da_reserve_space(struct inode *inode, int nrblocks) | 1530 | static int ext4_da_reserve_space(struct inode *inode, int nrblocks) |
| 1500 | { | 1531 | { |
| @@ -1518,7 +1549,6 @@ static int ext4_da_reserve_space(struct inode *inode, int nrblocks) | |||
| 1518 | spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); | 1549 | spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); |
| 1519 | return -ENOSPC; | 1550 | return -ENOSPC; |
| 1520 | } | 1551 | } |
| 1521 | |||
| 1522 | /* reduce fs free blocks counter */ | 1552 | /* reduce fs free blocks counter */ |
| 1523 | percpu_counter_sub(&sbi->s_freeblocks_counter, total); | 1553 | percpu_counter_sub(&sbi->s_freeblocks_counter, total); |
| 1524 | 1554 | ||
| @@ -1529,35 +1559,31 @@ static int ext4_da_reserve_space(struct inode *inode, int nrblocks) | |||
| 1529 | return 0; /* success */ | 1559 | return 0; /* success */ |
| 1530 | } | 1560 | } |
| 1531 | 1561 | ||
| 1532 | void ext4_da_release_space(struct inode *inode, int used, int to_free) | 1562 | static void ext4_da_release_space(struct inode *inode, int to_free) |
| 1533 | { | 1563 | { |
| 1534 | struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); | 1564 | struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); |
| 1535 | int total, mdb, mdb_free, release; | 1565 | int total, mdb, mdb_free, release; |
| 1536 | 1566 | ||
| 1537 | spin_lock(&EXT4_I(inode)->i_block_reservation_lock); | 1567 | spin_lock(&EXT4_I(inode)->i_block_reservation_lock); |
| 1538 | /* recalculate the number of metablocks still need to be reserved */ | 1568 | /* recalculate the number of metablocks still need to be reserved */ |
| 1539 | total = EXT4_I(inode)->i_reserved_data_blocks - used - to_free; | 1569 | total = EXT4_I(inode)->i_reserved_data_blocks - to_free; |
| 1540 | mdb = ext4_calc_metadata_amount(inode, total); | 1570 | mdb = ext4_calc_metadata_amount(inode, total); |
| 1541 | 1571 | ||
| 1542 | /* figure out how many metablocks to release */ | 1572 | /* figure out how many metablocks to release */ |
| 1543 | BUG_ON(mdb > EXT4_I(inode)->i_reserved_meta_blocks); | 1573 | BUG_ON(mdb > EXT4_I(inode)->i_reserved_meta_blocks); |
| 1544 | mdb_free = EXT4_I(inode)->i_reserved_meta_blocks - mdb; | 1574 | mdb_free = EXT4_I(inode)->i_reserved_meta_blocks - mdb; |
| 1545 | 1575 | ||
| 1546 | /* Account for allocated meta_blocks */ | ||
| 1547 | mdb_free -= EXT4_I(inode)->i_allocated_meta_blocks; | ||
| 1548 | |||
| 1549 | release = to_free + mdb_free; | 1576 | release = to_free + mdb_free; |
| 1550 | 1577 | ||
| 1551 | /* update fs free blocks counter for truncate case */ | 1578 | /* update fs free blocks counter for truncate case */ |
| 1552 | percpu_counter_add(&sbi->s_freeblocks_counter, release); | 1579 | percpu_counter_add(&sbi->s_freeblocks_counter, release); |
| 1553 | 1580 | ||
| 1554 | /* update per-inode reservations */ | 1581 | /* update per-inode reservations */ |
| 1555 | BUG_ON(used + to_free > EXT4_I(inode)->i_reserved_data_blocks); | 1582 | BUG_ON(to_free > EXT4_I(inode)->i_reserved_data_blocks); |
| 1556 | EXT4_I(inode)->i_reserved_data_blocks -= (used + to_free); | 1583 | EXT4_I(inode)->i_reserved_data_blocks -= to_free; |
| 1557 | 1584 | ||
| 1558 | BUG_ON(mdb > EXT4_I(inode)->i_reserved_meta_blocks); | 1585 | BUG_ON(mdb > EXT4_I(inode)->i_reserved_meta_blocks); |
| 1559 | EXT4_I(inode)->i_reserved_meta_blocks = mdb; | 1586 | EXT4_I(inode)->i_reserved_meta_blocks = mdb; |
| 1560 | EXT4_I(inode)->i_allocated_meta_blocks = 0; | ||
| 1561 | spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); | 1587 | spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); |
| 1562 | } | 1588 | } |
| 1563 | 1589 | ||
| @@ -1579,7 +1605,7 @@ static void ext4_da_page_release_reservation(struct page *page, | |||
| 1579 | } | 1605 | } |
| 1580 | curr_off = next_off; | 1606 | curr_off = next_off; |
| 1581 | } while ((bh = bh->b_this_page) != head); | 1607 | } while ((bh = bh->b_this_page) != head); |
| 1582 | ext4_da_release_space(page->mapping->host, 0, to_release); | 1608 | ext4_da_release_space(page->mapping->host, to_release); |
| 1583 | } | 1609 | } |
| 1584 | 1610 | ||
| 1585 | /* | 1611 | /* |
