Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma
[linux-2.6-microblaze.git] / fs / block_dev.c
index 3b8963e..4aa1f88 100644 (file)
@@ -126,11 +126,18 @@ int truncate_bdev_range(struct block_device *bdev, fmode_t mode,
                bd_abort_claiming(bdev, truncate_bdev_range);
        return 0;
 }
-EXPORT_SYMBOL(truncate_bdev_range);
 
 static void set_init_blocksize(struct block_device *bdev)
 {
-       bdev->bd_inode->i_blkbits = blksize_bits(bdev_logical_block_size(bdev));
+       unsigned int bsize = bdev_logical_block_size(bdev);
+       loff_t size = i_size_read(bdev->bd_inode);
+
+       while (bsize < PAGE_SIZE) {
+               if (size & bsize)
+                       break;
+               bsize <<= 1;
+       }
+       bdev->bd_inode->i_blkbits = blksize_bits(bsize);
 }
 
 int set_blocksize(struct block_device *bdev, int size)
@@ -214,7 +221,7 @@ static void blkdev_bio_end_io_simple(struct bio *bio)
 
 static ssize_t
 __blkdev_direct_IO_simple(struct kiocb *iocb, struct iov_iter *iter,
-               int nr_pages)
+               unsigned int nr_pages)
 {
        struct file *file = iocb->ki_filp;
        struct block_device *bdev = I_BDEV(bdev_file_inode(file));
@@ -348,8 +355,8 @@ static void blkdev_bio_end_io(struct bio *bio)
        }
 }
 
-static ssize_t
-__blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter, int nr_pages)
+static ssize_t __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter,
+               unsigned int nr_pages)
 {
        struct file *file = iocb->ki_filp;
        struct inode *inode = bdev_file_inode(file);
@@ -416,7 +423,7 @@ __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter, int nr_pages)
                dio->size += bio->bi_iter.bi_size;
                pos += bio->bi_iter.bi_size;
 
-               nr_pages = iov_iter_npages(iter, BIO_MAX_PAGES);
+               nr_pages = bio_iov_vecs_to_alloc(iter, BIO_MAX_PAGES);
                if (!nr_pages) {
                        bool polled = false;
 
@@ -479,15 +486,16 @@ __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter, int nr_pages)
 static ssize_t
 blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
 {
-       int nr_pages;
+       unsigned int nr_pages;
 
-       nr_pages = iov_iter_npages(iter, BIO_MAX_PAGES + 1);
-       if (!nr_pages)
+       if (!iov_iter_count(iter))
                return 0;
+
+       nr_pages = bio_iov_vecs_to_alloc(iter, BIO_MAX_PAGES + 1);
        if (is_sync_kiocb(iocb) && nr_pages <= BIO_MAX_PAGES)
                return __blkdev_direct_IO_simple(iocb, iter, nr_pages);
 
-       return __blkdev_direct_IO(iocb, iter, min(nr_pages, BIO_MAX_PAGES));
+       return __blkdev_direct_IO(iocb, iter, bio_max_segs(nr_pages));
 }
 
 static __init int blkdev_init(void)
@@ -680,7 +688,7 @@ int blkdev_fsync(struct file *filp, loff_t start, loff_t end, int datasync)
         * i_mutex and doing so causes performance issues with concurrent
         * O_SYNC writers to a block device.
         */
-       error = blkdev_issue_flush(bdev, GFP_KERNEL);
+       error = blkdev_issue_flush(bdev);
        if (error == -EOPNOTSUPP)
                error = 0;
 
@@ -1262,7 +1270,7 @@ rescan:
        return ret;
 }
 /*
- * Only exported for for loop and dasd for historic reasons.  Don't use in new
+ * Only exported for loop and dasd for historic reasons.  Don't use in new
  * code!
  */
 EXPORT_SYMBOL_GPL(bdev_disk_changed);
@@ -1800,13 +1808,11 @@ static long blkdev_fallocate(struct file *file, int mode, loff_t start,
                return error;
 
        /*
-        * Invalidate again; if someone wandered in and dirtied a page,
-        * the caller will be given -EBUSY.  The third argument is
-        * inclusive, so the rounding here is safe.
+        * Invalidate the page cache again; if someone wandered in and dirtied
+        * a page, we just discard it - userspace has no way of knowing whether
+        * the write happened before or after discard completing...
         */
-       return invalidate_inode_pages2_range(bdev->bd_inode->i_mapping,
-                                            start >> PAGE_SHIFT,
-                                            end >> PAGE_SHIFT);
+       return truncate_bdev_range(bdev, file->f_mode, start, end);
 }
 
 const struct file_operations def_blk_fops = {