|
@@ -1069,11 +1069,14 @@ static int trim_caps(struct ceph_mds_client *mdsc,
|
|
int ceph_add_cap_releases(struct ceph_mds_client *mdsc,
|
|
int ceph_add_cap_releases(struct ceph_mds_client *mdsc,
|
|
struct ceph_mds_session *session)
|
|
struct ceph_mds_session *session)
|
|
{
|
|
{
|
|
- struct ceph_msg *msg;
|
|
|
|
|
|
+ struct ceph_msg *msg, *partial = NULL;
|
|
struct ceph_mds_cap_release *head;
|
|
struct ceph_mds_cap_release *head;
|
|
int err = -ENOMEM;
|
|
int err = -ENOMEM;
|
|
int extra = mdsc->client->mount_args->cap_release_safety;
|
|
int extra = mdsc->client->mount_args->cap_release_safety;
|
|
|
|
+ int num;
|
|
|
|
|
|
|
|
+ dout("add_cap_releases %p mds%d extra %d\n", session, session->s_mds,
|
|
|
|
+ extra);
|
|
|
|
|
|
spin_lock(&session->s_cap_lock);
|
|
spin_lock(&session->s_cap_lock);
|
|
|
|
|
|
@@ -1082,9 +1085,14 @@ int ceph_add_cap_releases(struct ceph_mds_client *mdsc,
|
|
struct ceph_msg,
|
|
struct ceph_msg,
|
|
list_head);
|
|
list_head);
|
|
head = msg->front.iov_base;
|
|
head = msg->front.iov_base;
|
|
- extra += CEPH_CAPS_PER_RELEASE - le32_to_cpu(head->num);
|
|
|
|
|
|
+ num = le32_to_cpu(head->num);
|
|
|
|
+ if (num) {
|
|
|
|
+ dout(" partial %p with (%d/%d)\n", msg, num,
|
|
|
|
+ (int)CEPH_CAPS_PER_RELEASE);
|
|
|
|
+ extra += CEPH_CAPS_PER_RELEASE - num;
|
|
|
|
+ partial = msg;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
-
|
|
|
|
while (session->s_num_cap_releases < session->s_nr_caps + extra) {
|
|
while (session->s_num_cap_releases < session->s_nr_caps + extra) {
|
|
spin_unlock(&session->s_cap_lock);
|
|
spin_unlock(&session->s_cap_lock);
|
|
msg = ceph_msg_new(CEPH_MSG_CLIENT_CAPRELEASE, PAGE_CACHE_SIZE,
|
|
msg = ceph_msg_new(CEPH_MSG_CLIENT_CAPRELEASE, PAGE_CACHE_SIZE,
|
|
@@ -1101,19 +1109,14 @@ int ceph_add_cap_releases(struct ceph_mds_client *mdsc,
|
|
session->s_num_cap_releases += CEPH_CAPS_PER_RELEASE;
|
|
session->s_num_cap_releases += CEPH_CAPS_PER_RELEASE;
|
|
}
|
|
}
|
|
|
|
|
|
- if (!list_empty(&session->s_cap_releases)) {
|
|
|
|
- msg = list_first_entry(&session->s_cap_releases,
|
|
|
|
- struct ceph_msg,
|
|
|
|
- list_head);
|
|
|
|
- head = msg->front.iov_base;
|
|
|
|
- if (head->num) {
|
|
|
|
- dout(" queueing non-full %p (%d)\n", msg,
|
|
|
|
- le32_to_cpu(head->num));
|
|
|
|
- list_move_tail(&msg->list_head,
|
|
|
|
- &session->s_cap_releases_done);
|
|
|
|
- session->s_num_cap_releases -=
|
|
|
|
- CEPH_CAPS_PER_RELEASE - le32_to_cpu(head->num);
|
|
|
|
- }
|
|
|
|
|
|
+ if (partial) {
|
|
|
|
+ head = partial->front.iov_base;
|
|
|
|
+ num = le32_to_cpu(head->num);
|
|
|
|
+ dout(" queueing partial %p with %d/%d\n", partial, num,
|
|
|
|
+ (int)CEPH_CAPS_PER_RELEASE);
|
|
|
|
+ list_move_tail(&partial->list_head,
|
|
|
|
+ &session->s_cap_releases_done);
|
|
|
|
+ session->s_num_cap_releases -= CEPH_CAPS_PER_RELEASE - num;
|
|
}
|
|
}
|
|
err = 0;
|
|
err = 0;
|
|
spin_unlock(&session->s_cap_lock);
|
|
spin_unlock(&session->s_cap_lock);
|