Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 999646e3 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'for-linus' of git://git.kernel.dk/linux-2.6-block

* 'for-linus' of git://git.kernel.dk/linux-2.6-block:
  cfq-iosched: do not leak ioc_data across iosched switches
  splice: fix infinite loop in generic_file_splice_read()
parents 76b0c26a 4faa3c81
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -1214,6 +1214,8 @@ static void cfq_exit_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq)
static void __cfq_exit_single_io_context(struct cfq_data *cfqd,
					 struct cfq_io_context *cic)
{
	struct io_context *ioc = cic->ioc;

	list_del_init(&cic->queue_list);

	/*
@@ -1223,6 +1225,9 @@ static void __cfq_exit_single_io_context(struct cfq_data *cfqd,
	cic->dead_key = (unsigned long) cic->key;
	cic->key = NULL;

	if (ioc->ioc_data == cic)
		rcu_assign_pointer(ioc->ioc_data, NULL);

	if (cic->cfqq[ASYNC]) {
		cfq_exit_cfqq(cfqd, cic->cfqq[ASYNC]);
		cic->cfqq[ASYNC] = NULL;
@@ -1255,7 +1260,6 @@ static void cfq_exit_single_io_context(struct io_context *ioc,
 */
static void cfq_exit_io_context(struct io_context *ioc)
{
	rcu_assign_pointer(ioc->ioc_data, NULL);
	call_for_each_cic(ioc, cfq_exit_single_io_context);
}

@@ -1478,8 +1482,7 @@ cfq_drop_dead_cic(struct cfq_data *cfqd, struct io_context *ioc,

	spin_lock_irqsave(&ioc->lock, flags);

	if (ioc->ioc_data == cic)
		rcu_assign_pointer(ioc->ioc_data, NULL);
	BUG_ON(ioc->ioc_data == cic);

	radix_tree_delete(&ioc->radix_root, (unsigned long) cfqd);
	hlist_del_rcu(&cic->cic_list);
+6 −25
Original line number Diff line number Diff line
@@ -370,8 +370,10 @@ __generic_file_splice_read(struct file *in, loff_t *ppos,
			 * for an in-flight io page
			 */
			if (flags & SPLICE_F_NONBLOCK) {
				if (TestSetPageLocked(page))
				if (TestSetPageLocked(page)) {
					error = -EAGAIN;
					break;
				}
			} else
				lock_page(page);

@@ -479,9 +481,8 @@ ssize_t generic_file_splice_read(struct file *in, loff_t *ppos,
				 struct pipe_inode_info *pipe, size_t len,
				 unsigned int flags)
{
	ssize_t spliced;
	int ret;
	loff_t isize, left;
	int ret;

	isize = i_size_read(in->f_mapping->host);
	if (unlikely(*ppos >= isize))
@@ -491,29 +492,9 @@ ssize_t generic_file_splice_read(struct file *in, loff_t *ppos,
	if (unlikely(left < len))
		len = left;

	ret = 0;
	spliced = 0;
	while (len && !spliced) {
	ret = __generic_file_splice_read(in, ppos, pipe, len, flags);

		if (ret < 0)
			break;
		else if (!ret) {
			if (spliced)
				break;
			if (flags & SPLICE_F_NONBLOCK) {
				ret = -EAGAIN;
				break;
			}
		}

	if (ret > 0)
		*ppos += ret;
		len -= ret;
		spliced += ret;
	}

	if (spliced)
		return spliced;

	return ret;
}