Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

nfsproxy: middleware chain hides CachingHandler and disables directory verifier caching

オープン
#3,552 コメント 1 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
4/5
見積もり時間
3〜5日
初心者へのやさしさ
64/100
issue の種類
バグ
明瞭さ
おおむね明確
活発さ
活発
技術スタック
go

調査の方向性

まず、tracing、metrics、logging、recovery の middleware の実装とヘルパー、および helpers.CachingHandler を見つけます。middleware チェーンがどのように組み立てられているかを追跡し、その後、完全なチェーンのカバレッジを追加する前に、既存の middleware テストを確認します。verifier の呼び出しとその引数および戻り値が基盤となる caching handler に到達し、recovery の動作が維持されれば完了です。

索引モデルが issue の本文から書いたものです。

説明

Symptom

The NFS proxy's directory verifier cache is silently bypassed.

Paginated READDIR and READDIRPLUS requests cannot reuse the directory listing associated with the cookie verifier returned by the first page. Each subsequent request reads and sorts the directory again.

If the directory changes between pages, the newly calculated verifier differs from the verifier supplied by the client, causing go-nfs to return NFS3ERR_BAD_COOKIE:

if obj.Cookie > 0 && obj.CookieVerif > 0 && verifier != obj.CookieVerif {
    return &NFSStatusError{NFSStatusBadCookie, nil}
}

Even when the directory does not change, the repeated ReadDir calls add unnecessary filesystem work for large paginated listings.

Root cause

The proxy creates a helpers.CachingHandler before applying its middleware:

handler = helpers.NewCachingHandler(handler, cacheLimit)

if config.Tracing {
    handler = tracing.WrapWithTracing(handler, config)
}

if config.Metrics {
    handler = metrics.WrapWithMetrics(handler, config)
}

if config.Logging {
    handler = logged.WrapWithLogging(ctx, handler, config)
}

handler = recovery.WrapWithRecovery(ctx, handler)

go-nfs checks the outermost handler for the optional nfs.CachingHandler interface:

if vh, ok := userHandle.(CachingHandler); verifier != 0 && ok {
    entries := vh.DataForVerifier(path, verifier)
    if entries != nil {
        return entries, verifier, nil
    }
}

The tracing, metrics, logging, and recovery handlers only implement nfs.Handler. They do not expose or forward:

VerifierFor(path string, contents []fs.FileInfo) uint64
DataForVerifier(path string, verifier uint64) []fs.FileInfo

Because recovery middleware is always installed, the outermost handler never satisfies nfs.CachingHandler, regardless of whether tracing, metrics, or logging are enabled.

As a result, go-nfs never reaches the verifier cache maintained by helpers.CachingHandler:

func (c *CachingHandler) VerifierFor(path string, contents []fs.FileInfo) uint64 {
    id := hashPathAndContents(path, contents)
    c.activeVerifiers.Add(id, verifier{path, contents})
    return id
}

func (c *CachingHandler) DataForVerifier(path string, id uint64) []fs.FileInfo {
    if cache, ok := c.activeVerifiers.Get(id); ok {
        return cache.contents
    }

    return nil
}

Why it matters

NFS directory cookies are indexes into the sorted directory listing:

cookie := uint64(i + 2)

For pagination to remain consistent, subsequent requests should use the same listing that produced the original cookie verifier.

Without verifier caching:

  • Every page performs another ReadDir and sort.
  • Insertions or removals can shift cookie indexes between pages.
  • Directory changes can cause NFS3ERR_BAD_COOKIE.
  • Large directory listings perform unnecessary repeated filesystem operations.

Proposed fix

Preserve nfs.CachingHandler through the complete middleware chain:

  • Implement VerifierFor and DataForVerifier on the tracing handler.
  • Implement VerifierFor and DataForVerifier on the metrics handler.
  • Implement VerifierFor and DataForVerifier on the logging handler.
  • Implement VerifierFor and DataForVerifier on the recovery handler.
  • Forward both calls to the wrapped handler when it implements nfs.CachingHandler.
  • Add compile-time assertions that each middleware implements nfs.CachingHandler.
  • Preserve panic recovery around verifier operations in the recovery handler.
  • Add a test covering the complete middleware chain and verifying that arguments and return values reach the underlying caching handler.
主要言語
Go
スター
1.6k
フォーク
438
PR マージ指標
30日以内にマージされた PR はありません

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

e2b-dev/runtime のほかの issue

e2b-dev/runtime の issue をすべて見る

似ている issue

Go の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。