diff options
author | Theodore Ts'o <tytso@mit.edu> | 2009-09-30 22:57:41 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2009-09-30 22:57:41 -0400 |
commit | 1f94533d9cd75f6d2826018d54a971b9cc085992 (patch) | |
tree | 16c85061eabfcdece2487909bc08c45d2c01d84f | |
parent | c1fccc0696bcaff6008c11865091f5ec4b0937ab (diff) |
ext4: fix a BUG_ON crash by checking that page has buffers attached to it
In ext4_num_dirty_pages() we were calling page_buffers() before
checking to see if the page actually had pages attached to it; this
would cause a BUG check crash in the inline function page_buffers().
Thanks to Markus Trippelsdorf for reporting this bug.
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
-rw-r--r-- | fs/ext4/inode.c | 22 |
1 files changed, 11 insertions, 11 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index ec367bce7215..6e65d0e25ed3 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -1146,8 +1146,8 @@ static int check_block_validity(struct inode *inode, const char *msg, | |||
1146 | } | 1146 | } |
1147 | 1147 | ||
1148 | /* | 1148 | /* |
1149 | * Return the number of dirty pages in the given inode starting at | 1149 | * Return the number of contiguous dirty pages in a given inode |
1150 | * page frame idx. | 1150 | * starting at page frame idx. |
1151 | */ | 1151 | */ |
1152 | static pgoff_t ext4_num_dirty_pages(struct inode *inode, pgoff_t idx, | 1152 | static pgoff_t ext4_num_dirty_pages(struct inode *inode, pgoff_t idx, |
1153 | unsigned int max_pages) | 1153 | unsigned int max_pages) |
@@ -1181,15 +1181,15 @@ static pgoff_t ext4_num_dirty_pages(struct inode *inode, pgoff_t idx, | |||
1181 | unlock_page(page); | 1181 | unlock_page(page); |
1182 | break; | 1182 | break; |
1183 | } | 1183 | } |
1184 | head = page_buffers(page); | 1184 | if (page_has_buffers(page)) { |
1185 | bh = head; | 1185 | bh = head = page_buffers(page); |
1186 | do { | 1186 | do { |
1187 | if (!buffer_delay(bh) && | 1187 | if (!buffer_delay(bh) && |
1188 | !buffer_unwritten(bh)) { | 1188 | !buffer_unwritten(bh)) |
1189 | done = 1; | 1189 | done = 1; |
1190 | break; | 1190 | bh = bh->b_this_page; |
1191 | } | 1191 | } while (!done && (bh != head)); |
1192 | } while ((bh = bh->b_this_page) != head); | 1192 | } |
1193 | unlock_page(page); | 1193 | unlock_page(page); |
1194 | if (done) | 1194 | if (done) |
1195 | break; | 1195 | break; |