private void cleanFileIfNeeded(FileStatus file, HStore store, AtomicLong deletedFiles,
    AtomicLong failedDeletes) {
    if (file.isDirectory()) {
      LOG.trace("This is a Directory {}, skip cleanup", file.getPath());
      return;
    }

    if (!validate(file.getPath())) {
      LOG.trace("Invalid file {}, skip cleanup", file.getPath());
      return;
    }

    if (!isOldEnough(file)) {
      LOG.trace("Fresh file {}, skip cleanup", file.getPath());
      return;
    }

    if (isActiveStorefile(file, store)) {
      LOG.trace("Actively used storefile file {}, skip cleanup", file.getPath());
      return;
    }

    // Compacted files can still have readers and are cleaned by a separate chore, so they have to
    // be skipped here
    if (isCompactedFile(file, store)) {
      LOG.trace("Cleanup is done by a different chore for file {}, skip cleanup", file.getPath());
      return;
    }

    if (isCompactionResultFile(file, store)) {
      LOG.trace("The file is the result of an ongoing compaction {}, skip cleanup", file.getPath());
      return;
    }

    // Adding the check here is enough to prevent accidentally deleting of intact HFiles.
    // If the region is still available, i.e, not closed or closing, all above checks are valid
    // so we are safe to delete the 'broken' files. And if the region is closed or closing when we
    // reach here, since we will always give up deleting, the only possible inconsistency is that
    // the file is broken since the region is not closing or close when performing above checks
    // but here we give up deleting it. So in either way, we will not accidentally deleting intact
    // HFiles, but only give up deleting broken files. But it is OK since we can still
    // delete them in the next round of cleaner run.
    if (!store.getHRegion().isAvailable()) {
      LOG.trace("This store's region {} is no longer open, so it might have moved elsewhere. "
        + "Skipping cleanup.", store.getRegionInfo().getEncodedName());
      return;
    }

    deleteFile(file, store, deletedFiles, failedDeletes);
  }
This Chore, every time it runs, will clear the unsused HFiles in the data folder.
hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/BrokenStoreFileCleaner.java