Đáng tiếc là câu trả lời của Dave là sai.
Không phải tất cả các hệ thống POSIX thậm chí có thể có bộ nhớ bền. Và nếu họ làm, nó vẫn được "cho phép" để được hosed sau khi một hệ thống sụp đổ. Đối với những hệ thống đó, một fsync no-op() có ý nghĩa, và fsync() được cho phép rõ ràng trong POSIX. Nó cũng là hợp pháp cho các tập tin được phục hồi trong thư mục cũ, thư mục mới, cả hai, hoặc bất kỳ vị trí nào khác. POSIX không đảm bảo cho sự cố hệ thống hoặc khôi phục hệ thống tệp.
Câu hỏi thực sự nên là:
Làm thế nào để làm một đổi tên bền trên các hệ thống có hỗ trợ thông qua các API POSIX?
Bạn cần phải thực hiện một fsync() trên cả hai, nguồn và thư mục đích, vì tối thiểu những fsync() s được cho là vẫn tồn tại như thế nào thư mục nguồn hoặc đích.
Có một fsync (destdirfd) cũng ngầm hoàn toàn fsync thư mục nguồn không?
- POSIX nói chung: không có, không có gì ngụ ý rằng
- ext3/4: Tôi không chắc chắn nếu cả hai thay đổi nguồn và đích dir kết thúc trong cùng một giao dịch trên tạp chí. Nếu họ làm, họ nhận được cả hai cam kết với nhau.
Hoặc tôi có thể kết thúc với tệp hiển thị trong cả hai thư mục sau một chu kỳ nguồn ("crash"), tức là không thể đảm bảo hoạt động di chuyển nguyên tử có thể kéo dài?
- POSIX nói chung: không có bảo lãnh, nhưng bạn đang phải fsync() cả hai thư mục, trong đó có thể không phải nguyên tử bền
- ext3/4: bao nhiêu fsync(), bạn có tối thiểu cần phụ thuộc vào các tùy chọn gắn kết. Ví dụ. nếu được gắn với “dirsync”, bạn không cần bất kỳ hai fsync() s nào. Hầu hết bạn cần cả hai fsync() s, nhưng tôi gần như chắc chắn một là đủ (nguyên tử bền sau đó).
Nếu tôi fsync thư mục nguồn thay vì thư mục đích, nó cũng sẽ ngầm đồng bộ hóa thư mục đích?
- POSIX: không
- ext3/4: Tôi thực sự tin rằng cả hai kết thúc trong cùng một giao dịch, vì vậy nó không quan trọng mà trong số họ bạn fsync() hạt nhân ext3
- cũ: (nếu chúng không nằm trong cùng một giao dịch) một số việc triển khai không quá tối ưu đã làm quá nhiều việc đồng bộ hóa trên fsync(), tôi đặt cược nó đã thực hiện mọi giao dịch đến trước đó. Và có, việc triển khai bình thường trước tiên sẽ liên kết nó đến đích và sau đó xóa nó khỏi nguồn. Vì vậy, fsync (srcdirfd) cũng sẽ kích hoạt fsync() của đích.
- ext4/ext3 mới nhất: nếu họ không nằm trong cùng một giao dịch, bạn có thể có thể hoàn toàn đồng bộ chúng một cách độc lập (do đó làm cả hai)
Có bất kỳ công cụ kiểm tra/gỡ lỗi/học tập hữu ích liên quan (kim phun lỗi, công cụ nội soi, hệ thống tập tin giả, v.v.)?
Để có sự cố thực sự, không. Bằng cách này, một vụ tai nạn thực sự vượt ra ngoài quan điểm của hạt nhân. Các phần cứng có thể sắp xếp lại viết (và không viết tất cả mọi thứ), làm hỏng hệ thống tập tin. Ext4 được chuẩn bị tốt hơn chống lại điều này, bởi vì nó cho phép ghi barries (tùy chọn gắn kết) theo mặc định (ext3 không) và có thể phát hiện tham nhũng với checksums tạp chí (cũng là một tùy chọn gắn kết).
Và để tìm hiểu: hãy tìm hiểu xem cả hai thay đổi có được liên kết bằng cách nào đó trên tạp chí không! :-P
Lý do ở đây là rất sai. - "atomicity" của rename(), ví dụ, đề cập đến "newpath", theo đó nên là tệp cũ (nếu có) hoặc tệp được đổi tên, không có trạng thái ở giữa (như được xem bởi các quy trình khác) . –
Robert chỉ ra, đổi tên là "nguyên tử" liên quan đến việc gán inode mới để đặt tên, cho dù điểm inode mới cho dữ liệu chưa được quét hay không không được xác định bởi POSIX. – ArekBulski