aboutsummaryrefslogtreecommitdiffstats
path: root/fs/buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/buffer.c')
-rw-r--r--fs/buffer.c103
1 files changed, 85 insertions, 18 deletions
diff --git a/fs/buffer.c b/fs/buffer.c
index 6569fda5cfed..665d446b25bc 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -99,10 +99,18 @@ __clear_page_buffers(struct page *page)
99 page_cache_release(page); 99 page_cache_release(page);
100} 100}
101 101
102
103static int quiet_error(struct buffer_head *bh)
104{
105 if (!test_bit(BH_Quiet, &bh->b_state) && printk_ratelimit())
106 return 0;
107 return 1;
108}
109
110
102static void buffer_io_error(struct buffer_head *bh) 111static void buffer_io_error(struct buffer_head *bh)
103{ 112{
104 char b[BDEVNAME_SIZE]; 113 char b[BDEVNAME_SIZE];
105
106 printk(KERN_ERR "Buffer I/O error on device %s, logical block %Lu\n", 114 printk(KERN_ERR "Buffer I/O error on device %s, logical block %Lu\n",
107 bdevname(bh->b_bdev, b), 115 bdevname(bh->b_bdev, b),
108 (unsigned long long)bh->b_blocknr); 116 (unsigned long long)bh->b_blocknr);
@@ -144,7 +152,7 @@ void end_buffer_write_sync(struct buffer_head *bh, int uptodate)
144 if (uptodate) { 152 if (uptodate) {
145 set_buffer_uptodate(bh); 153 set_buffer_uptodate(bh);
146 } else { 154 } else {
147 if (!buffer_eopnotsupp(bh) && printk_ratelimit()) { 155 if (!buffer_eopnotsupp(bh) && !quiet_error(bh)) {
148 buffer_io_error(bh); 156 buffer_io_error(bh);
149 printk(KERN_WARNING "lost page write due to " 157 printk(KERN_WARNING "lost page write due to "
150 "I/O error on %s\n", 158 "I/O error on %s\n",
@@ -195,10 +203,25 @@ int fsync_bdev(struct block_device *bdev)
195 * happen on bdev until thaw_bdev() is called. 203 * happen on bdev until thaw_bdev() is called.
196 * If a superblock is found on this device, we take the s_umount semaphore 204 * If a superblock is found on this device, we take the s_umount semaphore
197 * on it to make sure nobody unmounts until the snapshot creation is done. 205 * on it to make sure nobody unmounts until the snapshot creation is done.
206 * The reference counter (bd_fsfreeze_count) guarantees that only the last
207 * unfreeze process can unfreeze the frozen filesystem actually when multiple
208 * freeze requests arrive simultaneously. It counts up in freeze_bdev() and
209 * count down in thaw_bdev(). When it becomes 0, thaw_bdev() will unfreeze
210 * actually.
198 */ 211 */
199struct super_block *freeze_bdev(struct block_device *bdev) 212struct super_block *freeze_bdev(struct block_device *bdev)
200{ 213{
201 struct super_block *sb; 214 struct super_block *sb;
215 int error = 0;
216
217 mutex_lock(&bdev->bd_fsfreeze_mutex);
218 if (bdev->bd_fsfreeze_count > 0) {
219 bdev->bd_fsfreeze_count++;
220 sb = get_super(bdev);
221 mutex_unlock(&bdev->bd_fsfreeze_mutex);
222 return sb;
223 }
224 bdev->bd_fsfreeze_count++;
202 225
203 down(&bdev->bd_mount_sem); 226 down(&bdev->bd_mount_sem);
204 sb = get_super(bdev); 227 sb = get_super(bdev);
@@ -213,11 +236,24 @@ struct super_block *freeze_bdev(struct block_device *bdev)
213 236
214 sync_blockdev(sb->s_bdev); 237 sync_blockdev(sb->s_bdev);
215 238
216 if (sb->s_op->write_super_lockfs) 239 if (sb->s_op->freeze_fs) {
217 sb->s_op->write_super_lockfs(sb); 240 error = sb->s_op->freeze_fs(sb);
241 if (error) {
242 printk(KERN_ERR
243 "VFS:Filesystem freeze failed\n");
244 sb->s_frozen = SB_UNFROZEN;
245 drop_super(sb);
246 up(&bdev->bd_mount_sem);
247 bdev->bd_fsfreeze_count--;
248 mutex_unlock(&bdev->bd_fsfreeze_mutex);
249 return ERR_PTR(error);
250 }
251 }
218 } 252 }
219 253
220 sync_blockdev(bdev); 254 sync_blockdev(bdev);
255 mutex_unlock(&bdev->bd_fsfreeze_mutex);
256
221 return sb; /* thaw_bdev releases s->s_umount and bd_mount_sem */ 257 return sb; /* thaw_bdev releases s->s_umount and bd_mount_sem */
222} 258}
223EXPORT_SYMBOL(freeze_bdev); 259EXPORT_SYMBOL(freeze_bdev);
@@ -229,20 +265,48 @@ EXPORT_SYMBOL(freeze_bdev);
229 * 265 *
230 * Unlocks the filesystem and marks it writeable again after freeze_bdev(). 266 * Unlocks the filesystem and marks it writeable again after freeze_bdev().
231 */ 267 */
232void thaw_bdev(struct block_device *bdev, struct super_block *sb) 268int thaw_bdev(struct block_device *bdev, struct super_block *sb)
233{ 269{
270 int error = 0;
271
272 mutex_lock(&bdev->bd_fsfreeze_mutex);
273 if (!bdev->bd_fsfreeze_count) {
274 mutex_unlock(&bdev->bd_fsfreeze_mutex);
275 return -EINVAL;
276 }
277
278 bdev->bd_fsfreeze_count--;
279 if (bdev->bd_fsfreeze_count > 0) {
280 if (sb)
281 drop_super(sb);
282 mutex_unlock(&bdev->bd_fsfreeze_mutex);
283 return 0;
284 }
285
234 if (sb) { 286 if (sb) {
235 BUG_ON(sb->s_bdev != bdev); 287 BUG_ON(sb->s_bdev != bdev);
236 288 if (!(sb->s_flags & MS_RDONLY)) {
237 if (sb->s_op->unlockfs) 289 if (sb->s_op->unfreeze_fs) {
238 sb->s_op->unlockfs(sb); 290 error = sb->s_op->unfreeze_fs(sb);
239 sb->s_frozen = SB_UNFROZEN; 291 if (error) {
240 smp_wmb(); 292 printk(KERN_ERR
241 wake_up(&sb->s_wait_unfrozen); 293 "VFS:Filesystem thaw failed\n");
294 sb->s_frozen = SB_FREEZE_TRANS;
295 bdev->bd_fsfreeze_count++;
296 mutex_unlock(&bdev->bd_fsfreeze_mutex);
297 return error;
298 }
299 }
300 sb->s_frozen = SB_UNFROZEN;
301 smp_wmb();
302 wake_up(&sb->s_wait_unfrozen);
303 }
242 drop_super(sb); 304 drop_super(sb);
243 } 305 }
244 306
245 up(&bdev->bd_mount_sem); 307 up(&bdev->bd_mount_sem);
308 mutex_unlock(&bdev->bd_fsfreeze_mutex);
309 return 0;
246} 310}
247EXPORT_SYMBOL(thaw_bdev); 311EXPORT_SYMBOL(thaw_bdev);
248 312
@@ -394,7 +458,7 @@ static void end_buffer_async_read(struct buffer_head *bh, int uptodate)
394 set_buffer_uptodate(bh); 458 set_buffer_uptodate(bh);
395 } else { 459 } else {
396 clear_buffer_uptodate(bh); 460 clear_buffer_uptodate(bh);
397 if (printk_ratelimit()) 461 if (!quiet_error(bh))
398 buffer_io_error(bh); 462 buffer_io_error(bh);
399 SetPageError(page); 463 SetPageError(page);
400 } 464 }
@@ -455,7 +519,7 @@ static void end_buffer_async_write(struct buffer_head *bh, int uptodate)
455 if (uptodate) { 519 if (uptodate) {
456 set_buffer_uptodate(bh); 520 set_buffer_uptodate(bh);
457 } else { 521 } else {
458 if (printk_ratelimit()) { 522 if (!quiet_error(bh)) {
459 buffer_io_error(bh); 523 buffer_io_error(bh);
460 printk(KERN_WARNING "lost page write due to " 524 printk(KERN_WARNING "lost page write due to "
461 "I/O error on %s\n", 525 "I/O error on %s\n",
@@ -878,6 +942,7 @@ void invalidate_inode_buffers(struct inode *inode)
878 spin_unlock(&buffer_mapping->private_lock); 942 spin_unlock(&buffer_mapping->private_lock);
879 } 943 }
880} 944}
945EXPORT_SYMBOL(invalidate_inode_buffers);
881 946
882/* 947/*
883 * Remove any clean buffers from the inode's buffer list. This is called 948 * Remove any clean buffers from the inode's buffer list. This is called
@@ -1987,7 +2052,7 @@ int block_write_begin(struct file *file, struct address_space *mapping,
1987 page = *pagep; 2052 page = *pagep;
1988 if (page == NULL) { 2053 if (page == NULL) {
1989 ownpage = 1; 2054 ownpage = 1;
1990 page = __grab_cache_page(mapping, index); 2055 page = grab_cache_page_write_begin(mapping, index, flags);
1991 if (!page) { 2056 if (!page) {
1992 status = -ENOMEM; 2057 status = -ENOMEM;
1993 goto out; 2058 goto out;
@@ -2013,7 +2078,6 @@ int block_write_begin(struct file *file, struct address_space *mapping,
2013 if (pos + len > inode->i_size) 2078 if (pos + len > inode->i_size)
2014 vmtruncate(inode, inode->i_size); 2079 vmtruncate(inode, inode->i_size);
2015 } 2080 }
2016 goto out;
2017 } 2081 }
2018 2082
2019out: 2083out:
@@ -2493,7 +2557,7 @@ int nobh_write_begin(struct file *file, struct address_space *mapping,
2493 from = pos & (PAGE_CACHE_SIZE - 1); 2557 from = pos & (PAGE_CACHE_SIZE - 1);
2494 to = from + len; 2558 to = from + len;
2495 2559
2496 page = __grab_cache_page(mapping, index); 2560 page = grab_cache_page_write_begin(mapping, index, flags);
2497 if (!page) 2561 if (!page)
2498 return -ENOMEM; 2562 return -ENOMEM;
2499 *pagep = page; 2563 *pagep = page;
@@ -2624,7 +2688,7 @@ int nobh_write_end(struct file *file, struct address_space *mapping,
2624 struct buffer_head *bh; 2688 struct buffer_head *bh;
2625 BUG_ON(fsdata != NULL && page_has_buffers(page)); 2689 BUG_ON(fsdata != NULL && page_has_buffers(page));
2626 2690
2627 if (unlikely(copied < len) && !page_has_buffers(page)) 2691 if (unlikely(copied < len) && head)
2628 attach_nobh_buffers(page, head); 2692 attach_nobh_buffers(page, head);
2629 if (page_has_buffers(page)) 2693 if (page_has_buffers(page))
2630 return generic_write_end(file, mapping, pos, len, 2694 return generic_write_end(file, mapping, pos, len,
@@ -2912,6 +2976,9 @@ static void end_bio_bh_io_sync(struct bio *bio, int err)
2912 set_bit(BH_Eopnotsupp, &bh->b_state); 2976 set_bit(BH_Eopnotsupp, &bh->b_state);
2913 } 2977 }
2914 2978
2979 if (unlikely (test_bit(BIO_QUIET,&bio->bi_flags)))
2980 set_bit(BH_Quiet, &bh->b_state);
2981
2915 bh->b_end_io(bh, test_bit(BIO_UPTODATE, &bio->bi_flags)); 2982 bh->b_end_io(bh, test_bit(BIO_UPTODATE, &bio->bi_flags));
2916 bio_put(bio); 2983 bio_put(bio);
2917} 2984}
@@ -3176,7 +3243,7 @@ void block_sync_page(struct page *page)
3176 * Use of bdflush() is deprecated and will be removed in a future kernel. 3243 * Use of bdflush() is deprecated and will be removed in a future kernel.
3177 * The `pdflush' kernel threads fully replace bdflush daemons and this call. 3244 * The `pdflush' kernel threads fully replace bdflush daemons and this call.
3178 */ 3245 */
3179asmlinkage long sys_bdflush(int func, long data) 3246SYSCALL_DEFINE2(bdflush, int, func, long, data)
3180{ 3247{
3181 static int msg_count; 3248 static int msg_count;
3182 3249