提交 91dee39e 编写于 作者: S Sage Weil

ceph: fix snap realm splits

The snap realm split was checking i_snap_realm, not the list_head, to
determine if an inode belonged in the new realm.  The check always failed,
which meant we always moved the inode, corrupting the old realm's list and
causing various crashes.

Also wait to release old realm reference to avoid possibility of use after
free.
Signed-off-by: NSage Weil <sage@newdream.net>
上级 c10f5e12
......@@ -869,16 +869,20 @@ void ceph_handle_snap(struct ceph_mds_client *mdsc,
continue;
ci = ceph_inode(inode);
spin_lock(&inode->i_lock);
if (!ci->i_snap_realm)
goto split_skip_inode;
ceph_put_snap_realm(mdsc, ci->i_snap_realm);
spin_lock(&realm->inodes_with_caps_lock);
list_add(&ci->i_snap_realm_item,
&realm->inodes_with_caps);
ci->i_snap_realm = realm;
spin_unlock(&realm->inodes_with_caps_lock);
ceph_get_snap_realm(mdsc, realm);
split_skip_inode:
if (list_empty(&ci->i_snap_realm_item)) {
struct ceph_snap_realm *oldrealm =
ci->i_snap_realm;
dout(" moving %p to split realm %llx %p\n",
inode, realm->ino, realm);
spin_lock(&realm->inodes_with_caps_lock);
list_add(&ci->i_snap_realm_item,
&realm->inodes_with_caps);
ci->i_snap_realm = realm;
spin_unlock(&realm->inodes_with_caps_lock);
ceph_get_snap_realm(mdsc, realm);
ceph_put_snap_realm(mdsc, oldrealm);
}
spin_unlock(&inode->i_lock);
iput(inode);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册