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.c37
1 files changed, 12 insertions, 25 deletions
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 256233098206..1e86823a9cbd 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}
@@ -1533,7 +1519,7 @@ ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov,
1533 1519
1534 blk_start_plug(&plug); 1520 blk_start_plug(&plug);
1535 ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos); 1521 ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos);
1536 if (ret > 0 || ret == -EIOCBQUEUED) { 1522 if (ret > 0) {
1537 ssize_t err; 1523 ssize_t err;
1538 1524
1539 err = generic_write_sync(file, pos, ret); 1525 err = generic_write_sync(file, pos, ret);
@@ -1556,7 +1542,7 @@ static ssize_t blkdev_aio_read(struct kiocb *iocb, const struct iovec *iov,
1556 return 0; 1542 return 0;
1557 1543
1558 size -= pos; 1544 size -= pos;
1559 if (size < iocb->ki_left) 1545 if (size < iocb->ki_nbytes)
1560 nr_segs = iov_shorten((struct iovec *)iov, nr_segs, size); 1546 nr_segs = iov_shorten((struct iovec *)iov, nr_segs, size);
1561 return generic_file_aio_read(iocb, iov, nr_segs, pos); 1547 return generic_file_aio_read(iocb, iov, nr_segs, pos);
1562} 1548}
@@ -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 = {