func (u *underlyingWriter) Write(p []byte) (int, error) {
	n, err := u.writer.Write(p)
	if err != nil {
		return 0, err
	}
	if u.hash == nil {
		u.digester.Hash().Write(p)
	}
	u.size += int64(len(p))
	return n, nil
}
Write write to the underlying writer
package content
import (
	"context"
	"errors"
	"io"
	"time"
	"github.com/containerd/containerd/content"
	"github.com/opencontainers/go-digest"
)
type PassthroughWriter struct {
	writer           content.Writer
	pipew            *io.PipeWriter
	digester         digest.Digester
	size             int64
	underlyingWriter *underlyingWriter
	reader           *io.PipeReader
	hash             *digest.Digest
	done             chan error
}
func NewPassthroughWriter(writer content.Writer, f func(r io.Reader, w io.Writer, done chan<- error), opts ...WriterOpt) content.Writer {
	wOpts := DefaultWriterOpts()
	for _, opt := range opts {
		if err := opt(&wOpts); err != nil {
			return nil
		}
	}
	r, w := io.Pipe()
	pw := &PassthroughWriter{
		writer:   writer,
		pipew:    w,
		digester: digest.Canonical.Digester(),
		underlyingWriter: &underlyingWriter{
			writer:   writer,
			digester: digest.Canonical.Digester(),
			hash:     wOpts.OutputHash,
		},
		reader: r,
		hash:   wOpts.InputHash,
		done:   make(chan error, 1),
	}
	go f(r, pw.underlyingWriter, pw.done)
	return pw
}
func (pw *PassthroughWriter) Write(p []byte) (n int, err error) {
	n, err = pw.pipew.Write(p)
	if pw.hash == nil {
		pw.digester.Hash().Write(p[:n])
	}
	pw.size += int64(n)
	return
}
func (pw *PassthroughWriter) Close() error {
	if pw.pipew != nil {
		pw.pipew.Close()
	}
	pw.writer.Close()
	return nil
}
func (pw *PassthroughWriter) Digest() digest.Digest {
	if pw.hash != nil {
		return *pw.hash
	}
	return pw.digester.Digest()
}
func (pw *PassthroughWriter) Commit(ctx context.Context, size int64, expected digest.Digest, opts ...content.Opt) error {
	if pw.pipew != nil {
		pw.pipew.Close()
	}
	err := <-pw.done
	if pw.reader != nil {
		pw.reader.Close()
	}
	if err != nil && err != io.EOF {
		return err
	}
	return pw.writer.Commit(ctx, pw.underlyingWriter.size, pw.underlyingWriter.Digest(), opts...)
}
func (pw *PassthroughWriter) Status() (content.Status, error) {
	return pw.writer.Status()
}
func (pw *PassthroughWriter) Truncate(size int64) error {
	return pw.writer.Truncate(size)
}
type underlyingWriter struct {
	writer   content.Writer
	digester digest.Digester
	size     int64
	hash     *digest.Digest
}