diff options
author | Duane Griffin <duaneg@dghda.com> | 2008-07-11 19:27:31 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2008-07-11 19:27:31 -0400 |
commit | 91ef4caf800030fa6e5224b8a41f8c74787b303d (patch) | |
tree | f0c058b50ac2eb9058aa8b077b2da733f8c3ee02 /fs/ext4/inode.c | |
parent | bce7f793daec3e65ec5c5705d2457b81fe7b5725 (diff) |
ext4: handle corrupted orphan list at mount
If the orphan node list includes valid, untruncatable nodes with nlink > 0
the ext4_orphan_cleanup loop which attempts to delete them will not do so,
causing it to loop forever. Fix by checking for such nodes in the
ext4_orphan_get function.
This patch fixes the second case (image hdb.20000009.softlockup.gz)
reported in http://bugzilla.kernel.org/show_bug.cgi?id=10882.
Signed-off-by: Duane Griffin <duaneg@dghda.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Diffstat (limited to 'fs/ext4/inode.c')
-rw-r--r-- | fs/ext4/inode.c | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 8d9707746413..269763b66361 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -2305,6 +2305,19 @@ static void ext4_free_branches(handle_t *handle, struct inode *inode, | |||
2305 | } | 2305 | } |
2306 | } | 2306 | } |
2307 | 2307 | ||
2308 | int ext4_can_truncate(struct inode *inode) | ||
2309 | { | ||
2310 | if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) | ||
2311 | return 0; | ||
2312 | if (S_ISREG(inode->i_mode)) | ||
2313 | return 1; | ||
2314 | if (S_ISDIR(inode->i_mode)) | ||
2315 | return 1; | ||
2316 | if (S_ISLNK(inode->i_mode)) | ||
2317 | return !ext4_inode_is_fast_symlink(inode); | ||
2318 | return 0; | ||
2319 | } | ||
2320 | |||
2308 | /* | 2321 | /* |
2309 | * ext4_truncate() | 2322 | * ext4_truncate() |
2310 | * | 2323 | * |
@@ -2349,12 +2362,7 @@ void ext4_truncate(struct inode *inode) | |||
2349 | unsigned blocksize = inode->i_sb->s_blocksize; | 2362 | unsigned blocksize = inode->i_sb->s_blocksize; |
2350 | struct page *page; | 2363 | struct page *page; |
2351 | 2364 | ||
2352 | if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || | 2365 | if (!ext4_can_truncate(inode)) |
2353 | S_ISLNK(inode->i_mode))) | ||
2354 | return; | ||
2355 | if (ext4_inode_is_fast_symlink(inode)) | ||
2356 | return; | ||
2357 | if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) | ||
2358 | return; | 2366 | return; |
2359 | 2367 | ||
2360 | /* | 2368 | /* |