Project

General

Profile

Bug #5418 » 0001-ceph-fix-freeing-inode-vs-removing-session-caps-race.patch

Zheng Yan, 07/23/2013 11:34 PM

View differences:

fs/ceph/inode.c
return inode;
}
struct inode *ceph_lookup_inode(struct super_block *sb, struct ceph_vino vino)
{
struct inode *inode;
ino_t t = ceph_vino_to_ino(vino);
inode = ilookup5_nowait(sb, t, ceph_ino_compare, &vino);
return inode;
}
/*
* get/constuct snapdir inode for a given directory
*/
fs/ceph/mds_client.c
{
dout("remove_session_caps on %p\n", session);
iterate_session_caps(session, remove_session_caps_cb, NULL);
spin_lock(&session->s_cap_lock);
if (session->s_nr_caps > 0) {
struct super_block *sb = session->s_mdsc->fsc->sb;
struct inode *inode;
struct ceph_cap *cap, *prev = NULL;
struct ceph_vino vino;
/*
* iterate_session_caps() skips inodes that are being
* deleted, we need to wait until deletions are complete.
* __wait_on_freeing_inode() is designed for the job,
* but it is not exported, so use lookup inode function
* to access it.
*/
while (!list_empty(&session->s_caps)) {
cap = list_entry(session->s_caps.next,
struct ceph_cap, session_caps);
if (cap == prev)
break;
prev = cap;
vino = cap->ci->i_vino;
spin_unlock(&session->s_cap_lock);
inode = ceph_lookup_inode(sb, vino);
iput(inode);
spin_lock(&session->s_cap_lock);
}
}
spin_unlock(&session->s_cap_lock);
BUG_ON(session->s_nr_caps > 0);
BUG_ON(!list_empty(&session->s_cap_flushing));
cleanup_cap_releases(session);
fs/ceph/super.h
extern struct inode *ceph_get_inode(struct super_block *sb,
struct ceph_vino vino);
extern struct inode *ceph_lookup_inode(struct super_block *sb,
struct ceph_vino vino);
extern struct inode *ceph_get_snapdir(struct inode *parent);
extern int ceph_fill_file_size(struct inode *inode, int issued,
u32 truncate_seq, u64 truncate_size, u64 size);
(4-4/4)