ceph-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 1/6] ceph: disable old fscache readpage handling
       [not found] <20210217125845.10319-1-jlayton@kernel.org>
@ 2021-02-17 12:58 ` Jeff Layton
  2021-02-19  5:09   ` Xiubo Li
  2021-02-17 12:58 ` [PATCH v2 2/6] ceph: rework PageFsCache handling Jeff Layton
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 12+ messages in thread
From: Jeff Layton @ 2021-02-17 12:58 UTC (permalink / raw)
  To: dhowells, idryomov; +Cc: xiubli, ceph-devel, linux-cachefs, linux-fsdevel

With the new netfs read helper functions, we won't need a lot of this
infrastructure as it handles the pagecache pages itself. Rip out the
read handling for now, and much of the old infrastructure that deals in
individual pages.

The cookie handling is mostly unchanged, however.

Signed-off-by: Jeff Layton <jlayton@kernel.org>
Cc: ceph-devel@vger.kernel.org
Cc: linux-cachefs@redhat.com
Cc: linux-fsdevel@vger.kernel.org
---
 fs/ceph/addr.c  |  31 +-----------
 fs/ceph/cache.c | 125 ------------------------------------------------
 fs/ceph/cache.h |  91 +----------------------------------
 fs/ceph/caps.c  |   9 ----
 4 files changed, 3 insertions(+), 253 deletions(-)

diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
index 950552944436..2b17bb36e548 100644
--- a/fs/ceph/addr.c
+++ b/fs/ceph/addr.c
@@ -155,8 +155,6 @@ static void ceph_invalidatepage(struct page *page, unsigned int offset,
 		return;
 	}
 
-	ceph_invalidate_fscache_page(inode, page);
-
 	WARN_ON(!PageLocked(page));
 	if (!PagePrivate(page))
 		return;
@@ -175,10 +173,6 @@ static int ceph_releasepage(struct page *page, gfp_t g)
 	dout("%p releasepage %p idx %lu (%sdirty)\n", page->mapping->host,
 	     page, page->index, PageDirty(page) ? "" : "not ");
 
-	/* Can we release the page from the cache? */
-	if (!ceph_release_fscache_page(page, g))
-		return 0;
-
 	return !PagePrivate(page);
 }
 
@@ -213,10 +207,6 @@ static int ceph_do_readpage(struct file *filp, struct page *page)
 		return 0;
 	}
 
-	err = ceph_readpage_from_fscache(inode, page);
-	if (err == 0)
-		return -EINPROGRESS;
-
 	dout("readpage ino %llx.%llx file %p off %llu len %llu page %p index %lu\n",
 	     vino.ino, vino.snap, filp, off, len, page, page->index);
 	req = ceph_osdc_new_request(osdc, &ci->i_layout, vino, off, &len, 0, 1,
@@ -241,7 +231,6 @@ static int ceph_do_readpage(struct file *filp, struct page *page)
 	if (err == -ENOENT)
 		err = 0;
 	if (err < 0) {
-		ceph_fscache_readpage_cancel(inode, page);
 		if (err == -EBLOCKLISTED)
 			fsc->blocklisted = true;
 		goto out;
@@ -253,8 +242,6 @@ static int ceph_do_readpage(struct file *filp, struct page *page)
 		flush_dcache_page(page);
 
 	SetPageUptodate(page);
-	ceph_readpage_to_fscache(inode, page);
-
 out:
 	return err < 0 ? err : 0;
 }
@@ -294,10 +281,8 @@ static void finish_read(struct ceph_osd_request *req)
 	for (i = 0; i < num_pages; i++) {
 		struct page *page = osd_data->pages[i];
 
-		if (rc < 0 && rc != -ENOENT) {
-			ceph_fscache_readpage_cancel(inode, page);
+		if (rc < 0 && rc != -ENOENT)
 			goto unlock;
-		}
 		if (bytes < (int)PAGE_SIZE) {
 			/* zero (remainder of) page */
 			int s = bytes < 0 ? 0 : bytes;
@@ -307,7 +292,6 @@ static void finish_read(struct ceph_osd_request *req)
 		     page->index);
 		flush_dcache_page(page);
 		SetPageUptodate(page);
-		ceph_readpage_to_fscache(inode, page);
 unlock:
 		unlock_page(page);
 		put_page(page);
@@ -408,7 +392,6 @@ static int start_read(struct inode *inode, struct ceph_rw_context *rw_ctx,
 		     page->index);
 		if (add_to_page_cache_lru(page, &inode->i_data, page->index,
 					  GFP_KERNEL)) {
-			ceph_fscache_uncache_page(inode, page);
 			put_page(page);
 			dout("start_read %p add_to_page_cache failed %p\n",
 			     inode, page);
@@ -440,10 +423,8 @@ static int start_read(struct inode *inode, struct ceph_rw_context *rw_ctx,
 	return nr_pages;
 
 out_pages:
-	for (i = 0; i < nr_pages; ++i) {
-		ceph_fscache_readpage_cancel(inode, pages[i]);
+	for (i = 0; i < nr_pages; ++i)
 		unlock_page(pages[i]);
-	}
 	ceph_put_page_vector(pages, nr_pages, false);
 out_put:
 	ceph_osdc_put_request(req);
@@ -471,12 +452,6 @@ static int ceph_readpages(struct file *file, struct address_space *mapping,
 	if (ceph_inode(inode)->i_inline_version != CEPH_INLINE_NONE)
 		return -EINVAL;
 
-	rc = ceph_readpages_from_fscache(mapping->host, mapping, page_list,
-					 &nr_pages);
-
-	if (rc == 0)
-		goto out;
-
 	rw_ctx = ceph_find_rw_context(fi);
 	max = fsc->mount_options->rsize >> PAGE_SHIFT;
 	dout("readpages %p file %p ctx %p nr_pages %d max %d\n",
@@ -487,8 +462,6 @@ static int ceph_readpages(struct file *file, struct address_space *mapping,
 			goto out;
 	}
 out:
-	ceph_fscache_readpages_cancel(inode, page_list);
-
 	dout("readpages %p file %p ret %d\n", inode, file, rc);
 	return rc;
 }
diff --git a/fs/ceph/cache.c b/fs/ceph/cache.c
index 2f5cb6bc78e1..9cfadbb86568 100644
--- a/fs/ceph/cache.c
+++ b/fs/ceph/cache.c
@@ -173,7 +173,6 @@ void ceph_fscache_unregister_inode_cookie(struct ceph_inode_info* ci)
 
 	ci->fscache = NULL;
 
-	fscache_uncache_all_inode_pages(cookie, &ci->vfs_inode);
 	fscache_relinquish_cookie(cookie, &ci->i_vino, false);
 }
 
@@ -194,7 +193,6 @@ void ceph_fscache_file_set_cookie(struct inode *inode, struct file *filp)
 		dout("fscache_file_set_cookie %p %p disabling cache\n",
 		     inode, filp);
 		fscache_disable_cookie(ci->fscache, &ci->i_vino, false);
-		fscache_uncache_all_inode_pages(ci->fscache, inode);
 	} else {
 		fscache_enable_cookie(ci->fscache, &ci->i_vino, i_size_read(inode),
 				      ceph_fscache_can_enable, inode);
@@ -205,108 +203,6 @@ void ceph_fscache_file_set_cookie(struct inode *inode, struct file *filp)
 	}
 }
 
-static void ceph_readpage_from_fscache_complete(struct page *page, void *data, int error)
-{
-	if (!error)
-		SetPageUptodate(page);
-
-	unlock_page(page);
-}
-
-static inline bool cache_valid(struct ceph_inode_info *ci)
-{
-	return ci->i_fscache_gen == ci->i_rdcache_gen;
-}
-
-
-/* Atempt to read from the fscache,
- *
- * This function is called from the readpage_nounlock context. DO NOT attempt to
- * unlock the page here (or in the callback).
- */
-int ceph_readpage_from_fscache(struct inode *inode, struct page *page)
-{
-	struct ceph_inode_info *ci = ceph_inode(inode);
-	int ret;
-
-	if (!cache_valid(ci))
-		return -ENOBUFS;
-
-	ret = fscache_read_or_alloc_page(ci->fscache, page,
-					 ceph_readpage_from_fscache_complete, NULL,
-					 GFP_KERNEL);
-
-	switch (ret) {
-		case 0: /* Page found */
-			dout("page read submitted\n");
-			return 0;
-		case -ENOBUFS: /* Pages were not found, and can't be */
-		case -ENODATA: /* Pages were not found */
-			dout("page/inode not in cache\n");
-			return ret;
-		default:
-			dout("%s: unknown error ret = %i\n", __func__, ret);
-			return ret;
-	}
-}
-
-int ceph_readpages_from_fscache(struct inode *inode,
-				  struct address_space *mapping,
-				  struct list_head *pages,
-				  unsigned *nr_pages)
-{
-	struct ceph_inode_info *ci = ceph_inode(inode);
-	int ret;
-
-	if (!cache_valid(ci))
-		return -ENOBUFS;
-
-	ret = fscache_read_or_alloc_pages(ci->fscache, mapping, pages, nr_pages,
-					  ceph_readpage_from_fscache_complete,
-					  NULL, mapping_gfp_mask(mapping));
-
-	switch (ret) {
-		case 0: /* All pages found */
-			dout("all-page read submitted\n");
-			return 0;
-		case -ENOBUFS: /* Some pages were not found, and can't be */
-		case -ENODATA: /* some pages were not found */
-			dout("page/inode not in cache\n");
-			return ret;
-		default:
-			dout("%s: unknown error ret = %i\n", __func__, ret);
-			return ret;
-	}
-}
-
-void ceph_readpage_to_fscache(struct inode *inode, struct page *page)
-{
-	struct ceph_inode_info *ci = ceph_inode(inode);
-	int ret;
-
-	if (!PageFsCache(page))
-		return;
-
-	if (!cache_valid(ci))
-		return;
-
-	ret = fscache_write_page(ci->fscache, page, i_size_read(inode),
-				 GFP_KERNEL);
-	if (ret)
-		 fscache_uncache_page(ci->fscache, page);
-}
-
-void ceph_invalidate_fscache_page(struct inode* inode, struct page *page)
-{
-	struct ceph_inode_info *ci = ceph_inode(inode);
-
-	if (!PageFsCache(page))
-		return;
-
-	fscache_wait_on_page_write(ci->fscache, page);
-	fscache_uncache_page(ci->fscache, page);
-}
-
 void ceph_fscache_unregister_fs(struct ceph_fs_client* fsc)
 {
 	if (fscache_cookie_valid(fsc->fscache)) {
@@ -329,24 +225,3 @@ void ceph_fscache_unregister_fs(struct ceph_fs_client* fsc)
 	}
 	fsc->fscache = NULL;
 }
-
-/*
- * caller should hold CEPH_CAP_FILE_{RD,CACHE}
- */
-void ceph_fscache_revalidate_cookie(struct ceph_inode_info *ci)
-{
-	if (cache_valid(ci))
-		return;
-
-	/* resue i_truncate_mutex. There should be no pending
-	 * truncate while the caller holds CEPH_CAP_FILE_RD */
-	mutex_lock(&ci->i_truncate_mutex);
-	if (!cache_valid(ci)) {
-		if (fscache_check_consistency(ci->fscache, &ci->i_vino))
-			fscache_invalidate(ci->fscache);
-		spin_lock(&ci->i_ceph_lock);
-		ci->i_fscache_gen = ci->i_rdcache_gen;
-		spin_unlock(&ci->i_ceph_lock);
-	}
-	mutex_unlock(&ci->i_truncate_mutex);
-}
diff --git a/fs/ceph/cache.h b/fs/ceph/cache.h
index 89dbdd1eb14a..10c21317b62f 100644
--- a/fs/ceph/cache.h
+++ b/fs/ceph/cache.h
@@ -29,13 +29,10 @@ int ceph_readpages_from_fscache(struct inode *inode,
 				struct address_space *mapping,
 				struct list_head *pages,
 				unsigned *nr_pages);
-void ceph_readpage_to_fscache(struct inode *inode, struct page *page);
-void ceph_invalidate_fscache_page(struct inode* inode, struct page *page);
 
 static inline void ceph_fscache_inode_init(struct ceph_inode_info *ci)
 {
 	ci->fscache = NULL;
-	ci->i_fscache_gen = 0;
 }
 
 static inline void ceph_fscache_invalidate(struct inode *inode)
@@ -43,40 +40,6 @@ static inline void ceph_fscache_invalidate(struct inode *inode)
 	fscache_invalidate(ceph_inode(inode)->fscache);
 }
 
-static inline void ceph_fscache_uncache_page(struct inode *inode,
-					     struct page *page)
-{
-	struct ceph_inode_info *ci = ceph_inode(inode);
-	return fscache_uncache_page(ci->fscache, page);
-}
-
-static inline int ceph_release_fscache_page(struct page *page, gfp_t gfp)
-{
-	struct inode* inode = page->mapping->host;
-	struct ceph_inode_info *ci = ceph_inode(inode);
-	return fscache_maybe_release_page(ci->fscache, page, gfp);
-}
-
-static inline void ceph_fscache_readpage_cancel(struct inode *inode,
-						struct page *page)
-{
-	struct ceph_inode_info *ci = ceph_inode(inode);
-	if (fscache_cookie_valid(ci->fscache) && PageFsCache(page))
-		__fscache_uncache_page(ci->fscache, page);
-}
-
-static inline void ceph_fscache_readpages_cancel(struct inode *inode,
-						 struct list_head *pages)
-{
-	struct ceph_inode_info *ci = ceph_inode(inode);
-	return fscache_readpages_cancel(ci->fscache, pages);
-}
-
-static inline void ceph_disable_fscache_readpage(struct ceph_inode_info *ci)
-{
-	ci->i_fscache_gen = ci->i_rdcache_gen - 1;
-}
-
 #else
 
 static inline int ceph_fscache_register(void)
@@ -115,62 +78,10 @@ static inline void ceph_fscache_file_set_cookie(struct inode *inode,
 {
 }
 
-static inline void ceph_fscache_revalidate_cookie(struct ceph_inode_info *ci)
-{
-}
-
-static inline void ceph_fscache_uncache_page(struct inode *inode,
-					     struct page *pages)
-{
-}
-
-static inline int ceph_readpage_from_fscache(struct inode* inode,
-					     struct page *page)
-{
-	return -ENOBUFS;
-}
-
-static inline int ceph_readpages_from_fscache(struct inode *inode,
-					      struct address_space *mapping,
-					      struct list_head *pages,
-					      unsigned *nr_pages)
-{
-	return -ENOBUFS;
-}
-
-static inline void ceph_readpage_to_fscache(struct inode *inode,
-					    struct page *page)
-{
-}
-
 static inline void ceph_fscache_invalidate(struct inode *inode)
 {
 }
 
-static inline void ceph_invalidate_fscache_page(struct inode *inode,
-						struct page *page)
-{
-}
-
-static inline int ceph_release_fscache_page(struct page *page, gfp_t gfp)
-{
-	return 1;
-}
-
-static inline void ceph_fscache_readpage_cancel(struct inode *inode,
-						struct page *page)
-{
-}
-
-static inline void ceph_fscache_readpages_cancel(struct inode *inode,
-						 struct list_head *pages)
-{
-}
-
-static inline void ceph_disable_fscache_readpage(struct ceph_inode_info *ci)
-{
-}
-
 #endif
 
-#endif
+#endif /* _CEPH_CACHE_H */
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index 255a512f1277..ca07dfc60652 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -2730,10 +2730,6 @@ static int try_get_cap_refs(struct inode *inode, int need, int want,
 				*got = need | want;
 			else
 				*got = need;
-			if (S_ISREG(inode->i_mode) &&
-			    (need & CEPH_CAP_FILE_RD) &&
-			    !(*got & CEPH_CAP_FILE_CACHE))
-				ceph_disable_fscache_readpage(ci);
 			ceph_take_cap_refs(ci, *got, true);
 			ret = 1;
 		}
@@ -2983,11 +2979,6 @@ int ceph_get_caps(struct file *filp, int need, int want,
 		}
 		break;
 	}
-
-	if (S_ISREG(ci->vfs_inode.i_mode) &&
-	    (_got & CEPH_CAP_FILE_RD) && (_got & CEPH_CAP_FILE_CACHE))
-		ceph_fscache_revalidate_cookie(ci);
-
 	*got = _got;
 	return 0;
 }
-- 
2.29.2


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v2 2/6] ceph: rework PageFsCache handling
       [not found] <20210217125845.10319-1-jlayton@kernel.org>
  2021-02-17 12:58 ` [PATCH v2 1/6] ceph: disable old fscache readpage handling Jeff Layton
