code: private LockedInodePath lockInodePathById(long id, LockPattern lockPattern)
        throws FileDoesNotExistException {
      int count = 0;
      while (true) {
        Optional<Inode> inode = mInodeStore.get(id);
        if (!inode.isPresent()) {
          throw new FileDoesNotExistException(ExceptionMessage.INODE_DOES_NOT_EXIST.getMessage(id));
        }
        // Compute the path given the target inode.
        StringBuilder builder = new StringBuilder();
        computePathForInode(inode.get(), builder);
        AlluxioURI uri = new AlluxioURI(builder.toString());
  
        boolean valid = false;
        LockedInodePath inodePath = null;
        try {
          inodePath = lockInodePath(uri, lockPattern);
          if (inodePath.getInode().getId() == id) {
            // Set to true, so the path is not unlocked before returning.
            valid = true;
            return inodePath;
          }
          // The path does not end up at the target inode id. Repeat the traversal.
        } catch (InvalidPathException e) {
          // ignore and repeat the loop
          LOG.debug("Inode lookup id {} computed path {} mismatch id. Repeating.", id, uri);
        } finally {
          if (!valid && inodePath != null) {
            inodePath.close();
          }
        }
        count++;
        if (count > PATH_TRAVERSAL_RETRIES) {
          throw new FileDoesNotExistException(
              ExceptionMessage.INODE_DOES_NOT_EXIST_RETRIES.getMessage(id));
        }
      }
    }
docs: Locks existing inodes on the path to the inode specified by an id, in the specified
  {@link LockPattern}. The target inode must exist. This may require multiple traversals of the
  tree, so may be inefficient.
  
  @param id the inode id
  @param lockPattern the {@link LockPattern} to lock the inodes with
  @return the {@link LockedInodePath} representing the locked path of inodes
  @throws FileDoesNotExistException if the target inode does not exist