@@ -2035,6 +2035,10 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags)
struct ceph_mds_session *session = NULL;
spin_lock(&ci->i_ceph_lock);
+
+ /* Cancel the delay caps checking */
+ __cap_delay_cancel(mdsc, ci);
+
if (ci->i_ceph_flags & CEPH_I_ASYNC_CREATE) {
ci->i_ceph_flags |= CEPH_I_ASYNC_CHECK_CAPS;
@@ -4644,8 +4648,6 @@ unsigned long ceph_check_delayed_caps(struct ceph_mds_client *mdsc)
if (time_before(jiffies, ci->i_hold_caps_max))
break;
}
- list_del_init(&ci->i_cap_delay_list);
-
inode = igrab(&ci->netfs.inode);
if (inode) {
spin_unlock(&mdsc->cap_delay_lock);
@@ -4654,7 +4656,10 @@ unsigned long ceph_check_delayed_caps(struct ceph_mds_client *mdsc)
ceph_check_caps(ci, 0);
iput(inode);
spin_lock(&mdsc->cap_delay_lock);
+ } else {
+ list_del_init(&ci->i_cap_delay_list);
}
+
}
spin_unlock(&mdsc->cap_delay_lock);
doutc(cl, "done\n");
@@ -2160,6 +2160,7 @@ static int trim_caps_cb(struct inode *inode, int mds, void *arg)
struct ceph_inode_info *ci = ceph_inode(inode);
int used, wanted, oissued, mine;
struct ceph_cap *cap;
+ bool check_cap = false;
if (*remaining <= 0)
return -1;
@@ -2180,9 +2181,6 @@ static int trim_caps_cb(struct inode *inode, int mds, void *arg)
ceph_cap_string(oissued), ceph_cap_string(used),
ceph_cap_string(wanted));
if (cap == ci->i_auth_cap) {
- if (ci->i_dirty_caps || ci->i_flushing_caps ||
- !list_empty(&ci->i_cap_snaps))
- goto out;
if ((used | wanted) & CEPH_CAP_ANY_WR)
goto out;
/* Note: it's possible that i_filelock_ref becomes non-zero
@@ -2190,6 +2188,8 @@ static int trim_caps_cb(struct inode *inode, int mds, void *arg)
* of lock mds request will re-add auth caps. */
if (atomic_read(&ci->i_filelock_ref) > 0)
goto out;
+ if (ci->i_dirty_caps || !list_empty(&ci->i_cap_snaps))
+ check_cap = true;
}
/* The inode has cached pages, but it's no longer used.
* we can safely drop it */
@@ -2202,7 +2202,7 @@ static int trim_caps_cb(struct inode *inode, int mds, void *arg)
if ((used | wanted) & ~oissued & mine)
goto out; /* we need these caps */
- if (oissued) {
+ if (oissued && cap != ci->i_auth_cap) {
/* we aren't the only cap.. just remove us */
ceph_remove_cap(mdsc, cap, true);
(*remaining)--;
@@ -2223,11 +2223,15 @@ static int trim_caps_cb(struct inode *inode, int mds, void *arg)
} else {
dput(dentry);
}
- return 0;
+ goto unlocked;
}
out:
spin_unlock(&ci->i_ceph_lock);
+
+unlocked:
+ if (check_cap)
+ ceph_check_caps(ci, CHECK_CAPS_FLUSH);
return 0;
}