Merge tag 'libata-5.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/dlemoal...
[linux-2.6-microblaze.git] / block / bdev.c
index 485a258..b4dab2f 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/major.h>
 #include <linux/device_cgroup.h>
 #include <linux/blkdev.h>
+#include <linux/blk-integrity.h>
 #include <linux/backing-dev.h>
 #include <linux/module.h>
 #include <linux/blkpg.h>
@@ -184,14 +185,13 @@ int sb_min_blocksize(struct super_block *sb, int size)
 
 EXPORT_SYMBOL(sb_min_blocksize);
 
-int __sync_blockdev(struct block_device *bdev, int wait)
+int sync_blockdev_nowait(struct block_device *bdev)
 {
        if (!bdev)
                return 0;
-       if (!wait)
-               return filemap_flush(bdev->bd_inode->i_mapping);
-       return filemap_write_and_wait(bdev->bd_inode->i_mapping);
+       return filemap_flush(bdev->bd_inode->i_mapping);
 }
+EXPORT_SYMBOL_GPL(sync_blockdev_nowait);
 
 /*
  * Write out and wait upon all the dirty data associated with a block
@@ -199,7 +199,9 @@ int __sync_blockdev(struct block_device *bdev, int wait)
  */
 int sync_blockdev(struct block_device *bdev)
 {
-       return __sync_blockdev(bdev, 1);
+       if (!bdev)
+               return 0;
+       return filemap_write_and_wait(bdev->bd_inode->i_mapping);
 }
 EXPORT_SYMBOL(sync_blockdev);
 
@@ -326,12 +328,12 @@ int bdev_read_page(struct block_device *bdev, sector_t sector,
        if (!ops->rw_page || bdev_get_integrity(bdev))
                return result;
 
-       result = blk_queue_enter(bdev->bd_disk->queue, 0);
+       result = blk_queue_enter(bdev_get_queue(bdev), 0);
        if (result)
                return result;
        result = ops->rw_page(bdev, sector + get_start_sect(bdev), page,
                              REQ_OP_READ);
-       blk_queue_exit(bdev->bd_disk->queue);
+       blk_queue_exit(bdev_get_queue(bdev));
        return result;
 }
 
@@ -362,7 +364,7 @@ int bdev_write_page(struct block_device *bdev, sector_t sector,
 
        if (!ops->rw_page || bdev_get_integrity(bdev))
                return -EOPNOTSUPP;
-       result = blk_queue_enter(bdev->bd_disk->queue, 0);
+       result = blk_queue_enter(bdev_get_queue(bdev), 0);
        if (result)
                return result;
 
@@ -375,7 +377,7 @@ int bdev_write_page(struct block_device *bdev, sector_t sector,
                clean_page_buffers(page);
                unlock_page(page);
        }
-       blk_queue_exit(bdev->bd_disk->queue);
+       blk_queue_exit(bdev_get_queue(bdev));
        return result;
 }
 
@@ -492,6 +494,7 @@ struct block_device *bdev_alloc(struct gendisk *disk, u8 partno)
        spin_lock_init(&bdev->bd_size_lock);
        bdev->bd_partno = partno;
        bdev->bd_inode = inode;
+       bdev->bd_queue = disk->queue;
        bdev->bd_stats = alloc_percpu(struct disk_stats);
        if (!bdev->bd_stats) {
                iput(inode);
@@ -962,9 +965,11 @@ EXPORT_SYMBOL(blkdev_put);
  * @pathname:  special file representing the block device
  * @dev:       return value of the block device's dev_t
  *
- * Get a reference to the blockdevice at @pathname in the current
- * namespace if possible and return it.  Return ERR_PTR(error)
- * otherwise.
+ * Lookup the block device's dev_t at @pathname in the current
+ * namespace if possible and return it by @dev.
+ *
+ * RETURNS:
+ * 0 if succeeded, errno otherwise.
  */
 int lookup_bdev(const char *pathname, dev_t *dev)
 {
@@ -1016,7 +1021,7 @@ int __invalidate_device(struct block_device *bdev, bool kill_dirty)
 }
 EXPORT_SYMBOL(__invalidate_device);
 
-void iterate_bdevs(void (*func)(struct block_device *, void *), void *arg)
+void sync_bdevs(bool wait)
 {
        struct inode *inode, *old_inode = NULL;
 
@@ -1047,8 +1052,19 @@ void iterate_bdevs(void (*func)(struct block_device *, void *), void *arg)
                bdev = I_BDEV(inode);
 
                mutex_lock(&bdev->bd_disk->open_mutex);
-               if (bdev->bd_openers)
-                       func(bdev, arg);
+               if (!bdev->bd_openers) {
+                       ; /* skip */
+               } else if (wait) {
+                       /*
+                        * We keep the error status of individual mapping so
+                        * that applications can catch the writeback error using
+                        * fsync(2). See filemap_fdatawait_keep_errors() for
+                        * details.
+                        */
+                       filemap_fdatawait_keep_errors(inode->i_mapping);
+               } else {
+                       filemap_fdatawrite(inode->i_mapping);
+               }
                mutex_unlock(&bdev->bd_disk->open_mutex);
 
                spin_lock(&blockdev_superblock->s_inode_list_lock);