diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-06-25 17:06:55 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-06-25 17:06:55 -0400 |
commit | d857da7b70b3a38a846211b30442aad10ce577bd (patch) | |
tree | c18aca19c2e9f28ad51d19d1efd051d8318d797f /fs/ext4/inode.c | |
parent | 77d431641e2b402fe98af3540e8fb1c77bf92c25 (diff) | |
parent | a2fd66d069d86d793e9d39d4079b96f46d13f237 (diff) |
Merge tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
Pull ext4 updates from Ted Ts'o:
"A very large number of cleanups and bug fixes --- in particular for
the ext4 encryption patches, which is a new feature added in the last
merge window. Also fix a number of long-standing xfstest failures.
(Quota writes failing due to ENOSPC, a race between truncate and
writepage in data=journalled mode that was causing generic/068 to
fail, and other corner cases.)
Also add support for FALLOC_FL_INSERT_RANGE, and improve jbd2
performance eliminating locking when a buffer is modified more than
once during a transaction (which is very common for allocation
bitmaps, for example), in which case the state of the journalled
buffer head doesn't need to change"
[ I renamed "ext4_follow_link()" to "ext4_encrypted_follow_link()" in
the merge resolution, to make it clear that that function is _only_
used for encrypted symlinks. The function doesn't actually work for
non-encrypted symlinks at all, and they use the generic helpers
- Linus ]
* tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: (52 commits)
ext4: set lazytime on remount if MS_LAZYTIME is set by mount
ext4: only call ext4_truncate when size <= isize
ext4: make online defrag error reporting consistent
ext4: minor cleanup of ext4_da_reserve_space()
ext4: don't retry file block mapping on bigalloc fs with non-extent file
ext4: prevent ext4_quota_write() from failing due to ENOSPC
ext4: call sync_blockdev() before invalidate_bdev() in put_super()
jbd2: speedup jbd2_journal_dirty_metadata()
jbd2: get rid of open coded allocation retry loop
ext4: improve warning directory handling messages
jbd2: fix ocfs2 corrupt when updating journal superblock fails
ext4: mballoc: avoid 20-argument function call
ext4: wait for existing dio workers in ext4_alloc_file_blocks()
ext4: recalculate journal credits as inode depth changes
jbd2: use GFP_NOFS in jbd2_cleanup_journal_tail()
ext4: use swap() in mext_page_double_lock()
ext4: use swap() in memswap()
ext4: fix race between truncate and __ext4_journalled_writepage()
ext4 crypto: fail the mount if blocksize != pagesize
ext4: Add support FALLOC_FL_INSERT_RANGE for fallocate
...
Diffstat (limited to 'fs/ext4/inode.c')
-rw-r--r-- | fs/ext4/inode.c | 93 |
1 files changed, 47 insertions, 46 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 5168c9b56880..f8a8d4ee7459 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -731,18 +731,18 @@ int ext4_get_block(struct inode *inode, sector_t iblock, | |||
731 | * `handle' can be NULL if create is zero | 731 | * `handle' can be NULL if create is zero |
732 | */ | 732 | */ |
733 | struct buffer_head *ext4_getblk(handle_t *handle, struct inode *inode, | 733 | struct buffer_head *ext4_getblk(handle_t *handle, struct inode *inode, |
734 | ext4_lblk_t block, int create) | 734 | ext4_lblk_t block, int map_flags) |
735 | { | 735 | { |
736 | struct ext4_map_blocks map; | 736 | struct ext4_map_blocks map; |
737 | struct buffer_head *bh; | 737 | struct buffer_head *bh; |
738 | int create = map_flags & EXT4_GET_BLOCKS_CREATE; | ||
738 | int err; | 739 | int err; |
739 | 740 | ||
740 | J_ASSERT(handle != NULL || create == 0); | 741 | J_ASSERT(handle != NULL || create == 0); |
741 | 742 | ||
742 | map.m_lblk = block; | 743 | map.m_lblk = block; |
743 | map.m_len = 1; | 744 | map.m_len = 1; |
744 | err = ext4_map_blocks(handle, inode, &map, | 745 | err = ext4_map_blocks(handle, inode, &map, map_flags); |
745 | create ? EXT4_GET_BLOCKS_CREATE : 0); | ||
746 | 746 | ||
747 | if (err == 0) | 747 | if (err == 0) |
748 | return create ? ERR_PTR(-ENOSPC) : NULL; | 748 | return create ? ERR_PTR(-ENOSPC) : NULL; |
@@ -788,11 +788,11 @@ errout: | |||
788 | } | 788 | } |
789 | 789 | ||
790 | struct buffer_head *ext4_bread(handle_t *handle, struct inode *inode, | 790 | struct buffer_head *ext4_bread(handle_t *handle, struct inode *inode, |
791 | ext4_lblk_t block, int create) | 791 | ext4_lblk_t block, int map_flags) |
792 | { | 792 | { |
793 | struct buffer_head *bh; | 793 | struct buffer_head *bh; |
794 | 794 | ||
795 | bh = ext4_getblk(handle, inode, block, create); | 795 | bh = ext4_getblk(handle, inode, block, map_flags); |
796 | if (IS_ERR(bh)) | 796 | if (IS_ERR(bh)) |
797 | return bh; | 797 | return bh; |
798 | if (!bh || buffer_uptodate(bh)) | 798 | if (!bh || buffer_uptodate(bh)) |
@@ -1261,13 +1261,12 @@ static int ext4_journalled_write_end(struct file *file, | |||
1261 | } | 1261 | } |
1262 | 1262 | ||
1263 | /* | 1263 | /* |
1264 | * Reserve a single cluster located at lblock | 1264 | * Reserve space for a single cluster |
1265 | */ | 1265 | */ |
1266 | static int ext4_da_reserve_space(struct inode *inode, ext4_lblk_t lblock) | 1266 | static int ext4_da_reserve_space(struct inode *inode) |
1267 | { | 1267 | { |
1268 | struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); | 1268 | struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); |
1269 | struct ext4_inode_info *ei = EXT4_I(inode); | 1269 | struct ext4_inode_info *ei = EXT4_I(inode); |
1270 | unsigned int md_needed; | ||
1271 | int ret; | 1270 | int ret; |
1272 | 1271 | ||
1273 | /* | 1272 | /* |
@@ -1279,25 +1278,14 @@ static int ext4_da_reserve_space(struct inode *inode, ext4_lblk_t lblock) | |||
1279 | if (ret) | 1278 | if (ret) |
1280 | return ret; | 1279 | return ret; |
1281 | 1280 | ||
1282 | /* | ||
1283 | * recalculate the amount of metadata blocks to reserve | ||
1284 | * in order to allocate nrblocks | ||
1285 | * worse case is one extent per block | ||
1286 | */ | ||
1287 | spin_lock(&ei->i_block_reservation_lock); | 1281 | spin_lock(&ei->i_block_reservation_lock); |
1288 | /* | ||
1289 | * ext4_calc_metadata_amount() has side effects, which we have | ||
1290 | * to be prepared undo if we fail to claim space. | ||
1291 | */ | ||
1292 | md_needed = 0; | ||
1293 | trace_ext4_da_reserve_space(inode, 0); | ||
1294 | |||
1295 | if (ext4_claim_free_clusters(sbi, 1, 0)) { | 1282 | if (ext4_claim_free_clusters(sbi, 1, 0)) { |
1296 | spin_unlock(&ei->i_block_reservation_lock); | 1283 | spin_unlock(&ei->i_block_reservation_lock); |
1297 | dquot_release_reservation_block(inode, EXT4_C2B(sbi, 1)); | 1284 | dquot_release_reservation_block(inode, EXT4_C2B(sbi, 1)); |
1298 | return -ENOSPC; | 1285 | return -ENOSPC; |
1299 | } | 1286 | } |
1300 | ei->i_reserved_data_blocks++; | 1287 | ei->i_reserved_data_blocks++; |
1288 | trace_ext4_da_reserve_space(inode); | ||
1301 | spin_unlock(&ei->i_block_reservation_lock); | 1289 | spin_unlock(&ei->i_block_reservation_lock); |
1302 | 1290 | ||
1303 | return 0; /* success */ | 1291 | return 0; /* success */ |
@@ -1566,9 +1554,9 @@ add_delayed: | |||
1566 | * then we don't need to reserve it again. However we still need | 1554 | * then we don't need to reserve it again. However we still need |
1567 | * to reserve metadata for every block we're going to write. | 1555 | * to reserve metadata for every block we're going to write. |
1568 | */ | 1556 | */ |
1569 | if (EXT4_SB(inode->i_sb)->s_cluster_ratio <= 1 || | 1557 | if (EXT4_SB(inode->i_sb)->s_cluster_ratio == 1 || |
1570 | !ext4_find_delalloc_cluster(inode, map->m_lblk)) { | 1558 | !ext4_find_delalloc_cluster(inode, map->m_lblk)) { |
1571 | ret = ext4_da_reserve_space(inode, iblock); | 1559 | ret = ext4_da_reserve_space(inode); |
1572 | if (ret) { | 1560 | if (ret) { |
1573 | /* not enough space to reserve */ | 1561 | /* not enough space to reserve */ |
1574 | retval = ret; | 1562 | retval = ret; |
@@ -1701,19 +1689,32 @@ static int __ext4_journalled_writepage(struct page *page, | |||
1701 | ext4_walk_page_buffers(handle, page_bufs, 0, len, | 1689 | ext4_walk_page_buffers(handle, page_bufs, 0, len, |
1702 | NULL, bget_one); | 1690 | NULL, bget_one); |
1703 | } | 1691 | } |
1704 | /* As soon as we unlock the page, it can go away, but we have | 1692 | /* |
1705 | * references to buffers so we are safe */ | 1693 | * We need to release the page lock before we start the |
1694 | * journal, so grab a reference so the page won't disappear | ||
1695 | * out from under us. | ||
1696 | */ | ||
1697 | get_page(page); | ||
1706 | unlock_page(page); | 1698 | unlock_page(page); |
1707 | 1699 | ||
1708 | handle = ext4_journal_start(inode, EXT4_HT_WRITE_PAGE, | 1700 | handle = ext4_journal_start(inode, EXT4_HT_WRITE_PAGE, |
1709 | ext4_writepage_trans_blocks(inode)); | 1701 | ext4_writepage_trans_blocks(inode)); |
1710 | if (IS_ERR(handle)) { | 1702 | if (IS_ERR(handle)) { |
1711 | ret = PTR_ERR(handle); | 1703 | ret = PTR_ERR(handle); |
1712 | goto out; | 1704 | put_page(page); |
1705 | goto out_no_pagelock; | ||
1713 | } | 1706 | } |
1714 | |||
1715 | BUG_ON(!ext4_handle_valid(handle)); | 1707 | BUG_ON(!ext4_handle_valid(handle)); |
1716 | 1708 | ||
1709 | lock_page(page); | ||
1710 | put_page(page); | ||
1711 | if (page->mapping != mapping) { | ||
1712 | /* The page got truncated from under us */ | ||
1713 | ext4_journal_stop(handle); | ||
1714 | ret = 0; | ||
1715 | goto out; | ||
1716 | } | ||
1717 | |||
1717 | if (inline_data) { | 1718 | if (inline_data) { |
1718 | BUFFER_TRACE(inode_bh, "get write access"); | 1719 | BUFFER_TRACE(inode_bh, "get write access"); |
1719 | ret = ext4_journal_get_write_access(handle, inode_bh); | 1720 | ret = ext4_journal_get_write_access(handle, inode_bh); |
@@ -1739,6 +1740,8 @@ static int __ext4_journalled_writepage(struct page *page, | |||
1739 | NULL, bput_one); | 1740 | NULL, bput_one); |
1740 | ext4_set_inode_state(inode, EXT4_STATE_JDATA); | 1741 | ext4_set_inode_state(inode, EXT4_STATE_JDATA); |
1741 | out: | 1742 | out: |
1743 | unlock_page(page); | ||
1744 | out_no_pagelock: | ||
1742 | brelse(inode_bh); | 1745 | brelse(inode_bh); |
1743 | return ret; | 1746 | return ret; |
1744 | } | 1747 | } |
@@ -4681,8 +4684,10 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr) | |||
4681 | ext4_journal_stop(handle); | 4684 | ext4_journal_stop(handle); |
4682 | } | 4685 | } |
4683 | 4686 | ||
4684 | if (attr->ia_valid & ATTR_SIZE && attr->ia_size != inode->i_size) { | 4687 | if (attr->ia_valid & ATTR_SIZE) { |
4685 | handle_t *handle; | 4688 | handle_t *handle; |
4689 | loff_t oldsize = inode->i_size; | ||
4690 | int shrink = (attr->ia_size <= inode->i_size); | ||
4686 | 4691 | ||
4687 | if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) { | 4692 | if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) { |
4688 | struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); | 4693 | struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); |
@@ -4690,24 +4695,26 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr) | |||
4690 | if (attr->ia_size > sbi->s_bitmap_maxbytes) | 4695 | if (attr->ia_size > sbi->s_bitmap_maxbytes) |
4691 | return -EFBIG; | 4696 | return -EFBIG; |
4692 | } | 4697 | } |
4698 | if (!S_ISREG(inode->i_mode)) | ||
4699 | return -EINVAL; | ||
4693 | 4700 | ||
4694 | if (IS_I_VERSION(inode) && attr->ia_size != inode->i_size) | 4701 | if (IS_I_VERSION(inode) && attr->ia_size != inode->i_size) |
4695 | inode_inc_iversion(inode); | 4702 | inode_inc_iversion(inode); |
4696 | 4703 | ||
4697 | if (S_ISREG(inode->i_mode) && | 4704 | if (ext4_should_order_data(inode) && |
4698 | (attr->ia_size < inode->i_size)) { | 4705 | (attr->ia_size < inode->i_size)) { |
4699 | if (ext4_should_order_data(inode)) { | 4706 | error = ext4_begin_ordered_truncate(inode, |
4700 | error = ext4_begin_ordered_truncate(inode, | ||
4701 | attr->ia_size); | 4707 | attr->ia_size); |
4702 | if (error) | 4708 | if (error) |
4703 | goto err_out; | 4709 | goto err_out; |
4704 | } | 4710 | } |
4711 | if (attr->ia_size != inode->i_size) { | ||
4705 | handle = ext4_journal_start(inode, EXT4_HT_INODE, 3); | 4712 | handle = ext4_journal_start(inode, EXT4_HT_INODE, 3); |
4706 | if (IS_ERR(handle)) { | 4713 | if (IS_ERR(handle)) { |
4707 | error = PTR_ERR(handle); | 4714 | error = PTR_ERR(handle); |
4708 | goto err_out; | 4715 | goto err_out; |
4709 | } | 4716 | } |
4710 | if (ext4_handle_valid(handle)) { | 4717 | if (ext4_handle_valid(handle) && shrink) { |
4711 | error = ext4_orphan_add(handle, inode); | 4718 | error = ext4_orphan_add(handle, inode); |
4712 | orphan = 1; | 4719 | orphan = 1; |
4713 | } | 4720 | } |
@@ -4726,15 +4733,13 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr) | |||
4726 | up_write(&EXT4_I(inode)->i_data_sem); | 4733 | up_write(&EXT4_I(inode)->i_data_sem); |
4727 | ext4_journal_stop(handle); | 4734 | ext4_journal_stop(handle); |
4728 | if (error) { | 4735 | if (error) { |
4729 | ext4_orphan_del(NULL, inode); | 4736 | if (orphan) |
4737 | ext4_orphan_del(NULL, inode); | ||
4730 | goto err_out; | 4738 | goto err_out; |
4731 | } | 4739 | } |
4732 | } else { | ||
4733 | loff_t oldsize = inode->i_size; | ||
4734 | |||
4735 | i_size_write(inode, attr->ia_size); | ||
4736 | pagecache_isize_extended(inode, oldsize, inode->i_size); | ||
4737 | } | 4740 | } |
4741 | if (!shrink) | ||
4742 | pagecache_isize_extended(inode, oldsize, inode->i_size); | ||
4738 | 4743 | ||
4739 | /* | 4744 | /* |
4740 | * Blocks are going to be removed from the inode. Wait | 4745 | * Blocks are going to be removed from the inode. Wait |
@@ -4754,13 +4759,9 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr) | |||
4754 | * in data=journal mode to make pages freeable. | 4759 | * in data=journal mode to make pages freeable. |
4755 | */ | 4760 | */ |
4756 | truncate_pagecache(inode, inode->i_size); | 4761 | truncate_pagecache(inode, inode->i_size); |
4762 | if (shrink) | ||
4763 | ext4_truncate(inode); | ||
4757 | } | 4764 | } |
4758 | /* | ||
4759 | * We want to call ext4_truncate() even if attr->ia_size == | ||
4760 | * inode->i_size for cases like truncation of fallocated space | ||
4761 | */ | ||
4762 | if (attr->ia_valid & ATTR_SIZE) | ||
4763 | ext4_truncate(inode); | ||
4764 | 4765 | ||
4765 | if (!rc) { | 4766 | if (!rc) { |
4766 | setattr_copy(inode, attr); | 4767 | setattr_copy(inode, attr); |