diff options
Diffstat (limited to 'fs/block_dev.c')
-rw-r--r-- | fs/block_dev.c | 27 |
1 files changed, 17 insertions, 10 deletions
diff --git a/fs/block_dev.c b/fs/block_dev.c index cdfb625824e2..7eeb0635338b 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -127,7 +127,7 @@ int set_blocksize(struct block_device *bdev, int size) | |||
127 | return -EINVAL; | 127 | return -EINVAL; |
128 | 128 | ||
129 | /* Prevent starting I/O or mapping the device */ | 129 | /* Prevent starting I/O or mapping the device */ |
130 | down_write(&bdev->bd_block_size_semaphore); | 130 | percpu_down_write(&bdev->bd_block_size_semaphore); |
131 | 131 | ||
132 | /* Check that the block device is not memory mapped */ | 132 | /* Check that the block device is not memory mapped */ |
133 | mapping = bdev->bd_inode->i_mapping; | 133 | mapping = bdev->bd_inode->i_mapping; |
@@ -135,7 +135,7 @@ int set_blocksize(struct block_device *bdev, int size) | |||
135 | if (!prio_tree_empty(&mapping->i_mmap) || | 135 | if (!prio_tree_empty(&mapping->i_mmap) || |
136 | !list_empty(&mapping->i_mmap_nonlinear)) { | 136 | !list_empty(&mapping->i_mmap_nonlinear)) { |
137 | mutex_unlock(&mapping->i_mmap_mutex); | 137 | mutex_unlock(&mapping->i_mmap_mutex); |
138 | up_write(&bdev->bd_block_size_semaphore); | 138 | percpu_up_write(&bdev->bd_block_size_semaphore); |
139 | return -EBUSY; | 139 | return -EBUSY; |
140 | } | 140 | } |
141 | mutex_unlock(&mapping->i_mmap_mutex); | 141 | mutex_unlock(&mapping->i_mmap_mutex); |
@@ -148,7 +148,7 @@ int set_blocksize(struct block_device *bdev, int size) | |||
148 | kill_bdev(bdev); | 148 | kill_bdev(bdev); |
149 | } | 149 | } |
150 | 150 | ||
151 | up_write(&bdev->bd_block_size_semaphore); | 151 | percpu_up_write(&bdev->bd_block_size_semaphore); |
152 | 152 | ||
153 | return 0; | 153 | return 0; |
154 | } | 154 | } |
@@ -460,6 +460,12 @@ static struct inode *bdev_alloc_inode(struct super_block *sb) | |||
460 | struct bdev_inode *ei = kmem_cache_alloc(bdev_cachep, GFP_KERNEL); | 460 | struct bdev_inode *ei = kmem_cache_alloc(bdev_cachep, GFP_KERNEL); |
461 | if (!ei) | 461 | if (!ei) |
462 | return NULL; | 462 | return NULL; |
463 | |||
464 | if (unlikely(percpu_init_rwsem(&ei->bdev.bd_block_size_semaphore))) { | ||
465 | kmem_cache_free(bdev_cachep, ei); | ||
466 | return NULL; | ||
467 | } | ||
468 | |||
463 | return &ei->vfs_inode; | 469 | return &ei->vfs_inode; |
464 | } | 470 | } |
465 | 471 | ||
@@ -468,6 +474,8 @@ static void bdev_i_callback(struct rcu_head *head) | |||
468 | struct inode *inode = container_of(head, struct inode, i_rcu); | 474 | struct inode *inode = container_of(head, struct inode, i_rcu); |
469 | struct bdev_inode *bdi = BDEV_I(inode); | 475 | struct bdev_inode *bdi = BDEV_I(inode); |
470 | 476 | ||
477 | percpu_free_rwsem(&bdi->bdev.bd_block_size_semaphore); | ||
478 | |||
471 | kmem_cache_free(bdev_cachep, bdi); | 479 | kmem_cache_free(bdev_cachep, bdi); |
472 | } | 480 | } |
473 | 481 | ||
@@ -491,7 +499,6 @@ static void init_once(void *foo) | |||
491 | inode_init_once(&ei->vfs_inode); | 499 | inode_init_once(&ei->vfs_inode); |
492 | /* Initialize mutex for freeze. */ | 500 | /* Initialize mutex for freeze. */ |
493 | mutex_init(&bdev->bd_fsfreeze_mutex); | 501 | mutex_init(&bdev->bd_fsfreeze_mutex); |
494 | init_rwsem(&bdev->bd_block_size_semaphore); | ||
495 | } | 502 | } |
496 | 503 | ||
497 | static inline void __bd_forget(struct inode *inode) | 504 | static inline void __bd_forget(struct inode *inode) |
@@ -1593,11 +1600,11 @@ ssize_t blkdev_aio_read(struct kiocb *iocb, const struct iovec *iov, | |||
1593 | ssize_t ret; | 1600 | ssize_t ret; |
1594 | struct block_device *bdev = I_BDEV(iocb->ki_filp->f_mapping->host); | 1601 | struct block_device *bdev = I_BDEV(iocb->ki_filp->f_mapping->host); |
1595 | 1602 | ||
1596 | down_read(&bdev->bd_block_size_semaphore); | 1603 | percpu_down_read(&bdev->bd_block_size_semaphore); |
1597 | 1604 | ||
1598 | ret = generic_file_aio_read(iocb, iov, nr_segs, pos); | 1605 | ret = generic_file_aio_read(iocb, iov, nr_segs, pos); |
1599 | 1606 | ||
1600 | up_read(&bdev->bd_block_size_semaphore); | 1607 | percpu_up_read(&bdev->bd_block_size_semaphore); |
1601 | 1608 | ||
1602 | return ret; | 1609 | return ret; |
1603 | } | 1610 | } |
@@ -1622,7 +1629,7 @@ ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
1622 | 1629 | ||
1623 | blk_start_plug(&plug); | 1630 | blk_start_plug(&plug); |
1624 | 1631 | ||
1625 | down_read(&bdev->bd_block_size_semaphore); | 1632 | percpu_down_read(&bdev->bd_block_size_semaphore); |
1626 | 1633 | ||
1627 | ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos); | 1634 | ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos); |
1628 | if (ret > 0 || ret == -EIOCBQUEUED) { | 1635 | if (ret > 0 || ret == -EIOCBQUEUED) { |
@@ -1633,7 +1640,7 @@ ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
1633 | ret = err; | 1640 | ret = err; |
1634 | } | 1641 | } |
1635 | 1642 | ||
1636 | up_read(&bdev->bd_block_size_semaphore); | 1643 | percpu_up_read(&bdev->bd_block_size_semaphore); |
1637 | 1644 | ||
1638 | blk_finish_plug(&plug); | 1645 | blk_finish_plug(&plug); |
1639 | 1646 | ||
@@ -1646,11 +1653,11 @@ int blkdev_mmap(struct file *file, struct vm_area_struct *vma) | |||
1646 | int ret; | 1653 | int ret; |
1647 | struct block_device *bdev = I_BDEV(file->f_mapping->host); | 1654 | struct block_device *bdev = I_BDEV(file->f_mapping->host); |
1648 | 1655 | ||
1649 | down_read(&bdev->bd_block_size_semaphore); | 1656 | percpu_down_read(&bdev->bd_block_size_semaphore); |
1650 | 1657 | ||
1651 | ret = generic_file_mmap(file, vma); | 1658 | ret = generic_file_mmap(file, vma); |
1652 | 1659 | ||
1653 | up_read(&bdev->bd_block_size_semaphore); | 1660 | percpu_up_read(&bdev->bd_block_size_semaphore); |
1654 | 1661 | ||
1655 | return ret; | 1662 | return ret; |
1656 | } | 1663 | } |