diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-11-29 13:49:50 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-11-29 13:52:19 -0500 |
commit | 1e8b33328a5407b447ff80953655a47014a6dcb9 (patch) | |
tree | cb5a5f90712bafe8fb64d3d221fc5213c53f681f | |
parent | 45bce8f3e3436bbe2e03dd2b076abdce79ffabb7 (diff) |
blockdev: remove bd_block_size_semaphore again
This reverts the block-device direct access code to the previous
unlocked code, now that fs/buffer.c no longer needs external locking.
With this, fs/block_dev.c is back to the original version, apart from a
whitespace cleanup that I didn't want to revert.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | drivers/char/raw.c | 2 | ||||
-rw-r--r-- | fs/block_dev.c | 105 | ||||
-rw-r--r-- | include/linux/fs.h | 4 |
3 files changed, 5 insertions, 106 deletions
diff --git a/drivers/char/raw.c b/drivers/char/raw.c index 0bb207eaef2f..54a3a6d09819 100644 --- a/drivers/char/raw.c +++ b/drivers/char/raw.c | |||
@@ -285,7 +285,7 @@ static long raw_ctl_compat_ioctl(struct file *file, unsigned int cmd, | |||
285 | 285 | ||
286 | static const struct file_operations raw_fops = { | 286 | static const struct file_operations raw_fops = { |
287 | .read = do_sync_read, | 287 | .read = do_sync_read, |
288 | .aio_read = blkdev_aio_read, | 288 | .aio_read = generic_file_aio_read, |
289 | .write = do_sync_write, | 289 | .write = do_sync_write, |
290 | .aio_write = blkdev_aio_write, | 290 | .aio_write = blkdev_aio_write, |
291 | .fsync = blkdev_fsync, | 291 | .fsync = blkdev_fsync, |
diff --git a/fs/block_dev.c b/fs/block_dev.c index 1a1e5e3b1eaf..47a949d8a07e 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -116,8 +116,6 @@ EXPORT_SYMBOL(invalidate_bdev); | |||
116 | 116 | ||
117 | int set_blocksize(struct block_device *bdev, int size) | 117 | int set_blocksize(struct block_device *bdev, int size) |
118 | { | 118 | { |
119 | struct address_space *mapping; | ||
120 | |||
121 | /* Size must be a power of two, and between 512 and PAGE_SIZE */ | 119 | /* 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)) | 120 | if (size > PAGE_SIZE || size < 512 || !is_power_of_2(size)) |
123 | return -EINVAL; | 121 | return -EINVAL; |
@@ -126,19 +124,6 @@ int set_blocksize(struct block_device *bdev, int size) | |||
126 | if (size < bdev_logical_block_size(bdev)) | 124 | if (size < bdev_logical_block_size(bdev)) |
127 | return -EINVAL; | 125 | return -EINVAL; |
128 | 126 | ||
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 */ | 127 | /* Don't change the size if it is same as current */ |
143 | if (bdev->bd_block_size != size) { | 128 | if (bdev->bd_block_size != size) { |
144 | sync_blockdev(bdev); | 129 | sync_blockdev(bdev); |
@@ -146,9 +131,6 @@ int set_blocksize(struct block_device *bdev, int size) | |||
146 | bdev->bd_inode->i_blkbits = blksize_bits(size); | 131 | bdev->bd_inode->i_blkbits = blksize_bits(size); |
147 | kill_bdev(bdev); | 132 | kill_bdev(bdev); |
148 | } | 133 | } |
149 | |||
150 | percpu_up_write(&bdev->bd_block_size_semaphore); | ||
151 | |||
152 | return 0; | 134 | return 0; |
153 | } | 135 | } |
154 | 136 | ||
@@ -459,12 +441,6 @@ static struct inode *bdev_alloc_inode(struct super_block *sb) | |||
459 | struct bdev_inode *ei = kmem_cache_alloc(bdev_cachep, GFP_KERNEL); | 441 | struct bdev_inode *ei = kmem_cache_alloc(bdev_cachep, GFP_KERNEL); |
460 | if (!ei) | 442 | if (!ei) |
461 | return NULL; | 443 | 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; | 444 | return &ei->vfs_inode; |
469 | } | 445 | } |
470 | 446 | ||
@@ -473,8 +449,6 @@ static void bdev_i_callback(struct rcu_head *head) | |||
473 | struct inode *inode = container_of(head, struct inode, i_rcu); | 449 | struct inode *inode = container_of(head, struct inode, i_rcu); |
474 | struct bdev_inode *bdi = BDEV_I(inode); | 450 | struct bdev_inode *bdi = BDEV_I(inode); |
475 | 451 | ||
476 | percpu_free_rwsem(&bdi->bdev.bd_block_size_semaphore); | ||
477 | |||
478 | kmem_cache_free(bdev_cachep, bdi); | 452 | kmem_cache_free(bdev_cachep, bdi); |
479 | } | 453 | } |
480 | 454 | ||
@@ -1593,22 +1567,6 @@ static long block_ioctl(struct file *file, unsigned cmd, unsigned long arg) | |||
1593 | return blkdev_ioctl(bdev, mode, cmd, arg); | 1567 | return blkdev_ioctl(bdev, mode, cmd, arg); |
1594 | } | 1568 | } |
1595 | 1569 | ||
1596 | ssize_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 | } | ||
1610 | EXPORT_SYMBOL_GPL(blkdev_aio_read); | ||
1611 | |||
1612 | /* | 1570 | /* |
1613 | * Write data to the block device. Only intended for the block device itself | 1571 | * 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. | 1572 | * and the raw driver which basically is a fake block device. |
@@ -1620,16 +1578,12 @@ ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
1620 | unsigned long nr_segs, loff_t pos) | 1578 | unsigned long nr_segs, loff_t pos) |
1621 | { | 1579 | { |
1622 | struct file *file = iocb->ki_filp; | 1580 | struct file *file = iocb->ki_filp; |
1623 | struct block_device *bdev = I_BDEV(file->f_mapping->host); | ||
1624 | struct blk_plug plug; | 1581 | struct blk_plug plug; |
1625 | ssize_t ret; | 1582 | ssize_t ret; |
1626 | 1583 | ||
1627 | BUG_ON(iocb->ki_pos != pos); | 1584 | BUG_ON(iocb->ki_pos != pos); |
1628 | 1585 | ||
1629 | blk_start_plug(&plug); | 1586 | 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); | 1587 | ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos); |
1634 | if (ret > 0 || ret == -EIOCBQUEUED) { | 1588 | if (ret > 0 || ret == -EIOCBQUEUED) { |
1635 | ssize_t err; | 1589 | ssize_t err; |
@@ -1638,62 +1592,11 @@ ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
1638 | if (err < 0 && ret > 0) | 1592 | if (err < 0 && ret > 0) |
1639 | ret = err; | 1593 | ret = err; |
1640 | } | 1594 | } |
1641 | |||
1642 | percpu_up_read(&bdev->bd_block_size_semaphore); | ||
1643 | |||
1644 | blk_finish_plug(&plug); | 1595 | blk_finish_plug(&plug); |
1645 | |||
1646 | return ret; | 1596 | return ret; |
1647 | } | 1597 | } |
1648 | EXPORT_SYMBOL_GPL(blkdev_aio_write); | 1598 | EXPORT_SYMBOL_GPL(blkdev_aio_write); |
1649 | 1599 | ||
1650 | static int blkdev_mmap(struct file *file, struct vm_area_struct *vma) | ||
1651 | { | ||
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 | |||
1664 | static 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 | |||
1680 | static 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 | { | ||
1684 | ssize_t ret; | ||
1685 | struct block_device *bdev = I_BDEV(file->f_mapping->host); | ||
1686 | |||
1687 | percpu_down_read(&bdev->bd_block_size_semaphore); | ||
1688 | |||
1689 | ret = generic_file_splice_write(pipe, file, ppos, len, flags); | ||
1690 | |||
1691 | percpu_up_read(&bdev->bd_block_size_semaphore); | ||
1692 | |||
1693 | return ret; | ||
1694 | } | ||
1695 | |||
1696 | |||
1697 | /* | 1600 | /* |
1698 | * Try to release a page associated with block device when the system | 1601 | * Try to release a page associated with block device when the system |
1699 | * is under memory pressure. | 1602 | * is under memory pressure. |
@@ -1724,16 +1627,16 @@ const struct file_operations def_blk_fops = { | |||
1724 | .llseek = block_llseek, | 1627 | .llseek = block_llseek, |
1725 | .read = do_sync_read, | 1628 | .read = do_sync_read, |
1726 | .write = do_sync_write, | 1629 | .write = do_sync_write, |
1727 | .aio_read = blkdev_aio_read, | 1630 | .aio_read = generic_file_aio_read, |
1728 | .aio_write = blkdev_aio_write, | 1631 | .aio_write = blkdev_aio_write, |
1729 | .mmap = blkdev_mmap, | 1632 | .mmap = generic_file_mmap, |
1730 | .fsync = blkdev_fsync, | 1633 | .fsync = blkdev_fsync, |
1731 | .unlocked_ioctl = block_ioctl, | 1634 | .unlocked_ioctl = block_ioctl, |
1732 | #ifdef CONFIG_COMPAT | 1635 | #ifdef CONFIG_COMPAT |
1733 | .compat_ioctl = compat_blkdev_ioctl, | 1636 | .compat_ioctl = compat_blkdev_ioctl, |
1734 | #endif | 1637 | #endif |
1735 | .splice_read = blkdev_splice_read, | 1638 | .splice_read = generic_file_splice_read, |
1736 | .splice_write = blkdev_splice_write, | 1639 | .splice_write = generic_file_splice_write, |
1737 | }; | 1640 | }; |
1738 | 1641 | ||
1739 | int ioctl_by_bdev(struct block_device *bdev, unsigned cmd, unsigned long arg) | 1642 | int ioctl_by_bdev(struct block_device *bdev, unsigned cmd, unsigned long arg) |
diff --git a/include/linux/fs.h b/include/linux/fs.h index b33cfc97b9ca..44f288e9726d 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -462,8 +462,6 @@ struct block_device { | |||
462 | int bd_fsfreeze_count; | 462 | int bd_fsfreeze_count; |
463 | /* Mutex for freeze */ | 463 | /* Mutex for freeze */ |
464 | struct mutex bd_fsfreeze_mutex; | 464 | struct mutex bd_fsfreeze_mutex; |
465 | /* A semaphore that prevents I/O while block size is being changed */ | ||
466 | struct percpu_rw_semaphore bd_block_size_semaphore; | ||
467 | }; | 465 | }; |
468 | 466 | ||
469 | /* | 467 | /* |
@@ -2379,8 +2377,6 @@ extern int generic_segment_checks(const struct iovec *iov, | |||
2379 | unsigned long *nr_segs, size_t *count, int access_flags); | 2377 | unsigned long *nr_segs, size_t *count, int access_flags); |
2380 | 2378 | ||
2381 | /* fs/block_dev.c */ | 2379 | /* fs/block_dev.c */ |
2382 | extern ssize_t blkdev_aio_read(struct kiocb *iocb, const struct iovec *iov, | ||
2383 | unsigned long nr_segs, loff_t pos); | ||
2384 | extern ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov, | 2380 | extern ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov, |
2385 | unsigned long nr_segs, loff_t pos); | 2381 | unsigned long nr_segs, loff_t pos); |
2386 | extern int blkdev_fsync(struct file *filp, loff_t start, loff_t end, | 2382 | extern int blkdev_fsync(struct file *filp, loff_t start, loff_t end, |