aboutsummaryrefslogtreecommitdiffstats
path: root/fs/buffer.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-01-16 11:46:22 -0500
committerIngo Molnar <mingo@elte.hu>2009-01-16 11:46:22 -0500
commit5a2dd72abdae75ea2960145e0549635ce4e0be96 (patch)
tree44dba0119c75679a17215200f92ab23bdde9efc2 /fs/buffer.c
parentefdc64f0c792ea744bcc9203f35b908e66d42f41 (diff)
parent7cb36b6ccdca03bd87e8faca7fd920643dd1aec7 (diff)
Merge branch 'linus' into irq/genirq
Diffstat (limited to 'fs/buffer.c')
-rw-r--r--fs/buffer.c100
1 files changed, 83 insertions, 17 deletions
diff --git a/fs/buffer.c b/fs/buffer.c
index 10179cfa1152..b58208f1640a 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",
@@ -1988,7 +2052,7 @@ int block_write_begin(struct file *file, struct address_space *mapping,
1988 page = *pagep; 2052 page = *pagep;
1989 if (page == NULL) { 2053 if (page == NULL) {
1990 ownpage = 1; 2054 ownpage = 1;
1991 page = __grab_cache_page(mapping, index); 2055 page = grab_cache_page_write_begin(mapping, index, flags);
1992 if (!page) { 2056 if (!page) {
1993 status = -ENOMEM; 2057 status = -ENOMEM;
1994 goto out; 2058 goto out;
@@ -2014,7 +2078,6 @@ int block_write_begin(struct file *file, struct address_space *mapping,
2014 if (pos + len > inode->i_size) 2078 if (pos + len > inode->i_size)
2015 vmtruncate(inode, inode->i_size); 2079 vmtruncate(inode, inode->i_size);
2016 } 2080 }
2017 goto out;
2018 } 2081 }
2019 2082
2020out: 2083out:
@@ -2494,7 +2557,7 @@ int nobh_write_begin(struct file *file, struct address_space *mapping,
2494 from = pos & (PAGE_CACHE_SIZE - 1); 2557 from = pos & (PAGE_CACHE_SIZE - 1);
2495 to = from + len; 2558 to = from + len;
2496 2559
2497 page = __grab_cache_page(mapping, index); 2560 page = grab_cache_page_write_begin(mapping, index, flags);
2498 if (!page) 2561 if (!page)
2499 return -ENOMEM; 2562 return -ENOMEM;
2500 *pagep = page; 2563 *pagep = page;
@@ -2913,6 +2976,9 @@ static void end_bio_bh_io_sync(struct bio *bio, int err)
2913 set_bit(BH_Eopnotsupp, &bh->b_state); 2976 set_bit(BH_Eopnotsupp, &bh->b_state);
2914 } 2977 }
2915 2978
2979 if (unlikely (test_bit(BIO_QUIET,&bio->bi_flags)))
2980 set_bit(BH_Quiet, &bh->b_state);
2981
2916 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));
2917 bio_put(bio); 2983 bio_put(bio);
2918} 2984}
@@ -3177,7 +3243,7 @@ void block_sync_page(struct page *page)
3177 * 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.
3178 * The `pdflush' kernel threads fully replace bdflush daemons and this call. 3244 * The `pdflush' kernel threads fully replace bdflush daemons and this call.
3179 */ 3245 */
3180asmlinkage long sys_bdflush(int func, long data) 3246SYSCALL_DEFINE2(bdflush, int, func, long, data)
3181{ 3247{
3182 static int msg_count; 3248 static int msg_count;
3183 3249