diff options
author | Sage Weil <sage@newdream.net> | 2011-02-28 15:49:15 -0500 |
---|---|---|
committer | Sage Weil <sage@newdream.net> | 2011-03-03 13:09:52 -0500 |
commit | 16a8b70a5a757db513f036bbcc73309f6c507d81 (patch) | |
tree | e075716a8e58149894fcad3fa36ebf6ea16cfc6e /fs/ceph | |
parent | b545cc1505eb49247071ce9f4092665de788ca00 (diff) |
ceph: do not clear I_COMPLETE from d_release
First, this was racy anyway: d_release isn't called until well after the
dentry is unhashed. Second, this runs afoul of the recent dcache change
that clears d_parent prior to calling d_release (949854d0), causing a NULL
pointer dereference.
Signed-off-by: Sage Weil <sage@newdream.net>
Diffstat (limited to 'fs/ceph')
-rw-r--r-- | fs/ceph/dir.c | 22 |
1 files changed, 1 insertions, 21 deletions
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index 9b4f9d9947b3..196fd4c62db7 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c | |||
@@ -1029,28 +1029,8 @@ out_touch: | |||
1029 | static void ceph_dentry_release(struct dentry *dentry) | 1029 | static void ceph_dentry_release(struct dentry *dentry) |
1030 | { | 1030 | { |
1031 | struct ceph_dentry_info *di = ceph_dentry(dentry); | 1031 | struct ceph_dentry_info *di = ceph_dentry(dentry); |
1032 | struct inode *parent_inode = NULL; | ||
1033 | u64 snapid = CEPH_NOSNAP; | ||
1034 | 1032 | ||
1035 | if (!IS_ROOT(dentry)) { | 1033 | dout("dentry_release %p\n", dentry); |
1036 | parent_inode = dentry->d_parent->d_inode; | ||
1037 | if (parent_inode) | ||
1038 | snapid = ceph_snap(parent_inode); | ||
1039 | } | ||
1040 | dout("dentry_release %p parent %p\n", dentry, parent_inode); | ||
1041 | if (parent_inode && snapid != CEPH_SNAPDIR) { | ||
1042 | struct ceph_inode_info *ci = ceph_inode(parent_inode); | ||
1043 | |||
1044 | spin_lock(&parent_inode->i_lock); | ||
1045 | if (ci->i_shared_gen == di->lease_shared_gen || | ||
1046 | snapid <= CEPH_MAXSNAP) { | ||
1047 | dout(" clearing %p complete (d_release)\n", | ||
1048 | parent_inode); | ||
1049 | ci->i_ceph_flags &= ~CEPH_I_COMPLETE; | ||
1050 | ci->i_release_count++; | ||
1051 | } | ||
1052 | spin_unlock(&parent_inode->i_lock); | ||
1053 | } | ||
1054 | if (di) { | 1034 | if (di) { |
1055 | ceph_dentry_lru_del(dentry); | 1035 | ceph_dentry_lru_del(dentry); |
1056 | if (di->lease_session) | 1036 | if (di->lease_session) |