"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "fs/block_dev.c" between
linux-5.3-rc3.tar.gz and linux-5.3-rc4.tar.gz

About: The full source of the development Linux kernel 5.3 (release candidate).

block_dev.c  (linux-5.3-rc3):block_dev.c  (linux-5.3-rc4)
skipping to change at line 352 skipping to change at line 352
struct block_device *bdev = I_BDEV(inode); struct block_device *bdev = I_BDEV(inode);
struct blk_plug plug; struct blk_plug plug;
struct blkdev_dio *dio; struct blkdev_dio *dio;
struct bio *bio; struct bio *bio;
bool is_poll = (iocb->ki_flags & IOCB_HIPRI) != 0; bool is_poll = (iocb->ki_flags & IOCB_HIPRI) != 0;
bool is_read = (iov_iter_rw(iter) == READ), is_sync; bool is_read = (iov_iter_rw(iter) == READ), is_sync;
bool nowait = (iocb->ki_flags & IOCB_NOWAIT) != 0; bool nowait = (iocb->ki_flags & IOCB_NOWAIT) != 0;
loff_t pos = iocb->ki_pos; loff_t pos = iocb->ki_pos;
blk_qc_t qc = BLK_QC_T_NONE; blk_qc_t qc = BLK_QC_T_NONE;
gfp_t gfp; gfp_t gfp;
ssize_t ret; int ret;
if ((pos | iov_iter_alignment(iter)) & if ((pos | iov_iter_alignment(iter)) &
(bdev_logical_block_size(bdev) - 1)) (bdev_logical_block_size(bdev) - 1))
return -EINVAL; return -EINVAL;
if (nowait) if (nowait)
gfp = GFP_NOWAIT; gfp = GFP_NOWAIT;
else else
gfp = GFP_KERNEL; gfp = GFP_KERNEL;
skipping to change at line 389 skipping to change at line 389
/* /*
* Don't plug for HIPRI/polled IO, as those should go straight * Don't plug for HIPRI/polled IO, as those should go straight
* to issue * to issue
*/ */
if (!is_poll) if (!is_poll)
blk_start_plug(&plug); blk_start_plug(&plug);
ret = 0; ret = 0;
for (;;) { for (;;) {
int err;
bio_set_dev(bio, bdev); bio_set_dev(bio, bdev);
bio->bi_iter.bi_sector = pos >> 9; bio->bi_iter.bi_sector = pos >> 9;
bio->bi_write_hint = iocb->ki_hint; bio->bi_write_hint = iocb->ki_hint;
bio->bi_private = dio; bio->bi_private = dio;
bio->bi_end_io = blkdev_bio_end_io; bio->bi_end_io = blkdev_bio_end_io;
bio->bi_ioprio = iocb->ki_ioprio; bio->bi_ioprio = iocb->ki_ioprio;
err = bio_iov_iter_get_pages(bio, iter); ret = bio_iov_iter_get_pages(bio, iter);
if (unlikely(err)) { if (unlikely(ret)) {
if (!ret)
ret = err;
bio->bi_status = BLK_STS_IOERR; bio->bi_status = BLK_STS_IOERR;
bio_endio(bio); bio_endio(bio);
break; break;
} }
if (is_read) { if (is_read) {
bio->bi_opf = REQ_OP_READ; bio->bi_opf = REQ_OP_READ;
if (dio->should_dirty) if (dio->should_dirty)
bio_set_pages_dirty(bio); bio_set_pages_dirty(bio);
} else { } else {
skipping to change at line 424 skipping to change at line 420
} }
/* /*
* Tell underlying layer to not block for resource shortage. * Tell underlying layer to not block for resource shortage.
* And if we would have blocked, return error inline instead * And if we would have blocked, return error inline instead
* of through the bio->bi_end_io() callback. * of through the bio->bi_end_io() callback.
*/ */
if (nowait) if (nowait)
bio->bi_opf |= (REQ_NOWAIT | REQ_NOWAIT_INLINE); bio->bi_opf |= (REQ_NOWAIT | REQ_NOWAIT_INLINE);
dio->size += bio->bi_iter.bi_size;
pos += bio->bi_iter.bi_size; pos += bio->bi_iter.bi_size;
nr_pages = iov_iter_npages(iter, BIO_MAX_PAGES); nr_pages = iov_iter_npages(iter, BIO_MAX_PAGES);
if (!nr_pages) { if (!nr_pages) {
bool polled = false; bool polled = false;
if (iocb->ki_flags & IOCB_HIPRI) { if (iocb->ki_flags & IOCB_HIPRI) {
bio_set_polled(bio, iocb); bio_set_polled(bio, iocb);
polled = true; polled = true;
} }
dio->size += bio->bi_iter.bi_size;
qc = submit_bio(bio); qc = submit_bio(bio);
if (qc == BLK_QC_T_EAGAIN) { if (qc == BLK_QC_T_EAGAIN) {
if (!ret) dio->size -= bio->bi_iter.bi_size;
ret = -EAGAIN; ret = -EAGAIN;
goto error; goto error;
} }
ret = dio->size;
if (polled) if (polled)
WRITE_ONCE(iocb->ki_cookie, qc); WRITE_ONCE(iocb->ki_cookie, qc);
break; break;
} }
if (!dio->multi_bio) { if (!dio->multi_bio) {
/* /*
* AIO needs an extra reference to ensure the dio * AIO needs an extra reference to ensure the dio
* structure which is embedded into the first bio * structure which is embedded into the first bio
* stays around. * stays around.
*/ */
if (!is_sync) if (!is_sync)
bio_get(bio); bio_get(bio);
dio->multi_bio = true; dio->multi_bio = true;
atomic_set(&dio->ref, 2); atomic_set(&dio->ref, 2);
} else { } else {
atomic_inc(&dio->ref); atomic_inc(&dio->ref);
} }
dio->size += bio->bi_iter.bi_size;
qc = submit_bio(bio); qc = submit_bio(bio);
if (qc == BLK_QC_T_EAGAIN) { if (qc == BLK_QC_T_EAGAIN) {
if (!ret) dio->size -= bio->bi_iter.bi_size;
ret = -EAGAIN; ret = -EAGAIN;
goto error; goto error;
} }
ret = dio->size;
bio = bio_alloc(gfp, nr_pages); bio = bio_alloc(gfp, nr_pages);
if (!bio) { if (!bio) {
if (!ret) ret = -EAGAIN;
ret = -EAGAIN;
goto error; goto error;
} }
} }
if (!is_poll) if (!is_poll)
blk_finish_plug(&plug); blk_finish_plug(&plug);
if (!is_sync) if (!is_sync)
return -EIOCBQUEUED; return -EIOCBQUEUED;
skipping to change at line 499 skipping to change at line 493
if (!(iocb->ki_flags & IOCB_HIPRI) || if (!(iocb->ki_flags & IOCB_HIPRI) ||
!blk_poll(bdev_get_queue(bdev), qc, true)) !blk_poll(bdev_get_queue(bdev), qc, true))
io_schedule(); io_schedule();
} }
__set_current_state(TASK_RUNNING); __set_current_state(TASK_RUNNING);
out: out:
if (!ret) if (!ret)
ret = blk_status_to_errno(dio->bio.bi_status); ret = blk_status_to_errno(dio->bio.bi_status);
if (likely(!ret))
ret = dio->size;
bio_put(&dio->bio); bio_put(&dio->bio);
return ret; return ret;
error: error:
if (!is_poll) if (!is_poll)
blk_finish_plug(&plug); blk_finish_plug(&plug);
goto out; goto out;
} }
static ssize_t static ssize_t
skipping to change at line 1757 skipping to change at line 1753
} }
} }
res = __blkdev_get(bdev, mode, 0); res = __blkdev_get(bdev, mode, 0);
if (whole) { if (whole) {
struct gendisk *disk = whole->bd_disk; struct gendisk *disk = whole->bd_disk;
/* finish claiming */ /* finish claiming */
mutex_lock(&bdev->bd_mutex); mutex_lock(&bdev->bd_mutex);
bd_finish_claiming(bdev, whole, holder); if (!res)
bd_finish_claiming(bdev, whole, holder);
else
bd_abort_claiming(bdev, whole, holder);
/* /*
* Block event polling for write claims if requested. Any * Block event polling for write claims if requested. Any
* write holder makes the write_holder state stick until * write holder makes the write_holder state stick until
* all are released. This is good enough and tracking * all are released. This is good enough and tracking
* individual writeable reference is too fragile given the * individual writeable reference is too fragile given the
* way @mode is used in blkdev_get/put(). * way @mode is used in blkdev_get/put().
*/ */
if (!res && (mode & FMODE_WRITE) && !bdev->bd_write_holder && if (!res && (mode & FMODE_WRITE) && !bdev->bd_write_holder &&
(disk->flags & GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE)) { (disk->flags & GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE)) {
bdev->bd_write_holder = true; bdev->bd_write_holder = true;
 End of changes. 13 change blocks. 
17 lines changed or deleted 16 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)