aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph/caps.c
diff options
context:
space:
mode:
authorYan, Zheng <zheng.z.yan@intel.com>2013-07-20 22:07:51 -0400
committerSage Weil <sage@inktank.com>2013-08-09 20:55:10 -0400
commitca20c991917ef6a98d6b40184fefe981727d9328 (patch)
treeefc1544a391cf6ffc26b3ddca265788d54acb08f /fs/ceph/caps.c
parent85ce127a9adf5ab9e9d57ddf64c858927d5e546d (diff)
ceph: trim deleted inode
The MDS uses caps message to notify clients about deleted inode. when receiving a such message, invalidate any alias of the inode. This makes the kernel release the inode ASAP. Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com> Reviewed-by: Sage Weil <sage@inktank.com>
Diffstat (limited to 'fs/ceph/caps.c')
-rw-r--r--fs/ceph/caps.c41
1 files changed, 40 insertions, 1 deletions
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index 25442b40c25a..430121a795bd 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -2334,6 +2334,38 @@ void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr,
2334} 2334}
2335 2335
2336/* 2336/*
2337 * Invalidate unlinked inode's aliases, so we can drop the inode ASAP.
2338 */
2339static void invalidate_aliases(struct inode *inode)
2340{
2341 struct dentry *dn, *prev = NULL;
2342
2343 dout("invalidate_aliases inode %p\n", inode);
2344 d_prune_aliases(inode);
2345 /*
2346 * For non-directory inode, d_find_alias() only returns
2347 * connected dentry. After calling d_delete(), the dentry
2348 * become disconnected.
2349 *
2350 * For directory inode, d_find_alias() only can return
2351 * disconnected dentry. But directory inode should have
2352 * one alias at most.
2353 */
2354 while ((dn = d_find_alias(inode))) {
2355 if (dn == prev) {
2356 dput(dn);
2357 break;
2358 }
2359 d_delete(dn);
2360 if (prev)
2361 dput(prev);
2362 prev = dn;
2363 }
2364 if (prev)
2365 dput(prev);
2366}
2367
2368/*
2337 * Handle a cap GRANT message from the MDS. (Note that a GRANT may 2369 * Handle a cap GRANT message from the MDS. (Note that a GRANT may
2338 * actually be a revocation if it specifies a smaller cap set.) 2370 * actually be a revocation if it specifies a smaller cap set.)
2339 * 2371 *
@@ -2363,6 +2395,7 @@ static void handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant,
2363 int writeback = 0; 2395 int writeback = 0;
2364 int revoked_rdcache = 0; 2396 int revoked_rdcache = 0;
2365 int queue_invalidate = 0; 2397 int queue_invalidate = 0;
2398 int deleted_inode = 0;
2366 2399
2367 dout("handle_cap_grant inode %p cap %p mds%d seq %d %s\n", 2400 dout("handle_cap_grant inode %p cap %p mds%d seq %d %s\n",
2368 inode, cap, mds, seq, ceph_cap_string(newcaps)); 2401 inode, cap, mds, seq, ceph_cap_string(newcaps));
@@ -2407,8 +2440,12 @@ static void handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant,
2407 from_kgid(&init_user_ns, inode->i_gid)); 2440 from_kgid(&init_user_ns, inode->i_gid));
2408 } 2441 }
2409 2442
2410 if ((issued & CEPH_CAP_LINK_EXCL) == 0) 2443 if ((issued & CEPH_CAP_LINK_EXCL) == 0) {
2411 set_nlink(inode, le32_to_cpu(grant->nlink)); 2444 set_nlink(inode, le32_to_cpu(grant->nlink));
2445 if (inode->i_nlink == 0 &&
2446 (newcaps & (CEPH_CAP_LINK_SHARED | CEPH_CAP_LINK_EXCL)))
2447 deleted_inode = 1;
2448 }
2412 2449
2413 if ((issued & CEPH_CAP_XATTR_EXCL) == 0 && grant->xattr_len) { 2450 if ((issued & CEPH_CAP_XATTR_EXCL) == 0 && grant->xattr_len) {
2414 int len = le32_to_cpu(grant->xattr_len); 2451 int len = le32_to_cpu(grant->xattr_len);
@@ -2517,6 +2554,8 @@ static void handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant,
2517 ceph_queue_writeback(inode); 2554 ceph_queue_writeback(inode);
2518 if (queue_invalidate) 2555 if (queue_invalidate)
2519 ceph_queue_invalidate(inode); 2556 ceph_queue_invalidate(inode);
2557 if (deleted_inode)
2558 invalidate_aliases(inode);
2520 if (wake) 2559 if (wake)
2521 wake_up_all(&ci->i_cap_wq); 2560 wake_up_all(&ci->i_cap_wq);
2522 2561