mirror of
https://github.com/deepseek-ai/3FS.git
synced 2026-11-05 00:47:47 +00:00
[GH-ISSUE #31] Potential orphaned loop issue in RenameOp operation #22
Labels
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
deepseek-ai/3FS#22
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @Clcanny on GitHub (Mar 1, 2025).
Original GitHub issue: https://github.com/deepseek-ai/3FS/issues/31
Originally assigned to: @yiyuanliu on GitHub.
Hi, thank you for your amazing work on this repository! I am currently exploring how 3FS handles distributed transactions on FoundationDB (potentially involving read and write sets across multiple partitions of FoundationDB) while maintaining excellent performance, as I am preparing to write a technical blog to introduce this topic. While reading through the code, I may have identified a potential issue related to the
RenameOpoperation, but I could be misunderstanding something. If that's the case, I sincerely apologize and would greatly appreciate any clarification.In the current implementation of
RenameOp, it appears that only the parent inodes and directory entries of the source and destination paths are added to the read conflict set. However, this approach might result in an orphaned loop problem, as described in Figure 8 of InfiniFS: An Efficient Metadata Service for Large-Scale Distributed Filesystems.To illustrate, here is an example scenario:
From FoundationDB's perspective, it seems these two transactions would not conflict because their read and write sets do not intersect. If that is true (please correct me if I'm wrong), this could result in an orphaned loop problem, violating serializability.
More complex scenarios could also be constructed (e.g., paths with longer hierarchies or additional concurrent operations), further demonstrating potential orphaned loop issues.
I suspect this issue might occur because not all accessed items (e.g., inodes or directory entries) are added to the read conflict set. As a result, FoundationDB's conflict detection may fail to identify conflicts between such transactions, leading to non-serializable outcomes.
@yiyuanliu commented on GitHub (Mar 2, 2025):
Thank you for your question. We check whether the
renameoperation could potentially create a loop by checking the target directory's ancestors. We record the parent directory in the inode. When renaming directory, we check all ancestors of the target directory and add them to the read conflict set (see implementation here and here). If such concurrentrenameexist, they should conflict.@Clcanny commented on GitHub (Mar 2, 2025):
Thank you so much for your clarification! I really appreciate it. I still have one more question, if you don’t mind:
From the perspective of the 3FS design, is it necessary to avoid cross-partition transactions in FoundationDB to achieve better performance? For most operations (except for cases like rename and mkdirs with missing ancestors), it seems that transactions typically involve only the parent's inode and its directory entry. Does 3FS ensure that the parent's inode and its children’s directory entries are colocated within the same partition in FoundationDB to avoid cross-partition transactions and improve performance?
Thank you again for your time and for sharing your insights!
@yiyuanliu commented on GitHub (Mar 2, 2025):
For FoundationDB, cross-partition transactions are handled the same way as single-partition transactions, and I don't think there would be significant performance differences between them. One of FoundationDB's cofounders mentioned in a related discussion:
No. In 3FS, inodes and directory entries use different key prefixes (INOD and DENT respectively), so they typically won't be in the same partition. Simply collocating a parent directory's inode and directory entries wouldn't eliminate cross-partition transactions. For example, when creating a file, you need to create both the directory entry and the child file's inode. To avoid cross-partition transactions, you would need to find a way to collocate the file's inode with its parent directory as well.
@Clcanny commented on GitHub (Mar 2, 2025):
Got it! Thank you so much!