Uploaded image for project: 'WiredTiger'
  1. WiredTiger
  2. WT-12946

__flush_tier_once may unlock the dhandle that is not locked in error path

    • Type: Icon: Bug Bug
    • Resolution: Gone away
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: None
    • Component/s: DHandles
    • Storage Engines
    • StorEng - Defined Pipeline

          while (cursor->next(cursor) == 0) {
              cursor->get_key(cursor, &key);
              cursor->get_value(cursor, &value);
              /* For now just switch tiers which just does metadata manipulation. */
              if (WT_PREFIX_MATCH(key, "tiered:")) {
                  __wt_verbose(
                    session, WT_VERB_TIERED, "FLUSH_TIER_ONCE: %s %s 0x%" PRIx32, key, value, flags);
                  if (!LF_ISSET(WT_FLUSH_TIER_FORCE)) {
                      /*
                       * Check the table's last checkpoint time and only flush trees that have a
                       * checkpoint more recent than the last flush time.
                       */
                      WT_ERR(__wt_meta_checkpoint(session, key, NULL, &ckpt));
                      /*
                       * XXX If/when flush tier no longer requires the checkpoint lock, this needs
                       * consideration.
                       */
                      ckpt_time = ckpt.sec;
                      __wt_meta_checkpoint_free(session, &ckpt);
                      WT_ERR(__wt_config_getones(session, value, "flush_time", &cval));
      
                      /* If nothing has changed, there's nothing to do. */
                      if (ckpt_time == 0 || (uint64_t)cval.val > ckpt_time) {
                          WT_STAT_CONN_INCR(session, flush_tier_skipped);
                          continue;
                      }
                  }
                  /* Only instantiate the handle if we need to flush. */
                  WT_ERR(__wt_session_get_dhandle(session, key, NULL, NULL, 0));
                  /*
                   * When we call wt_tiered_switch the session->dhandle points to the tiered: entry and
                   * the arg is the config string that is currently in the metadata.
                   */
                  WT_ERR(__wt_tiered_switch(session, value));
                  WT_STAT_CONN_INCR(session, flush_tier_switched);
                  WT_ERR(__wt_session_release_dhandle(session));
              }
          }
          WT_ERR(__wt_metadata_cursor_release(session, &cursor));
      
          return (0);
      
      err:
          WT_TRET(__wt_session_release_dhandle(session));
          WT_TRET(__wt_metadata_cursor_release(session, &cursor));
          return (ret);
      

      The line WT_ERR(__wt_session_get_dhandle(session, key, NULL, NULL, 0)); may fail without locking the dhandle. Therefore, in the error path, we may unlock the dhandle without locking it before.

            Assignee:
            backlog-server-storage-engines [DO NOT USE] Backlog - Storage Engines Team
            Reporter:
            chenhao.qu@mongodb.com Chenhao Qu
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved: