aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext3/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext3/inode.c')
-rw-r--r--fs/ext3/inode.c46
1 files changed, 39 insertions, 7 deletions
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index 6ae4ecf3ce40..3bf07d70b914 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -2127,7 +2127,21 @@ static void ext3_free_data(handle_t *handle, struct inode *inode,
2127 2127
2128 if (this_bh) { 2128 if (this_bh) {
2129 BUFFER_TRACE(this_bh, "call ext3_journal_dirty_metadata"); 2129 BUFFER_TRACE(this_bh, "call ext3_journal_dirty_metadata");
2130 ext3_journal_dirty_metadata(handle, this_bh); 2130
2131 /*
2132 * The buffer head should have an attached journal head at this
2133 * point. However, if the data is corrupted and an indirect
2134 * block pointed to itself, it would have been detached when
2135 * the block was cleared. Check for this instead of OOPSing.
2136 */
2137 if (bh2jh(this_bh))
2138 ext3_journal_dirty_metadata(handle, this_bh);
2139 else
2140 ext3_error(inode->i_sb, "ext3_free_data",
2141 "circular indirect block detected, "
2142 "inode=%lu, block=%llu",
2143 inode->i_ino,
2144 (unsigned long long)this_bh->b_blocknr);
2131 } 2145 }
2132} 2146}
2133 2147
@@ -2253,6 +2267,19 @@ static void ext3_free_branches(handle_t *handle, struct inode *inode,
2253 } 2267 }
2254} 2268}
2255 2269
2270int ext3_can_truncate(struct inode *inode)
2271{
2272 if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
2273 return 0;
2274 if (S_ISREG(inode->i_mode))
2275 return 1;
2276 if (S_ISDIR(inode->i_mode))
2277 return 1;
2278 if (S_ISLNK(inode->i_mode))
2279 return !ext3_inode_is_fast_symlink(inode);
2280 return 0;
2281}
2282
2256/* 2283/*
2257 * ext3_truncate() 2284 * ext3_truncate()
2258 * 2285 *
@@ -2297,12 +2324,7 @@ void ext3_truncate(struct inode *inode)
2297 unsigned blocksize = inode->i_sb->s_blocksize; 2324 unsigned blocksize = inode->i_sb->s_blocksize;
2298 struct page *page; 2325 struct page *page;
2299 2326
2300 if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || 2327 if (!ext3_can_truncate(inode))
2301 S_ISLNK(inode->i_mode)))
2302 return;
2303 if (ext3_inode_is_fast_symlink(inode))
2304 return;
2305 if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
2306 return; 2328 return;
2307 2329
2308 /* 2330 /*
@@ -2513,6 +2535,16 @@ static int __ext3_get_inode_loc(struct inode *inode,
2513 } 2535 }
2514 if (!buffer_uptodate(bh)) { 2536 if (!buffer_uptodate(bh)) {
2515 lock_buffer(bh); 2537 lock_buffer(bh);
2538
2539 /*
2540 * If the buffer has the write error flag, we have failed
2541 * to write out another inode in the same block. In this
2542 * case, we don't have to read the block because we may
2543 * read the old inode data successfully.
2544 */
2545 if (buffer_write_io_error(bh) && !buffer_uptodate(bh))
2546 set_buffer_uptodate(bh);
2547
2516 if (buffer_uptodate(bh)) { 2548 if (buffer_uptodate(bh)) {
2517 /* someone brought it uptodate while we waited */ 2549 /* someone brought it uptodate while we waited */
2518 unlock_buffer(bh); 2550 unlock_buffer(bh);