aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext4')
-rw-r--r--fs/ext4/ext4.h6
-rw-r--r--fs/ext4/inode.c36
-rw-r--r--fs/ext4/mballoc.c6
-rw-r--r--fs/ext4/super.c5
4 files changed, 29 insertions, 24 deletions
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index ab31e65d46d0..56f9271ee8cc 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -704,6 +704,10 @@ struct ext4_inode_info {
704 __u16 i_extra_isize; 704 __u16 i_extra_isize;
705 705
706 spinlock_t i_block_reservation_lock; 706 spinlock_t i_block_reservation_lock;
707#ifdef CONFIG_QUOTA
708 /* quota space reservation, managed internally by quota code */
709 qsize_t i_reserved_quota;
710#endif
707 711
708 /* completed async DIOs that might need unwritten extents handling */ 712 /* completed async DIOs that might need unwritten extents handling */
709 struct list_head i_aio_dio_complete_list; 713 struct list_head i_aio_dio_complete_list;
@@ -1435,7 +1439,7 @@ extern int ext4_chunk_trans_blocks(struct inode *, int nrblocks);
1435extern int ext4_block_truncate_page(handle_t *handle, 1439extern int ext4_block_truncate_page(handle_t *handle,
1436 struct address_space *mapping, loff_t from); 1440 struct address_space *mapping, loff_t from);
1437extern int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf); 1441extern int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf);
1438extern qsize_t ext4_get_reserved_space(struct inode *inode); 1442extern qsize_t *ext4_get_reserved_space(struct inode *inode);
1439extern int flush_aio_dio_completed_IO(struct inode *inode); 1443extern int flush_aio_dio_completed_IO(struct inode *inode);
1440/* ioctl.c */ 1444/* ioctl.c */
1441extern long ext4_ioctl(struct file *, unsigned int, unsigned long); 1445extern long ext4_ioctl(struct file *, unsigned int, unsigned long);
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 5352db1a3086..ab807963a614 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -1003,17 +1003,12 @@ out:
1003 return err; 1003 return err;
1004} 1004}
1005 1005
1006qsize_t ext4_get_reserved_space(struct inode *inode) 1006#ifdef CONFIG_QUOTA
1007qsize_t *ext4_get_reserved_space(struct inode *inode)
1007{ 1008{
1008 unsigned long long total; 1009 return &EXT4_I(inode)->i_reserved_quota;
1009
1010 spin_lock(&EXT4_I(inode)->i_block_reservation_lock);
1011 total = EXT4_I(inode)->i_reserved_data_blocks +
1012 EXT4_I(inode)->i_reserved_meta_blocks;
1013 spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
1014
1015 return (total << inode->i_blkbits);
1016} 1010}
1011#endif
1017/* 1012/*
1018 * Calculate the number of metadata blocks need to reserve 1013 * Calculate the number of metadata blocks need to reserve
1019 * to allocate @blocks for non extent file based file 1014 * to allocate @blocks for non extent file based file
@@ -1051,7 +1046,7 @@ static int ext4_calc_metadata_amount(struct inode *inode, int blocks)
1051static void ext4_da_update_reserve_space(struct inode *inode, int used) 1046static void ext4_da_update_reserve_space(struct inode *inode, int used)
1052{ 1047{
1053 struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); 1048 struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
1054 int total, mdb, mdb_free; 1049 int total, mdb, mdb_free, mdb_claim = 0;
1055 1050
1056 spin_lock(&EXT4_I(inode)->i_block_reservation_lock); 1051 spin_lock(&EXT4_I(inode)->i_block_reservation_lock);
1057 /* recalculate the number of metablocks still need to be reserved */ 1052 /* recalculate the number of metablocks still need to be reserved */
@@ -1064,7 +1059,9 @@ static void ext4_da_update_reserve_space(struct inode *inode, int used)
1064 1059
1065 if (mdb_free) { 1060 if (mdb_free) {
1066 /* Account for allocated meta_blocks */ 1061 /* Account for allocated meta_blocks */
1067 mdb_free -= EXT4_I(inode)->i_allocated_meta_blocks; 1062 mdb_claim = EXT4_I(inode)->i_allocated_meta_blocks;
1063 BUG_ON(mdb_free < mdb_claim);
1064 mdb_free -= mdb_claim;
1068 1065
1069 /* update fs dirty blocks counter */ 1066 /* update fs dirty blocks counter */
1070 percpu_counter_sub(&sbi->s_dirtyblocks_counter, mdb_free); 1067 percpu_counter_sub(&sbi->s_dirtyblocks_counter, mdb_free);
@@ -1075,8 +1072,11 @@ static void ext4_da_update_reserve_space(struct inode *inode, int used)
1075 /* update per-inode reservations */ 1072 /* update per-inode reservations */
1076 BUG_ON(used > EXT4_I(inode)->i_reserved_data_blocks); 1073 BUG_ON(used > EXT4_I(inode)->i_reserved_data_blocks);
1077 EXT4_I(inode)->i_reserved_data_blocks -= used; 1074 EXT4_I(inode)->i_reserved_data_blocks -= used;
1075 percpu_counter_sub(&sbi->s_dirtyblocks_counter, used + mdb_claim);
1078 spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); 1076 spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
1079 1077
1078 vfs_dq_claim_block(inode, used + mdb_claim);
1079
1080 /* 1080 /*
1081 * free those over-booking quota for metadata blocks 1081 * free those over-booking quota for metadata blocks
1082 */ 1082 */
@@ -1816,19 +1816,17 @@ repeat:
1816 1816
1817 md_needed = mdblocks - EXT4_I(inode)->i_reserved_meta_blocks; 1817 md_needed = mdblocks - EXT4_I(inode)->i_reserved_meta_blocks;
1818 total = md_needed + nrblocks; 1818 total = md_needed + nrblocks;
1819 spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
1819 1820
1820 /* 1821 /*
1821 * Make quota reservation here to prevent quota overflow 1822 * Make quota reservation here to prevent quota overflow
1822 * later. Real quota accounting is done at pages writeout 1823 * later. Real quota accounting is done at pages writeout
1823 * time. 1824 * time.
1824 */ 1825 */
1825 if (vfs_dq_reserve_block(inode, total)) { 1826 if (vfs_dq_reserve_block(inode, total))
1826 spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
1827 return -EDQUOT; 1827 return -EDQUOT;
1828 }
1829 1828
1830 if (ext4_claim_free_blocks(sbi, total)) { 1829 if (ext4_claim_free_blocks(sbi, total)) {
1831 spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
1832 vfs_dq_release_reservation_block(inode, total); 1830 vfs_dq_release_reservation_block(inode, total);
1833 if (ext4_should_retry_alloc(inode->i_sb, &retries)) { 1831 if (ext4_should_retry_alloc(inode->i_sb, &retries)) {
1834 yield(); 1832 yield();
@@ -1836,10 +1834,11 @@ repeat:
1836 } 1834 }
1837 return -ENOSPC; 1835 return -ENOSPC;
1838 } 1836 }
1837 spin_lock(&EXT4_I(inode)->i_block_reservation_lock);
1839 EXT4_I(inode)->i_reserved_data_blocks += nrblocks; 1838 EXT4_I(inode)->i_reserved_data_blocks += nrblocks;
1840 EXT4_I(inode)->i_reserved_meta_blocks = mdblocks; 1839 EXT4_I(inode)->i_reserved_meta_blocks += md_needed;
1841
1842 spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); 1840 spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
1841
1843 return 0; /* success */ 1842 return 0; /* success */
1844} 1843}
1845 1844
@@ -4794,6 +4793,9 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
4794 ((__u64)le16_to_cpu(raw_inode->i_file_acl_high)) << 32; 4793 ((__u64)le16_to_cpu(raw_inode->i_file_acl_high)) << 32;
4795 inode->i_size = ext4_isize(raw_inode); 4794 inode->i_size = ext4_isize(raw_inode);
4796 ei->i_disksize = inode->i_size; 4795 ei->i_disksize = inode->i_size;
4796#ifdef CONFIG_QUOTA
4797 ei->i_reserved_quota = 0;
4798#endif
4797 inode->i_generation = le32_to_cpu(raw_inode->i_generation); 4799 inode->i_generation = le32_to_cpu(raw_inode->i_generation);
4798 ei->i_block_group = iloc.block_group; 4800 ei->i_block_group = iloc.block_group;
4799 ei->i_last_alloc_group = ~0; 4801 ei->i_last_alloc_group = ~0;
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index b1fd3daadc9c..d34afad3e137 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -2755,12 +2755,6 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac,
2755 if (!(ac->ac_flags & EXT4_MB_DELALLOC_RESERVED)) 2755 if (!(ac->ac_flags & EXT4_MB_DELALLOC_RESERVED))
2756 /* release all the reserved blocks if non delalloc */ 2756 /* release all the reserved blocks if non delalloc */
2757 percpu_counter_sub(&sbi->s_dirtyblocks_counter, reserv_blks); 2757 percpu_counter_sub(&sbi->s_dirtyblocks_counter, reserv_blks);
2758 else {
2759 percpu_counter_sub(&sbi->s_dirtyblocks_counter,
2760 ac->ac_b_ex.fe_len);
2761 /* convert reserved quota blocks to real quota blocks */
2762 vfs_dq_claim_block(ac->ac_inode, ac->ac_b_ex.fe_len);
2763 }
2764 2758
2765 if (sbi->s_log_groups_per_flex) { 2759 if (sbi->s_log_groups_per_flex) {
2766 ext4_group_t flex_group = ext4_flex_group(sbi, 2760 ext4_group_t flex_group = ext4_flex_group(sbi,
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 827bde1f2594..6ed9aa91f27d 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -704,6 +704,9 @@ static struct inode *ext4_alloc_inode(struct super_block *sb)
704 ei->i_allocated_meta_blocks = 0; 704 ei->i_allocated_meta_blocks = 0;
705 ei->i_delalloc_reserved_flag = 0; 705 ei->i_delalloc_reserved_flag = 0;
706 spin_lock_init(&(ei->i_block_reservation_lock)); 706 spin_lock_init(&(ei->i_block_reservation_lock));
707#ifdef CONFIG_QUOTA
708 ei->i_reserved_quota = 0;
709#endif
707 INIT_LIST_HEAD(&ei->i_aio_dio_complete_list); 710 INIT_LIST_HEAD(&ei->i_aio_dio_complete_list);
708 ei->cur_aio_dio = NULL; 711 ei->cur_aio_dio = NULL;
709 ei->i_sync_tid = 0; 712 ei->i_sync_tid = 0;
@@ -1014,7 +1017,9 @@ static const struct dquot_operations ext4_quota_operations = {
1014 .reserve_space = dquot_reserve_space, 1017 .reserve_space = dquot_reserve_space,
1015 .claim_space = dquot_claim_space, 1018 .claim_space = dquot_claim_space,
1016 .release_rsv = dquot_release_reserved_space, 1019 .release_rsv = dquot_release_reserved_space,
1020#ifdef CONFIG_QUOTA
1017 .get_reserved_space = ext4_get_reserved_space, 1021 .get_reserved_space = ext4_get_reserved_space,
1022#endif
1018 .alloc_inode = dquot_alloc_inode, 1023 .alloc_inode = dquot_alloc_inode,
1019 .free_space = dquot_free_space, 1024 .free_space = dquot_free_space,
1020 .free_inode = dquot_free_inode, 1025 .free_inode = dquot_free_inode,