@ 2021-02-17 12:58 ` Jeff Layton
  2021-02-17 14:38   ` Matthew Wilcox
  2021-02-17 12:58 ` [PATCH v2 3/6] ceph: fix fscache invalidation Jeff Layton
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 12+ messages in thread
From: Jeff Layton @ 2021-02-17 12:58 UTC (permalink / raw)
  To: dhowells, idryomov; +Cc: xiubli, ceph-devel, linux-cachefs, linux-fsdevel

With the new fscache API, the PageFsCache bit now indicates that the
page is being written to the cache and shouldn't be modified or released
until it's finished.

Change releasepage and invalidatepage to wait on that bit before
returning.

Also define FSCACHE_USE_NEW_IO_API so that we opt into the new fscache
API.

Signed-off-by: Jeff Layton <jlayton@kernel.org>
Cc: ceph-devel@vger.kernel.org
Cc: linux-cachefs@redhat.com
Cc: linux-fsdevel@vger.kernel.org
---
 fs/ceph/addr.c  | 9 ++++++++-
 fs/ceph/super.h | 1 +
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
index 2b17bb36e548..fbfa49db06fd 100644
--- a/fs/ceph/addr.c
+++ b/fs/ceph/addr.c
@@ -146,6 +146,8 @@ static void ceph_invalidatepage(struct page *page, unsigned int offset,
 	struct ceph_inode_info *ci;
 	struct ceph_snap_context *snapc = page_snap_context(page);
 
+	wait_on_page_fscache(page);
+
 	inode = page->mapping->host;
 	ci = ceph_inode(inode);
 
@@ -168,11 +170,16 @@ static void ceph_invalidatepage(struct page *page, unsigned int offset,
 	ClearPagePrivate(page);
 }
 
-static int ceph_releasepage(struct page *page, gfp_t g)
+static int ceph_releasepage(struct page *page, gfp_t gfp_flags)
 {
 	dout("%p releasepage %p idx %lu (%sdirty)\n", page->mapping->host,
 	     page, page->index, PageDirty(page) ? "" : "not ");
 
+	if (PageFsCache(page)) {
+		if (!(gfp_flags & __GFP_DIRECT_RECLAIM) || !(gfp_flags & __GFP_FS))
+			return 0;
+		wait_on_page_fscache(page);
+	}
 	return !PagePrivate(page);
 }
 
diff --git a/fs/ceph/super.h b/fs/ceph/super.h
index b62d8fee3b86..96bd3487d788 100644
--- a/fs/ceph/super.h
+++ b/fs/ceph/super.h
@@ -21,6 +21,7 @@
 #include <linux/ceph/libceph.h>
 
 #ifdef CONFIG_CEPH_FSCACHE
+#define FSCACHE_USE_NEW_IO_API
 #include <linux/fscache.h>
 #endif
 
-- 
2.29.2


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v2 3/6] ceph: fix fscache invalidation
       [not found] <20210217125845.10319-1-jlayton@kernel.org>
  2021-02-17 12:58 ` [PATCH v2 1/6] ceph: disable old fscache readpage handling Jeff Layton
  2021-02-17 12:58 ` [PATCH v2 2/6] ceph: rework PageFsCache handling Jeff Layton
@ 2021-02-17 12:58 ` Jeff Layton
  2021-02-17 12:58 ` [PATCH v2 4/6] ceph: convert readpage to fscache read helper Jeff Layton
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 12+ messages in thread
From: Jeff Layton @ 2021-02-17 12:58 UTC (permalink / raw)
  To: dhowells, idryomov; +Cc: xiubli, ceph-devel, linux-cachefs, linux-fsdevel

Ensure that we invalidate the fscache whenever we invalidate the
pagecache.

Signed-off-by: Jeff Layton <jlayton@kernel.org>
Cc: ceph-devel@vger.kernel.org
Cc: linux-cachefs@redhat.com
Cc: linux-fsdevel@vger.kernel.org
---
 fs/ceph/caps.c  | 1 +
 fs/ceph/inode.c | 1 +
 2 files changed, 2 insertions(+)

diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index ca07dfc60652..c40f713d6d21 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -1867,6 +1867,7 @@ static int try_nonblocking_invalidate(struct inode *inode)
 	u32 invalidating_gen = ci->i_rdcache_gen;
 
 	spin_unlock(&ci->i_ceph_lock);
+	ceph_fscache_invalidate(inode);
 	invalidate_mapping_pages(&inode->i_data, 0, -1);
 	spin_lock(&ci->i_ceph_lock);
 
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c
index adc8fc3c5d85..2caa6df0bcdf 100644
--- a/fs/ceph/inode.c
+++ b/fs/ceph/inode.c
@@ -1906,6 +1906,7 @@ static void ceph_do_invalidate_pages(struct inode *inode)
 	orig_gen = ci->i_rdcache_gen;
 	spin_unlock(&ci->i_ceph_lock);
 
+	ceph_fscache_invalidate(inode);
 	if (invalidate_inode_pages2(inode->i_mapping) < 0) {
 		pr_err("invalidate_pages %p fails\n", inode);
 	}
-- 
2.29.2


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v2 4/6] ceph: convert readpage to fscache read helper
       [not found] <20210217125845.10319-1-jlayton@kernel.org>
                   ` (2 preceding siblings ...)
  2021-02-17 12:58 ` [PATCH v2 3/6] ceph: fix fscache invalidation Jeff Layton
@ 2021-02-17 12:58 ` Jeff Layton
  2021-02-17 12:58 ` [PATCH v2 5/6] ceph: plug write_begin into " Jeff Layton
  2021-02-17 12:58 ` [PATCH v2 6/6] ceph: convert ceph_readpages to ceph_readahead Jeff Layton
  5 siblings, 0 replies; 12+ messages in thread
