diff options
| -rw-r--r-- | drivers/block/loop.c | 13 | ||||
| -rw-r--r-- | drivers/block/loop.h | 1 | 
2 files changed, 14 insertions, 0 deletions
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 85de67334695..fd4eff5f5b76 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -476,6 +476,8 @@ static void lo_rw_aio_complete(struct kiocb *iocb, long ret, long ret2)  {  	struct loop_cmd *cmd = container_of(iocb, struct loop_cmd, iocb); +	if (cmd->css) +		css_put(cmd->css);  	cmd->ret = ret;  	lo_rw_aio_do_completion(cmd);  } @@ -535,6 +537,8 @@ static int lo_rw_aio(struct loop_device *lo, struct loop_cmd *cmd,  	cmd->iocb.ki_filp = file;  	cmd->iocb.ki_complete = lo_rw_aio_complete;  	cmd->iocb.ki_flags = IOCB_DIRECT; +	if (cmd->css) +		kthread_associate_blkcg(cmd->css);  	if (rw == WRITE)  		ret = call_write_iter(file, &cmd->iocb, &iter); @@ -542,6 +546,7 @@ static int lo_rw_aio(struct loop_device *lo, struct loop_cmd *cmd,  		ret = call_read_iter(file, &cmd->iocb, &iter);  	lo_rw_aio_do_completion(cmd); +	kthread_associate_blkcg(NULL);  	if (ret != -EIOCBQUEUED)  		cmd->iocb.ki_complete(&cmd->iocb, ret, 0); @@ -1686,6 +1691,14 @@ static blk_status_t loop_queue_rq(struct blk_mq_hw_ctx *hctx,  		break;  	} +	/* always use the first bio's css */ +#ifdef CONFIG_CGROUPS +	if (cmd->use_aio && cmd->rq->bio && cmd->rq->bio->bi_css) { +		cmd->css = cmd->rq->bio->bi_css; +		css_get(cmd->css); +	} else +#endif +		cmd->css = NULL;  	kthread_queue_work(&lo->worker, &cmd->work);  	return BLK_STS_OK; diff --git a/drivers/block/loop.h b/drivers/block/loop.h index 1f3956702993..0f45416e4fcf 100644 --- a/drivers/block/loop.h +++ b/drivers/block/loop.h @@ -72,6 +72,7 @@ struct loop_cmd {  	long ret;  	struct kiocb iocb;  	struct bio_vec *bvec; +	struct cgroup_subsys_state *css;  };  /* Support for loadable transfer modules */  | 
