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

Commit 1afe4785 authored by Yan, Zheng's avatar Yan, Zheng Committed by Ilya Dryomov
Browse files

ceph: fix error handling of start_read()



If start_page() fails to add a page to page cache or fails to send
OSD request. It should cal put_page() (instead of free_page()) for
relevant pages.

Besides, start_page() need to cancel fscache readpage if it fails
to send OSD request.

Signed-off-by: default avatarYan, Zheng <zyan@redhat.com>
Reported-by: default avatarZhi Zhang <zhang.david2011@gmail.com>
parent 0dcc685e
Loading
Loading
Loading
Loading
+9 −10
Original line number Diff line number Diff line
@@ -298,14 +298,6 @@ static void finish_read(struct ceph_osd_request *req)
	kfree(osd_data->pages);
}

static void ceph_unlock_page_vector(struct page **pages, int num_pages)
{
	int i;

	for (i = 0; i < num_pages; i++)
		unlock_page(pages[i]);
}

/*
 * start an async read(ahead) operation.  return nr_pages we submitted
 * a read for on success, or negative error code.
@@ -370,6 +362,10 @@ static int start_read(struct inode *inode, struct list_head *page_list, int max)
			dout("start_read %p add_to_page_cache failed %p\n",
			     inode, page);
			nr_pages = i;
			if (nr_pages > 0) {
				len = nr_pages << PAGE_SHIFT;
				break;
			}
			goto out_pages;
		}
		pages[i] = page;
@@ -386,8 +382,11 @@ static int start_read(struct inode *inode, struct list_head *page_list, int max)
	return nr_pages;

out_pages:
	ceph_unlock_page_vector(pages, nr_pages);
	ceph_release_page_vector(pages, nr_pages);
	for (i = 0; i < nr_pages; ++i) {
		ceph_fscache_readpage_cancel(inode, pages[i]);
		unlock_page(pages[i]);
	}
	ceph_put_page_vector(pages, nr_pages, false);
out:
	ceph_osdc_put_request(req);
	return ret;