From: Jeff Layton @ 2021-02-17 12:58 UTC (permalink / raw)
  To: dhowells, idryomov; +Cc: xiubli, ceph-devel, linux-cachefs, linux-fsdevel

Have the ceph KConfig select NETFS_SUPPORT. Add a new netfs ops
structure and the operations for it. Convert ceph_readpage to use
the new netfs_readpage helper.

Signed-off-by: Jeff Layton <jlayton@kernel.org>
Cc: ceph-devel@vger.kernel.org
Cc: linux-cachefs@redhat.com
Cc: linux-fsdevel@vger.kernel.org
---
 fs/ceph/Kconfig |   1 +
 fs/ceph/addr.c  | 167 +++++++++++++++++++++++++++++++++++++++++++++---
 fs/ceph/cache.h |  36 +++++++++++
 3 files changed, 194 insertions(+), 10 deletions(-)

diff --git a/fs/ceph/Kconfig b/fs/ceph/Kconfig
index 471e40156065..94df854147d3 100644
--- a/fs/ceph/Kconfig
+++ b/fs/ceph/Kconfig
@@ -6,6 +6,7 @@ config CEPH_FS
 	select LIBCRC32C
 	select CRYPTO_AES
 	select CRYPTO
+	select NETFS_SUPPORT
 	default n
 	help
 	  Choose Y or M here to include support for mounting the
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
index fbfa49db06fd..6d4de969f761 100644
--- a/fs/ceph/addr.c
+++ b/fs/ceph/addr.c
@@ -12,6 +12,7 @@
 #include <linux/signal.h>
 #include <linux/iversion.h>
 #include <linux/ktime.h>
+#include <linux/netfs.h>
 
 #include "super.h"
 #include "mds_client.h"
@@ -183,6 +184,162 @@ static int ceph_releasepage(struct page *page, gfp_t gfp_flags)
 	return !PagePrivate(page);
 }
 
+static void ceph_netfs_expand_readahead(struct netfs_read_request *rreq)
+{
+	struct inode *inode = rreq->mapping->host;
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	struct ceph_file_layout *lo = &ci->i_layout;
+	u32 blockoff;
+	u64 blockno;
+
+	/* Expand the start downward */
+	blockno = div_u64_rem(rreq->start, lo->stripe_unit, &blockoff);
+	rreq->start = blockno * lo->stripe_unit;
+	rreq->len += blockoff;
+
+	/* Now, round up the length to the next block */
+	rreq->len = roundup(rreq->len, lo->stripe_unit);
+}
+
+static bool ceph_netfs_clamp_length(struct netfs_read_subrequest *subreq)
+{
+	struct inode *inode = subreq->rreq->mapping->host;
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	u64 objno, objoff;
+	u32 xlen;
+
+	/* Truncate the extent at the end of the current block */
+	ceph_calc_file_object_mapping(&ci->i_layout, subreq->start, subreq->len,
+				      &objno, &objoff, &xlen);
+	subreq->len = xlen;
+	return true;
+}
+
+static void finish_netfs_read(struct ceph_osd_request *req)
+{
+	struct ceph_fs_client *fsc = ceph_inode_to_client(req->r_inode);
+	struct ceph_osd_data *osd_data = osd_req_op_extent_osd_data(req, 0);
+	struct netfs_read_subrequest *subreq = req->r_priv;
+	int num_pages;
+	int err = req->r_result;
+
+	ceph_update_read_latency(&fsc->mdsc->metric, req->r_start_latency,
+				 req->r_end_latency, err);
+
+	dout("%s: result %d subreq->len=%zu i_size=%lld\n", __func__, req->r_result,
+	     subreq->len, i_size_read(req->r_inode));
+
+	/* no object means success but no data */
+	if (err == -ENOENT)
+		err = 0;
+	else if (err == -EBLOCKLISTED)
+		fsc->blocklisted = true;
+
+	if (err >= 0 && err < subreq->len)
+		__set_bit(NETFS_SREQ_CLEAR_TAIL, &subreq->flags);
+
+	netfs_subreq_terminated(subreq, err);
+
+	num_pages = calc_pages_for(osd_data->alignment, osd_data->length);
+	ceph_put_page_vector(osd_data->pages, num_pages, false);
+	iput(req->r_inode);
+}
+
+static void ceph_netfs_issue_op(struct netfs_read_subrequest *subreq)
+{
+	struct netfs_read_request *rreq = subreq->rreq;
+	struct inode *inode = rreq->mapping->host;
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
+	struct ceph_osd_request *req;
+	struct ceph_vino vino = ceph_vino(inode);
+	struct iov_iter iter;
+	struct page **pages;
+	size_t page_off;
+	int err = 0;
+	u64 len = subreq->len;
+
+	req = ceph_osdc_new_request(&fsc->client->osdc, &ci->i_layout, vino, subreq->start, &len,
+			0, 1, CEPH_OSD_OP_READ,
+			CEPH_OSD_FLAG_READ | fsc->client->osdc.client->options->read_from_replica,
+			NULL, ci->i_truncate_seq, ci->i_truncate_size, false);
+	if (IS_ERR(req)) {
+		err = PTR_ERR(req);
+		req = NULL;
+		goto out;
+	}
+
+	dout("%s: pos=%llu orig_len=%zu len=%llu\n", __func__, subreq->start, subreq->len, len);
+	iov_iter_xarray(&iter, READ, &rreq->mapping->i_pages, subreq->start, len);
+	err = iov_iter_get_pages_alloc(&iter, &pages, len, &page_off);
+	if (err < 0) {
+		dout("%s: iov_ter_get_pages_alloc returned %d\n", __func__, err);
+		goto out;
+	}
+
+	/* should always give us a page-aligned read */
+	WARN_ON_ONCE(page_off);
+	len = err;
+
+	osd_req_op_extent_osd_data_pages(req, 0, pages, len, 0, false, false);
+	req->r_callback = finish_netfs_read;
+	req->r_priv = subreq;
+	req->r_inode = inode;
+	ihold(inode);
+
+	err = ceph_osdc_start_request(req->r_osdc, req, false);
+	if (err)
+		iput(inode);
+out:
+	ceph_osdc_put_request(req);
+	if (err)
+		netfs_subreq_terminated(subreq, err);
+	dout("%s: result %d\n", __func__, err);
+}
+
+static void ceph_init_rreq(struct netfs_read_request *rreq, struct file *file)
+{
+}
+
+const struct netfs_read_request_ops ceph_readpage_netfs_ops = {
+	.init_rreq		= ceph_init_rreq,
+	.is_cache_enabled	= ceph_is_cache_enabled,
+	.begin_cache_operation	= ceph_begin_cache_operation,
+	.issue_op		= ceph_netfs_issue_op,
+	.expand_readahead	= ceph_netfs_expand_readahead,
+	.clamp_length		= ceph_netfs_clamp_length,
+};
+
+/* read a single page, without unlocking it. */
+static int ceph_readpage(struct file *file, struct page *page)
+{
+	struct inode *inode = file_inode(file);
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	struct ceph_vino vino = ceph_vino(inode);
+	u64 off = page_offset(page);
+	u64 len = PAGE_SIZE;
+
+	if (ci->i_inline_version != CEPH_INLINE_NONE) {
+		/*
+		 * Uptodate inline data should have been added
+		 * into page cache while getting Fcr caps.
+		 */
+		if (off == 0) {
+			unlock_page(page);
+			return -EINVAL;
+		}
+		zero_user_segment(page, 0, PAGE_SIZE);
+		SetPageUptodate(page);
+		unlock_page(page);
+		return 0;
+	}
+
+	dout("readpage ino %llx.%llx file %p off %llu len %llu page %p index %lu\n",
+	     vino.ino, vino.snap, file, off, len, page, page->index);
+
+	return netfs_readpage(file, page, &ceph_readpage_netfs_ops, NULL);
+}
+
 /* read a single page, without unlocking it. */
 static int ceph_do_readpage(struct file *filp, struct page *page)
 {
@@ -253,16 +410,6 @@ static int ceph_do_readpage(struct file *filp, struct page *page)
 	return err < 0 ? err : 0;
 }
 
