Skip to content

fix: ensure forward progress in __file_lookup when nr_blk = 0#88

Closed
EricKim27 wants to merge 3 commits into
sysprog21:masterfrom
EricKim27:master
Closed

fix: ensure forward progress in __file_lookup when nr_blk = 0#88
EricKim27 wants to merge 3 commits into
sysprog21:masterfrom
EricKim27:master

Conversation

@EricKim27

@EricKim27 EricKim27 commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

At __file_lookup, it sets its starting index to look for files using hashes. Unfortunately, in some cases, that points to an uninitialised dir entry, which sets nr_blk to 0, and adds nothing at

_fi += dblock->files[_fi].nr_blk;

which causes a soft lockup in some cases.
This commit fixes that by adding 1 to _fi index when nr_blk is 0, to ensure that the index moves by 1 when nr_blk is 0, which would mean it is an invalid dir entry.


Summary by cubic

Prevent infinite loop in __file_lookup by advancing the file index when nr_blk == 0. Skip the empty entry by 1 to ensure forward progress; otherwise add nr_blk, with clearer inline comments and small style cleanup.

Written for commit 444918a. Summary will update on new commits.

Review in cubic

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 1 file

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread inode.c Outdated
@EricKim27

Copy link
Copy Markdown
Contributor Author

For the record, this would need some modifications to the __file_lookup in the future, because it seems like it did not check whether the block it is looking for is initialized or not.
Changes to the code is required.

@RoyWFHuang

RoyWFHuang commented Jun 20, 2026

Copy link
Copy Markdown
Collaborator

I don't think the guard in __file_lookup() is necessary — the lookup loop is actually correct, and under normal operation the scan can never land on a head with nr_blk == 0.

Why a normal lookup never reads nr_blk == 0

A directory block uses a run-length layout: the scan walks only the "head" slots and advances by _fi += files[_fi].nr_blk. The only three functions that modify this layout all keep every head's nr_blk >= 1:

  1. simplefs_get_new_ext() — initializes each block with files[0].nr_blk = SIMPLEFS_FILES_PER_BLOCK, i.e. one run of length N.

  2. simplefs_set_file_into_dir() — nr_blk is the run length of an entry:

  • nr_blk = 1 → this file only
  • nr_blk = 3 → this file + 2 trailing empty slots
  • Inserting splits a run of length L (>= 2) into 1 + (L-1), so both halves stay >= 1.
  1. simplefs_try_remove_entry() — merges the freed entry into the previous allocated entry (or into the first slot); it only adds to a head's nr_blk, never zeroes one.

So every head the scan visits always has nr_blk >= 1; the loop always advances and never reads nr_blk == 0.

actually, the nr_blk == 0 will be tirggered by other case
like this issue: issues89

@EricKim27

EricKim27 commented Jun 20, 2026

Copy link
Copy Markdown
Contributor Author

I don't think the guard in __file_lookup() is necessary — the lookup loop is actually correct, and under normal operation the scan can never land on a head with nr_blk == 0.

Why a normal lookup never reads nr_blk == 0

A directory block uses a run-length layout: the scan walks only the "head" slots and advances by _fi += files[_fi].nr_blk. The only three functions that modify this layout all keep every head's nr_blk >= 1:

1. simplefs_get_new_ext() — initializes each block with files[0].nr_blk = SIMPLEFS_FILES_PER_BLOCK, i.e. one run of length N.

2. simplefs_set_file_into_dir() — nr_blk is the run length of an entry:


* nr_blk = 1 → this file only

* nr_blk = 3 → this file + 2 trailing empty slots

* Inserting splits a run of length L (>= 2) into 1 + (L-1), so both halves stay >= 1.


3. simplefs_try_remove_entry() — merges the freed entry into the previous allocated entry (or into the first slot); it only adds to a head's nr_blk, never zeroes one.

So every head the scan visits always has nr_blk >= 1; the loop always advances and never reads nr_blk == 0.

actually, the nr_blk == 0 will be tirggered by other case like this issue: issues89

The issue you pointed out was what was happening to me, and it makes sense that the lookup function should not have to go through this safe guard.

After debugging, it seems like the simplefs_extent that points to a dir entry is valid, but the actual dir entry is being written way back from the place it should, Which matches your explanation on pull request 90

I will close this pull request, since this does not fix the root cause.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants