Commit 97d8cc20 authored by Linus Torvalds's avatar Linus Torvalds

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
parents 9b49ceb8 a9e6ffbc
...@@ -1743,7 +1743,11 @@ int __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask, ...@@ -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) 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) 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, ...@@ -1778,7 +1782,7 @@ static bool __detach_cap_flush_from_mdsc(struct ceph_mds_client *mdsc,
prev->wake = true; prev->wake = true;
wake = false; wake = false;
} }
list_del(&cf->g_list); list_del_init(&cf->g_list);
return wake; return wake;
} }
...@@ -1793,7 +1797,7 @@ static bool __detach_cap_flush_from_ci(struct ceph_inode_info *ci, ...@@ -1793,7 +1797,7 @@ static bool __detach_cap_flush_from_ci(struct ceph_inode_info *ci,
prev->wake = true; prev->wake = true;
wake = false; wake = false;
} }
list_del(&cf->i_list); list_del_init(&cf->i_list);
return wake; return wake;
} }
...@@ -2352,7 +2356,7 @@ static void __kick_flushing_caps(struct ceph_mds_client *mdsc, ...@@ -2352,7 +2356,7 @@ static void __kick_flushing_caps(struct ceph_mds_client *mdsc,
ci->i_ceph_flags &= ~CEPH_I_KICK_FLUSH; ci->i_ceph_flags &= ~CEPH_I_KICK_FLUSH;
list_for_each_entry_reverse(cf, &ci->i_cap_flush_list, i_list) { 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; last_snap_flush = cf->tid;
break; break;
} }
...@@ -2371,7 +2375,7 @@ static void __kick_flushing_caps(struct ceph_mds_client *mdsc, ...@@ -2371,7 +2375,7 @@ static void __kick_flushing_caps(struct ceph_mds_client *mdsc,
first_tid = cf->tid + 1; first_tid = cf->tid + 1;
if (cf->caps) { if (!cf->is_capsnap) {
struct cap_msg_args arg; struct cap_msg_args arg;
dout("kick_flushing_caps %p cap %p tid %llu %s\n", 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, ...@@ -3516,7 +3520,7 @@ static void handle_cap_flush_ack(struct inode *inode, u64 flush_tid,
cleaned = cf->caps; cleaned = cf->caps;
/* Is this a capsnap? */ /* Is this a capsnap? */
if (cf->caps == 0) if (cf->is_capsnap)
continue; continue;
if (cf->tid <= flush_tid) { if (cf->tid <= flush_tid) {
...@@ -3589,7 +3593,8 @@ static void handle_cap_flush_ack(struct inode *inode, u64 flush_tid, ...@@ -3589,7 +3593,8 @@ static void handle_cap_flush_ack(struct inode *inode, u64 flush_tid,
while (!list_empty(&to_remove)) { while (!list_empty(&to_remove)) {
cf = list_first_entry(&to_remove, cf = list_first_entry(&to_remove,
struct ceph_cap_flush, i_list); struct ceph_cap_flush, i_list);
list_del(&cf->i_list); list_del_init(&cf->i_list);
if (!cf->is_capsnap)
ceph_free_cap_flush(cf); ceph_free_cap_flush(cf);
} }
......
...@@ -1616,7 +1616,7 @@ static int remove_session_caps_cb(struct inode *inode, struct ceph_cap *cap, ...@@ -1616,7 +1616,7 @@ static int remove_session_caps_cb(struct inode *inode, struct ceph_cap *cap,
spin_lock(&mdsc->cap_dirty_lock); spin_lock(&mdsc->cap_dirty_lock);
list_for_each_entry(cf, &to_remove, i_list) 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)) { if (!list_empty(&ci->i_dirty_item)) {
pr_warn_ratelimited( pr_warn_ratelimited(
...@@ -1668,7 +1668,8 @@ static int remove_session_caps_cb(struct inode *inode, struct ceph_cap *cap, ...@@ -1668,7 +1668,8 @@ static int remove_session_caps_cb(struct inode *inode, struct ceph_cap *cap,
struct ceph_cap_flush *cf; struct ceph_cap_flush *cf;
cf = list_first_entry(&to_remove, cf = list_first_entry(&to_remove,
struct ceph_cap_flush, i_list); struct ceph_cap_flush, i_list);
list_del(&cf->i_list); list_del_init(&cf->i_list);
if (!cf->is_capsnap)
ceph_free_cap_flush(cf); ceph_free_cap_flush(cf);
} }
......
...@@ -394,9 +394,11 @@ void ceph_mdsmap_destroy(struct ceph_mdsmap *m) ...@@ -394,9 +394,11 @@ void ceph_mdsmap_destroy(struct ceph_mdsmap *m)
{ {
int i; int i;
if (m->m_info) {
for (i = 0; i < m->possible_max_rank; i++) for (i = 0; i < m->possible_max_rank; i++)
kfree(m->m_info[i].export_targets); kfree(m->m_info[i].export_targets);
kfree(m->m_info); kfree(m->m_info);
}
kfree(m->m_data_pg_pools); kfree(m->m_data_pg_pools);
kfree(m); kfree(m);
} }
......
...@@ -487,6 +487,9 @@ static void ceph_queue_cap_snap(struct ceph_inode_info *ci) ...@@ -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); pr_err("ENOMEM allocating ceph_cap_snap on %p\n", inode);
return; 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); spin_lock(&ci->i_ceph_lock);
used = __ceph_caps_used(ci); used = __ceph_caps_used(ci);
......
...@@ -182,8 +182,9 @@ struct ceph_cap { ...@@ -182,8 +182,9 @@ struct ceph_cap {
struct ceph_cap_flush { struct ceph_cap_flush {
u64 tid; u64 tid;
int caps; /* 0 means capsnap */ int caps;
bool wake; /* wake up flush waiters when finish ? */ bool wake; /* wake up flush waiters when finish ? */
bool is_capsnap; /* true means capsnap */
struct list_head g_list; // global struct list_head g_list; // global
struct list_head i_list; // per inode struct list_head i_list; // per inode
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment