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.c48
1 files changed, 6 insertions, 42 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 3dca5264ccff..9b82ac7b0f55 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -47,6 +47,7 @@
47#include "xattr.h" 47#include "xattr.h"
48#include "acl.h" 48#include "acl.h"
49#include "ext4_extents.h" 49#include "ext4_extents.h"
50#include "truncate.h"
50 51
51#include <trace/events/ext4.h> 52#include <trace/events/ext4.h>
52 53
@@ -89,33 +90,6 @@ static int ext4_inode_is_fast_symlink(struct inode *inode)
89} 90}
90 91
91/* 92/*
92 * Work out how many blocks we need to proceed with the next chunk of a
93 * truncate transaction.
94 */
95static unsigned long blocks_for_truncate(struct inode *inode)
96{
97 ext4_lblk_t needed;
98
99 needed = inode->i_blocks >> (inode->i_sb->s_blocksize_bits - 9);
100
101 /* Give ourselves just enough room to cope with inodes in which
102 * i_blocks is corrupt: we've seen disk corruptions in the past
103 * which resulted in random data in an inode which looked enough
104 * like a regular file for ext4 to try to delete it. Things
105 * will go a bit crazy if that happens, but at least we should
106 * try not to panic the whole kernel. */
107 if (needed < 2)
108 needed = 2;
109
110 /* But we need to bound the transaction so we don't overflow the
111 * journal. */
112 if (needed > EXT4_MAX_TRANS_DATA)
113 needed = EXT4_MAX_TRANS_DATA;
114
115 return EXT4_DATA_TRANS_BLOCKS(inode->i_sb) + needed;
116}
117
118/*
119 * Truncate transactions can be complex and absolutely huge. So we need to 93 * Truncate transactions can be complex and absolutely huge. So we need to
120 * be able to restart the transaction at a conventient checkpoint to make 94 * be able to restart the transaction at a conventient checkpoint to make
121 * sure we don't overflow the journal. 95 * sure we don't overflow the journal.
@@ -129,7 +103,7 @@ static handle_t *start_transaction(struct inode *inode)
129{ 103{
130 handle_t *result; 104 handle_t *result;
131 105
132 result = ext4_journal_start(inode, blocks_for_truncate(inode)); 106 result = ext4_journal_start(inode, ext4_blocks_for_truncate(inode));
133 if (!IS_ERR(result)) 107 if (!IS_ERR(result))
134 return result; 108 return result;
135 109
@@ -149,7 +123,7 @@ static int try_to_extend_transaction(handle_t *handle, struct inode *inode)
149 return 0; 123 return 0;
150 if (ext4_handle_has_enough_credits(handle, EXT4_RESERVE_TRANS_BLOCKS+1)) 124 if (ext4_handle_has_enough_credits(handle, EXT4_RESERVE_TRANS_BLOCKS+1))
151 return 0; 125 return 0;
152 if (!ext4_journal_extend(handle, blocks_for_truncate(inode))) 126 if (!ext4_journal_extend(handle, ext4_blocks_for_truncate(inode)))
153 return 0; 127 return 0;
154 return 1; 128 return 1;
155} 129}
@@ -204,7 +178,7 @@ void ext4_evict_inode(struct inode *inode)
204 if (is_bad_inode(inode)) 178 if (is_bad_inode(inode))
205 goto no_delete; 179 goto no_delete;
206 180
207 handle = ext4_journal_start(inode, blocks_for_truncate(inode)+3); 181 handle = ext4_journal_start(inode, ext4_blocks_for_truncate(inode)+3);
208 if (IS_ERR(handle)) { 182 if (IS_ERR(handle)) {
209 ext4_std_error(inode->i_sb, PTR_ERR(handle)); 183 ext4_std_error(inode->i_sb, PTR_ERR(handle));
210 /* 184 /*
@@ -1555,16 +1529,6 @@ static int do_journal_get_write_access(handle_t *handle,
1555 return ret; 1529 return ret;
1556} 1530}
1557 1531
1558/*
1559 * Truncate blocks that were not used by write. We have to truncate the
1560 * pagecache as well so that corresponding buffers get properly unmapped.
1561 */
1562static void ext4_truncate_failed_write(struct inode *inode)
1563{
1564 truncate_inode_pages(inode->i_mapping, inode->i_size);
1565 ext4_truncate(inode);
1566}
1567
1568static int ext4_get_block_write(struct inode *inode, sector_t iblock, 1532static int ext4_get_block_write(struct inode *inode, sector_t iblock,
1569 struct buffer_head *bh_result, int create); 1533 struct buffer_head *bh_result, int create);
1570static int ext4_write_begin(struct file *file, struct address_space *mapping, 1534static int ext4_write_begin(struct file *file, struct address_space *mapping,
@@ -4134,7 +4098,7 @@ static int ext4_clear_blocks(handle_t *handle, struct inode *inode,
4134 if (unlikely(err)) 4098 if (unlikely(err))
4135 goto out_err; 4099 goto out_err;
4136 err = ext4_truncate_restart_trans(handle, inode, 4100 err = ext4_truncate_restart_trans(handle, inode,
4137 blocks_for_truncate(inode)); 4101 ext4_blocks_for_truncate(inode));
4138 if (unlikely(err)) 4102 if (unlikely(err))
4139 goto out_err; 4103 goto out_err;
4140 if (bh) { 4104 if (bh) {
@@ -4329,7 +4293,7 @@ static void ext4_free_branches(handle_t *handle, struct inode *inode,
4329 if (try_to_extend_transaction(handle, inode)) { 4293 if (try_to_extend_transaction(handle, inode)) {
4330 ext4_mark_inode_dirty(handle, inode); 4294 ext4_mark_inode_dirty(handle, inode);
4331 ext4_truncate_restart_trans(handle, inode, 4295 ext4_truncate_restart_trans(handle, inode,
4332 blocks_for_truncate(inode)); 4296 ext4_blocks_for_truncate(inode));
4333 } 4297 }
4334 4298
4335 /* 4299 /*