aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph/cache.c
diff options
context:
space:
mode:
authorYan, Zheng <zyan@redhat.com>2017-08-03 23:22:31 -0400
committerIlya Dryomov <idryomov@gmail.com>2017-08-31 18:04:26 -0400
commitdd2bc473482eedc60c29cf00ad12568ce40ce511 (patch)
treee06527af35691390fce75993b0986cad10be1225 /fs/ceph/cache.c
parentcc4a41fe5541a73019a864883297bd5043aa6d98 (diff)
ceph: fix readpage from fscache
ceph_readpage() unlocks page prematurely prematurely in the case that page is reading from fscache. Caller of readpage expects that page is uptodate when it get unlocked. So page shoule get locked by completion callback of fscache_read_or_alloc_pages() Cc: stable@vger.kernel.org # 4.1+, needs backporting for < 4.7 Signed-off-by: "Yan, Zheng" <zyan@redhat.com> Reviewed-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Diffstat (limited to 'fs/ceph/cache.c')
-rw-r--r--fs/ceph/cache.c12
1 files changed, 3 insertions, 9 deletions
diff --git a/fs/ceph/cache.c b/fs/ceph/cache.c
index fd1172823f86..337f88673ed9 100644
--- a/fs/ceph/cache.c
+++ b/fs/ceph/cache.c
@@ -297,13 +297,7 @@ void ceph_fscache_file_set_cookie(struct inode *inode, struct file *filp)
297 } 297 }
298} 298}
299 299
300static void ceph_vfs_readpage_complete(struct page *page, void *data, int error) 300static void ceph_readpage_from_fscache_complete(struct page *page, void *data, int error)
301{
302 if (!error)
303 SetPageUptodate(page);
304}
305
306static void ceph_vfs_readpage_complete_unlock(struct page *page, void *data, int error)
307{ 301{
308 if (!error) 302 if (!error)
309 SetPageUptodate(page); 303 SetPageUptodate(page);
@@ -331,7 +325,7 @@ int ceph_readpage_from_fscache(struct inode *inode, struct page *page)
331 return -ENOBUFS; 325 return -ENOBUFS;
332 326
333 ret = fscache_read_or_alloc_page(ci->fscache, page, 327 ret = fscache_read_or_alloc_page(ci->fscache, page,
334 ceph_vfs_readpage_complete, NULL, 328 ceph_readpage_from_fscache_complete, NULL,
335 GFP_KERNEL); 329 GFP_KERNEL);
336 330
337 switch (ret) { 331 switch (ret) {
@@ -360,7 +354,7 @@ int ceph_readpages_from_fscache(struct inode *inode,
360 return -ENOBUFS; 354 return -ENOBUFS;
361 355
362 ret = fscache_read_or_alloc_pages(ci->fscache, mapping, pages, nr_pages, 356 ret = fscache_read_or_alloc_pages(ci->fscache, mapping, pages, nr_pages,
363 ceph_vfs_readpage_complete_unlock, 357 ceph_readpage_from_fscache_complete,
364 NULL, mapping_gfp_mask(mapping)); 358 NULL, mapping_gfp_mask(mapping));
365 359
366 switch (ret) { 360 switch (ret) {