Tại sao lại là '.' một liên kết cứng trong Unix?


51

Tôi đã thấy nhiều lời giải thích tại sao số lượng liên kết cho một thư mục trống trong các hệ điều hành dựa trên Unix là 2 thay vì 1. Tất cả đều nói rằng đó là vì '.' thư mục mà mọi thư mục đều trỏ về chính nó. Tôi hiểu tại sao có một số khái niệm về '.' là hữu ích để chỉ định các đường dẫn tương đối, nhưng những gì đạt được bằng cách thực hiện nó ở cấp hệ thống tập tin? Tại sao không có shell hoặc các cuộc gọi hệ thống có đường dẫn biết cách diễn giải nó?

Đó là '..' là một liên kết thực sự có ý nghĩa hơn đối với tôi - hệ thống tập tin cần lưu trữ một con trỏ trở lại thư mục mẹ để điều hướng đến nó. Nhưng tôi không hiểu tại sao '.' là một liên kết thực sự là cần thiết. Có vẻ như nó cũng dẫn đến một trường hợp đặc biệt xấu xí khi triển khai - bạn sẽ nghĩ rằng bạn chỉ có thể giải phóng không gian được sử dụng bởi các nút có số lượng liên kết nhỏ hơn 1, nhưng nếu chúng là thư mục, bạn thực sự cần phải kiểm tra một liên kết đếm ít hơn 2. Tại sao sự không nhất quán?


1
Khi bạn đã có các liên kết ..cứng, phần mềm đi bộ trên cây của bạn đã cần phải có ngoại lệ "không theo chu kỳ trên liên kết thư mục mẹ" , do đó, nó cũng ít phức tạp hơn ngoại trừ .liên kết.
dmckee

Câu trả lời:


37

Một câu hỏi thú vị, thực sự. Thoạt nhìn tôi thấy những ưu điểm sau:

Trước hết, bạn tuyên bố rằng việc diễn giải " ." như thư mục hiện tại có thể được thực hiện bởi Shell hoặc bằng các cuộc gọi hệ thống. Nhưng việc có dấu chấm trong thư mục thực sự loại bỏ sự cần thiết này và buộc tính nhất quán ở mức độ thấp hơn.

Nhưng tôi không nghĩ rằng đây là ý tưởng cơ bản đằng sau quyết định thiết kế này.

Khi một tập tin đang được tạo hoặc xóa khỏi một thư mục, dấu thời gian sửa đổi của thư mục cũng phải được cập nhật. Dấu thời gian này được lưu trữ trong inode của nó. Số inode được lưu trong mục thư mục tương ứng.

NẾU mục nhập dấu chấm sẽ không có ở đó, các thường trình sẽ phải tìm kiếm số inode tại mục nhập cho thư mục này trong thư mục mẹ, điều này sẽ gây ra một lần tìm kiếm thư mục.

NHƯNG may mắn có mục nhập trong thư mục hiện tại. Thường trình thêm hoặc xóa một tệp trong thư mục hiện tại chỉ cần quay lại mục nhập đầu tiên (nơi mục nhập thường nằm) và ngay lập tức đã tìm thấy số inode cho thư mục hiện tại.

Có một điều tốt đẹp thứ ba về mục chấm:

Khi fsckkiểm tra một hệ thống tập tin thối và phải xử lý các khối không được kết nối cũng không có trong danh sách miễn phí, thật dễ dàng để xác minh xem một khối dữ liệu (khi được hiểu là danh sách thư mục) có mục nhập dấu chấm trỏ đến một nút lần lượt quay lại khối dữ liệu này. Nếu vậy, khối dữ liệu này có thể được coi là một thư mục bị mất phải được kết nối lại.


Câu trả lời rất hữu ích.
Navaneeth KN

6
Nhận xét về thói quen tìm kiếm thư mục inode là không có thật. Các thường trình kernel không cần phải tra cứu .trong thư mục hiện tại. Trừ khi bạn có thể tìm thấy một hạt nhân nơi nó thực sự hoạt động theo cách này (tôi nghi ngờ nó ...)
Dietrich Epp

