aboutsummaryrefslogtreecommitdiffstats
path: root/fs/block_dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/block_dev.c')
-rw-r--r--fs/block_dev.c33
1 files changed, 10 insertions, 23 deletions
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 2091db8cdd78..c7bda5cd3da7 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -58,17 +58,24 @@ static void bdev_inode_switch_bdi(struct inode *inode,
58 struct backing_dev_info *dst) 58 struct backing_dev_info *dst)
59{ 59{
60 struct backing_dev_info *old = inode->i_data.backing_dev_info; 60 struct backing_dev_info *old = inode->i_data.backing_dev_info;
61 bool wakeup_bdi = false;
61 62
62 if (unlikely(dst == old)) /* deadlock avoidance */ 63 if (unlikely(dst == old)) /* deadlock avoidance */
63 return; 64 return;
64 bdi_lock_two(&old->wb, &dst->wb); 65 bdi_lock_two(&old->wb, &dst->wb);
65 spin_lock(&inode->i_lock); 66 spin_lock(&inode->i_lock);
66 inode->i_data.backing_dev_info = dst; 67 inode->i_data.backing_dev_info = dst;
67 if (inode->i_state & I_DIRTY) 68 if (inode->i_state & I_DIRTY) {
69 if (bdi_cap_writeback_dirty(dst) && !wb_has_dirty_io(&dst->wb))
70 wakeup_bdi = true;
68 list_move(&inode->i_wb_list, &dst->wb.b_dirty); 71 list_move(&inode->i_wb_list, &dst->wb.b_dirty);
72 }
69 spin_unlock(&inode->i_lock); 73 spin_unlock(&inode->i_lock);
70 spin_unlock(&old->wb.list_lock); 74 spin_unlock(&old->wb.list_lock);
71 spin_unlock(&dst->wb.list_lock); 75 spin_unlock(&dst->wb.list_lock);
76
77 if (wakeup_bdi)
78 bdi_wakeup_thread_delayed(dst);
72} 79}
73 80
74/* Kill _all_ buffers and pagecache , dirty or not.. */ 81/* Kill _all_ buffers and pagecache , dirty or not.. */
@@ -325,31 +332,10 @@ static int blkdev_write_end(struct file *file, struct address_space *mapping,
325static loff_t block_llseek(struct file *file, loff_t offset, int whence) 332static loff_t block_llseek(struct file *file, loff_t offset, int whence)
326{ 333{
327 struct inode *bd_inode = file->f_mapping->host; 334 struct inode *bd_inode = file->f_mapping->host;
328 loff_t size;
329 loff_t retval; 335 loff_t retval;
330 336
331 mutex_lock(&bd_inode->i_mutex); 337 mutex_lock(&bd_inode->i_mutex);
332 size = i_size_read(bd_inode); 338 retval = fixed_size_llseek(file, offset, whence, i_size_read(bd_inode));
333
334 retval = -EINVAL;
335 switch (whence) {
336 case SEEK_END:
337 offset += size;
338 break;
339 case SEEK_CUR:
340 offset += file->f_pos;
341 case SEEK_SET:
342 break;
343 default:
344 goto out;
345 }
346 if (offset >= 0 && offset <= size) {
347 if (offset != file->f_pos) {
348 file->f_pos = offset;
349 }
350 retval = offset;
351 }
352out:
353 mutex_unlock(&bd_inode->i_mutex); 339 mutex_unlock(&bd_inode->i_mutex);
354 return retval; 340 return retval;
355} 341}
@@ -1583,6 +1569,7 @@ static const struct address_space_operations def_blk_aops = {
1583 .writepages = generic_writepages, 1569 .writepages = generic_writepages,
1584 .releasepage = blkdev_releasepage, 1570 .releasepage = blkdev_releasepage,
1585 .direct_IO = blkdev_direct_IO, 1571 .direct_IO = blkdev_direct_IO,
1572 .is_dirty_writeback = buffer_check_dirty_writeback,
1586}; 1573};
1587 1574
1588const struct file_operations def_blk_fops = { 1575const struct file_operations def_blk_fops = {