Commit 66802884 authored by Xuehan Xu's avatar Xuehan Xu Committed by Ilya Dryomov
Browse files

ceph: set timeout conditionally in __cap_delay_requeue

__cap_delay_requeue could be invoked through ceph_check_caps when there
exists caps that needs to be sent and are delayed by "i_hold_caps_min"
or "i_hold_caps_max". If __cap_delay_requeue sets timeout unconditionally,
there could be a chance that some "wanted" caps can not be release for a
long since their timeouts are reset every time they get delayed.

Fixes: http://tracker.ceph.com/issues/36369


Signed-off-by: default avatarXuehan Xu <xuxuehan@360.cn>
Reviewed-by: default avatar"Yan, Zheng" <zyan@redhat.com>
Signed-off-by: default avatarIlya Dryomov <idryomov@gmail.com>
parent 89486833
Loading
Loading
Loading
Loading
+8 −6
Original line number Diff line number Diff line
@@ -519,7 +519,8 @@ static void __cap_set_timeouts(struct ceph_mds_client *mdsc,
 *    -> we take mdsc->cap_delay_lock
 */
static void __cap_delay_requeue(struct ceph_mds_client *mdsc,
				struct ceph_inode_info *ci)
				struct ceph_inode_info *ci,
				bool set_timeout)
{
	dout("__cap_delay_requeue %p flags %d at %lu\n", &ci->vfs_inode,
	     ci->i_ceph_flags, ci->i_hold_caps_max);
@@ -530,6 +531,7 @@ static void __cap_delay_requeue(struct ceph_mds_client *mdsc,
				goto no_change;
			list_del_init(&ci->i_cap_delay_list);
		}
		if (set_timeout)
			__cap_set_timeouts(mdsc, ci);
		list_add_tail(&ci->i_cap_delay_list, &mdsc->cap_delay_list);
no_change:
@@ -720,7 +722,7 @@ void ceph_add_cap(struct inode *inode,
		dout(" issued %s, mds wanted %s, actual %s, queueing\n",
		     ceph_cap_string(issued), ceph_cap_string(wanted),
		     ceph_cap_string(actual_wanted));
		__cap_delay_requeue(mdsc, ci);
		__cap_delay_requeue(mdsc, ci, true);
	}

	if (flags & CEPH_CAP_FLAG_AUTH) {
@@ -1647,7 +1649,7 @@ int __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask,
	if (((was | ci->i_flushing_caps) & CEPH_CAP_FILE_BUFFER) &&
	    (mask & CEPH_CAP_FILE_BUFFER))
		dirty |= I_DIRTY_DATASYNC;
	__cap_delay_requeue(mdsc, ci);
	__cap_delay_requeue(mdsc, ci, true);
	return dirty;
}

@@ -2065,7 +2067,7 @@ ack:

	/* Reschedule delayed caps release if we delayed anything */
	if (delayed)
		__cap_delay_requeue(mdsc, ci);
		__cap_delay_requeue(mdsc, ci, false);

	spin_unlock(&ci->i_ceph_lock);

@@ -2125,7 +2127,7 @@ retry:

		if (delayed) {
			spin_lock(&ci->i_ceph_lock);
			__cap_delay_requeue(mdsc, ci);
			__cap_delay_requeue(mdsc, ci, true);
			spin_unlock(&ci->i_ceph_lock);
		}
	} else {