aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext4/inode.c')
-rw-r--r--fs/ext4/inode.c45
1 files changed, 39 insertions, 6 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index c7fed5b18745..dd82ff390067 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -975,6 +975,17 @@ out:
975 return err; 975 return err;
976} 976}
977 977
978qsize_t ext4_get_reserved_space(struct inode *inode)
979{
980 unsigned long long total;
981
982 spin_lock(&EXT4_I(inode)->i_block_reservation_lock);
983 total = EXT4_I(inode)->i_reserved_data_blocks +
984 EXT4_I(inode)->i_reserved_meta_blocks;
985 spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
986
987 return total;
988}
978/* 989/*
979 * Calculate the number of metadata blocks need to reserve 990 * Calculate the number of metadata blocks need to reserve
980 * to allocate @blocks for non extent file based file 991 * to allocate @blocks for non extent file based file
@@ -1036,8 +1047,14 @@ static void ext4_da_update_reserve_space(struct inode *inode, int used)
1036 /* update per-inode reservations */ 1047 /* update per-inode reservations */
1037 BUG_ON(used > EXT4_I(inode)->i_reserved_data_blocks); 1048 BUG_ON(used > EXT4_I(inode)->i_reserved_data_blocks);
1038 EXT4_I(inode)->i_reserved_data_blocks -= used; 1049 EXT4_I(inode)->i_reserved_data_blocks -= used;
1039
1040 spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); 1050 spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
1051
1052 /*
1053 * free those over-booking quota for metadata blocks
1054 */
1055
1056 if (mdb_free)
1057 vfs_dq_release_reservation_block(inode, mdb_free);
1041} 1058}
1042 1059
1043/* 1060/*
@@ -1553,8 +1570,8 @@ static int ext4_journalled_write_end(struct file *file,
1553static int ext4_da_reserve_space(struct inode *inode, int nrblocks) 1570static int ext4_da_reserve_space(struct inode *inode, int nrblocks)
1554{ 1571{
1555 int retries = 0; 1572 int retries = 0;
1556 struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); 1573 struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
1557 unsigned long md_needed, mdblocks, total = 0; 1574 unsigned long md_needed, mdblocks, total = 0;
1558 1575
1559 /* 1576 /*
1560 * recalculate the amount of metadata blocks to reserve 1577 * recalculate the amount of metadata blocks to reserve
@@ -1570,12 +1587,23 @@ repeat:
1570 md_needed = mdblocks - EXT4_I(inode)->i_reserved_meta_blocks; 1587 md_needed = mdblocks - EXT4_I(inode)->i_reserved_meta_blocks;
1571 total = md_needed + nrblocks; 1588 total = md_needed + nrblocks;
1572 1589
1590 /*
1591 * Make quota reservation here to prevent quota overflow
1592 * later. Real quota accounting is done at pages writeout
1593 * time.
1594 */
1595 if (vfs_dq_reserve_block(inode, total)) {
1596 spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
1597 return -EDQUOT;
1598 }
1599
1573 if (ext4_claim_free_blocks(sbi, total)) { 1600 if (ext4_claim_free_blocks(sbi, total)) {
1574 spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); 1601 spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
1575 if (ext4_should_retry_alloc(inode->i_sb, &retries)) { 1602 if (ext4_should_retry_alloc(inode->i_sb, &retries)) {
1576 yield(); 1603 yield();
1577 goto repeat; 1604 goto repeat;
1578 } 1605 }
1606 vfs_dq_release_reservation_block(inode, total);
1579 return -ENOSPC; 1607 return -ENOSPC;
1580 } 1608 }
1581 EXT4_I(inode)->i_reserved_data_blocks += nrblocks; 1609 EXT4_I(inode)->i_reserved_data_blocks += nrblocks;
@@ -1629,6 +1657,8 @@ static void ext4_da_release_space(struct inode *inode, int to_free)
1629 BUG_ON(mdb > EXT4_I(inode)->i_reserved_meta_blocks); 1657 BUG_ON(mdb > EXT4_I(inode)->i_reserved_meta_blocks);
1630 EXT4_I(inode)->i_reserved_meta_blocks = mdb; 1658 EXT4_I(inode)->i_reserved_meta_blocks = mdb;
1631 spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); 1659 spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
1660
1661 vfs_dq_release_reservation_block(inode, release);
1632} 1662}
1633 1663
1634static void ext4_da_page_release_reservation(struct page *page, 1664static void ext4_da_page_release_reservation(struct page *page,
@@ -4612,7 +4642,7 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
4612 error = PTR_ERR(handle); 4642 error = PTR_ERR(handle);
4613 goto err_out; 4643 goto err_out;
4614 } 4644 }
4615 error = DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0; 4645 error = vfs_dq_transfer(inode, attr) ? -EDQUOT : 0;
4616 if (error) { 4646 if (error) {
4617 ext4_journal_stop(handle); 4647 ext4_journal_stop(handle);
4618 return error; 4648 return error;
@@ -4991,7 +5021,7 @@ int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode)
4991 * i_size has been changed by generic_commit_write() and we thus need 5021 * i_size has been changed by generic_commit_write() and we thus need
4992 * to include the updated inode in the current transaction. 5022 * to include the updated inode in the current transaction.
4993 * 5023 *
4994 * Also, DQUOT_ALLOC_SPACE() will always dirty the inode when blocks 5024 * Also, vfs_dq_alloc_block() will always dirty the inode when blocks
4995 * are allocated to the file. 5025 * are allocated to the file.
4996 * 5026 *
4997 * If the inode is marked synchronous, we don't honour that here - doing 5027 * If the inode is marked synchronous, we don't honour that here - doing
@@ -5116,8 +5146,9 @@ static int ext4_bh_unmapped(handle_t *handle, struct buffer_head *bh)
5116 return !buffer_mapped(bh); 5146 return !buffer_mapped(bh);
5117} 5147}
5118 5148
5119int ext4_page_mkwrite(struct vm_area_struct *vma, struct page *page) 5149int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
5120{ 5150{
5151 struct page *page = vmf->page;
5121 loff_t size; 5152 loff_t size;
5122 unsigned long len; 5153 unsigned long len;
5123 int ret = -EINVAL; 5154 int ret = -EINVAL;
@@ -5169,6 +5200,8 @@ int ext4_page_mkwrite(struct vm_area_struct *vma, struct page *page)
5169 goto out_unlock; 5200 goto out_unlock;
5170 ret = 0; 5201 ret = 0;
5171out_unlock: 5202out_unlock:
5203 if (ret)
5204 ret = VM_FAULT_SIGBUS;
5172 up_read(&inode->i_alloc_sem); 5205 up_read(&inode->i_alloc_sem);
5173 return ret; 5206 return ret;
5174} 5207}