code: FSImageStorageInspector readAndInspectDirs()
        throws IOException {
      int minLayoutVersion = Integer.MAX_VALUE; // the newest
      int maxLayoutVersion = Integer.MIN_VALUE; // the oldest
      
      // First determine what range of layout versions we're going to inspect
      for (Iterator<StorageDirectory> it = dirIterator();
           it.hasNext();) {
        StorageDirectory sd = it.next();
        if (!sd.getVersionFile().exists()) {
          FSImage.LOG.warn("Storage directory " + sd + " contains no VERSION file. Skipping...");
          continue;
        }
        sd.read(); // sets layoutVersion
        minLayoutVersion = Math.min(minLayoutVersion, getLayoutVersion());
        maxLayoutVersion = Math.max(maxLayoutVersion, getLayoutVersion());
      }
      
      if (minLayoutVersion > maxLayoutVersion) {
        throw new IOException("No storage directories contained VERSION information");
      }
      assert minLayoutVersion <= maxLayoutVersion;
      
      // If we have any storage directories with the new layout version
      // (ie edits_<txnid>) then use the new inspector, which will ignore
      // the old format dirs.
      FSImageStorageInspector inspector;
      if (LayoutVersion.supports(Feature.TXID_BASED_LAYOUT, minLayoutVersion)) {
        inspector = new FSImageTransactionalStorageInspector();
        if (!LayoutVersion.supports(Feature.TXID_BASED_LAYOUT, maxLayoutVersion)) {
          FSImage.LOG.warn("Ignoring one or more storage directories with old layouts");
        }
      } else {
        inspector = new FSImagePreTransactionalStorageInspector(conf);
      }
      
      inspectStorageDirs(inspector);
      return inspector;
    }
docs: Iterate over all of the storage dirs, reading their contents to determine
  their layout versions. Returns an FSImageStorageInspector which has
  inspected each directory.
  
  <b>Note:</b> this can mutate the storage info fields (ctime, version, etc).
  @throws IOException if no valid storage dirs are found