Commit cfb31624 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'ceph-for-6.2-rc1' of https://github.com/ceph/ceph-client

Pull cph update from Ilya Dryomov:
 "A fix to facilitate prompt cap releases on async creates from Xiubo.

  This should address sporadic "client isn't responding to mclientcaps
  (revoke) ..." warnings and potential associated MDS hangs"

* tag 'ceph-for-6.2-rc1' of https://github.com/ceph/ceph-client:
  ceph: try to check caps immediately after async creating finishes
  ceph: remove useless session parameter for check_caps()
parents 87be9499 68c62bee
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1367,7 +1367,7 @@ static int ceph_write_end(struct file *file, struct address_space *mapping,
	folio_put(folio);

	if (check_cap)
		ceph_check_caps(ceph_inode(inode), CHECK_CAPS_AUTHONLY, NULL);
		ceph_check_caps(ceph_inode(inode), CHECK_CAPS_AUTHONLY);

	return copied;
}
+11 −14
Original line number Diff line number Diff line
@@ -1898,8 +1898,7 @@ bool __ceph_should_report_size(struct ceph_inode_info *ci)
 *  CHECK_CAPS_FLUSH - we should flush any dirty caps immediately, without
 *    further delay.
 */
void ceph_check_caps(struct ceph_inode_info *ci, int flags,
		     struct ceph_mds_session *session)
void ceph_check_caps(struct ceph_inode_info *ci, int flags)
{
	struct inode *inode = &ci->netfs.inode;
	struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(inode->i_sb);
@@ -1913,15 +1912,14 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags,
	bool queue_invalidate = false;
	bool tried_invalidate = false;
	bool queue_writeback = false;

	if (session)
		ceph_get_mds_session(session);
	struct ceph_mds_session *session = NULL;

	spin_lock(&ci->i_ceph_lock);
	if (ci->i_ceph_flags & CEPH_I_ASYNC_CREATE) {
		ci->i_ceph_flags |= CEPH_I_ASYNC_CHECK_CAPS;

		/* Don't send messages until we get async create reply */
		spin_unlock(&ci->i_ceph_lock);
		ceph_put_mds_session(session);
		return;
	}

@@ -2851,7 +2849,7 @@ static void check_max_size(struct inode *inode, loff_t endoff)
		check = 1;
	spin_unlock(&ci->i_ceph_lock);
	if (check)
		ceph_check_caps(ci, CHECK_CAPS_AUTHONLY, NULL);
		ceph_check_caps(ci, CHECK_CAPS_AUTHONLY);
}