1
Tôi đồng ý với @DietrichEpp; để hệ thống nhìn vào các mục nhập thư mục ở vị trí đầu tiên , nó phải biết về inode - bởi vì đó là cách nó đến các khối dữ liệu chứa các mục nhập thư mục.
Lqueryvg

10

(Hmm: phần sau đây là một chút sử thi ...)

Thiết kế của thư mục trên hệ thống tập tin unix (trong đó, là gàn dở, đang thường nhưng không nhất thiết phải gắn liền với unix OSS) đại diện cho một cái nhìn sâu sắc tuyệt vời, mà thực sự làm giảm số trường hợp đặc biệt cần thiết.

Một 'thư mục' thực sự chỉ là một tệp trong hệ thống tệp. Tất cả nội dung thực tế của các tệp trong hệ thống tệp đều ở dạng inodes (từ câu hỏi của bạn, tôi có thể thấy rằng bạn đã biết về một số nội dung này). Không có cấu trúc nào cho các nút trên đĩa - chúng chỉ là một bó lớn các byte được đánh số, trải đều như bơ đậu phộng trên đĩa. Điều này không hữu ích, và thực sự là không thích hợp với bất cứ ai có đầu óc gọn gàng.

Các chỉ inode đặc biệt là inode số 2 (không phải 0 hoặc 1, vì lý do truyền thống); inode 2 là một tệp thư mục: thư mục gốc . Khi hệ thống gắn kết hệ thống tập tin, nó 'biết' nó phải thực hiện lại ở nút 2, để tự khởi động.

Một tệp thư mục chỉ là một tệp, với cấu trúc bên trong được đọc bởi opendir (3) và bạn bè. Bạn có thể thấy cấu trúc bên trong của nó được ghi lại trong thư mục (5) (tùy thuộc vào hệ điều hành của bạn); nếu bạn nhìn vào đó, bạn sẽ thấy rằng mục nhập tệp thư mục chứa hầu như không có thông tin nào về tệp - đó là tất cả trong tệp inode. Một trong những điều đặc biệt về tệp này là hàm mở (2) sẽ gặp lỗi nếu bạn cố mở tệp thư mục có chế độ cho phép ghi. Nhiều lệnh khác (chỉ chọn một ví dụ hexdump) sẽ từ chối hành động theo cách thông thường với các tệp thư mục, chỉ vì đó có thể không phải là điều bạn muốn làm (nhưng đó là trường hợp đặc biệt của chúng, không phải của hệ thống tệp).

Một liên kết cứng không gì khác hơn là một mục trong bản đồ của tệp thư mục. Bạn có thể có hai (hoặc nhiều) mục trong một bản đồ mà cả hai ánh xạ tới cùng một số inode: do đó inode có hai (hoặc nhiều) liên kết cứng. Điều này cũng giải thích tại sao mọi tệp có ít nhất một "liên kết cứng". Inode có số tham chiếu, ghi lại số lần inode được đề cập trong tệp thư mục ở đâu đó trong hệ thống tệp (đây là số mà bạn thấy khi bạn thực hiện ls -l).

OK: chúng ta đang đi đến điểm bây giờ.

Tệp thư mục là bản đồ của các chuỗi ('tên tệp') thành số (số inode). Các số inode đó là số lượng các nút của các tệp nằm trong thư mục đó. Các tệp nằm trong thư mục đó có thể bao gồm các tệp thư mục khác, vì vậy số inode của chúng sẽ nằm trong số các tệp được liệt kê trong thư mục. Vì vậy, nếu bạn có một tệp /tmp/foo/bar, thì tệp thư mục foobao gồm một mục nhập bar, ánh xạ chuỗi đó sang nút cho tệp đó. Ngoài ra còn có một mục trong tệp thư mục /tmp, cho tệp thư mục foo'trong' thư mục /tmp.

