| From bc476d1a48a5a417aed2d3ad666346872d8bdee7 Mon Sep 17 00:00:00 2001 |
| From: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> |
| Date: Wed, 9 Sep 2009 22:36:03 -0400 |
| Subject: [PATCH 20/85] ext4: Take page lock before looking at attached buffer_heads flags |
| |
| (cherry picked from commit a827eaffff07c7d58a4cb32158cbeb4849f4e33a) |
| |
| In order to check whether the buffer_heads are mapped we need to hold |
| page lock. Otherwise a reclaim can cleanup the attached buffer_heads. |
| |
| Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> |
| Signed-off-by: "Theodore Ts'o" <tytso@mit.edu> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| --- |
| fs/ext4/inode.c | 13 +++++++++++-- |
| 1 file changed, 11 insertions(+), 2 deletions(-) |
| |
| --- a/fs/ext4/inode.c |
| +++ b/fs/ext4/inode.c |
| @@ -5298,12 +5298,21 @@ int ext4_page_mkwrite(struct vm_area_str |
| else |
| len = PAGE_CACHE_SIZE; |
| |
| + lock_page(page); |
| + /* |
| + * return if we have all the buffers mapped. This avoid |
| + * the need to call write_begin/write_end which does a |
| + * journal_start/journal_stop which can block and take |
| + * long time |
| + */ |
| if (page_has_buffers(page)) { |
| - /* return if we have all the buffers mapped */ |
| if (!walk_page_buffers(NULL, page_buffers(page), 0, len, NULL, |
| - ext4_bh_unmapped)) |
| + ext4_bh_unmapped)) { |
| + unlock_page(page); |
| goto out_unlock; |
| + } |
| } |
| + unlock_page(page); |
| /* |
| * OK, we need to fill the hole... Do write_begin write_end |
| * to do block allocation/reservation.We are not holding |