Two memory management fixes for the filesystem.
-----BEGIN PGP SIGNATURE----- iQFHBAABCAAxFiEEydHwtzie9C7TfviiSn/eOAIR84sFAmEntw0THGlkcnlvbW92 QGdtYWlsLmNvbQAKCRBKf944AhHzi8CFB/4/1LVBiC2P9tqIr0S4rLaCBW91Xm4v oYbqoEuzzzl9FPYndSka2hq5x8wg+0nBCXiejafYVbIZsvE/UN+C5+H1mCD5NwyO imXHJ3lqKuZRHrGCkMSM3TJuOijPIU2gqVR+xb0vIfqjr0mU6YgLvvRBcY0QNimQ gLPoMwFGYwGWSLdcBfnHYSGWzmJk4rE94SSkL9Rg1NjkPslBahOrpA/GwNbltGsU +jYIWAZwpfgu2SCWPdUdYpA/Rw518WjGjZ9pOuZmFKg8R2mSJ4LVb5wZ4bsi1b5j CGc4KjNV+koeSMBlBex1EDdVXvqxkviNiWP1jm4FKz/fWcpD5DWv5467 =t1nf -----END PGP SIGNATURE----- Merge tag 'ceph-for-5.14-rc8' of git://github.com/ceph/ceph-client Pull ceph fixes from Ilya Dryomov: "Two memory management fixes for the filesystem" * tag 'ceph-for-5.14-rc8' of git://github.com/ceph/ceph-client: ceph: fix possible null-pointer dereference in ceph_mdsmap_decode() ceph: correctly handle releasing an embedded cap flush
This commit is contained in:
commit
97d8cc2008
@ -1743,7 +1743,11 @@ int __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask,
|
||||
|
||||
struct ceph_cap_flush *ceph_alloc_cap_flush(void)
|
||||
{
|
||||
return kmem_cache_alloc(ceph_cap_flush_cachep, GFP_KERNEL);
|
||||
struct ceph_cap_flush *cf;
|
||||
|
||||
cf = kmem_cache_alloc(ceph_cap_flush_cachep, GFP_KERNEL);
|
||||
cf->is_capsnap = false;
|
||||
return cf;
|
||||
}
|
||||
|
||||
void ceph_free_cap_flush(struct ceph_cap_flush *cf)
|
||||
@ -1778,7 +1782,7 @@ static bool __detach_cap_flush_from_mdsc(struct ceph_mds_client *mdsc,
|
||||
prev->wake = true;
|
||||
wake = false;
|
||||
}
|
||||
list_del(&cf->g_list);
|
||||
list_del_init(&cf->g_list);
|
||||
return wake;
|
||||
}
|
||||
|
||||
@ -1793,7 +1797,7 @@ static bool __detach_cap_flush_from_ci(struct ceph_inode_info *ci,
|
||||
prev->wake = true;
|
||||
wake = false;
|
||||
}
|
||||
list_del(&cf->i_list);
|
||||
list_del_init(&cf->i_list);
|
||||
return wake;
|
||||
}
|
||||
|
||||
@ -2352,7 +2356,7 @@ static void __kick_flushing_caps(struct ceph_mds_client *mdsc,
|
||||
ci->i_ceph_flags &= ~CEPH_I_KICK_FLUSH;
|
||||
|
||||
list_for_each_entry_reverse(cf, &ci->i_cap_flush_list, i_list) {
|
||||
if (!cf->caps) {
|
||||
if (cf->is_capsnap) {
|
||||
last_snap_flush = cf->tid;
|
||||
break;
|
||||
}
|
||||
@ -2371,7 +2375,7 @@ static void __kick_flushing_caps(struct ceph_mds_client *mdsc,
|
||||
|
||||
first_tid = cf->tid + 1;
|
||||
|
||||
if (cf->caps) {
|
||||
if (!cf->is_capsnap) {
|
||||
struct cap_msg_args arg;
|
||||
|
||||
dout("kick_flushing_caps %p cap %p tid %llu %s\n",
|
||||
@ -3516,7 +3520,7 @@ static void handle_cap_flush_ack(struct inode *inode, u64 flush_tid,
|
||||
cleaned = cf->caps;
|
||||
|
||||
/* Is this a capsnap? */
|
||||
if (cf->caps == 0)
|
||||
if (cf->is_capsnap)
|
||||
continue;
|
||||
|
||||
if (cf->tid <= flush_tid) {
|
||||
@ -3589,8 +3593,9 @@ out:
|
||||
while (!list_empty(&to_remove)) {
|
||||
cf = list_first_entry(&to_remove,
|
||||
struct ceph_cap_flush, i_list);
|
||||
list_del(&cf->i_list);
|
||||
ceph_free_cap_flush(cf);
|
||||
list_del_init(&cf->i_list);
|
||||
if (!cf->is_capsnap)
|
||||
ceph_free_cap_flush(cf);
|
||||
}
|
||||
|
||||
if (wake_ci)
|
||||
|
@ -1616,7 +1616,7 @@ static int remove_session_caps_cb(struct inode *inode, struct ceph_cap *cap,
|
||||
spin_lock(&mdsc->cap_dirty_lock);
|
||||
|
||||
list_for_each_entry(cf, &to_remove, i_list)
|
||||
list_del(&cf->g_list);
|
||||
list_del_init(&cf->g_list);
|
||||
|
||||
if (!list_empty(&ci->i_dirty_item)) {
|
||||
pr_warn_ratelimited(
|
||||
@ -1668,8 +1668,9 @@ static int remove_session_caps_cb(struct inode *inode, struct ceph_cap *cap,
|
||||
struct ceph_cap_flush *cf;
|
||||
cf = list_first_entry(&to_remove,
|
||||
struct ceph_cap_flush, i_list);
|
||||
list_del(&cf->i_list);
|
||||
ceph_free_cap_flush(cf);
|
||||
list_del_init(&cf->i_list);
|
||||
if (!cf->is_capsnap)
|
||||
ceph_free_cap_flush(cf);
|
||||
}
|
||||
|
||||
wake_up_all(&ci->i_cap_wq);
|
||||
|
@ -394,9 +394,11 @@ void ceph_mdsmap_destroy(struct ceph_mdsmap *m)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < m->possible_max_rank; i++)
|
||||
kfree(m->m_info[i].export_targets);
|
||||
kfree(m->m_info);
|
||||
if (m->m_info) {
|
||||
for (i = 0; i < m->possible_max_rank; i++)
|
||||
kfree(m->m_info[i].export_targets);
|
||||
kfree(m->m_info);
|
||||
}
|
||||
kfree(m->m_data_pg_pools);
|
||||
kfree(m);
|
||||
}
|
||||
|
@ -487,6 +487,9 @@ static void ceph_queue_cap_snap(struct ceph_inode_info *ci)
|
||||
pr_err("ENOMEM allocating ceph_cap_snap on %p\n", inode);
|
||||
return;
|
||||
}
|
||||
capsnap->cap_flush.is_capsnap = true;
|
||||
INIT_LIST_HEAD(&capsnap->cap_flush.i_list);
|
||||
INIT_LIST_HEAD(&capsnap->cap_flush.g_list);
|
||||
|
||||
spin_lock(&ci->i_ceph_lock);
|
||||
used = __ceph_caps_used(ci);
|
||||
|
@ -182,8 +182,9 @@ struct ceph_cap {
|
||||
|
||||
struct ceph_cap_flush {
|
||||
u64 tid;
|
||||
int caps; /* 0 means capsnap */
|
||||
int caps;
|
||||
bool wake; /* wake up flush waiters when finish ? */
|
||||
bool is_capsnap; /* true means capsnap */
|
||||
struct list_head g_list; // global
|
||||
struct list_head i_list; // per inode
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user