All of lore.kernel.org
 help / color / mirror / Atom feed
From: David Howells <dhowells@redhat.com>
To: Jens Axboe <axboe@kernel.dk>, Al Viro <viro@zeniv.linux.org.uk>,
	Christoph Hellwig <hch@infradead.org>
Cc: David Howells <dhowells@redhat.com>,
	Matthew Wilcox <willy@infradead.org>, Jan Kara <jack@suse.cz>,
	Jeff Layton <jlayton@kernel.org>,
	David Hildenbrand <david@redhat.com>,
	Jason Gunthorpe <jgg@nvidia.com>,
	Logan Gunthorpe <logang@deltatee.com>,
	Hillf Danton <hdanton@sina.com>,
	Christian Brauner <brauner@kernel.org>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	linux-fsdevel@vger.kernel.org, linux-block@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-mm@kvack.org,
	Xiubo Li <xiubli@redhat.com>, Christoph Hellwig <hch@lst.de>,
	Ilya Dryomov <idryomov@gmail.com>,
	ceph-devel@vger.kernel.org
Subject: [PATCH v22 16/31] ceph: Provide a splice-read wrapper
Date: Mon, 22 May 2023 14:50:03 +0100	[thread overview]
Message-ID: <20230522135018.2742245-17-dhowells@redhat.com> (raw)
In-Reply-To: <20230522135018.2742245-1-dhowells@redhat.com>

Provide a splice_read wrapper for Ceph.  This does the inode shutdown check
before proceeding and jumps to copy_splice_read() if the file has inline
data or is a synchronous file.

We try and get FILE_RD and either FILE_CACHE and/or FILE_LAZYIO caps and
hold them across filemap_splice_read().  If we fail to get FILE_CACHE or
FILE_LAZYIO capabilities, we use copy_splice_read() instead.

Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: Xiubo Li <xiubli@redhat.com>
cc: Christoph Hellwig <hch@lst.de>
cc: Al Viro <viro@zeniv.linux.org.uk>
cc: Jens Axboe <axboe@kernel.dk>
cc: Ilya Dryomov <idryomov@gmail.com>
cc: Jeff Layton <jlayton@kernel.org>
cc: ceph-devel@vger.kernel.org
cc: linux-fsdevel@vger.kernel.org
cc: linux-block@vger.kernel.org
cc: linux-mm@kvack.org
---

Notes:
    ver #21)
     - Need to drop the caps ref.
     - O_DIRECT is handled by the caller.

 fs/ceph/file.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 64 insertions(+), 1 deletion(-)

diff --git a/fs/ceph/file.c b/fs/ceph/file.c
index f4d8bf7dec88..4285f6cb5d3b 100644
--- a/fs/ceph/file.c
+++ b/fs/ceph/file.c
@@ -1745,6 +1745,69 @@ static ssize_t ceph_read_iter(struct kiocb *iocb, struct iov_iter *to)
 	return ret;
 }
 