-static int ceph_readpage(struct file *filp, struct page *page)
-{
-	int r = ceph_do_readpage(filp, page);
-	if (r != -EINPROGRESS)
-		unlock_page(page);
-	else
-		r = 0;
-	return r;
-}
-
 /*
  * Finish an async read(ahead) op.
  */
diff --git a/fs/ceph/cache.h b/fs/ceph/cache.h
index 10c21317b62f..1409d6149281 100644
--- a/fs/ceph/cache.h
+++ b/fs/ceph/cache.h
@@ -9,6 +9,8 @@
 #ifndef _CEPH_CACHE_H
 #define _CEPH_CACHE_H
 
+#include <linux/netfs.h>
+
 #ifdef CONFIG_CEPH_FSCACHE
 
 extern struct fscache_netfs ceph_cache_netfs;
@@ -35,11 +37,31 @@ static inline void ceph_fscache_inode_init(struct ceph_inode_info *ci)
 	ci->fscache = NULL;
 }
 
+static inline struct fscache_cookie *ceph_fscache_cookie(struct ceph_inode_info *ci)
+{
+	return ci->fscache;
+}
+
 static inline void ceph_fscache_invalidate(struct inode *inode)
 {
 	fscache_invalidate(ceph_inode(inode)->fscache);
 }
 
+static inline bool ceph_is_cache_enabled(struct inode *inode)
+{
+	struct fscache_cookie *cookie = ceph_fscache_cookie(ceph_inode(inode));
+
+	if (!cookie)
+		return false;
+	return fscache_cookie_enabled(cookie);
+}
+
+static inline int ceph_begin_cache_operation(struct netfs_read_request *rreq)
+{
+	struct fscache_cookie *cookie = ceph_fscache_cookie(ceph_inode(rreq->inode));
+
+	return fscache_begin_read_operation(rreq, cookie);
+}
 #else
 
 static inline int ceph_fscache_register(void)
@@ -65,6 +87,11 @@ static inline void ceph_fscache_inode_init(struct ceph_inode_info *ci)
 {
 }
 
+static inline struct fscache_cookie *ceph_fscache_cookie(struct ceph_inode_info *ci)
+{
+	return NULL;
+}
+
 static inline void ceph_fscache_register_inode_cookie(struct inode *inode)
 {
 }
@@ -82,6 +109,15 @@ static inline void ceph_fscache_invalidate(struct inode *inode)
 {
 }
 
+static inline bool ceph_is_cache_enabled(struct inode *inode)
+{
+	return false;
+}
+
+static inline int ceph_begin_cache_operation(struct netfs_read_request *rreq)
+{
+	return -ENOBUFS;
+}
 #endif
 
 #endif /* _CEPH_CACHE_H */
-- 
2.29.2


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v2 5/6] ceph: plug write_begin into read helper
       [not found] <20210217125845.10319-1-jlayton@kernel.org>
                   ` (3 preceding siblings ...)
  2021-02-17 12:58 ` [PATCH v2 4/6] ceph: convert readpage to fscache read helper Jeff Layton
@ 2021-02-17 12:58 ` Jeff Layton
  2021-02-17 12:58 ` [PATCH v2 6/6] ceph: convert ceph_readpages to ceph_readahead Jeff Layton
  5 siblings, 0 replies; 12+ messages in thread
From: Jeff Layton @ 2021-02-17 12:58 UTC (permalink / raw)
  To: dhowells, idryomov; +Cc: xiubli, ceph-devel, linux-cachefs, linux-fsdevel

Convert ceph_write_begin to use the netfs_write_begin helper. Most of
the ops we need for it are already in place from the readpage conversion
but we do add a new check_write_begin op since ceph needs to be able to
vet whether there is an incompatible writeback already in flight before
reading in the page.

With this, we can also remove the old ceph_do_readpage helper.

Signed-off-by: Jeff Layton <jlayton@kernel.org>
Cc: ceph-devel@vger.kernel.org
Cc: linux-cachefs@redhat.com
Cc: linux-fsdevel@vger.kernel.org
---
 fs/ceph/addr.c | 188 ++++++++++++++++---------------------------------
 1 file changed, 62 insertions(+), 126 deletions(-)

diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
index 6d4de969f761..774fd4efffd7 100644
--- a/fs/ceph/addr.c
+++ b/fs/ceph/addr.c
@@ -340,76 +340,6 @@ static int ceph_readpage(struct file *file, struct page *page)
 	return netfs_readpage(file, page, &ceph_readpage_netfs_ops, NULL);
 }
 
-/* read a single page, without unlocking it. */
-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);
-	struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
-	struct ceph_osd_client *osdc = &fsc->client->osdc;
-	struct ceph_osd_request *req;
-	struct ceph_vino vino = ceph_vino(inode);
-	int err = 0;
-	u64 off = page_offset(page);
-	u64 len = PAGE_SIZE;
-
-	if (off >= i_size_read(inode)) {
-		zero_user_segment(page, 0, PAGE_SIZE);
-		SetPageUptodate(page);
-		return 0;
-	}
-
-	if (ci->i_inline_version != CEPH_INLINE_NONE) {
-		/*
-		 * Uptodate inline data should have been added
-		 * into page cache while getting Fcr caps.
-		 */
-		if (off == 0)
-			return -EINVAL;
-		zero_user_segment(page, 0, PAGE_SIZE);
-		SetPageUptodate(page);
-		return 0;
-	}
-
-	dout("readpage ino %llx.%llx file %p off %llu len %llu page %p index %lu\n",
-	     vino.ino, vino.snap, filp, off, len, page, page->index);
-	req = ceph_osdc_new_request(osdc, &ci->i_layout, vino, off, &len, 0, 1,
-				    CEPH_OSD_OP_READ, CEPH_OSD_FLAG_READ, NULL,
-				    ci->i_truncate_seq, ci->i_truncate_size,
-				    false);
-	if (IS_ERR(req))
-		return PTR_ERR(req);
-
-	osd_req_op_extent_osd_data_pages(req, 0, &page, len, 0, false, false);
-
-	err = ceph_osdc_start_request(osdc, req, false);
-	if (!err)
-		err = ceph_osdc_wait_request(osdc, req);
-
-	ceph_update_read_latency(&fsc->mdsc->metric, req->r_start_latency,
-				 req->r_end_latency, err);
-
-	ceph_osdc_put_request(req);
-	dout("readpage result %d\n", err);
-
-	if (err == -ENOENT)
-		err = 0;
-	if (err < 0) {
-		if (err == -EBLOCKLISTED)
-			fsc->blocklisted = true;
-		goto out;
-	}
-	if (err < PAGE_SIZE)
-		/* zero fill remainder of page */
-		zero_user_segment(page, err, PAGE_SIZE);
-	else
-		flush_dcache_page(page);
-
-	SetPageUptodate(page);
-out:
-	return err < 0 ? err : 0;
-}
-
 /*
  * Finish an async read(ahead) op.
  */
@@ -1429,6 +1359,41 @@ ceph_find_incompatible(struct page *page)
 	return NULL;
 }
 
+static int ceph_netfs_check_write_begin(struct file *file, loff_t pos, unsigned int len,
+					struct page *page, void **_fsdata)
+{
+	struct inode *inode = file_inode(file);
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	struct ceph_snap_context *snapc;
+
+	snapc = ceph_find_incompatible(page);
+	if (snapc) {
+		int r;
+
+		unlock_page(page);
+		put_page(page);
+		if (IS_ERR(snapc))
+			return PTR_ERR(snapc);
+
+		ceph_queue_writeback(inode);
+		r = wait_event_killable(ci->i_cap_wq,
+					context_is_writeable_or_written(inode, snapc));
+		ceph_put_snap_context(snapc);
+		return r == 0 ? -EAGAIN : r;
+	}
+	return 0;
+}
+
+const struct netfs_read_request_ops ceph_netfs_write_begin_ops = {
+	.init_rreq		= ceph_init_rreq,
+	.is_cache_enabled	= ceph_is_cache_enabled,
+	.begin_cache_operation	= ceph_begin_cache_operation,
+	.issue_op		= ceph_netfs_issue_op,
+	.expand_readahead	= ceph_netfs_expand_readahead,
+	.clamp_length		= ceph_netfs_clamp_length,
+	.check_write_begin	= ceph_netfs_check_write_begin,
+};
+
 /*
  * We are only allowed to write into/dirty the page if the page is
  * clean, or already dirty within the same snap context.
@@ -1439,75 +1404,46 @@ static int ceph_write_begin(struct file *file, struct address_space *mapping,
 {
 	struct inode *inode = file_inode(file);
 	struct ceph_inode_info *ci = ceph_inode(inode);
-	struct ceph_snap_context *snapc;
 	struct page *page = NULL;
 	pgoff_t index = pos >> PAGE_SHIFT;
-	int pos_in_page = pos & ~PAGE_MASK;
-	int r = 0;
-
-	dout("write_begin file %p inode %p page %p %d~%d\n", file, inode, page, (int)pos, (int)len);
-
-	for (;;) {
-		page = grab_cache_page_write_begin(mapping, index, flags);
-		if (!page) {
-			r = -ENOMEM;
-			break;
-		}
-
-		snapc = ceph_find_incompatible(page);
-		if (snapc) {
-			if (IS_ERR(snapc)) {
-				r = PTR_ERR(snapc);
-				break;
-			}
-			unlock_page(page);
-			put_page(page);
-			page = NULL;
-			ceph_queue_writeback(inode);
-			r = wait_event_killable(ci->i_cap_wq,
-						context_is_writeable_or_written(inode, snapc));
-			ceph_put_snap_context(snapc);
-			if (r != 0)
-				break;
-			continue;
-		}
-
-		if (PageUptodate(page)) {
-			dout(" page %p already uptodate\n", page);
-			break;
-		}
+	int r;
 
+	if (ci->i_inline_version != CEPH_INLINE_NONE) {
 		/*
-		 * In some cases we don't need to read at all:
-		 * - full page write
-		 * - write that lies completely beyond EOF
-		 * - write that covers the the page from start to EOF or beyond it
+		 * In principle, we should never get here, as the inode should have been uninlined
+		 * before we're allowed to write to the page (in write_iter or page_mkwrite).
 		 */
