Skip to content

Serialize operations on directory position #1290

Description

@CvvT

Weiteng Chen (@CvvT): a comment from the agent:

Pre-existing race on  Diroff , now also reachable across dup'd fds (file.rs:761-774, 2640-2698)

This isn't a new race introduced by this PR — the underlying pattern already existed:  sys_getdirent64  and directory  lseek  ( SEEK_CUR ) both do a non-atomic read →  read_dir /compute → write of  Diroff  (read the offset under a lock, drop the lock, do the work, then re-acquire a write lock to store the new value). Even before this fix, two threads calling  getdents64 / lseek  concurrently on the same fd could already race and lose an update.

What this PR changes is the blast radius: since  Diroff  is now aliased via  set_entry_metadata  across all fds sharing the same open-file-description entry (which is the whole point of the fix — dup'd fds should share position), that same unprotected read-modify-write window now also lets  getdents64 / lseek  on two different fds (e.g.  dir_fd  and  dup(dir_fd) ) race with each other. Before this change that was impossible, since dup'd fds had fully independent offsets. Concretely: thread A on  dir_fd  and thread B on  dup_fd  can both read  Diroff=0 , both enumerate entries  [0..2) , and whichever writes back last clobbers the other's advance — silently duplicating or skipping entries, which is exactly the shared-position semantics this PR is trying to guarantee. Linux avoids this by holding  f_pos_lock  across the whole operation.

Suggested fix: hold a single exclusive guard on the shared entry across the read →  read_dir /compute → write sequence (or use a CAS loop on  Diroff ) in both  sys_getdirent64  and the directory  lseek  branch, instead of taking separate read and write locks with a gap in between.

Originally posted by Weidong Cui (@wdcui) in #1275 (comment)

Activity

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

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions