8000 Merge branch 'for-linus' of git://git.kernel.dk/linux-block · bsd-unix/linux@ac904ae · GitHub
[go: up one dir, main page]

Skip to content

Commit ac904ae

Browse files
committed
Merge branch 'for-linus' of git://git.kernel.dk/linux-block
Pull block IO fixes from Jens Axboe: "Three small fixes that have been queued up and tested for this series: - A bug fix for xen-blkfront from Bob Liu, fixing an issue with incomplete requests during migration. - A fix for an ancient issue in retrieving the IO priority of a different PID than self, preventing that task from going away while we access it. From Omar. - A writeback fix from Tahsin, fixing a case where we'd call ihold() with a zero ref count inode" * 'for-linus' of git://git.kernel.dk/linux-block: block: fix use-after-free in sys_ioprio_get() writeback: inode cgroup wb switch should not call ihold() xen-blkfront: save uncompleted reqs in blkfront_resume()
2 parents 4c2a849 + 8ba8682 commit ac904ae

File tree

3 files changed

+43
-52
lines changed

3 files changed

+43
-52
lines changed

block/ioprio.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,10 @@ static int get_task_ioprio(struct task_struct *p)
150150
if (ret)
151151
goto out;
152152
ret = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_NONE, IOPRIO_NORM);
153+
task_lock(p);
153154
if (p->io_context)
154155
ret = p->io_context->ioprio;
156+
task_unlock(p);
155157
out:
156158
return ret;
157159
}

drivers/block/xen-blkfront.c

Lines changed: 40 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,9 @@ struct blkfront_info
207207
struct blk_mq_tag_set tag_set;
208208
struct blkfront_ring_info *rinfo;
209209
unsigned int nr_rings;
210+
/* Save uncomplete reqs and bios for migration. */
211+
struct list_head requests;
212+
struct bio_list bio_list;
210213
};
211214

212215
static unsigned int nr_minors;
@@ -2002,69 +2005,22 @@ static int blkif_recover(struct blkfront_info *info)
20022005
{
20032006
unsigned int i, r_index;
20042007
struct request *req, *n;
2005-
struct blk_shadow *copy;
20062008
int rc;
20072009
struct bio *bio, *cloned_bio;
2008-
struct bio_list bio_list, merge_bio;
20092010
unsigned int segs, offset;
20102011
int pending, size;
20112012
struct split_bio *split_bio;
2012-
struct list_head requests;
20132013

20142014
blkfront_gather_backend_features(info);
20152015
segs = info->max_indirect_segments ? : BLKIF_MAX_SEGMENTS_PER_REQUEST;
20162016
blk_queue_max_segments(info->rq, segs);
2017-
bio_list_init(&bio_list);
2018-
INIT_LIST_HEAD(&requests);
20192017

20202018
for (r_index = 0; r_index < info->nr_rings; r_index++) {
2021-
struct blkfront_ring_info *rinfo;
2022-
2023-
rinfo = &info->rinfo[r_index];
2024-
/* Stage 1: Make a safe copy of the shadow state. */
2025-
copy = kmemdup(rinfo->shadow, sizeof(rinfo->shadow),
2026-
GFP_NOIO | __GFP_REPEAT | __GFP_HIGH);
2027-
if (!copy)
2028-
return -ENOMEM;
2029-
2030-
/* Stage 2: Set up free list. */
2031-
memset(&rinfo->shadow, 0, sizeof(rinfo->shadow));
2032-
for (i = 0; i < BLK_RING_SIZE(info); i++)
2033-
rinfo->shadow[i].req.u.rw.id = i+1;
2034-
rinfo->shadow_free = rinfo->ring.req_prod_pvt;
2035-
rinfo->shadow[BLK_RING_SIZE(info)-1].req.u.rw.id = 0x0fffffff;
2019+
struct blkfront_ring_info *rinfo = &info->rinfo[r_index];
20362020

20372021
rc = blkfront_setup_indirect(rinfo);
2038-
if (rc) {
2039-
kfree(copy);
2022+
if (rc)
20402023
return rc;
2041-
}
2042-
2043-
for (i = 0; i < BLK_RING_SIZE(info); i++) {
2044-
/* Not in use? */
2045-
if (!copy[i].request)
2046-
continue;
2047-
2048-
/*
2049-
* Get the bios in the request so we can re-queue them.
2050-
*/
2051-
if (copy[i].request->cmd_flags &
2052-
(REQ_FLUSH | REQ_FUA | REQ_DISCARD | REQ_SECURE)) {
2053-
/*
2054-
* Flush operations don't contain bios, so
2055-
* we need to requeue the whole request
2056-
*/
2057-
list_add(&copy[i].request->queuelist, &requests);
2058-
continue;
2059-
}
2060-
merge_bio.head = copy[i].request->bio;
2061-
merge_bio.tail = copy[i].request->biotail;
2062-
bio_list_merge(&bio_list, &merge_bio);
2063-
copy[i].request->bio = NULL;
2064-
blk_end_request_all(copy[i].request, 0);
2065-
}
2066-
2067-
kfree(copy);
20682024
}
20692025
xenbus_switch_state(info->xbdev, XenbusStateConnected);
20702026

@@ -2079,15 +2035,15 @@ static int blkif_recover(struct blkfront_info *info)
20792035
kick_pending_request_queues(rinfo);
20802036
}
20812037

2082-
list_for_each_entry_safe(req, n, &requests, queuelist) {
2038+
list_for_each_entry_safe(req, n, &info->requests, queuelist) {
20832039
/* Requeue pending requests (flush or discard) */
20842040
list_del_init(&req->queuelist);
20852041
BUG_ON(req->nr_phys_segments > segs);
20862042
blk_mq_requeue_request(req);
20872043
}
20882044
blk_mq_kick_requeue_list(info->rq);
20892045

2090-
while ((bio = bio_list_pop(&bio_list)) != NULL) {
2046+
while ((bio = bio_list_pop(&info->bio_list)) != NULL) {
20912047
/* Traverse the list of pending bios and re-queue them */
20922048
if (bio_segments(bio) > segs) {
20932049
/*
@@ -2133,9 +2089,42 @@ static int blkfront_resume(struct xenbus_device *dev)
21332089
{
21342090
struct blkfront_info *info = dev_get_drvdata(&dev->dev);
21352091
int err = 0;
2092+
unsigned int i, j;
21362093

21372094
dev_dbg(&dev->dev, "blkfront_resume: %s\n", dev->nodename);
21382095

2096+
bio_list_init(&info->bio_list);
2097+
INIT_LIST_HEAD(&info->requests);
2098+
for (i = 0; i < info->nr_rings; i++) {
2099+
struct blkfront_ring_info *rinfo = &info->rinfo[i];
2100+
struct bio_list merge_bio;
2101+
struct blk_shadow *shadow = rinfo->shadow;
2102+
2103+
for (j = 0; j < BLK_RING_SIZE(info); j++) {
2104+
/* Not in use? */
2105+
if (!shadow[j].request)
2106+
continue;
2107+
2108+
/*
2109+
* Get the bios in the request so we can re-queue them.
2110+
*/
2111 10072 +
if (shadow[j].request->cmd_flags &
2112+
(REQ_FLUSH | REQ_FUA | REQ_DISCARD | REQ_SECURE)) {
2113+
/*
2114+
* Flush operations don't contain bios, so
2115+
* we need to requeue the whole request
2116+
*/
2117+
list_add(&shadow[j].request->queuelist, &info->requests);
2118+
continue;
2119+
}
2120+
merge_bio.head = shadow[j].request->bio;
2121+
merge_bio.tail = shadow[j].request->biotail;
2122+
bio_list_merge(&info->bio_list, &merge_bio);
2123+
shadow[j].request->bio = NULL;
2124+
blk_mq_end_request(shadow[j].request, 0);
2125+
}
2126+
}
2127+
21392128
blkif_free(info, info->connected == BLKIF_STATE_CONNECTED);
21402129

21412130
err = negotiate_mq(info);

fs/fs-writeback.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -483,9 +483,9 @@ static void inode_switch_wbs(struct inode *inode, int new_wb_id)
483483
goto out_free;
484484
}
485485
inode->i_state |= I_WB_SWITCH;
486+
__iget(inode);
486487
spin_unlock(&inode->i_lock);
487488

488-
ihold(inode);
489489
isw->inode = inode;
490490

491491
atomic_inc(&isw_nr_in_flight);

0 commit comments

Comments
 (0)
0