All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3] ceph: always try to uninline inline data when opening files
@ 2022-05-06 15:38 Xiubo Li
  2022-05-06 16:33 ` Jeff Layton
  0 siblings, 1 reply; 3+ messages in thread
From: Xiubo Li @ 2022-05-06 15:38 UTC (permalink / raw)
  To: jlayton; +Cc: idryomov, vshankar, ceph-devel, Xiubo Li

This will help reduce possible deadlock while holding Fcr to use
getattr for read case.

Usually we shouldn't use getattr to fetch inline data after getting
Fcr caps, because it can cause deadlock. The solution is try uniline
the inline data when opening files, thanks David Howells' previous
work on uninlining the inline data work.

It was caused from one possible call path:
  ceph_filemap_fault()-->
     ceph_get_caps(Fcr);
     filemap_fault()-->
        do_sync_mmap_readahead()-->
           page_cache_ra_order()-->
              read_pages()-->
                 aops->readahead()-->
                    netfs_readahead()-->
                       netfs_begin_read()-->
                          netfs_rreq_submit_slice()-->
                             netfs_read_from_server()-->
                                netfs_ops->issue_read()-->
                                   ceph_netfs_issue_read()-->
                                      ceph_netfs_issue_op_inline()-->
                                         getattr()
      ceph_pu_caps_ref(Fcr);

This because if the Locker state is LOCK_EXEC_MIX for auth MDS, and
the replica MDSes' lock state is LOCK_LOCK. Then the kclient could
get 'Frwcb' caps from both auth and replica MDSes.

But if the getattr is sent to any MDS, the MDS needs to do Locker
transition to LOCK_MIX first and then to LOCK_SYNC. But when
transfering to LOCK_MIX state the MDS Locker need to revoke the Fcb
caps back, but the kclient already holding it and waiting the MDS
to finish.

Signed-off-by: Xiubo Li <xiubli@redhat.com>
---
 fs/ceph/file.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/fs/ceph/file.c b/fs/ceph/file.c
index 8c8226c0feac..5d5386c7ef01 100644
--- a/fs/ceph/file.c
+++ b/fs/ceph/file.c
@@ -241,11 +241,16 @@ static int ceph_init_file_info(struct inode *inode, struct file *file,
 	INIT_LIST_HEAD(&fi->rw_contexts);
 	fi->filp_gen = READ_ONCE(ceph_inode_to_client(inode)->filp_gen);
 
-	if ((file->f_mode & FMODE_WRITE) &&
-	    ci->i_inline_version != CEPH_INLINE_NONE) {
-		ret = ceph_uninline_data(file);
-		if (ret < 0)
+	if (ci->i_inline_version != CEPH_INLINE_NONE) {
+		ret = ceph_pool_perm_check(inode, CEPH_CAP_FILE_WR);
+		if (!ret) {
+			ret = ceph_uninline_data(file);
+			/* Ignore the error for readonly case */
+			if (ret < 0 && (file->f_mode & FMODE_WRITE))
+				goto error;
+		} else if (ret != -EPERM) {
 			goto error;
+		}
 	}
 
 	return 0;
-- 
2.36.0.rc1


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

end of thread, other threads:[~2022-05-07  0:52 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-06 15:38 [PATCH v3] ceph: always try to uninline inline data when opening files Xiubo Li
2022-05-06 16:33 ` Jeff Layton
2022-05-07  0:52   ` Xiubo Li

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.