diff options
Diffstat (limited to 'fs/ext4')
| -rw-r--r-- | fs/ext4/Kconfig | 1 | ||||
| -rw-r--r-- | fs/ext4/ext4.h | 6 | ||||
| -rw-r--r-- | fs/ext4/inode.c | 36 | ||||
| -rw-r--r-- | fs/ext4/mballoc.c | 6 | ||||
| -rw-r--r-- | fs/ext4/super.c | 5 |
5 files changed, 29 insertions, 25 deletions
diff --git a/fs/ext4/Kconfig b/fs/ext4/Kconfig index e5f6774846e4..9acf7e808139 100644 --- a/fs/ext4/Kconfig +++ b/fs/ext4/Kconfig | |||
| @@ -2,7 +2,6 @@ config EXT4_FS | |||
| 2 | tristate "The Extended 4 (ext4) filesystem" | 2 | tristate "The Extended 4 (ext4) filesystem" |
| 3 | select JBD2 | 3 | select JBD2 |
| 4 | select CRC16 | 4 | select CRC16 |
| 5 | select FS_JOURNAL_INFO | ||
| 6 | help | 5 | help |
| 7 | This is the next generation of the ext3 filesystem. | 6 | This is the next generation of the ext3 filesystem. |
| 8 | 7 | ||
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); | |||
| 1435 | extern int ext4_block_truncate_page(handle_t *handle, | 1439 | extern int ext4_block_truncate_page(handle_t *handle, |
| 1436 | struct address_space *mapping, loff_t from); | 1440 | struct address_space *mapping, loff_t from); |
| 1437 | extern int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf); | 1441 | extern int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf); |
| 1438 | extern qsize_t ext4_get_reserved_space(struct inode *inode); | 1442 | extern qsize_t *ext4_get_reserved_space(struct inode *inode); |
| 1439 | extern int flush_aio_dio_completed_IO(struct inode *inode); | 1443 | extern int flush_aio_dio_completed_IO(struct inode *inode); |
| 1440 | /* ioctl.c */ | 1444 | /* ioctl.c */ |
| 1441 | extern long ext4_ioctl(struct file *, unsigned int, unsigned long); | 1445 | extern 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 | ||
| 1006 | qsize_t ext4_get_reserved_space(struct inode *inode) | 1006 | #ifdef CONFIG_QUOTA |
| 1007 | qsize_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) | |||
| 1051 | static void ext4_da_update_reserve_space(struct inode *inode, int used) | 1046 | static 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, |
