mirror of
https://github.com/ceph/ceph
synced 2024-12-18 01:16:55 +00:00
client: invalidate snap inodes after removing snapshot
Signed-off-by: Yan, Zheng <zyan@redhat.com>
This commit is contained in:
parent
85e687de87
commit
f180ad149a
@ -1779,8 +1779,10 @@ void Client::put_request(MetaRequest *request)
|
||||
|
||||
if (other_in) {
|
||||
if (other_in->dir &&
|
||||
(op == CEPH_MDS_OP_RMDIR || op == CEPH_MDS_OP_RENAME))
|
||||
_try_to_trim_inode(other_in.get());
|
||||
(op == CEPH_MDS_OP_RMDIR ||
|
||||
op == CEPH_MDS_OP_RENAME ||
|
||||
op == CEPH_MDS_OP_RMSNAP))
|
||||
_try_to_trim_inode(other_in.get(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4797,7 +4799,7 @@ void Client::_schedule_invalidate_dentry_callback(Dentry *dn, bool del)
|
||||
async_dentry_invalidator.queue(new C_Client_DentryInvalidate(this, dn, del));
|
||||
}
|
||||
|
||||
void Client::_try_to_trim_inode(Inode *in)
|
||||
void Client::_try_to_trim_inode(Inode *in, bool sched_inval)
|
||||
{
|
||||
int ref = in->get_num_ref();
|
||||
|
||||
@ -4806,22 +4808,31 @@ void Client::_try_to_trim_inode(Inode *in)
|
||||
p != in->dir->dentries.end(); ) {
|
||||
Dentry *dn = p->second;
|
||||
++p;
|
||||
if (dn->lru_is_expireable())
|
||||
unlink(dn, false, false); // close dir, drop dentry
|
||||
}
|
||||
--ref;
|
||||
}
|
||||
// make sure inode was not freed when closing dir
|
||||
if (ref == 0)
|
||||
return;
|
||||
/* rmsnap removes whole subtree, need trim inodes recursively.
|
||||
* we don't need to invalidate dentries recursively. because
|
||||
* invalidating a directory dentry effectively invalidate
|
||||
* whole subtree */
|
||||
if (in->snapid != CEPH_NOSNAP && dn->inode && dn->inode->is_dir())
|
||||
_try_to_trim_inode(dn->inode.get(), false);
|
||||
|
||||
set<Dentry*>::iterator q = in->dn_set.begin();
|
||||
while (q != in->dn_set.end()) {
|
||||
Dentry *dn = *q++;
|
||||
// FIXME: we play lots of unlink/link tricks when handling MDS replies,
|
||||
// so in->dn_set doesn't always reflect the state of kernel's dcache.
|
||||
_schedule_invalidate_dentry_callback(dn, true);
|
||||
unlink(dn, true, true);
|
||||
if (dn->lru_is_expireable())
|
||||
unlink(dn, true, false); // keep dir, drop dentry
|
||||
}
|
||||
if (in->dir->dentries.empty()) {
|
||||
close_dir(in->dir);
|
||||
--ref;
|
||||
}
|
||||
}
|
||||
|
||||
if (ref > 0 && in->ll_ref > 0 && sched_inval) {
|
||||
set<Dentry*>::iterator q = in->dn_set.begin();
|
||||
while (q != in->dn_set.end()) {
|
||||
Dentry *dn = *q++;
|
||||
// FIXME: we play lots of unlink/link tricks when handling MDS replies,
|
||||
// so in->dn_set doesn't always reflect the state of kernel's dcache.
|
||||
_schedule_invalidate_dentry_callback(dn, true);
|
||||
unlink(dn, true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -4932,7 +4943,7 @@ void Client::handle_cap_grant(MetaSession *session, Inode *in, Cap *cap, MClient
|
||||
|
||||
// may drop inode's last ref
|
||||
if (deleted_inode)
|
||||
_try_to_trim_inode(in);
|
||||
_try_to_trim_inode(in, true);
|
||||
|
||||
m->put();
|
||||
}
|
||||
@ -10905,6 +10916,7 @@ int Client::_rmdir(Inode *dir, const char *name, int uid, int gid)
|
||||
req->set_other_inode(in.get());
|
||||
} else {
|
||||
unlink(de, true, true);
|
||||
req->set_other_inode(in.get());
|
||||
}
|
||||
|
||||
res = make_request(req, uid, gid);
|
||||
|
@ -657,7 +657,7 @@ protected:
|
||||
|
||||
void _schedule_invalidate_dentry_callback(Dentry *dn, bool del);
|
||||
void _async_dentry_invalidate(vinodeno_t dirino, vinodeno_t ino, string& name);
|
||||
void _try_to_trim_inode(Inode *in);
|
||||
void _try_to_trim_inode(Inode *in, bool sched_inval);
|
||||
|
||||
void _schedule_invalidate_callback(Inode *in, int64_t off, int64_t len);
|
||||
void _invalidate_inode_cache(Inode *in);
|
||||
|
Loading…
Reference in New Issue
Block a user