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.c166
1 files changed, 16 insertions, 150 deletions
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 1a1e5e3b1eaf..ab3a456f6650 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -70,19 +70,6 @@ static void bdev_inode_switch_bdi(struct inode *inode,
70 spin_unlock(&dst->wb.list_lock); 70 spin_unlock(&dst->wb.list_lock);
71} 71}
72 72
73sector_t blkdev_max_block(struct block_device *bdev)
74{
75 sector_t retval = ~((sector_t)0);
76 loff_t sz = i_size_read(bdev->bd_inode);
77
78 if (sz) {
79 unsigned int size = block_size(bdev);
80 unsigned int sizebits = blksize_bits(size);
81 retval = (sz >> sizebits);
82 }
83 return retval;
84}
85
86/* Kill _all_ buffers and pagecache , dirty or not.. */ 73/* Kill _all_ buffers and pagecache , dirty or not.. */
87void kill_bdev(struct block_device *bdev) 74void kill_bdev(struct block_device *bdev)
88{ 75{
@@ -116,8 +103,6 @@ EXPORT_SYMBOL(invalidate_bdev);
116 103
117int set_blocksize(struct block_device *bdev, int size) 104int set_blocksize(struct block_device *bdev, int size)
118{ 105{
119 struct address_space *mapping;
120
121 /* Size must be a power of two, and between 512 and PAGE_SIZE */ 106 /* Size must be a power of two, and between 512 and PAGE_SIZE */
122 if (size > PAGE_SIZE || size < 512 || !is_power_of_2(size)) 107 if (size > PAGE_SIZE || size < 512 || !is_power_of_2(size))
123 return -EINVAL; 108 return -EINVAL;
@@ -126,19 +111,6 @@ int set_blocksize(struct block_device *bdev, int size)
126 if (size < bdev_logical_block_size(bdev)) 111 if (size < bdev_logical_block_size(bdev))
127 return -EINVAL; 112 return -EINVAL;
128 113
129 /* Prevent starting I/O or mapping the device */
130 percpu_down_write(&bdev->bd_block_size_semaphore);
131
132 /* Check that the block device is not memory mapped */
133 mapping = bdev->bd_inode->i_mapping;
134 mutex_lock(&mapping->i_mmap_mutex);
135 if (mapping_mapped(mapping)) {
136 mutex_unlock(&mapping->i_mmap_mutex);
137 percpu_up_write(&bdev->bd_block_size_semaphore);
138 return -EBUSY;
139 }
140 mutex_unlock(&mapping->i_mmap_mutex);
141
142 /* Don't change the size if it is same as current */ 114 /* Don't change the size if it is same as current */
143 if (bdev->bd_block_size != size) { 115 if (bdev->bd_block_size != size) {
144 sync_blockdev(bdev); 116 sync_blockdev(bdev);
@@ -146,9 +118,6 @@ int set_blocksize(struct block_device *bdev, int size)
146 bdev->bd_inode->i_blkbits = blksize_bits(size); 118 bdev->bd_inode->i_blkbits = blksize_bits(size);
147 kill_bdev(bdev); 119 kill_bdev(bdev);
148 } 120 }
149
150 percpu_up_write(&bdev->bd_block_size_semaphore);
151
152 return 0; 121 return 0;
153} 122}
154 123
@@ -181,52 +150,12 @@ static int
181blkdev_get_block(struct inode *inode, sector_t iblock, 150blkdev_get_block(struct inode *inode, sector_t iblock,
182 struct buffer_head *bh, int create) 151 struct buffer_head *bh, int create)
183{ 152{
184 if (iblock >= blkdev_max_block(I_BDEV(inode))) {
185 if (create)
186 return -EIO;
187
188 /*
189 * for reads, we're just trying to fill a partial page.
190 * return a hole, they will have to call get_block again
191 * before they can fill it, and they will get -EIO at that
192 * time
193 */
194 return 0;
195 }
196 bh->b_bdev = I_BDEV(inode); 153 bh->b_bdev = I_BDEV(inode);
197 bh->b_blocknr = iblock; 154 bh->b_blocknr = iblock;
198 set_buffer_mapped(bh); 155 set_buffer_mapped(bh);
199 return 0; 156 return 0;
200} 157}
201 158
202static int
203blkdev_get_blocks(struct inode *inode, sector_t iblock,
204 struct buffer_head *bh, int create)
205{
206 sector_t end_block = blkdev_max_block(I_BDEV(inode));
207 unsigned long max_blocks = bh->b_size >> inode->i_blkbits;
208
209 if ((iblock + max_blocks) > end_block) {
210 max_blocks = end_block - iblock;
211 if ((long)max_blocks <= 0) {
212 if (create)
213 return -EIO; /* write fully beyond EOF */
214 /*
215 * It is a read which is fully beyond EOF. We return
216 * a !buffer_mapped buffer
217 */
218 max_blocks = 0;
219 }
220 }
221
222 bh->b_bdev = I_BDEV(inode);
223 bh->b_blocknr = iblock;
224 bh->b_size = max_blocks << inode->i_blkbits;
225 if (max_blocks)
226 set_buffer_mapped(bh);
227 return 0;
228}
229
230static ssize_t 159static ssize_t
231blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, 160blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
232 loff_t offset, unsigned long nr_segs) 161 loff_t offset, unsigned long nr_segs)
@@ -235,7 +164,7 @@ blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
235 struct inode *inode = file->f_mapping->host; 164 struct inode *inode = file->f_mapping->host;
236 165
237 return __blockdev_direct_IO(rw, iocb, inode, I_BDEV(inode), iov, offset, 166 return __blockdev_direct_IO(rw, iocb, inode, I_BDEV(inode), iov, offset,
238 nr_segs, blkdev_get_blocks, NULL, NULL, 0); 167 nr_segs, blkdev_get_block, NULL, NULL, 0);
239} 168}
240 169
241int __sync_blockdev(struct block_device *bdev, int wait) 170int __sync_blockdev(struct block_device *bdev, int wait)
@@ -459,12 +388,6 @@ static struct inode *bdev_alloc_inode(struct super_block *sb)
459 struct bdev_inode *ei = kmem_cache_alloc(bdev_cachep, GFP_KERNEL); 388 struct bdev_inode *ei = kmem_cache_alloc(bdev_cachep, GFP_KERNEL);
460 if (!ei) 389 if (!ei)
461 return NULL; 390 return NULL;
462
463 if (unlikely(percpu_init_rwsem(&ei->bdev.bd_block_size_semaphore))) {
464 kmem_cache_free(bdev_cachep, ei);
465 return NULL;
466 }
467
468 return &ei->vfs_inode; 391 return &ei->vfs_inode;
469} 392}
470 393
@@ -473,8 +396,6 @@ static void bdev_i_callback(struct rcu_head *head)
473 struct inode *inode = container_of(head, struct inode, i_rcu); 396 struct inode *inode = container_of(head, struct inode, i_rcu);
474 struct bdev_inode *bdi = BDEV_I(inode); 397 struct bdev_inode *bdi = BDEV_I(inode);
475 398
476 percpu_free_rwsem(&bdi->bdev.bd_block_size_semaphore);
477
478 kmem_cache_free(bdev_cachep, bdi); 399 kmem_cache_free(bdev_cachep, bdi);
479} 400}
480 401
@@ -1593,22 +1514,6 @@ static long block_ioctl(struct file *file, unsigned cmd, unsigned long arg)
1593 return blkdev_ioctl(bdev, mode, cmd, arg); 1514 return blkdev_ioctl(bdev, mode, cmd, arg);
1594} 1515}
1595 1516
1596ssize_t blkdev_aio_read(struct kiocb *iocb, const struct iovec *iov,
1597 unsigned long nr_segs, loff_t pos)
1598{
1599 ssize_t ret;
1600 struct block_device *bdev = I_BDEV(iocb->ki_filp->f_mapping->host);
1601
1602 percpu_down_read(&bdev->bd_block_size_semaphore);
1603
1604 ret = generic_file_aio_read(iocb, iov, nr_segs, pos);
1605
1606 percpu_up_read(&bdev->bd_block_size_semaphore);
1607
1608 return ret;
1609}
1610EXPORT_SYMBOL_GPL(blkdev_aio_read);
1611
1612/* 1517/*
1613 * Write data to the block device. Only intended for the block device itself 1518 * Write data to the block device. Only intended for the block device itself
1614 * and the raw driver which basically is a fake block device. 1519 * and the raw driver which basically is a fake block device.
@@ -1620,16 +1525,12 @@ ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov,
1620 unsigned long nr_segs, loff_t pos) 1525 unsigned long nr_segs, loff_t pos)
1621{ 1526{
1622 struct file *file = iocb->ki_filp; 1527 struct file *file = iocb->ki_filp;
1623 struct block_device *bdev = I_BDEV(file->f_mapping->host);
1624 struct blk_plug plug; 1528 struct blk_plug plug;
1625 ssize_t ret; 1529 ssize_t ret;
1626 1530
1627 BUG_ON(iocb->ki_pos != pos); 1531 BUG_ON(iocb->ki_pos != pos);
1628 1532
1629 blk_start_plug(&plug); 1533 blk_start_plug(&plug);
1630
1631 percpu_down_read(&bdev->bd_block_size_semaphore);
1632
1633 ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos); 1534 ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos);
1634 if (ret > 0 || ret == -EIOCBQUEUED) { 1535 if (ret > 0 || ret == -EIOCBQUEUED) {
1635 ssize_t err; 1536 ssize_t err;
@@ -1638,62 +1539,27 @@ ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov,
1638 if (err < 0 && ret > 0) 1539 if (err < 0 && ret > 0)
1639 ret = err; 1540 ret = err;
1640 } 1541 }
1641
1642 percpu_up_read(&bdev->bd_block_size_semaphore);
1643
1644 blk_finish_plug(&plug); 1542 blk_finish_plug(&plug);
1645
1646 return ret; 1543 return ret;
1647} 1544}
1648EXPORT_SYMBOL_GPL(blkdev_aio_write); 1545EXPORT_SYMBOL_GPL(blkdev_aio_write);
1649 1546
1650static int blkdev_mmap(struct file *file, struct vm_area_struct *vma) 1547static ssize_t blkdev_aio_read(struct kiocb *iocb, const struct iovec *iov,
1651{ 1548 unsigned long nr_segs, loff_t pos)
1652 int ret;
1653 struct block_device *bdev = I_BDEV(file->f_mapping->host);
1654
1655 percpu_down_read(&bdev->bd_block_size_semaphore);
1656
1657 ret = generic_file_mmap(file, vma);
1658
1659 percpu_up_read(&bdev->bd_block_size_semaphore);
1660
1661 return ret;
1662}
1663
1664static ssize_t blkdev_splice_read(struct file *file, loff_t *ppos,
1665 struct pipe_inode_info *pipe, size_t len,
1666 unsigned int flags)
1667{
1668 ssize_t ret;
1669 struct block_device *bdev = I_BDEV(file->f_mapping->host);
1670
1671 percpu_down_read(&bdev->bd_block_size_semaphore);
1672
1673 ret = generic_file_splice_read(file, ppos, pipe, len, flags);
1674
1675 percpu_up_read(&bdev->bd_block_size_semaphore);
1676
1677 return ret;
1678}
1679
1680static ssize_t blkdev_splice_write(struct pipe_inode_info *pipe,
1681 struct file *file, loff_t *ppos, size_t len,
1682 unsigned int flags)
1683{ 1549{
1684 ssize_t ret; 1550 struct file *file = iocb->ki_filp;
1685 struct block_device *bdev = I_BDEV(file->f_mapping->host); 1551 struct inode *bd_inode = file->f_mapping->host;
1686 1552 loff_t size = i_size_read(bd_inode);
1687 percpu_down_read(&bdev->bd_block_size_semaphore);
1688
1689 ret = generic_file_splice_write(pipe, file, ppos, len, flags);
1690 1553
1691 percpu_up_read(&bdev->bd_block_size_semaphore); 1554 if (pos >= size)
1555 return 0;
1692 1556
1693 return ret; 1557 size -= pos;
1558 if (size < INT_MAX)
1559 nr_segs = iov_shorten((struct iovec *)iov, nr_segs, size);
1560 return generic_file_aio_read(iocb, iov, nr_segs, pos);
1694} 1561}
1695 1562
1696
1697/* 1563/*
1698 * Try to release a page associated with block device when the system 1564 * Try to release a page associated with block device when the system
1699 * is under memory pressure. 1565 * is under memory pressure.
@@ -1724,16 +1590,16 @@ const struct file_operations def_blk_fops = {
1724 .llseek = block_llseek, 1590 .llseek = block_llseek,
1725 .read = do_sync_read, 1591 .read = do_sync_read,
1726 .write = do_sync_write, 1592 .write = do_sync_write,
1727 .aio_read = blkdev_aio_read, 1593 .aio_read = blkdev_aio_read,
1728 .aio_write = blkdev_aio_write, 1594 .aio_write = blkdev_aio_write,
1729 .mmap = blkdev_mmap, 1595 .mmap = generic_file_mmap,
1730 .fsync = blkdev_fsync, 1596 .fsync = blkdev_fsync,
1731 .unlocked_ioctl = block_ioctl, 1597 .unlocked_ioctl = block_ioctl,
1732#ifdef CONFIG_COMPAT 1598#ifdef CONFIG_COMPAT
1733 .compat_ioctl = compat_blkdev_ioctl, 1599 .compat_ioctl = compat_blkdev_ioctl,
1734#endif 1600#endif
1735 .splice_read = blkdev_splice_read, 1601 .splice_read = generic_file_splice_read,
1736 .splice_write = blkdev_splice_write, 1602 .splice_write = generic_file_splice_write,
1737}; 1603};
1738 1604
1739int ioctl_by_bdev(struct block_device *bdev, unsigned cmd, unsigned long arg) 1605int ioctl_by_bdev(struct block_device *bdev, unsigned cmd, unsigned long arg)