Repository: containerd/containerd
File: internal/erofsutils/mount_linux.go (Go)

Code before:

	// For regular readers, create a temporary file
	tempFile, err := os.CreateTemp("", "erofs-tar-*")
	if err != nil {
		return nil, false, fmt.Errorf("failed to create temporary tar file: %w", err)
	}

	// For temp files, we need to copy the content
	if _, err := io.Copy(tempFile, r); err != nil {
		tempFile.Close()
		os.Remove(tempFile.Name())
		return nil, false, fmt.Errorf("failed to write tar content to temp file: %w", err)
	}

	// Reset to beginning of file
	if _, err := tempFile.Seek(0, io.SeekStart); err != nil {
		tempFile.Close()
		os.Remove(tempFile.Name())
		return nil, false, fmt.Errorf("failed to seek to beginning of tar file: %w", err)
	}

	return tempFile, true, nil
}

// GenerateTarIndexAndAppendTar calculates tar index using --tar=i option
// and appends the original tar content to create a combined EROFS layer.
//
// The `--tar=i` option instructs mkfs.erofs to only generate the tar index
// for the tar content. The resulting file structure is:
// [Tar index][Original tar content]
func GenerateTarIndexAndAppendTar(ctx context.Context, r io.Reader, layerPath string, mkfsExtraOpts []string) error {
	tarFile, isTemp, err := prepareInputFile(ctx, r)
	if err != nil {
		return err
	}

	if isTemp {
		defer func() {
			tarFile.Close()
			os.Remove(tarFile.Name())
		}()
	}

	// Generate tar index directly to layerPath using --tar=i option
	args := append([]string{"--tar=i", "--aufs", "--quiet"}, mkfsExtraOpts...)
	args = append(args, layerPath)
	cmd := exec.CommandContext(ctx, "mkfs.erofs", args...)
	cmd.Stdin = tarFile
	out, err := cmd.CombinedOutput()
	if err != nil {
		return fmt.Errorf("tar index generation failed with command 'mkfs.erofs %s': %s: %w",

Review comment (suggestion):
we could consider to try to use `FALLOC_FL_INSERT_RANGE` later if needed too.

Code after:
	if err != nil {
		return fmt.Errorf("failed to create temporary tar file: %w", err)
	}
	defer os.Remove(tarFile.Name())
	defer tarFile.Close()

	// Use TeeReader to process the input once while saving it to disk
	teeReader := io.TeeReader(r, tarFile)

	// Generate tar index directly to layerPath using --tar=i option
	args := append([]string{"--tar=i", "--aufs", "--quiet"}, mkfsExtraOpts...)
	args = append(args, layerPath)
	cmd := exec.CommandContext(ctx, "mkfs.erofs", args...)
	cmd.Stdin = teeReader
	out, err := cmd.CombinedOutput()
	if err != nil {
		return fmt.Errorf("tar index generation failed with command 'mkfs.erofs %s': %s: %w",
			strings.Join(args, " "), out, err)
	}

	// Log the command execution for debugging
	log.G(ctx).Tracef("Generated tar index with command: %s %s, output: %s",
		cmd.Path, strings.Join(cmd.Args, " "), string(out))

	// Open layerPath for appending
	f, err := os.OpenFile(layerPath, os.O_APPEND|os.O_WRONLY, 0644)
	if err != nil {
		return fmt.Errorf("failed to open layer file for appending: %w", err)
	}
	defer f.Close()

	// Rewind the temporary file
	if _, err := tarFile.Seek(0, 0); err != nil {
		return fmt.Errorf("failed to seek to the beginning of tar file: %w", err)
	}

	// Append tar content
	if _, err := io.Copy(f, tarFile); err != nil {
		return fmt.Errorf("failed to append tar to layer: %w", err)
	}

	log.G(ctx).Infof("Successfully generated EROFS layer with tar index and tar content: %s", layerPath)

	return nil
}

func ConvertErofs(ctx context.Context, layerPath string, srcDir string, mkfsExtraOpts []string) error {
	args := append([]string{"--quiet", "-Enoinline_data"}, mkfsExtraOpts...)
	args = append(args, layerPath, srcDir)
	cmd := exec.CommandContext(ctx, "mkfs.erofs", args...)
	out, err := cmd.CombinedOutput()