ceph: skip checking caps when session reconnecting and releasing reqs

It make no sense to check the caps when reconnecting to mds. And
for the async dirop caps, they will be put by its _cb() function,
so when releasing the requests, it will make no sense too.

URL: https://tracker.ceph.com/issues/45635
Signed-off-by: Xiubo Li <xiubli@redhat.com>
Reviewed-by: "Yan, Zheng" <zyan@redhat.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
This commit is contained in:
Xiubo Li 2020-05-27 09:09:27 -04:00 коммит произвёл Ilya Dryomov
Родитель ea8412b284
Коммит e64f44a884
4 изменённых файлов: 30 добавлений и 4 удалений

Просмотреть файл

@ -3016,7 +3016,8 @@ static int ceph_try_drop_cap_snap(struct ceph_inode_info *ci,
* If we are releasing a WR cap (from a sync write), finalize any affected * If we are releasing a WR cap (from a sync write), finalize any affected
* cap_snap, and wake up any waiters. * cap_snap, and wake up any waiters.
*/ */
void ceph_put_cap_refs(struct ceph_inode_info *ci, int had) static void __ceph_put_cap_refs(struct ceph_inode_info *ci, int had,
bool skip_checking_caps)
{ {
struct inode *inode = &ci->vfs_inode; struct inode *inode = &ci->vfs_inode;
int last = 0, put = 0, flushsnaps = 0, wake = 0; int last = 0, put = 0, flushsnaps = 0, wake = 0;
@ -3072,7 +3073,7 @@ void ceph_put_cap_refs(struct ceph_inode_info *ci, int had)
dout("put_cap_refs %p had %s%s%s\n", inode, ceph_cap_string(had), dout("put_cap_refs %p had %s%s%s\n", inode, ceph_cap_string(had),
last ? " last" : "", put ? " put" : ""); last ? " last" : "", put ? " put" : "");
if (last) if (last && !skip_checking_caps)
ceph_check_caps(ci, 0, NULL); ceph_check_caps(ci, 0, NULL);
else if (flushsnaps) else if (flushsnaps)
ceph_flush_snaps(ci, NULL); ceph_flush_snaps(ci, NULL);
@ -3082,6 +3083,16 @@ void ceph_put_cap_refs(struct ceph_inode_info *ci, int had)
iput(inode); iput(inode);
} }
void ceph_put_cap_refs(struct ceph_inode_info *ci, int had)
{
__ceph_put_cap_refs(ci, had, false);
}
void ceph_put_cap_refs_no_check_caps(struct ceph_inode_info *ci, int had)
{
__ceph_put_cap_refs(ci, had, true);
}
/* /*
* Release @nr WRBUFFER refs on dirty pages for the given @snapc snap * Release @nr WRBUFFER refs on dirty pages for the given @snapc snap
* context. Adjust per-snap dirty page accounting as appropriate. * context. Adjust per-snap dirty page accounting as appropriate.

Просмотреть файл

@ -804,7 +804,7 @@ void ceph_mdsc_release_request(struct kref *kref)
struct ceph_mds_request *req = container_of(kref, struct ceph_mds_request *req = container_of(kref,
struct ceph_mds_request, struct ceph_mds_request,
r_kref); r_kref);
ceph_mdsc_release_dir_caps(req); ceph_mdsc_release_dir_caps_no_check(req);
destroy_reply_info(&req->r_reply_info); destroy_reply_info(&req->r_reply_info);
if (req->r_request) if (req->r_request)
ceph_msg_put(req->r_request); ceph_msg_put(req->r_request);
@ -3402,6 +3402,18 @@ void ceph_mdsc_release_dir_caps(struct ceph_mds_request *req)
} }
} }
void ceph_mdsc_release_dir_caps_no_check(struct ceph_mds_request *req)
{
int dcaps;
dcaps = xchg(&req->r_dir_caps, 0);
if (dcaps) {
dout("releasing r_dir_caps=%s\n", ceph_cap_string(dcaps));
ceph_put_cap_refs_no_check_caps(ceph_inode(req->r_parent),
dcaps);
}
}
/* /*
* called under session->mutex. * called under session->mutex.
*/ */
@ -3434,7 +3446,7 @@ static void replay_unsafe_requests(struct ceph_mds_client *mdsc,
if (req->r_session->s_mds != session->s_mds) if (req->r_session->s_mds != session->s_mds)
continue; continue;
ceph_mdsc_release_dir_caps(req); ceph_mdsc_release_dir_caps_no_check(req);
__send_request(mdsc, session, req, true); __send_request(mdsc, session, req, true);
} }

Просмотреть файл

@ -507,6 +507,7 @@ extern int ceph_mdsc_do_request(struct ceph_mds_client *mdsc,
struct inode *dir, struct inode *dir,
struct ceph_mds_request *req); struct ceph_mds_request *req);
extern void ceph_mdsc_release_dir_caps(struct ceph_mds_request *req); extern void ceph_mdsc_release_dir_caps(struct ceph_mds_request *req);
extern void ceph_mdsc_release_dir_caps_no_check(struct ceph_mds_request *req);
static inline void ceph_mdsc_get_request(struct ceph_mds_request *req) static inline void ceph_mdsc_get_request(struct ceph_mds_request *req)
{ {
kref_get(&req->r_kref); kref_get(&req->r_kref);

Просмотреть файл

@ -1095,6 +1095,8 @@ extern void ceph_take_cap_refs(struct ceph_inode_info *ci, int caps,
bool snap_rwsem_locked); bool snap_rwsem_locked);
extern void ceph_get_cap_refs(struct ceph_inode_info *ci, int caps); extern void ceph_get_cap_refs(struct ceph_inode_info *ci, int caps);
extern void ceph_put_cap_refs(struct ceph_inode_info *ci, int had); extern void ceph_put_cap_refs(struct ceph_inode_info *ci, int had);
extern void ceph_put_cap_refs_no_check_caps(struct ceph_inode_info *ci,
int had);
extern void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr, extern void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr,
struct ceph_snap_context *snapc); struct ceph_snap_context *snapc);
extern void ceph_flush_snaps(struct ceph_inode_info *ci, extern void ceph_flush_snaps(struct ceph_inode_info *ci,