diff options
author | Sage Weil <sage@newdream.net> | 2011-03-15 18:53:40 -0400 |
---|---|---|
committer | Sage Weil <sage@newdream.net> | 2011-11-03 12:23:49 -0400 |
commit | b58dc4100b9190f2cb437f1f67ffcb9f9acc4923 (patch) | |
tree | 5956065af3d9b126b8ae4a37551837c389f12702 /fs/ceph/dir.c | |
parent | 3f8ddb032afa729d4bad1bf2965d3ec068de6b72 (diff) |
ceph: clear parent D_COMPLETE flag when on dentry prune
When the VFS prunes a dentry from the cache, clear the D_COMPLETE flag
on the parent dentry. Do this for the live and snapshotted namespaces. Do
not bother for the .snap dir contents, since we do not cache that.
Signed-off-by: Sage Weil <sage@newdream.net>
Diffstat (limited to 'fs/ceph/dir.c')
-rw-r--r-- | fs/ceph/dir.c | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index 382abc9a6a54..97fb155b3242 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c | |||
@@ -1092,7 +1092,33 @@ static int ceph_snapdir_d_revalidate(struct dentry *dentry, | |||
1092 | return 1; | 1092 | return 1; |
1093 | } | 1093 | } |
1094 | 1094 | ||
1095 | /* | ||
1096 | * When the VFS prunes a dentry from the cache, we need to clear the | ||
1097 | * complete flag on the parent directory. | ||
1098 | * | ||
1099 | * Called under dentry->d_lock. | ||
1100 | */ | ||
1101 | static void ceph_d_prune(struct dentry *dentry) | ||
1102 | { | ||
1103 | struct ceph_dentry_info *di; | ||
1104 | |||
1105 | dout("d_release %p\n", dentry); | ||
1106 | |||
1107 | /* do we have a valid parent? */ | ||
1108 | if (!dentry->d_parent || IS_ROOT(dentry)) | ||
1109 | return; | ||
1110 | |||
1111 | /* if we are not hashed, we don't affect D_COMPLETE */ | ||
1112 | if (d_unhashed(dentry)) | ||
1113 | return; | ||
1095 | 1114 | ||
1115 | /* | ||
1116 | * we hold d_lock, so d_parent is stable, and d_fsdata is never | ||
1117 | * cleared until d_release | ||
1118 | */ | ||
1119 | di = ceph_dentry(dentry->d_parent); | ||
1120 | clear_bit(CEPH_D_COMPLETE, &di->flags); | ||
1121 | } | ||
1096 | 1122 | ||
1097 | /* | 1123 | /* |
1098 | * read() on a dir. This weird interface hack only works if mounted | 1124 | * read() on a dir. This weird interface hack only works if mounted |
@@ -1306,6 +1332,7 @@ const struct inode_operations ceph_dir_iops = { | |||
1306 | const struct dentry_operations ceph_dentry_ops = { | 1332 | const struct dentry_operations ceph_dentry_ops = { |
1307 | .d_revalidate = ceph_d_revalidate, | 1333 | .d_revalidate = ceph_d_revalidate, |
1308 | .d_release = ceph_d_release, | 1334 | .d_release = ceph_d_release, |
1335 | .d_prune = ceph_d_prune, | ||
1309 | }; | 1336 | }; |
1310 | 1337 | ||
1311 | const struct dentry_operations ceph_snapdir_dentry_ops = { | 1338 | const struct dentry_operations ceph_snapdir_dentry_ops = { |
@@ -1315,4 +1342,5 @@ const struct dentry_operations ceph_snapdir_dentry_ops = { | |||
1315 | 1342 | ||
1316 | const struct dentry_operations ceph_snap_dentry_ops = { | 1343 | const struct dentry_operations ceph_snap_dentry_ops = { |
1317 | .d_release = ceph_d_release, | 1344 | .d_release = ceph_d_release, |
1345 | .d_prune = ceph_d_prune, | ||
1318 | }; | 1346 | }; |