diff --git a/src/client/Client.cc b/src/client/Client.cc index fae1fecea3a..0f0fb4a6031 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -1777,12 +1777,11 @@ void Client::put_request(MetaRequest *request) request->take_other_inode(&other_in); delete request; - if (other_in) { - if (other_in->dir && - (op == CEPH_MDS_OP_RMDIR || - op == CEPH_MDS_OP_RENAME || - op == CEPH_MDS_OP_RMSNAP)) - _try_to_trim_inode(other_in.get(), false); + if (other_in && + (op == CEPH_MDS_OP_RMDIR || + op == CEPH_MDS_OP_RENAME || + op == CEPH_MDS_OP_RMSNAP)) { + _try_to_trim_inode(other_in.get(), false); } } } @@ -4824,6 +4823,12 @@ void Client::_try_to_trim_inode(Inode *in, bool sched_inval) } } + if (ref > 0 && (in->flags & I_SNAPDIR_OPEN)) { + InodeRef snapdir = open_snapdir(in); + _try_to_trim_inode(snapdir.get(), false); + --ref; + } + if (ref > 0 && in->ll_ref > 0 && sched_inval) { set::iterator q = in->dn_set.begin(); while (q != in->dn_set.end()) { @@ -9487,6 +9492,7 @@ Inode *Client::open_snapdir(Inode *diri) in->dirfragtree.clear(); in->snapdir_parent = diri; + diri->flags |= I_SNAPDIR_OPEN; inode_map[vino] = in; if (use_faked_inos()) _assign_faked_ino(in); diff --git a/src/client/Inode.cc b/src/client/Inode.cc index 68446e7deef..99f763a0c19 100644 --- a/src/client/Inode.cc +++ b/src/client/Inode.cc @@ -15,7 +15,11 @@ Inode::~Inode() { cap_item.remove_myself(); snaprealm_item.remove_myself(); - snapdir_parent.reset(); + + if (snapdir_parent) { + snapdir_parent->flags &= ~I_SNAPDIR_OPEN; + snapdir_parent.reset(); + } if (!oset.objects.empty()) { lsubdout(client->cct, client, 0) << __func__ << ": leftover objects on inode 0x" diff --git a/src/client/Inode.h b/src/client/Inode.h index daead05e19a..b7ed726a2df 100644 --- a/src/client/Inode.h +++ b/src/client/Inode.h @@ -78,6 +78,7 @@ struct CapSnap { #define I_COMPLETE 1 #define I_DIR_ORDERED 2 #define I_CAP_DROPPED 4 +#define I_SNAPDIR_OPEN 8 struct Inode { Client *client;