-		if ((pos_in_page == 0 && len == PAGE_SIZE) ||
-		    (pos >= i_size_read(inode)) ||
-		    (pos_in_page == 0 && (pos + len) >= i_size_read(inode))) {
-			zero_user_segments(page, 0, pos_in_page,
-					   pos_in_page + len, PAGE_SIZE);
-			break;
-		}
+		WARN_ONCE(1, "ceph: write_begin called on still-inlined inode!\n");
 
 		/*
-		 * We need to read it. If we get back -EINPROGRESS, then the page was
-		 * handed off to fscache and it will be unlocked when the read completes.
-		 * Refind the page in that case so we can reacquire the page lock. Otherwise
-		 * we got a hard error or the read was completed synchronously.
+		 * Uptodate inline data should have been added
+		 * into page cache while getting Fcr caps.
 		 */
-		r = ceph_do_readpage(file, page);
-		if (r != -EINPROGRESS)
-			break;
+		if (index == 0) {
+			r = -EINVAL;
+			goto out;
+		}
+
+		page = grab_cache_page_write_begin(mapping, index, flags);
+		if (!page)
+			return -ENOMEM;
+
+		zero_user_segment(page, 0, PAGE_SIZE);
+		SetPageUptodate(page);
+		r = 0;
+		goto out;
 	}
 
+	r = netfs_write_begin(file, inode->i_mapping, pos, len, 0, &page, NULL,
+			      &ceph_netfs_write_begin_ops, NULL);
+out:
+	if (r == 0)
+		wait_on_page_fscache(page);
 	if (r < 0) {
-		if (page) {
-			unlock_page(page);
+		if (page)
 			put_page(page);
-		}
 	} else {
+		WARN_ON_ONCE(!PageLocked(page));
 		*pagep = page;
 	}
 	return r;
-- 
2.29.2


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v2 6/6] ceph: convert ceph_readpages to ceph_readahead
       [not found] <20210217125845.10319-1-jlayton@kernel.org>
                   ` (4 preceding siblings ...)
  2021-02-17 12:58 ` [PATCH v2 5/6] ceph: plug write_begin into " Jeff Layton
@ 2021-02-17 12:58 ` Jeff Layton
  2021-02-17 15:15   ` Matthew Wilcox
  5 siblings, 1 reply; 12+ messages in thread
From: Jeff Layton @ 2021-02-17 12:58 UTC (permalink / raw)
  To: dhowells, idryomov; +Cc: xiubli, ceph-devel, linux-cachefs, linux-fsdevel

Convert ceph_readpages to ceph_readahead and make it use
netfs_readahead. With this we can rip out a lot of the old
readpage/readpages infrastructure.

Signed-off-by: Jeff Layton <jlayton@kernel.org>
Cc: ceph-devel@vger.kernel.org
Cc: linux-cachefs@redhat.com
Cc: linux-fsdevel@vger.kernel.org
---
 fs/ceph/addr.c | 230 ++++++++-----------------------------------------
 1 file changed, 35 insertions(+), 195 deletions(-)

diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
index 774fd4efffd7..4f6c8cc0eec9 100644
--- a/fs/ceph/addr.c
+++ b/fs/ceph/addr.c
@@ -340,214 +340,54 @@ static int ceph_readpage(struct file *file, struct page *page)
 	return netfs_readpage(file, page, &ceph_readpage_netfs_ops, NULL);
 }
 
-/*
- * Finish an async read(ahead) op.
- */
-static void finish_read(struct ceph_osd_request *req)
-{
-	struct inode *inode = req->r_inode;
-	struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
-	struct ceph_osd_data *osd_data;
-	int rc = req->r_result <= 0 ? req->r_result : 0;
-	int bytes = req->r_result >= 0 ? req->r_result : 0;
-	int num_pages;
-	int i;
-
-	dout("finish_read %p req %p rc %d bytes %d\n", inode, req, rc, bytes);
-	if (rc == -EBLOCKLISTED)
-		ceph_inode_to_client(inode)->blocklisted = true;
-
-	/* unlock all pages, zeroing any data we didn't read */
-	osd_data = osd_req_op_extent_osd_data(req, 0);
-	BUG_ON(osd_data->type != CEPH_OSD_DATA_TYPE_PAGES);
-	num_pages = calc_pages_for((u64)osd_data->alignment,
-					(u64)osd_data->length);
-	for (i = 0; i < num_pages; i++) {
-		struct page *page = osd_data->pages[i];
-
-		if (rc < 0 && rc != -ENOENT)
-			goto unlock;
-		if (bytes < (int)PAGE_SIZE) {
-			/* zero (remainder of) page */
-			int s = bytes < 0 ? 0 : bytes;
-			zero_user_segment(page, s, PAGE_SIZE);
-		}
- 		dout("finish_read %p uptodate %p idx %lu\n", inode, page,
-		     page->index);
-		flush_dcache_page(page);
-		SetPageUptodate(page);
-unlock:
-		unlock_page(page);
-		put_page(page);
-		bytes -= PAGE_SIZE;
-	}
-
-	ceph_update_read_latency(&fsc->mdsc->metric, req->r_start_latency,
-				 req->r_end_latency, rc);
-
-	kfree(osd_data->pages);
-}
-
-/*
- * start an async read(ahead) operation.  return nr_pages we submitted
- * a read for on success, or negative error code.
- */
-static int start_read(struct inode *inode, struct ceph_rw_context *rw_ctx,
-		      struct list_head *page_list, int max)
+static void ceph_readahead_cleanup(struct address_space *mapping, void *priv)
 {
-	struct ceph_osd_client *osdc =
-		&ceph_inode_to_client(inode)->client->osdc;
+	struct inode *inode = mapping->host;
 	struct ceph_inode_info *ci = ceph_inode(inode);
-	struct page *page = lru_to_page(page_list);
-	struct ceph_vino vino;
-	struct ceph_osd_request *req;
-	u64 off;
-	u64 len;
-	int i;
-	struct page **pages;
-	pgoff_t next_index;
-	int nr_pages = 0;
-	int got = 0;
-	int ret = 0;
+	int got = (int)(uintptr_t)priv;
 
-	if (!rw_ctx) {
-		/* caller of readpages does not hold buffer and read caps
-		 * (fadvise, madvise and readahead cases) */
-		int want = CEPH_CAP_FILE_CACHE;
-		ret = ceph_try_get_caps(inode, CEPH_CAP_FILE_RD, want,
-					true, &got);
-		if (ret < 0) {
-			dout("start_read %p, error getting cap\n", inode);
-		} else if (!(got & want)) {
-			dout("start_read %p, no cache cap\n", inode);
-			ret = 0;
-		}
-		if (ret <= 0) {
-			if (got)
-				ceph_put_cap_refs(ci, got);
-			while (!list_empty(page_list)) {
-				page = lru_to_page(page_list);
-				list_del(&page->lru);
-				put_page(page);
-			}
-			return ret;
-		}
-	}
-
-	off = (u64) page_offset(page);
-
-	/* count pages */
-	next_index = page->index;
-	list_for_each_entry_reverse(page, page_list, lru) {
-		if (page->index != next_index)
-			break;
-		nr_pages++;
-		next_index++;
-		if (max && nr_pages == max)
-			break;
-	}
-	len = nr_pages << PAGE_SHIFT;
-	dout("start_read %p nr_pages %d is %lld~%lld\n", inode, nr_pages,
-	     off, len);
-	vino = ceph_vino(inode);
-	req = ceph_osdc_new_request(osdc, &ci->i_layout, vino, off, &len,
-				    0, 1, CEPH_OSD_OP_READ,
-				    CEPH_OSD_FLAG_READ, NULL,
-				    ci->i_truncate_seq, ci->i_truncate_size,
-				    false);
-	if (IS_ERR(req)) {
-		ret = PTR_ERR(req);
-		goto out;
-	}
-
-	/* build page vector */
-	nr_pages = calc_pages_for(0, len);
-	pages = kmalloc_array(nr_pages, sizeof(*pages), GFP_KERNEL);
-	if (!pages) {
-		ret = -ENOMEM;
-		goto out_put;
-	}
-	for (i = 0; i < nr_pages; ++i) {
-		page = list_entry(page_list->prev, struct page, lru);
-		BUG_ON(PageLocked(page));
-		list_del(&page->lru);
-
- 		dout("start_read %p adding %p idx %lu\n", inode, page,
-		     page->index);
-		if (add_to_page_cache_lru(page, &inode->i_data, page->index,
-					  GFP_KERNEL)) {
-			put_page(page);
-			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;
-				osd_req_op_extent_update(req, 0, len);
-				break;
-			}
-			goto out_pages;
-		}
-		pages[i] = page;
-	}
-	osd_req_op_extent_osd_data_pages(req, 0, pages, len, 0, false, false);
-	req->r_callback = finish_read;
-	req->r_inode = inode;
-
-	dout("start_read %p starting %p %lld~%lld\n", inode, req, off, len);
-	ret = ceph_osdc_start_request(osdc, req, false);
-	if (ret < 0)
-		goto out_pages;
-	ceph_osdc_put_request(req);
-
-	/* After adding locked pages to page cache, the inode holds cache cap.
-	 * So we can drop our cap refs. */
 	if (got)
 		ceph_put_cap_refs(ci, got);
