aboutsummaryrefslogtreecommitdiffstats
path: root/fs/buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/buffer.c')
-rw-r--r--fs/buffer.c28
1 files changed, 20 insertions, 8 deletions
diff --git a/fs/buffer.c b/fs/buffer.c
index 7ba58386beee..39ff14403d13 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -1181,7 +1181,20 @@ __getblk_slow(struct block_device *bdev, sector_t block, int size)
1181void mark_buffer_dirty(struct buffer_head *bh) 1181void mark_buffer_dirty(struct buffer_head *bh)
1182{ 1182{
1183 WARN_ON_ONCE(!buffer_uptodate(bh)); 1183 WARN_ON_ONCE(!buffer_uptodate(bh));
1184 if (!buffer_dirty(bh) && !test_set_buffer_dirty(bh)) 1184
1185 /*
1186 * Very *carefully* optimize the it-is-already-dirty case.
1187 *
1188 * Don't let the final "is it dirty" escape to before we
1189 * perhaps modified the buffer.
1190 */
1191 if (buffer_dirty(bh)) {
1192 smp_mb();
1193 if (buffer_dirty(bh))
1194 return;
1195 }
1196
1197 if (!test_set_buffer_dirty(bh))
1185 __set_page_dirty(bh->b_page, page_mapping(bh->b_page), 0); 1198 __set_page_dirty(bh->b_page, page_mapping(bh->b_page), 0);
1186} 1199}
1187 1200
@@ -2564,14 +2577,13 @@ int nobh_write_end(struct file *file, struct address_space *mapping,
2564 struct inode *inode = page->mapping->host; 2577 struct inode *inode = page->mapping->host;
2565 struct buffer_head *head = fsdata; 2578 struct buffer_head *head = fsdata;
2566 struct buffer_head *bh; 2579 struct buffer_head *bh;
2580 BUG_ON(fsdata != NULL && page_has_buffers(page));
2567 2581
2568 if (!PageMappedToDisk(page)) { 2582 if (unlikely(copied < len) && !page_has_buffers(page))
2569 if (unlikely(copied < len) && !page_has_buffers(page)) 2583 attach_nobh_buffers(page, head);
2570 attach_nobh_buffers(page, head); 2584 if (page_has_buffers(page))
2571 if (page_has_buffers(page)) 2585 return generic_write_end(file, mapping, pos, len,
2572 return generic_write_end(file, mapping, pos, len, 2586 copied, page, fsdata);
2573 copied, page, fsdata);
2574 }
2575 2587
2576 SetPageUptodate(page); 2588 SetPageUptodate(page);
2577 set_page_dirty(page); 2589 set_page_dirty(page);