+/*
+ * Wrap filemap_splice_read with checks for cap bits on the inode.
+ * Atomically grab references, so that those bits are not released
+ * back to the MDS mid-read.
+ */
+static ssize_t ceph_splice_read(struct file *in, loff_t *ppos,
+				struct pipe_inode_info *pipe,
+				size_t len, unsigned int flags)
+{
+	struct ceph_file_info *fi = in->private_data;
+	struct inode *inode = file_inode(in);
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	ssize_t ret;
+	int want = 0, got = 0;
+	CEPH_DEFINE_RW_CONTEXT(rw_ctx, 0);
+
+	dout("splice_read %p %llx.%llx %llu~%zu trying to get caps on %p\n",
+	     inode, ceph_vinop(inode), *ppos, len, inode);
+
+	if (ceph_inode_is_shutdown(inode))
+		return -ESTALE;
+
+	if (ceph_has_inline_data(ci) ||
+	    (fi->flags & CEPH_F_SYNC))
+		return copy_splice_read(in, ppos, pipe, len, flags);
+
+	ceph_start_io_read(inode);
+
+	want = CEPH_CAP_FILE_CACHE;
+	if (fi->fmode & CEPH_FILE_MODE_LAZY)
+		want |= CEPH_CAP_FILE_LAZYIO;
+
+	ret = ceph_get_caps(in, CEPH_CAP_FILE_RD, want, -1, &got);
+	if (ret < 0)
+		goto out_end;
+
+	if ((got & (CEPH_CAP_FILE_CACHE | CEPH_CAP_FILE_LAZYIO)) == 0) {
+		dout("splice_read/sync %p %llx.%llx %llu~%zu got cap refs on %s\n",
+		     inode, ceph_vinop(inode), *ppos, len,
+		     ceph_cap_string(got));
+
+		ceph_put_cap_refs(ci, got);
+		ceph_end_io_read(inode);
+		return copy_splice_read(in, ppos, pipe, len, flags);
+	}
+
+	dout("splice_read %p %llx.%llx %llu~%zu got cap refs on %s\n",
+	     inode, ceph_vinop(inode), *ppos, len, ceph_cap_string(got));
+
+	rw_ctx.caps = got;
+	ceph_add_rw_context(fi, &rw_ctx);
+	ret = filemap_splice_read(in, ppos, pipe, len, flags);
+	ceph_del_rw_context(fi, &rw_ctx);
+
+	dout("splice_read %p %llx.%llx dropping cap refs on %s = %zd\n",
+	     inode, ceph_vinop(inode), ceph_cap_string(got), ret);
+
+	ceph_put_cap_refs(ci, got);
+out_end:
+	ceph_end_io_read(inode);
+	return ret;
+}
+
 /*
  * Take cap references to avoid releasing caps to MDS mid-write.
  *
@@ -2593,7 +2656,7 @@ const struct file_operations ceph_file_fops = {
 	.lock = ceph_lock,
 	.setlease = simple_nosetlease,
 	.flock = ceph_flock,
-	.splice_read = generic_file_splice_read,
+	.splice_read = ceph_splice_read,
 	.splice_write = iter_file_splice_write,
 	.unlocked_ioctl = ceph_ioctl,
 	.compat_ioctl = compat_ptr_ioctl,


  parent reply	other threads:[~2023-05-22 13:54 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-05-22 13:49 [PATCH v22 00/31] splice: Kill ITER_PIPE David Howells
2023-05-22 13:49 ` [PATCH v22 01/31] splice: Fix filemap_splice_read() to use the correct inode David Howells
2023-05-22 13:49 ` [PATCH v22 02/31] splice: Make filemap_splice_read() check s_maxbytes David Howells
2023-05-22 13:49 ` [PATCH v22 03/31] splice: Rename direct_splice_read() to copy_splice_read() David Howells
2023-05-22 13:49 ` [PATCH v22 04/31] splice: Clean up copy_splice_read() a bit David Howells
2023-05-22 13:49 ` [PATCH v22 05/31] splice: Make do_splice_to() generic and export it David Howells
2023-05-22 13:49 ` [PATCH v22 06/31] splice: Check for zero count in vfs_splice_read() David Howells
2023-05-22 13:49 ` [PATCH v22 07/31] splice: Make splice from an O_DIRECT fd use copy_splice_read() David Howells
2023-05-22 13:49 ` [PATCH v22 08/31] splice: Make splice from a DAX file " David Howells
2023-05-22 13:49   ` David Howells
2023-05-22 13:49 ` [PATCH v22 09/31] shmem: Implement splice-read David Howells
2023-05-22 13:49 ` [PATCH v22 10/31] overlayfs: " David Howells
2023-05-22 13:49 ` [PATCH v22 11/31] coda: " David Howells
2023-05-22 13:49 ` [PATCH v22 12/31] tty, proc, kernfs, random: Use copy_splice_read() David Howells
2023-05-22 13:50 ` [PATCH v22 13/31] net: Make sock_splice_read() use copy_splice_read() by default David Howells
2023-05-22 13:50 ` [PATCH v22 14/31] 9p: Add splice_read wrapper David Howells
2023-05-22 13:50 ` [PATCH v22 15/31] afs: Provide a splice-read wrapper David Howells
2023-05-22 13:50 ` David Howells [this message]
2023-05-22 13:50 ` [PATCH v22 17/31] ecryptfs: " David Howells
2023-05-22 13:50 ` [PATCH v22 18/31] ext4: " David Howells
2023-05-22 13:50 ` [PATCH v22 19/31] f2fs: " David Howells
2023-05-22 13:50   ` [f2fs-dev] " David Howells
2023-05-24  3:01   ` Chao Yu
2023-05-24  3:01     ` [f2fs-dev] " Chao Yu
2023-07-06  0:18   ` patchwork-bot+f2fs
2023-07-06  0:18     ` patchwork-bot+f2fs
2023-05-22 13:50 ` [PATCH v22 20/31] nfs: " David Howells
2023-05-22 13:50 ` [PATCH v22 21/31] ntfs3: " David Howells
2023-05-22 13:50 ` [PATCH v22 22/31] ocfs2: " David Howells
2023-05-22 13:50   ` [Ocfs2-devel] " David Howells via Ocfs2-devel
2023-05-22 13:50 ` [PATCH v22 23/31] orangefs: " David Howells
2023-05-22 13:50 ` [PATCH v22 24/31] xfs: " David Howells
2023-05-22 13:50 ` [PATCH v22 25/31] zonefs: " David Howells
2023-05-23  2:48   ` Damien Le Moal
2023-05-23 20:43   ` David Howells
2023-05-24 23:13     ` Damien Le Moal
2023-05-22 13:50 ` [PATCH v22 26/31] trace: Convert trace/seq to use copy_splice_read() David Howells
2023-05-22 13:50 ` [PATCH v22 27/31] cifs: Use filemap_splice_read() David Howells
2023-05-22 13:50 ` [PATCH v22 28/31] splice: Use filemap_splice_read() instead of generic_file_splice_read() David Howells
2023-05-22 13:50 ` [PATCH v22 29/31] splice: Remove generic_file_splice_read() David Howells
2023-05-22 13:50 ` [PATCH v22 30/31] iov_iter: Kill ITER_PIPE David Howells
2023-05-22 13:50 ` [PATCH v22 31/31] splice: kdoc for filemap_splice_read() and copy_splice_read() David Howells
2023-05-23 17:47 ` [PATCH v22 00/31] splice: Kill ITER_PIPE Jens Axboe

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230522135018.2742245-17-dhowells@redhat.com \
    --to=dhowells@redhat.com \
    --cc=axboe@kernel.dk \
    --cc=brauner@kernel.org \
    --cc=ceph-devel@vger.kernel.org \
    --cc=david@redhat.com \
    --cc=hch@infradead.org \
    --cc=hch@lst.de \
    --cc=hdanton@sina.com \
    --cc=idryomov@gmail.com \
    --cc=jack@suse.cz \
    --cc=jgg@nvidia.com \
    --cc=jlayton@kernel.org \
    --cc=linux-block@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=logang@deltatee.com \
    --cc=torvalds@linux-foundation.org \
    --cc=viro@zeniv.linux.org.uk \
    --cc=willy@infradead.org \
    --cc=xiubli@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.