@@ -10374,13 +10374,21 @@ void MDCache::notify_global_snaprealm_update(int snap_op)
1037410374
1037510375struct C_MDC_RetryScanStray : public MDCacheContext {
1037610376 dirfrag_t next;
10377- C_MDC_RetryScanStray (MDCache *c, dirfrag_t n) : MDCacheContext(c), next(n) { }
10377+ std::unique_ptr<MDCache::C_MDS_DumpStrayDirCtx> cmd_ctx;
10378+ C_MDC_RetryScanStray (MDCache *c, dirfrag_t n, std::unique_ptr<MDCache::C_MDS_DumpStrayDirCtx> ctx) :
10379+ MDCacheContext (c), next(n), cmd_ctx(std::move(ctx)) {}
1037810380 void finish (int r) override {
10379- mdcache->scan_stray_dir (next);
10381+ mdcache->scan_stray_dir (next, std::move (cmd_ctx) );
1038010382 }
1038110383};
1038210384
10383- void MDCache::scan_stray_dir (dirfrag_t next)
10385+ /*
10386+ * If the cmd_ctx is not nullptr, the caller is asok command handler,
10387+ * which will block until the on_finish will be called.
10388+ * The cmd_ctx holds the formatter to dump stray dir content while scanning.
10389+ * The function can return EAGAIN, to make possible waiting semantics clear.
10390+ */
10391+ int MDCache::scan_stray_dir (dirfrag_t next, std::unique_ptr<MDCache::C_MDS_DumpStrayDirCtx> cmd_ctx)
1038410392{
1038510393 dout (10 ) << " scan_stray_dir " << next << dendl;
1038610394
@@ -10399,13 +10407,13 @@ void MDCache::scan_stray_dir(dirfrag_t next)
1039910407 continue ;
1040010408
1040110409 if (!dir->can_auth_pin ()) {
10402- dir->add_waiter (CDir::WAIT_UNFREEZE, new C_MDC_RetryScanStray (this , dir->dirfrag ()));
10403- return ;
10410+ dir->add_waiter (CDir::WAIT_UNFREEZE, new C_MDC_RetryScanStray (this , dir->dirfrag (), std::move (cmd_ctx) ));
10411+ return -EAGAIN ;
1040410412 }
1040510413
1040610414 if (!dir->is_complete ()) {
10407- dir->fetch (new C_MDC_RetryScanStray (this , dir->dirfrag ()));
10408- return ;
10415+ dir->fetch (new C_MDC_RetryScanStray (this , dir->dirfrag (), std::move (cmd_ctx) ));
10416+ return -EAGAIN ;
1040910417 }
1041010418
1041110419 for (auto &p : dir->items ) {
@@ -10414,14 +10422,32 @@ void MDCache::scan_stray_dir(dirfrag_t next)
1041410422 CDentry::linkage_t *dnl = dn->get_projected_linkage ();
1041510423 if (dnl->is_primary ()) {
1041610424 CInode *in = dnl->get_inode ();
10425+ // only if we came from asok cmd handler
10426+ if (cmd_ctx) {
10427+ cmd_ctx->begin_dump ();
10428+ cmd_ctx->get_formatter ()->open_object_section (" stray_inode" );
10429+ cmd_ctx->get_formatter ()->dump_int (" ino: " , in->ino ());
10430+ cmd_ctx->get_formatter ()->dump_string (" stray_prior_path: " , in->get_inode ()->stray_prior_path );
10431+ in->dump (cmd_ctx->get_formatter (), CInode::DUMP_CAPS);
10432+ cmd_ctx->get_formatter ()->close_section ();
10433+ }
1041710434 if (in->get_inode ()->nlink == 0 )
1041810435 in->state_set (CInode::STATE_ORPHAN);
10419- maybe_eval_stray (in);
10436+ // no need to evaluate stray when dumping the dir content
10437+ if (!cmd_ctx) {
10438+ maybe_eval_stray (in);
10439+ }
1042010440 }
1042110441 }
1042210442 }
1042310443 next.frag = frag_t ();
1042410444 }
10445+ // only if we came from asok cmd handler
10446+ if (cmd_ctx) {
10447+ cmd_ctx->end_dump ();
10448+ cmd_ctx->finish (0 );
10449+ }
10450+ return 0 ;
1042510451}
1042610452
1042710453void MDCache::fetch_backtrace (inodeno_t ino, int64_t pool, bufferlist& bl, Context *fin)
@@ -10432,9 +10458,10 @@ void MDCache::fetch_backtrace(inodeno_t ino, int64_t pool, bufferlist& bl, Conte
1043210458 mds->logger ->inc (l_mds_openino_backtrace_fetch);
1043310459}
1043410460
10435-
10436-
10437-
10461+ int MDCache::stray_status (std::unique_ptr<C_MDS_DumpStrayDirCtx> ctx)
10462+ {
10463+ return scan_stray_dir (dirfrag_t (), std::move (ctx));
10464+ }
1043810465
1043910466// ========================================================================================
1044010467// DISCOVER
0 commit comments