Patch "ceph: fix readpage from fscache" has been added to the 4.4-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
ceph: fix readpage from fscache
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
ceph-fix-readpage-from-fscache.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
dd2bc473482eedc60c29cf00ad12568ce40ce511Mon Sep 17 00:00:00 2001
From: "Yan, Zheng" <[email protected]>
Date: Fri, 4 Aug 2017 11:22:31 +0800
Subject: ceph: fix readpage from fscache
From: Yan, Zheng <[email protected]>
commit dd2bc473482eedc60c29cf00ad12568ce40ce511 upstream.
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()
--- fs/ceph/addr.c | 24 +++++++++++++++--------- fs/ceph/cache.c | 12 +++--------- 2 files changed, 18 insertions(+), 18 deletions(-)
fs/ceph/addr.c +15 -9
@@ -189,7 +189,7 @@ static int ceph_releasepage(struct page/* * read a single page, without unlocking it. */ -static int readpage_nounlock (struct file *filp,struct page *page) +static int ceph_do_readpage (struct file *filp,struct page *page) {struct inode *inode =file_inode (filp);struct ceph_inode_info *ci =ceph_inode (inode);
@@ -219,7 +219,7 @@ static int readpage_nounlock(struct file err =ceph_readpage_from_fscache (inode, page);if (err ==0 ) - goto out; +return -EINPROGRESS ;dout ("readpage inode %p file %p page %p index %lu\n" , inode, filp, page, page->index);
@@ -249,8 +249,11 @@ out:static int ceph_readpage (struct file *filp,struct page *page) { -int r =readpage_nounlock (filp, page); -unlock_page (page); +int r =ceph_do_readpage (filp, page); +if (r != -EINPROGRESS ) +unlock_page (page); +else + r =0 ;return r; }
@@ -1094,7 +1097,7 @@ retry_locked: goto retry_locked; r =writepage_nounlock (page,NULL );if (r <0 ) - goto fail_nosnap; + goto fail_unlock; goto retry_locked; }
@@ -1122,11 +1125,14 @@ retry_locked: }/* we need to read it. */ - r =readpage_nounlock (file, page); -if (r <0 ) - goto fail_nosnap; + r =ceph_do_readpage (file, page); +if (r <0 ) { +if (r == -EINPROGRESS ) +return -EAGAIN ; + goto fail_unlock; + } goto retry_locked; -fail_nosnap: +fail_unlock:unlock_page (page);return r; }
fs/ceph/cache.c +3 -9
@@ -224,13 +224,7 @@ void ceph_fscache_unregister_inode_cookifscache_relinquish_cookie (cookie,0 ); } -static void ceph_vfs_readpage_complete (struct page *page,void *data,int error) -{ -if (!error) -SetPageUptodate (page); -} - -static void ceph_vfs_readpage_complete_unlock (struct page *page,void *data,int error) +static void ceph_readpage_from_fscache_complete (struct page *page,void *data,int error) {if (!error)SetPageUptodate (page);
@@ -259,7 +253,7 @@ int ceph_readpage_from_fscache(struct inreturn -ENOBUFS ; ret =fscache_read_or_alloc_page (ci->fscache, page, - ceph_vfs_readpage_complete,NULL , + ceph_readpage_from_fscache_complete,NULL ,GFP_KERNEL );switch (ret) {
@@ -288,7 +282,7 @@ int ceph_readpages_from_fscache(struct ireturn -ENOBUFS ; ret =fscache_read_or_alloc_pages (ci->fscache, mapping, pages, nr_pages, - ceph_vfs_readpage_complete_unlock, + ceph_readpage_from_fscache_complete,NULL ,mapping_gfp_mask (mapping));switch (ret) {
Patches currently in stable-queue which might be from [email protected] are
queue-4.4/ceph-fix-readpage-from-fscache.patch