Lưu ý
Mục đích của file này là để độc giả tiếng Việt có thể đọc và hiểu tài liệu nhân kernel dễ dàng hơn, không phải để tạo ra một nhánh tài liệu riêng. Nếu bạn có bất kỳ nhận xét hoặc cập nhật nào cho file này, vui lòng thử cập nhật file tiếng Anh gốc trước. Nếu bạn thấy có sự khác biệt giữa bản dịch và bản gốc, hoặc có vấn đề về bản dịch, vui lòng gửi góp ý hoặc patch cho người dịch của file này, hoặc nhờ người bảo trì và người review tài liệu tiếng Việt giúp đỡ.
- Bản gốc:
- Người dịch:
Google Translate (machine translation)
- Phiên bản gốc:
8541d8f725c6
Cảnh báo
Tài liệu này được dịch tự động bằng máy và chưa được review bởi người dịch. Nội dung có thể không chính xác hoặc khó hiểu ở một số chỗ. Khi có sự khác biệt với bản gốc, bản gốc luôn là chuẩn. Bản dịch chất lượng cao (được review) được đặt trong thư mục vi_VN/.
Nhật ký Linux API¶
Tổng quan¶
Chi tiết¶
Lớp nhật ký rất dễ sử dụng. Trước hết bạn cần tạo một
cấu trúc dữ liệu tạp chí_t. Có hai cuộc gọi để thực hiện việc này phụ thuộc vào
cách bạn quyết định phân bổ phương tiện vật lý mà tạp chí sử dụng
cư trú. Lệnh gọi jbd2_journal_init_inode() dành cho các tạp chí được lưu trữ trong
các nút hệ thống tập tin hoặc có thể sử dụng lệnh gọi jbd2_journal_init_dev()
dành cho nhật ký được lưu trữ trên thiết bị thô (trong một phạm vi khối liên tục). A
tạp chí_t là một typedef cho một con trỏ cấu trúc, vì vậy khi cuối cùng bạn
xong nhớ gọi jbd2_journal_destroy() trên đó để giải phóng
bất kỳ bộ nhớ kernel đã sử dụng nào.
Khi bạn đã có đối tượng Journal_t, bạn cần ‘gắn kết’ hoặc tải
tập tin tạp chí. Lớp nhật ký mong đợi không gian cho tạp chí
đã được phân bổ và khởi tạo đúng cách bởi các công cụ không gian người dùng.
Khi tải nhật ký bạn phải gọi jbd2_journal_load() để xử lý
nội dung tạp chí. Nếu hệ thống tệp khách hàng phát hiện nội dung tạp chí
không cần phải xử lý (hoặc thậm chí không cần có nội dung hợp lệ), nó
có thể gọi jbd2_journal_wipe() để xóa nội dung tạp chí trước
gọi jbd2_journal_load().
Lưu ý rằng các cuộc gọi jbd2_journal_wipe(..,0)
jbd2_journal_skip_recovery() cho bạn nếu phát hiện bất kỳ khoản nợ nào
giao dịch trong tạp chí và tương tự jbd2_journal_load() sẽ
gọi jbd2_journal_recover() nếu cần. Tôi khuyên bạn nên đọc
ext4_load_journal() trong fs/ext4/super.c để biết ví dụ ở giai đoạn này.
Bây giờ bạn có thể tiếp tục và bắt đầu sửa đổi hệ thống tập tin cơ bản. Hầu hết.
Bạn vẫn cần phải ghi lại những thay đổi trong hệ thống tập tin của mình, việc này đã được thực hiện
bằng cách gói chúng vào các giao dịch. Ngoài ra bạn cũng cần phải bọc
việc sửa đổi từng bộ đệm bằng các lệnh gọi đến lớp nhật ký,
để nó biết những sửa đổi bạn thực sự đang thực hiện là gì. để làm
việc này sử dụng jbd2_journal_start() để trả về một thẻ xử lý giao dịch.
jbd2_journal_start() và đối tác của nó là jbd2_journal_stop(),
cho biết sự kết thúc của giao dịch là các cuộc gọi có thể lồng nhau, vì vậy bạn có thể
nhập lại giao dịch nếu cần, nhưng hãy nhớ rằng bạn phải gọi
jbd2_journal_stop() cùng số lần như
jbd2_journal_start() trước khi giao dịch hoàn tất (hoặc hơn
chính xác rời khỏi giai đoạn cập nhật). Ext4/VFS sử dụng tính năng này để
đơn giản hóa việc xử lý việc làm bẩn inode, hỗ trợ hạn ngạch, v.v.
Bên trong mỗi giao dịch, bạn cần bao gồm các sửa đổi đối với
bộ đệm riêng lẻ (khối). Trước khi bắt đầu sửa đổi bộ đệm, bạn
cần gọi jbd2_journal_get_create_access() /
jbd2_journal_get_write_access() /
jbd2_journal_get_undo_access() nếu thích hợp, điều này cho phép
lớp nhật ký để sao chép phần chưa sửa đổi
dữ liệu nếu cần. Suy cho cùng, bộ đệm có thể là một phần của bộ đệm trước đó
giao dịch không cam kết. Tại thời điểm này, cuối cùng bạn đã sẵn sàng sửa đổi một
đệm và sau khi đã hoàn tất, bạn cần gọi
jbd2_journal_dirty_metadata(). Hoặc nếu bạn đã yêu cầu quyền truy cập vào một
bộ đệm mà bạn biết giờ đây cần được đẩy lùi về phía sau lâu hơn
thiết bị bạn có thể gọi jbd2_journal_forget() theo cách tương tự như bạn
có thể đã sử dụng bforget() trong quá khứ.
Một jbd2_journal_flush() có thể được gọi bất cứ lúc nào để cam kết và
kiểm tra tất cả các giao dịch của bạn.
Sau đó, vào thời điểm umount, trong put_super() bạn có thể gọi
jbd2_journal_destroy() để dọn sạch đối tượng nhật ký trong lõi của bạn.
Thật không may, có một số cách mà lớp tạp chí có thể gây ra
bế tắc. Điều đầu tiên cần lưu ý là mỗi nhiệm vụ chỉ có thể có một
giao dịch chưa thanh toán duy nhất tại một thời điểm, hãy nhớ không có gì cam kết
cho đến jbd2_journal_stop() ngoài cùng. Điều này có nghĩa là bạn phải hoàn thành
giao dịch ở cuối mỗi tệp/inode/địa chỉ, v.v. thao tác bạn
thực hiện để hệ thống ghi nhật ký không được nhập lại vào một hệ thống khác
tạp chí. Vì các giao dịch không thể được lồng/theo nhóm trên nhiều nền tảng khác nhau.
các tạp chí và hệ thống tập tin khác không phải của bạn (chẳng hạn như ext4) có thể
được sửa đổi trong một syscall sau này.
Trường hợp thứ hai cần lưu ý là jbd2_journal_start() có thể chặn
nếu không có đủ chỗ trong nhật ký cho giao dịch của bạn (dựa trên
trên thông số nblocks đã qua) - khi nó chặn nó chỉ (!) cần đợi
để các giao dịch hoàn thành và được cam kết từ các nhiệm vụ khác, vì vậy
về cơ bản chúng tôi đang đợi jbd2_journal_stop(). Vì vậy để tránh
bế tắc bạn phải xử lý jbd2_journal_start() /
jbd2_journal_stop() như thể chúng là các ẩn dụ và đưa chúng vào
quy tắc đặt hàng semaphore của bạn để ngăn chặn
bế tắc. Lưu ý rằng jbd2_journal_extend() có tính năng chặn tương tự
hành vi đối với jbd2_journal_start() để bạn có thể bế tắc ở đây giống như
dễ dàng như trên jbd2_journal_start().
Cố gắng dự trữ đúng số khối trong lần đầu tiên. ;-). Điều này sẽ là số khối tối đa bạn sẽ chạm vào trong này giao dịch. Tôi khuyên bạn nên xem ít nhất ext4_jbd.h để xem cơ sở mà ext4 sử dụng để đưa ra các quyết định này.
Một điều rắc rối khác cần chú ý là việc phân bổ khối trên đĩa của bạn chiến lược. Tại sao? Bởi vì, nếu bạn thực hiện xóa, bạn cần đảm bảo rằng bạn chưa sử dụng lại bất kỳ khối giải phóng nào cho đến khi giải phóng giao dịch các khối này cam kết. Nếu bạn sử dụng lại các khối này và xảy ra sự cố, không có cách nào để khôi phục nội dung của các khối được phân bổ lại tại kết thúc giao dịch được cam kết đầy đủ cuối cùng. Một cách làm đơn giản điều này là để đánh dấu các khối là miễn phí trong phân bổ khối trong bộ nhớ nội bộ cấu trúc chỉ sau khi giao dịch giải phóng chúng cam kết. Sử dụng Ext4 tạp chí cam kết gọi lại cho mục đích này.
Với các lệnh gọi lại cam kết nhật ký, bạn có thể yêu cầu lớp ghi nhật ký gọi chức năng gọi lại khi giao dịch cuối cùng được chuyển vào đĩa, để bạn có thể thực hiện một số công việc quản lý của riêng mình. Bạn hỏi tờ báo lớp để gọi lại cuộc gọi lại bằng cách cài đặt đơn giản Con trỏ hàm ZZ0000ZZ và hàm đó là được gọi sau mỗi lần cam kết giao dịch.
JBD2 cũng cung cấp cách chặn tất cả các cập nhật giao dịch thông qua
jbd2_journal_lock_updates() /
jbd2_journal_unlock_updates(). Ext4 sử dụng điều này khi nó muốn
cửa sổ với fs sạch sẽ và ổn định trong giây lát. Ví dụ.
- jbd2_journal_lock_updates() //ngăn chặn những điều mới xảy ra..
jbd2_journal_flush()// kiểm tra mọi thứ. ..do stuff on stable fs
jbd2_journal_unlock_updates() // tiếp tục sử dụng hệ thống tập tin.
Cơ hội lạm dụng và tấn công DOS bằng cách này là hiển nhiên, nếu bạn cho phép không gian người dùng không có đặc quyền kích hoạt các đường dẫn mã có chứa những cuộc gọi này.
Cam kết nhanh¶
JBD2 cũng cho phép bạn thực hiện các cam kết delta cụ thể của hệ thống tệp được gọi là cam kết nhanh chóng. Để sử dụng các cam kết nhanh, bạn sẽ cần phải thiết lập sau cuộc gọi lại thực hiện công việc tương ứng:
ZZ0000ZZ: Chức năng dọn dẹp được gọi sau mỗi lần xác nhận đầy đủ và cam kết nhanh chóng.
ZZ0000ZZ: Chức năng phát lại được gọi để phát lại cam kết nhanh khối.
Hệ thống tập tin có thể tự do thực hiện các cam kết nhanh chóng khi nào nó muốn miễn là nó được JBD2 cho phép làm như vậy bằng cách gọi hàm ZZ0000ZZ. Sau khi một cam kết nhanh được thực hiện, khách hàng hệ thống tập tin sẽ thông báo cho JBD2 về nó bằng cách gọi ZZ0001ZZ. Nếu hệ thống tập tin muốn JBD2 thực hiện đầy đủ cam kết ngay sau khi dừng cam kết nhanh, nó có thể thực hiện bằng cách gọi ZZ0002ZZ. Điều này rất hữu ích nếu hoạt động cam kết nhanh không thành công vì lý do nào đó và cách duy nhất để đảm bảo tính nhất quán là JBD2 thực hiện đầy đủ cam kết truyền thống.
Chức năng trợ giúp JBD2 để quản lý bộ đệm cam kết nhanh. Hệ thống tập tin có thể sử dụng ZZ0000ZZ và ZZ0001ZZ để phân bổ và đợi IO hoàn thành bộ đệm cam kết nhanh.
Hiện tại, chỉ Ext4 thực hiện các cam kết nhanh. Để biết chi tiết về việc thực hiện nó về các cam kết nhanh, vui lòng tham khảo các nhận xét cấp cao nhất trong fs/ext4/fast_commit.c.
Bản tóm tắt¶
Sử dụng nhật ký là vấn đề bao hàm những thay đổi bối cảnh khác nhau, là mỗi lần gắn kết, mỗi lần sửa đổi (giao dịch) và mỗi lần thay đổi đệm để thông báo cho lớp nhật ký về chúng.
Kiểu dữ liệu¶
Lớp nhật ký sử dụng typedefs để ‘ẩn’ các định nghĩa cụ thể của các kết cấu được sử dụng. Là khách hàng của lớp JBD2, bạn chỉ có thể tin cậy về việc sử dụng con trỏ như một loại bánh quy ma thuật nào đó. Rõ ràng là việc ẩn không được thực thi vì đây là ‘C’.
Cấu trúc¶
Chức năng¶
Các chức năng ở đây được chia thành hai nhóm ảnh hưởng đến tạp chí nói chung và những thứ được sử dụng để quản lý giao dịch
Cấp tạp chí¶
Cấp độ giao dịch¶
Xem thêm¶
ZZ0000ZZ
ZZ0000ZZ