-
-	return nr_pages;
-
-out_pages:
-	for (i = 0; i < nr_pages; ++i)
-		unlock_page(pages[i]);
-	ceph_put_page_vector(pages, nr_pages, false);
-out_put:
-	ceph_osdc_put_request(req);
-out:
-	if (got)
-		ceph_put_cap_refs(ci, got);
-	return ret;
 }
+const struct netfs_read_request_ops ceph_readahead_netfs_ops = {
+	.init_rreq		= ceph_init_rreq,
+	.is_cache_enabled	= ceph_is_cache_enabled,
+	.begin_cache_operation	= ceph_begin_cache_operation,
+	.issue_op		= ceph_netfs_issue_op,
+	.expand_readahead	= ceph_netfs_expand_readahead,
+	.clamp_length		= ceph_netfs_clamp_length,
+	.cleanup		= ceph_readahead_cleanup,
+};
 
-
-/*
- * Read multiple pages.  Leave pages we don't read + unlock in page_list;
- * the caller (VM) cleans them up.
- */
-static int ceph_readpages(struct file *file, struct address_space *mapping,
-			  struct list_head *page_list, unsigned nr_pages)
+static void ceph_readahead(struct readahead_control *ractl)
 {
-	struct inode *inode = file_inode(file);
-	struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
-	struct ceph_file_info *fi = file->private_data;
+	struct inode *inode = file_inode(ractl->file);
+	struct ceph_file_info *fi = ractl->file->private_data;
 	struct ceph_rw_context *rw_ctx;
-	int rc = 0;
-	int max = 0;
+	int got = 0;
+	int ret = 0;
 
 	if (ceph_inode(inode)->i_inline_version != CEPH_INLINE_NONE)
-		return -EINVAL;
+		return;
 
 	rw_ctx = ceph_find_rw_context(fi);
-	max = fsc->mount_options->rsize >> PAGE_SHIFT;
-	dout("readpages %p file %p ctx %p nr_pages %d max %d\n",
-	     inode, file, rw_ctx, nr_pages, max);
-	while (!list_empty(page_list)) {
-		rc = start_read(inode, rw_ctx, page_list, max);
-		if (rc < 0)
-			goto out;
+	if (!rw_ctx) {
+		/*
+		 * readahead callers do not necessarily hold Fcb caps
+		 * (e.g. fadvise, madvise).
+		 */
+		int want = CEPH_CAP_FILE_CACHE;
+
+		ret = ceph_try_get_caps(inode, CEPH_CAP_FILE_RD, want, true, &got);
+		if (ret < 0)
+			dout("start_read %p, error getting cap\n", inode);
+		else if (!(got & want))
+			dout("start_read %p, no cache cap\n", inode);
+
+		if (ret <= 0)
+			return;
 	}
-out:
-	dout("readpages %p file %p ret %d\n", inode, file, rc);
-	return rc;
+	netfs_readahead(ractl, &ceph_readahead_netfs_ops, (void *)(uintptr_t)got);
 }
 
 struct ceph_writeback_ctl
@@ -1501,7 +1341,7 @@ static ssize_t ceph_direct_io(struct kiocb *iocb, struct iov_iter *iter)
 
 const struct address_space_operations ceph_aops = {
 	.readpage = ceph_readpage,
-	.readpages = ceph_readpages,
+	.readahead = ceph_readahead,
 	.writepage = ceph_writepage,
 	.writepages = ceph_writepages_start,
 	.write_begin = ceph_write_begin,
-- 
2.29.2


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 2/6] ceph: rework PageFsCache handling
  2021-02-17 12:58 ` [PATCH v2 2/6] ceph: rework PageFsCache handling Jeff Layton
@ 2021-02-17 14:38   ` Matthew Wilcox
  2021-02-17 14:59     ` Jeff Layton
  0 siblings, 1 reply; 12+ messages in thread
From: Matthew Wilcox @ 2021-02-17 14:38 UTC (permalink / raw)
  To: Jeff Layton
  Cc: dhowells, idryomov, xiubli, ceph-devel, linux-cachefs, linux-fsdevel

On Wed, Feb 17, 2021 at 07:58:41AM -0500, Jeff Layton wrote:
> -static int ceph_releasepage(struct page *page, gfp_t g)
> +static int ceph_releasepage(struct page *page, gfp_t gfp_flags)
>  {
>  	dout("%p releasepage %p idx %lu (%sdirty)\n", page->mapping->host,
>  	     page, page->index, PageDirty(page) ? "" : "not ");
>  
> +	if (PageFsCache(page)) {
> +		if (!(gfp_flags & __GFP_DIRECT_RECLAIM) || !(gfp_flags & __GFP_FS))

If you called it 'gfp' instead of 'gfp_flags', you wouldn't go over 80
columns ;-)

		if (!(gfp & __GFP_DIRECT_RECLAIM) || !(gfp & __GFP_FS))


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 2/6] ceph: rework PageFsCache handling
  2021-02-17 14:38   ` Matthew Wilcox
@ 2021-02-17 14:59     ` Jeff Layton
  0 siblings, 0 replies; 12+ messages in thread
From: Jeff Layton @ 2021-02-17 14:59 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: dhowells, idryomov, xiubli, ceph-devel, linux-cachefs, linux-fsdevel

On Wed, 2021-02-17 at 14:38 +0000, Matthew Wilcox wrote:
> On Wed, Feb 17, 2021 at 07:58:41AM -0500, Jeff Layton wrote:
> > -static int ceph_releasepage(struct page *page, gfp_t g)
> > +static int ceph_releasepage(struct page *page, gfp_t gfp_flags)
> >  {
> >  	dout("%p releasepage %p idx %lu (%sdirty)\n", page->mapping->host,
> >  	     page, page->index, PageDirty(page) ? "" : "not ");
> >  
> > 
> > +	if (PageFsCache(page)) {
> > +		if (!(gfp_flags & __GFP_DIRECT_RECLAIM) || !(gfp_flags & __GFP_FS))
> 
> If you called it 'gfp' instead of 'gfp_flags', you wouldn't go over 80
> columns ;-)
> 
> 		if (!(gfp & __GFP_DIRECT_RECLAIM) || !(gfp & __GFP_FS))
> 

Fair enough -- I'll fix it up since you mentioned it. ;)
-- 
Jeff Layton <jlayton@kernel.org>


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 6/6] ceph: convert ceph_readpages to ceph_readahead
  2021-02-17 12:58 ` [PATCH v2 6/6] ceph: convert ceph_readpages to ceph_readahead Jeff Layton
@ 2021-02-17 15:15   ` Matthew Wilcox
  2021-02-17 15:46     ` Jeff Layton
  0 siblings, 1 reply; 12+ messages in thread
From: Matthew Wilcox @ 2021-02-17 15:15 UTC (permalink / raw)
  To: Jeff Layton
  Cc: dhowells, idryomov, xiubli, ceph-devel, linux-cachefs, linux-fsdevel

On Wed, Feb 17, 2021 at 07:58:45AM -0500, Jeff Layton wrote:
> +static void ceph_readahead_cleanup(struct address_space *mapping, void *priv)
>  {
> +	struct inode *inode = mapping->host;
>  	struct ceph_inode_info *ci = ceph_inode(inode);
> +	int got = (int)(uintptr_t)priv;
>  
>  	if (got)
>  		ceph_put_cap_refs(ci, got);
>  }
> +const struct netfs_read_request_ops ceph_readahead_netfs_ops = {
> +	.init_rreq		= ceph_init_rreq,
> +	.is_cache_enabled	= ceph_is_cache_enabled,
> +	.begin_cache_operation	= ceph_begin_cache_operation,
> +	.issue_op		= ceph_netfs_issue_op,
> +	.expand_readahead	= ceph_netfs_expand_readahead,
> +	.clamp_length		= ceph_netfs_clamp_length,
> +	.cleanup		= ceph_readahead_cleanup,
> +};

It looks to me like this netfs_read_request_ops is the same as the
ceph_readpage_netfs_ops except for the addition of ceph_readahead_cleanup.
If so, since readpage passes NULL as 'priv', the two read_request_ops
can be the same ... right?

also, you don't need that '(int)' cast -- can be just:

	int got = (uintptr_t)priv;

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 6/6] ceph: convert ceph_readpages to ceph_readahead
  2021-02-17 15:15   ` Matthew Wilcox
@ 2021-02-17 15:46     ` Jeff Layton
  0 siblings, 0 replies; 12+ messages in thread
From: Jeff Layton @ 2021-02-17 15:46 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: dhowells, idryomov, xiubli, ceph-devel, linux-cachefs, linux-fsdevel