Khi bạn tạo một thư mục với mkdir (2), chức năng đó

  1. tạo một tệp thư mục (với một số số inode) với cấu trúc bên trong chính xác,
  2. thêm một mục vào thư mục mẹ, ánh xạ tên của thư mục mới vào inode mới này (chiếm một trong các liên kết),
  3. thêm một mục vào thư mục mới, ánh xạ chuỗi '.' vào cùng một nút (tài khoản này cho liên kết khác) và
  4. thêm một mục khác vào thư mục mới, ánh xạ chuỗi '..' vào nút của tệp thư mục mà nó đã sửa đổi ở bước (2) (tài khoản này cho số lượng lớn hơn các liên kết cứng bạn sẽ thấy trên các tệp thư mục chứa thư mục con ).

Kết quả cuối cùng là (hầu hết) các trường hợp đặc biệt duy nhất là:

  • Hàm open (2) cố gắng làm cho việc bắn vào chân bạn khó hơn, bằng cách ngăn bạn mở các tệp thư mục để ghi.
  • Hàm mkdir (2) làm cho mọi thứ trở nên dễ dàng và dễ dàng bằng cách thêm một vài mục nhập bổ sung ('.' Và '..') vào tệp thư mục mới, hoàn toàn để thuận tiện cho việc di chuyển xung quanh hệ thống tệp. Tôi nghi ngờ rằng hệ thống tập tin sẽ hoạt động hoàn hảo mà không có '.' và '..', nhưng sẽ là một nỗi đau để sử dụng.
  • Tệp thư mục là một trong số ít các loại tệp được gắn cờ là 'đặc biệt' - đây thực sự là thứ cho phép những thứ như mở (2) hoạt động hơi khác. Xem st_modetrong stat (2).

(được sao chép từ câu hỏi ban đầu stackoverflow, 2011-10-20)


1
Bạn đang nhầm lẫn các khối với inodes. Trong trường hợp đặc biệt, đối với các tệp ngắn, nội dung tệp thể nằm trong nút, nhưng sai khi khẳng định rằng các nút không có cấu trúc. Chúng có cấu trúc cao, chứa hầu hết tất cả các siêu dữ liệu tệp ngoại trừ tên tệp mà tệp có thể được tìm thấy. Inode chứa các con trỏ (trực tiếp, gián tiếp, gián tiếp gấp đôi, v.v.) cho các khối trên đĩa, nơi chứa nội dung tệp.
Phil P

1
Không, tôi không nhầm lẫn các khối với inodes. Các nút là một sự trừu tượng nằm trên các khối và điểm của bài đăng này là để mô tả mối quan hệ giữa các tệp và thư mục và nội dung của chúng: tất cả các cấu trúc hệ thống tệp đến từ các tệp thư mục. Nó đã đủ dài mà không bị sa lầy vào việc triển khai inode! (điều đó nói rằng, tôi có thể có thể viết một vài đoạn đầu tiên rõ ràng hơn). Ngoài ra, như bạn thấy, tôi tuyên bố rõ ràng rằng tất cả các thông tin về tệp (ngoại trừ tên của nó) đều nằm trong nút và không có trong tệp thư mục.
Norman Grey

@NormanGray: Ngay cả khi bạn tự vệ, bạn tự bắn vào chân mình. Bạn nói, "Tất cả nội dung thực tế của các tệp trong hệ thống tệp đều ở chế độ inodes ...." Điều đó sai.  Thuộc tính / thuộc tính của một tệp (ví dụ: chủ sở hữu, quyền, thời gian sửa đổi, v.v.) được lưu trữ trong nút. Các nội dung của một tập tin bình thường được lưu trữ trong các khối dữ liệu. Nếu bạn không muốn bị sa lầy vào việc triển khai inode, thì đừng, nhưng xin vui lòng đừng thực hiện quá mức sai lệch.
G-Man nói 'Phục hồi Monica'
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.