CEPH_MDS_OP_ENQUEUE_SCRUB = 0x01503,
CEPH_MDS_OP_REPAIR_FRAGSTATS = 0x01504,
CEPH_MDS_OP_REPAIR_INODESTATS = 0x01505,
+ CEPH_MDS_OP_RDLOCK_FRAGSSTATS = 0x01507
};
extern const char *ceph_mds_op_name(int op);
}
bool check_dirfrag_rstats() {
- return immediate(DIRFRAGS, 0);
+ if (in->has_subtree_root_dirfrag()) {
+ in->mdcache->rdlock_dirfrags_stats(in, get_internal_callback(DIRFRAGS));
+ return false;
+ } else {
+ return immediate(DIRFRAGS, 0);
+ }
}
bool _dirfrags(int rval) {
case CEPH_MDS_OP_REPAIR_INODESTATS:
repair_inode_stats_work(mdr);
break;
+ case CEPH_MDS_OP_RDLOCK_FRAGSSTATS:
+ rdlock_dirfrags_stats_work(mdr);
+ break;
default:
ceph_abort();
}
mds->server->respond_to_request(mdr, 0);
}
+void MDCache::rdlock_dirfrags_stats(CInode *diri, MDSInternalContext* fin)
+{
+ MDRequestRef mdr = request_start_internal(CEPH_MDS_OP_RDLOCK_FRAGSSTATS);
+ mdr->pin(diri);
+ mdr->internal_op_private = diri;
+ mdr->internal_op_finish = fin;
+ return rdlock_dirfrags_stats_work(mdr);
+}
+
+void MDCache::rdlock_dirfrags_stats_work(MDRequestRef& mdr)
+{
+ CInode *diri = static_cast<CInode*>(mdr->internal_op_private);
+ dout(10) << __func__ << " " << *diri << dendl;
+ if (!diri->is_auth()) {
+ mds->server->respond_to_request(mdr, -ESTALE);
+ return;
+ }
+ if (!diri->is_dir()) {
+ mds->server->respond_to_request(mdr, -ENOTDIR);
+ return;
+ }
+
+ MutationImpl::LockOpVec lov;
+ lov.add_rdlock(&diri->dirfragtreelock);
+ lov.add_rdlock(&diri->nestlock);
+ lov.add_rdlock(&diri->filelock);
+ if (!mds->locker->acquire_locks(mdr, lov))
+ return;
+ dout(10) << __func__ << " start dirfrags : " << *diri << dendl;
+
+ mds->server->respond_to_request(mdr, 0);
+ return;
+}
+
void MDCache::flush_dentry(std::string_view path, Context *fin)
{
if (is_readonly()) {
Formatter *f, Context *fin);
void repair_inode_stats(CInode *diri);
void repair_dirfrag_stats(CDir *dir);
+ void rdlock_dirfrags_stats(CInode *diri, MDSInternalContext *fin);
// my leader
MDSRank *mds;
void enqueue_scrub_work(MDRequestRef& mdr);
void repair_inode_stats_work(MDRequestRef& mdr);
void repair_dirfrag_stats_work(MDRequestRef& mdr);
+ void rdlock_dirfrags_stats_work(MDRequestRef& mdr);
ceph::unordered_map<inodeno_t,CInode*> inode_map; // map of head inodes by ino
map<vinodeno_t, CInode*> snap_inode_map; // map of snap inodes by ino
class MDSContinuation : public Continuation {
protected:
Server *server;
- MDSContext *get_internal_callback(int stage) {
+ MDSInternalContext *get_internal_callback(int stage) {
return new MDSInternalContextWrapper(server->mds, get_callback(stage));
}
MDSIOContextBase *get_io_callback(int stage) {