On Wed, 2021-02-17 at 15:15 +0000, Matthew Wilcox wrote:
> On Wed, Feb 17, 2021 at 07:58:45AM -0500, Jeff Layton wrote:
> > +static void ceph_readahead_cleanup(struct address_space *mapping, void *priv)
> >  {
> > +	struct inode *inode = mapping->host;
> >  	struct ceph_inode_info *ci = ceph_inode(inode);
> > +	int got = (int)(uintptr_t)priv;
> >  
> > 
> > 
> > 
> >  	if (got)
> >  		ceph_put_cap_refs(ci, got);
> >  }
> > +const struct netfs_read_request_ops ceph_readahead_netfs_ops = {
> > +	.init_rreq		= ceph_init_rreq,
> > +	.is_cache_enabled	= ceph_is_cache_enabled,
> > +	.begin_cache_operation	= ceph_begin_cache_operation,
> > +	.issue_op		= ceph_netfs_issue_op,
> > +	.expand_readahead	= ceph_netfs_expand_readahead,
> > +	.clamp_length		= ceph_netfs_clamp_length,
> > +	.cleanup		= ceph_readahead_cleanup,
> > +};
> 
> It looks to me like this netfs_read_request_ops is the same as the
> ceph_readpage_netfs_ops except for the addition of ceph_readahead_cleanup.
> If so, since readpage passes NULL as 'priv', the two read_request_ops
> can be the same ... right?
> 

Yeah. I can also do the same for the write_begin one. The only
difference there is check_write_begin op, and it's only called in the
write_begin helper.

> also, you don't need that '(int)' cast -- can be just:
> 
> 	int got = (uintptr_t)priv;

Got it, fixed. I'll do some testing with this and re-post in a few days
if it all looks good.

Thanks!
-- 
Jeff Layton <jlayton@kernel.org>


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 1/6] ceph: disable old fscache readpage handling
  2021-02-17 12:58 ` [PATCH v2 1/6] ceph: disable old fscache readpage handling Jeff Layton
@ 2021-02-19  5:09   ` Xiubo Li
  2021-02-22 14:47     ` Jeff Layton
  0 siblings, 1 reply; 12+ messages in thread
From: Xiubo Li @ 2021-02-19  5:09 UTC (permalink / raw)
  To: Jeff Layton, dhowells, idryomov; +Cc: ceph-devel, linux-cachefs, linux-fsdevel

On 2021/2/17 20:58, Jeff Layton wrote:
> With the new netfs read helper functions, we won't need a lot of this
> infrastructure as it handles the pagecache pages itself. Rip out the
> read handling for now, and much of the old infrastructure that deals in
> individual pages.
>
> The cookie handling is mostly unchanged, however.
>
> Signed-off-by: Jeff Layton <jlayton@kernel.org>
> Cc: ceph-devel@vger.kernel.org
> Cc: linux-cachefs@redhat.com
> Cc: linux-fsdevel@vger.kernel.org
> ---
>   fs/ceph/addr.c  |  31 +-----------
>   fs/ceph/cache.c | 125 ------------------------------------------------
>   fs/ceph/cache.h |  91 +----------------------------------
>   fs/ceph/caps.c  |   9 ----
>   4 files changed, 3 insertions(+), 253 deletions(-)
>
> diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
> index 950552944436..2b17bb36e548 100644
> --- a/fs/ceph/addr.c
> +++ b/fs/ceph/addr.c
> @@ -155,8 +155,6 @@ static void ceph_invalidatepage(struct page *page, unsigned int offset,
>   		return;
>   	}
>   
> -	ceph_invalidate_fscache_page(inode, page);
> -
>   	WARN_ON(!PageLocked(page));
>   	if (!PagePrivate(page))
>   		return;
> @@ -175,10 +173,6 @@ static int ceph_releasepage(struct page *page, gfp_t g)
>   	dout("%p releasepage %p idx %lu (%sdirty)\n", page->mapping->host,
>   	     page, page->index, PageDirty(page) ? "" : "not ");
>   
> -	/* Can we release the page from the cache? */
> -	if (!ceph_release_fscache_page(page, g))
> -		return 0;
> -
>   	return !PagePrivate(page);
>   }
>   
> @@ -213,10 +207,6 @@ static int ceph_do_readpage(struct file *filp, struct page *page)
>   		return 0;
>   	}
>   
> -	err = ceph_readpage_from_fscache(inode, page);
> -	if (err == 0)
> -		return -EINPROGRESS;
> -
>   	dout("readpage ino %llx.%llx file %p off %llu len %llu page %p index %lu\n",
>   	     vino.ino, vino.snap, filp, off, len, page, page->index);
>   	req = ceph_osdc_new_request(osdc, &ci->i_layout, vino, off, &len, 0, 1,
> @@ -241,7 +231,6 @@ static int ceph_do_readpage(struct file *filp, struct page *page)
>   	if (err == -ENOENT)
>   		err = 0;
>   	if (err < 0) {
> -		ceph_fscache_readpage_cancel(inode, page);
>   		if (err == -EBLOCKLISTED)
>   			fsc->blocklisted = true;
>   		goto out;
> @@ -253,8 +242,6 @@ static int ceph_do_readpage(struct file *filp, struct page *page)
>   		flush_dcache_page(page);
>   
>   	SetPageUptodate(page);
> -	ceph_readpage_to_fscache(inode, page);
> -
>   out:
>   	return err < 0 ? err : 0;
>   }
> @@ -294,10 +281,8 @@ static void finish_read(struct ceph_osd_request *req)
>   	for (i = 0; i < num_pages; i++) {
>   		struct page *page = osd_data->pages[i];
>   
> -		if (rc < 0 && rc != -ENOENT) {
> -			ceph_fscache_readpage_cancel(inode, page);
> +		if (rc < 0 && rc != -ENOENT)
>   			goto unlock;
> -		}
>   		if (bytes < (int)PAGE_SIZE) {
>   			/* zero (remainder of) page */
>   			int s = bytes < 0 ? 0 : bytes;
> @@ -307,7 +292,6 @@ static void finish_read(struct ceph_osd_request *req)
>   		     page->index);
>   		flush_dcache_page(page);
>   		SetPageUptodate(page);
> -		ceph_readpage_to_fscache(inode, page);
>   unlock:
>   		unlock_page(page);
>   		put_page(page);
> @@ -408,7 +392,6 @@ static int start_read(struct inode *inode, struct ceph_rw_context *rw_ctx,
>   		     page->index);
>   		if (add_to_page_cache_lru(page, &inode->i_data, page->index,
>   					  GFP_KERNEL)) {
> -			ceph_fscache_uncache_page(inode, page);
>   			put_page(page);
>   			dout("start_read %p add_to_page_cache failed %p\n",
>   			     inode, page);
> @@ -440,10 +423,8 @@ static int start_read(struct inode *inode, struct ceph_rw_context *rw_ctx,
>   	return nr_pages;
>   
>   out_pages:
> -	for (i = 0; i < nr_pages; ++i) {
> -		ceph_fscache_readpage_cancel(inode, pages[i]);
> +	for (i = 0; i < nr_pages; ++i)
>   		unlock_page(pages[i]);
> -	}
>   	ceph_put_page_vector(pages, nr_pages, false);
>   out_put:
>   	ceph_osdc_put_request(req);
> @@ -471,12 +452,6 @@ static int ceph_readpages(struct file *file, struct address_space *mapping,
>   	if (ceph_inode(inode)->i_inline_version != CEPH_INLINE_NONE)
>   		return -EINVAL;
>   
> -	rc = ceph_readpages_from_fscache(mapping->host, mapping, page_list,
> -					 &nr_pages);
> -
> -	if (rc == 0)
> -		goto out;
> -
>   	rw_ctx = ceph_find_rw_context(fi);
>   	max = fsc->mount_options->rsize >> PAGE_SHIFT;
>   	dout("readpages %p file %p ctx %p nr_pages %d max %d\n",
> @@ -487,8 +462,6 @@ static int ceph_readpages(struct file *file, struct address_space *mapping,
>   			goto out;
>   	}
>   out:
> -	ceph_fscache_readpages_cancel(inode, page_list);
> -
>   	dout("readpages %p file %p ret %d\n", inode, file, rc);
>   	return rc;
>   }
> diff --git a/fs/ceph/cache.c b/fs/ceph/cache.c
> index 2f5cb6bc78e1..9cfadbb86568 100644
> --- a/fs/ceph/cache.c
> +++ b/fs/ceph/cache.c
> @@ -173,7 +173,6 @@ void ceph_fscache_unregister_inode_cookie(struct ceph_inode_info* ci)
>   
>   	ci->fscache = NULL;
>   
> -	fscache_uncache_all_inode_pages(cookie, &ci->vfs_inode);
>   	fscache_relinquish_cookie(cookie, &ci->i_vino, false);
>   }
>   
> @@ -194,7 +193,6 @@ void ceph_fscache_file_set_cookie(struct inode *inode, struct file *filp)
>   		dout("fscache_file_set_cookie %p %p disabling cache\n",
>   		     inode, filp);
>   		fscache_disable_cookie(ci->fscache, &ci->i_vino, false);
> -		fscache_uncache_all_inode_pages(ci->fscache, inode);
>   	} else {
>   		fscache_enable_cookie(ci->fscache, &ci->i_vino, i_size_read(inode),
>   				      ceph_fscache_can_enable, inode);
> @@ -205,108 +203,6 @@ void ceph_fscache_file_set_cookie(struct inode *inode, struct file *filp)
>   	}
>   }
>   
> -static void ceph_readpage_from_fscache_complete(struct page *page, void *data, int error)
> -{
> -	if (!error)
> -		SetPageUptodate(page);
> -
> -	unlock_page(page);
> -}
> -
> -static inline bool cache_valid(struct ceph_inode_info *ci)
> -{
> -	return ci->i_fscache_gen == ci->i_rdcache_gen;
> -}
> -

Hi Jeff,

Please delete the "i_fscache_gen" member from the struct ceph_inode_info 
if we are not using it any more.

Thanks

Xiubo



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 1/6] ceph: disable old fscache readpage handling
  2021-02-19  5:09   ` Xiubo Li