static inline int get_used_fmode(int caps)
@@ -3140,7 +3138,7 @@ static void __ceph_put_cap_refs(struct ceph_inode_info *ci, int had,
	switch (mode) {
	case PUT_CAP_REFS_SYNC:
		if (last)
			ceph_check_caps(ci, 0, NULL);
			ceph_check_caps(ci, 0);
		else if (flushsnaps)
			ceph_flush_snaps(ci, NULL);
		break;
@@ -3255,7 +3253,7 @@ void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr,
	spin_unlock(&ci->i_ceph_lock);

	if (last) {
		ceph_check_caps(ci, 0, NULL);
		ceph_check_caps(ci, 0);
	} else if (flush_snaps) {
		ceph_flush_snaps(ci, NULL);
	}
@@ -3604,10 +3602,9 @@ static void handle_cap_grant(struct inode *inode,

	mutex_unlock(&session->s_mutex);
	if (check_caps == 1)
		ceph_check_caps(ci, CHECK_CAPS_AUTHONLY | CHECK_CAPS_NOINVAL,
				session);
		ceph_check_caps(ci, CHECK_CAPS_AUTHONLY | CHECK_CAPS_NOINVAL);
	else if (check_caps == 2)
		ceph_check_caps(ci, CHECK_CAPS_NOINVAL, session);
		ceph_check_caps(ci, CHECK_CAPS_NOINVAL);
}

/*
@@ -4333,7 +4330,7 @@ unsigned long ceph_check_delayed_caps(struct ceph_mds_client *mdsc)
		if (inode) {
			spin_unlock(&mdsc->cap_delay_lock);
			dout("check_delayed_caps on %p\n", inode);
			ceph_check_caps(ci, 0, NULL);
			ceph_check_caps(ci, 0);
			iput(inode);
			spin_lock(&mdsc->cap_delay_lock);
		}
@@ -4362,7 +4359,7 @@ static void flush_dirty_session_caps(struct ceph_mds_session *s)
		dout("flush_dirty_caps %llx.%llx\n", ceph_vinop(inode));
		spin_unlock(&mdsc->cap_dirty_lock);
		ceph_wait_on_async_create(inode);
		ceph_check_caps(ci, CHECK_CAPS_FLUSH, NULL);
		ceph_check_caps(ci, CHECK_CAPS_FLUSH);
		iput(inode);
		spin_lock(&mdsc->cap_dirty_lock);
	}
+16 −10
Original line number Diff line number Diff line
@@ -313,7 +313,7 @@ int ceph_renew_caps(struct inode *inode, int fmode)
		spin_unlock(&ci->i_ceph_lock);
		dout("renew caps %p want %s issued %s updating mds_wanted\n",
		     inode, ceph_cap_string(wanted), ceph_cap_string(issued));
		ceph_check_caps(ci, 0, NULL);
		ceph_check_caps(ci, 0);
		return 0;
	}
	spin_unlock(&ci->i_ceph_lock);
@@ -408,7 +408,7 @@ int ceph_open(struct inode *inode, struct file *file)
		if ((issued & wanted) != wanted &&
		    (mds_wanted & wanted) != wanted &&
		    ceph_snap(inode) != CEPH_SNAPDIR)
			ceph_check_caps(ci, 0, NULL);
			ceph_check_caps(ci, 0);

		return ceph_init_file(inode, file, fmode);
	} else if (ceph_snap(inode) != CEPH_NOSNAP &&
@@ -534,14 +534,23 @@ static void wake_async_create_waiters(struct inode *inode,
				      struct ceph_mds_session *session)
{
	struct ceph_inode_info *ci = ceph_inode(inode);
	bool check_cap = false;

	spin_lock(&ci->i_ceph_lock);
	if (ci->i_ceph_flags & CEPH_I_ASYNC_CREATE) {
		ci->i_ceph_flags &= ~CEPH_I_ASYNC_CREATE;
		wake_up_bit(&ci->i_ceph_flags, CEPH_ASYNC_CREATE_BIT);

		if (ci->i_ceph_flags & CEPH_I_ASYNC_CHECK_CAPS) {
			ci->i_ceph_flags &= ~CEPH_I_ASYNC_CHECK_CAPS;
			check_cap = true;
		}
	}
	ceph_kick_flushing_inode_caps(session, ci);
	spin_unlock(&ci->i_ceph_lock);

	if (check_cap)
		ceph_check_caps(ci, CHECK_CAPS_FLUSH);
}

static void ceph_async_create_cb(struct ceph_mds_client *mdsc,
@@ -1092,7 +1101,7 @@ static void ceph_aio_complete(struct inode *inode,
		loff_t endoff = aio_req->iocb->ki_pos + aio_req->total_len;
		if (endoff > i_size_read(inode)) {
			if (ceph_inode_set_size(inode, endoff))
				ceph_check_caps(ci, CHECK_CAPS_AUTHONLY, NULL);
				ceph_check_caps(ci, CHECK_CAPS_AUTHONLY);
		}

		spin_lock(&ci->i_ceph_lock);
@@ -1421,8 +1430,7 @@ ceph_direct_read_write(struct kiocb *iocb, struct iov_iter *iter,
		if (write && pos > size) {
			if (ceph_inode_set_size(inode, pos))
				ceph_check_caps(ceph_inode(inode),
						CHECK_CAPS_AUTHONLY,
						NULL);
						CHECK_CAPS_AUTHONLY);
		}
	}

@@ -1577,8 +1585,7 @@ ceph_sync_write(struct kiocb *iocb, struct iov_iter *from, loff_t pos,
			check_caps = ceph_inode_set_size(inode, pos);
			if (check_caps)
				ceph_check_caps(ceph_inode(inode),
						CHECK_CAPS_AUTHONLY,
						NULL);
						CHECK_CAPS_AUTHONLY);
		}

	}
@@ -1906,7 +1913,7 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from)
		if (dirty)
			__mark_inode_dirty(inode, dirty);
		if (ceph_quota_is_max_bytes_approaching(inode, iocb->ki_pos))
			ceph_check_caps(ci, CHECK_CAPS_FLUSH, NULL);
			ceph_check_caps(ci, CHECK_CAPS_FLUSH);
	}

	dout("aio_write %p %llx.%llx %llu~%u  dropping cap refs on %s\n",
@@ -2521,8 +2528,7 @@ static ssize_t __ceph_copy_file_range(struct file *src_file, loff_t src_off,
		/* Let the MDS know about dst file size change */
		if (ceph_inode_set_size(dst_inode, dst_off) ||
		    ceph_quota_is_max_bytes_approaching(dst_inode, dst_off))
			ceph_check_caps(dst_ci, CHECK_CAPS_AUTHONLY | CHECK_CAPS_FLUSH,
					NULL);
			ceph_check_caps(dst_ci, CHECK_CAPS_AUTHONLY | CHECK_CAPS_FLUSH);
	}
	/* Mark Fw dirty */
	spin_lock(&dst_ci->i_ceph_lock);
+3 −3
Original line number Diff line number Diff line
@@ -1909,7 +1909,7 @@ static void ceph_do_invalidate_pages(struct inode *inode)
	mutex_unlock(&ci->i_truncate_mutex);
out:
	if (check)
		ceph_check_caps(ci, 0, NULL);
		ceph_check_caps(ci, 0);
}

/*
@@ -1969,7 +1969,7 @@ void __ceph_do_pending_vmtruncate(struct inode *inode)
	mutex_unlock(&ci->i_truncate_mutex);

	if (wrbuffer_refs == 0)
		ceph_check_caps(ci, 0, NULL);
		ceph_check_caps(ci, 0);

	wake_up_all(&ci->i_cap_wq);
}
@@ -1991,7 +1991,7 @@ static void ceph_inode_work(struct work_struct *work)
		__ceph_do_pending_vmtruncate(inode);

	if (test_and_clear_bit(CEPH_I_WORK_CHECK_CAPS, &ci->i_work_mask))
		ceph_check_caps(ci, 0, NULL);
		ceph_check_caps(ci, 0);

	if (test_and_clear_bit(CEPH_I_WORK_FLUSH_SNAPS, &ci->i_work_mask))
		ceph_flush_snaps(ci, NULL);
+1 −1
Original line number Diff line number Diff line
@@ -253,7 +253,7 @@ static long ceph_ioctl_lazyio(struct file *file)
		spin_unlock(&ci->i_ceph_lock);
		dout("ioctl_layzio: file %p marked lazy\n", file);

		ceph_check_caps(ci, 0, NULL);
		ceph_check_caps(ci, 0);
	} else {
		dout("ioctl_layzio: file %p already lazy\n", file);
	}
Loading