@ 2021-02-22 14:47     ` Jeff Layton
  0 siblings, 0 replies; 12+ messages in thread
From: Jeff Layton @ 2021-02-22 14:47 UTC (permalink / raw)
  To: Xiubo Li, dhowells, idryomov; +Cc: ceph-devel, linux-cachefs, linux-fsdevel

On Fri, 2021-02-19 at 13:09 +0800, Xiubo Li wrote:
> On 2021/2/17 20:58, Jeff Layton wrote:
> > With the new netfs read helper functions, we won't need a lot of this
> > infrastructure as it handles the pagecache pages itself. Rip out the
> > read handling for now, and much of the old infrastructure that deals in
> > individual pages.
> > 
> > The cookie handling is mostly unchanged, however.
> > 
> > Signed-off-by: Jeff Layton <jlayton@kernel.org>
> > Cc: ceph-devel@vger.kernel.org
> > Cc: linux-cachefs@redhat.com
> > Cc: linux-fsdevel@vger.kernel.org
> > ---
> >   fs/ceph/addr.c  |  31 +-----------
> >   fs/ceph/cache.c | 125 ------------------------------------------------
> >   fs/ceph/cache.h |  91 +----------------------------------
> >   fs/ceph/caps.c  |   9 ----
> >   4 files changed, 3 insertions(+), 253 deletions(-)
> > 
> > diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
> > index 950552944436..2b17bb36e548 100644
> > --- a/fs/ceph/addr.c
> > +++ b/fs/ceph/addr.c
> > @@ -155,8 +155,6 @@ static void ceph_invalidatepage(struct page *page, unsigned int offset,
> >   		return;
> >   	}
> >   
> > 
> > -	ceph_invalidate_fscache_page(inode, page);
> > -
> >   	WARN_ON(!PageLocked(page));
> >   	if (!PagePrivate(page))
> >   		return;
> > @@ -175,10 +173,6 @@ static int ceph_releasepage(struct page *page, gfp_t g)
> >   	dout("%p releasepage %p idx %lu (%sdirty)\n", page->mapping->host,
> >   	     page, page->index, PageDirty(page) ? "" : "not ");
> >   
> > 
> > -	/* Can we release the page from the cache? */
> > -	if (!ceph_release_fscache_page(page, g))
> > -		return 0;
> > -
> >   	return !PagePrivate(page);
> >   }
> >   
> > 
> > @@ -213,10 +207,6 @@ static int ceph_do_readpage(struct file *filp, struct page *page)
> >   		return 0;
> >   	}
> >   
> > 
> > -	err = ceph_readpage_from_fscache(inode, page);
> > -	if (err == 0)
> > -		return -EINPROGRESS;
> > -
> >   	dout("readpage ino %llx.%llx file %p off %llu len %llu page %p index %lu\n",
> >   	     vino.ino, vino.snap, filp, off, len, page, page->index);
> >   	req = ceph_osdc_new_request(osdc, &ci->i_layout, vino, off, &len, 0, 1,
> > @@ -241,7 +231,6 @@ static int ceph_do_readpage(struct file *filp, struct page *page)
> >   	if (err == -ENOENT)
> >   		err = 0;
> >   	if (err < 0) {
> > -		ceph_fscache_readpage_cancel(inode, page);
> >   		if (err == -EBLOCKLISTED)
> >   			fsc->blocklisted = true;
> >   		goto out;
> > @@ -253,8 +242,6 @@ static int ceph_do_readpage(struct file *filp, struct page *page)
> >   		flush_dcache_page(page);
> >   
> > 
> >   	SetPageUptodate(page);
> > -	ceph_readpage_to_fscache(inode, page);
> > -
> >   out:
> >   	return err < 0 ? err : 0;
> >   }
> > @@ -294,10 +281,8 @@ static void finish_read(struct ceph_osd_request *req)
> >   	for (i = 0; i < num_pages; i++) {
> >   		struct page *page = osd_data->pages[i];
> >   
> > 
> > -		if (rc < 0 && rc != -ENOENT) {
> > -			ceph_fscache_readpage_cancel(inode, page);
> > +		if (rc < 0 && rc != -ENOENT)
> >   			goto unlock;
> > -		}
> >   		if (bytes < (int)PAGE_SIZE) {
> >   			/* zero (remainder of) page */
> >   			int s = bytes < 0 ? 0 : bytes;
> > @@ -307,7 +292,6 @@ static void finish_read(struct ceph_osd_request *req)
> >   		     page->index);
> >   		flush_dcache_page(page);
> >   		SetPageUptodate(page);
> > -		ceph_readpage_to_fscache(inode, page);
> >   unlock:
> >   		unlock_page(page);
> >   		put_page(page);
> > @@ -408,7 +392,6 @@ static int start_read(struct inode *inode, struct ceph_rw_context *rw_ctx,
> >   		     page->index);
> >   		if (add_to_page_cache_lru(page, &inode->i_data, page->index,
> >   					  GFP_KERNEL)) {
> > -			ceph_fscache_uncache_page(inode, page);
> >   			put_page(page);
> >   			dout("start_read %p add_to_page_cache failed %p\n",
> >   			     inode, page);
> > @@ -440,10 +423,8 @@ static int start_read(struct inode *inode, struct ceph_rw_context *rw_ctx,
> >   	return nr_pages;
> >   
> > 
> >   out_pages:
> > -	for (i = 0; i < nr_pages; ++i) {
> > -		ceph_fscache_readpage_cancel(inode, pages[i]);
> > +	for (i = 0; i < nr_pages; ++i)
> >   		unlock_page(pages[i]);
> > -	}
> >   	ceph_put_page_vector(pages, nr_pages, false);
> >   out_put:
> >   	ceph_osdc_put_request(req);
> > @@ -471,12 +452,6 @@ static int ceph_readpages(struct file *file, struct address_space *mapping,
> >   	if (ceph_inode(inode)->i_inline_version != CEPH_INLINE_NONE)
> >   		return -EINVAL;
> >   
> > 
> > -	rc = ceph_readpages_from_fscache(mapping->host, mapping, page_list,
> > -					 &nr_pages);
> > -
> > -	if (rc == 0)
> > -		goto out;
> > -
> >   	rw_ctx = ceph_find_rw_context(fi);
> >   	max = fsc->mount_options->rsize >> PAGE_SHIFT;
> >   	dout("readpages %p file %p ctx %p nr_pages %d max %d\n",
> > @@ -487,8 +462,6 @@ static int ceph_readpages(struct file *file, struct address_space *mapping,
> >   			goto out;
> >   	}
> >   out:
> > -	ceph_fscache_readpages_cancel(inode, page_list);
> > -
> >   	dout("readpages %p file %p ret %d\n", inode, file, rc);
> >   	return rc;
> >   }
> > diff --git a/fs/ceph/cache.c b/fs/ceph/cache.c
> > index 2f5cb6bc78e1..9cfadbb86568 100644
> > --- a/fs/ceph/cache.c
> > +++ b/fs/ceph/cache.c
> > @@ -173,7 +173,6 @@ void ceph_fscache_unregister_inode_cookie(struct ceph_inode_info* ci)
> >   
> > 
> >   	ci->fscache = NULL;
> >   
> > 
> > -	fscache_uncache_all_inode_pages(cookie, &ci->vfs_inode);
> >   	fscache_relinquish_cookie(cookie, &ci->i_vino, false);
> >   }
> >   
> > 
> > @@ -194,7 +193,6 @@ void ceph_fscache_file_set_cookie(struct inode *inode, struct file *filp)
> >   		dout("fscache_file_set_cookie %p %p disabling cache\n",
> >   		     inode, filp);
> >   		fscache_disable_cookie(ci->fscache, &ci->i_vino, false);
> > -		fscache_uncache_all_inode_pages(ci->fscache, inode);
> >   	} else {
> >   		fscache_enable_cookie(ci->fscache, &ci->i_vino, i_size_read(inode),
> >   				      ceph_fscache_can_enable, inode);
> > @@ -205,108 +203,6 @@ void ceph_fscache_file_set_cookie(struct inode *inode, struct file *filp)
> >   	}
> >   }
> >   
> > 
> > -static void ceph_readpage_from_fscache_complete(struct page *page, void *data, int error)
> > -{
> > -	if (!error)
> > -		SetPageUptodate(page);
> > -
> > -	unlock_page(page);
> > -}
> > -
> > -static inline bool cache_valid(struct ceph_inode_info *ci)
> > -{
> > -	return ci->i_fscache_gen == ci->i_rdcache_gen;
> > -}
> > -
> 
> Hi Jeff,
> 
> Please delete the "i_fscache_gen" member from the struct ceph_inode_info 
> if we are not using it any more.
> 

Good catch. Fixed in my tree. I'll post an updated set in another day or
so with this rolled in.

Thanks,
-- 
Jeff Layton <jlayton@kernel.org>


^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2021-02-22 14:48 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <20210217125845.10319-1-jlayton@kernel.org>
2021-02-17 12:58 ` [PATCH v2 1/6] ceph: disable old fscache readpage handling Jeff Layton
2021-02-19  5:09   ` Xiubo Li
2021-02-22 14:47     ` Jeff Layton
2021-02-17 12:58 ` [PATCH v2 2/6] ceph: rework PageFsCache handling Jeff Layton
2021-02-17 14:38   ` Matthew Wilcox
2021-02-17 14:59     ` Jeff Layton
2021-02-17 12:58 ` [PATCH v2 3/6] ceph: fix fscache invalidation Jeff Layton
2021-02-17 12:58 ` [PATCH v2 4/6] ceph: convert readpage to fscache read helper Jeff Layton
2021-02-17 12:58 ` [PATCH v2 5/6] ceph: plug write_begin into " Jeff Layton
2021-02-17 12:58 ` [PATCH v2 6/6] ceph: convert ceph_readpages to ceph_readahead Jeff Layton
2021-02-17 15:15   ` Matthew Wilcox
2021-02-17 15:46     ` Jeff Layton

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).