Mọi điều bạn từng muốn biết về inodes trên Linux
Hệ thống tệp Linux dựa trên inodes. Những phần quan trọng này trong hoạt động bên trong của hệ thống tệp thường bị hiểu nhầm. Hãy xem xét chính xác họ là gì và họ làm gì.
Các yếu tố của một hệ thống tệp
Theo định nghĩa, một hệ thống tệp cần phải lưu trữ các tệp và chúng cũng chứa các thư mục. Các tệp được lưu trữ trong các thư mục và các thư mục này có thể có các thư mục con. Một cái gì đó, ở đâu đó, phải ghi lại vị trí của tất cả các tệp trong hệ thống tệp, chúng được gọi là gì, chúng thuộc về tài khoản nào, quyền nào chúng có và hơn thế nữa. Thông tin này được gọi là siêu dữ liệu vì đó là dữ liệu mô tả các dữ liệu khác.
Trong hệ thống tệp ext4 của Linux, cấu trúc inode và thư mục làm việc cùng nhau để cung cấp một khung cơ sở lưu trữ tất cả siêu dữ liệu cho mọi tệp và thư mục. Họ cung cấp siêu dữ liệu cho bất kỳ ai yêu cầu, cho dù đó là nhân, ứng dụng người dùng hay tiện ích Linux, chẳng hạn như ls
, chỉ số
, và df
.
Inodes và Kích thước hệ thống tệp
Mặc dù đúng là có một cặp cấu trúc, nhưng hệ thống tệp yêu cầu nhiều hơn thế. Có hàng ngàn và hàng ngàn mỗi cấu trúc. Mọi tệp và thư mục đều yêu cầu inode và vì mọi tệp đều nằm trong một thư mục nên mọi tệp cũng yêu cầu cấu trúc thư mục. Cấu trúc thư mục còn được gọi là các mục nhập thư mục, hoặc “răng giả”.
Mỗi inode có một số inode, là số duy nhất trong một hệ thống tệp. Cùng một số inode có thể xuất hiện trong nhiều hệ thống tệp. Tuy nhiên, ID hệ thống tệp và số inode kết hợp để tạo thành một mã định danh duy nhất, bất kể có bao nhiêu hệ thống tệp được gắn trên hệ thống Linux của bạn.
Hãy nhớ rằng, trong Linux, bạn không gắn ổ cứng hoặc phân vùng. Bạn gắn hệ thống tệp trên phân vùng, do đó, bạn dễ dàng có nhiều hệ thống tệp mà không nhận ra. Nếu bạn có nhiều ổ cứng hoặc phân vùng trên một ổ đĩa, bạn có nhiều hệ thống tệp. Chúng có thể là cùng một loại — chẳng hạn như tất cả ext4 — nhưng chúng vẫn sẽ là các hệ thống tệp riêng biệt.
Tất cả các inodes được tổ chức trong một bảng. Sử dụng số inode, hệ thống tệp dễ dàng tính toán phần bù vào bảng inode mà tại đó inode được đặt. Bạn có thể thấy lý do tại sao chữ “i” trong inode là viết tắt của chỉ mục.
Biến chứa số inode được khai báo trong mã nguồn dưới dạng số nguyên dài 32 bit, không dấu. Điều này có nghĩa là số inode là một giá trị nguyên với kích thước tối đa là 2 ^ 32, tính ra 4,294,967,295 — hơn 4 tỷ inode.
Đó là mức tối đa lý thuyết. Trên thực tế, số lượng inode trong hệ thống tệp ext4 được xác định khi hệ thống tệp được tạo theo tỷ lệ mặc định là một inode trên 16 KB dung lượng hệ thống tệp. Cấu trúc thư mục được tạo ngay lập tức khi hệ thống tệp đang được sử dụng, vì tệp và thư mục được tạo trong hệ thống tệp.
Bạn có thể sử dụng một lệnh để xem có bao nhiêu inodes trong hệ thống tệp trên máy tính của mình. Các -Tôi
(inodes) tùy chọn của df
lệnh hướng dẫn nó hiển thị đầu ra của nó với số lượng inode.
Chúng tôi sẽ xem xét hệ thống tệp trên phân vùng đầu tiên trên ổ cứng đầu tiên, vì vậy chúng tôi nhập như sau:
df -i / dev / sda1
Đầu ra cho chúng ta:
- Hệ thống tập tin: Hệ thống tệp đang được báo cáo.
- Inodes: Tổng số inode trong hệ thống tệp này.
- IUsed: Số inode đang được sử dụng.
- IFree: Số inode còn lại có sẵn để sử dụng.
- Tôi sử dụng%: Phần trăm inodes đã sử dụng.
- Gắn trên: Điểm gắn kết cho hệ thống tệp này.
Chúng tôi đã sử dụng 10% inodes trong hệ thống tệp này. Các tệp được lưu trữ trên ổ cứng trong các khối đĩa. Mỗi inode trỏ đến các khối đĩa lưu trữ nội dung của tệp mà chúng đại diện. Nếu bạn có hàng triệu tệp nhỏ, bạn có thể sử dụng hết inodes trước khi hết dung lượng ổ cứng. Tuy nhiên, đó là một vấn đề rất khó gặp phải.
Trước đây, một số máy chủ thư lưu trữ thư email dưới dạng tệp rời rạc (nhanh chóng dẫn đến bộ sưu tập lớn các tệp nhỏ) đã gặp sự cố này. Tuy nhiên, khi các ứng dụng đó thay đổi kết thúc của chúng thành cơ sở dữ liệu, điều này đã giải quyết được vấn đề. Hệ thống gia đình trung bình sẽ không hết inodes, điều này cũng giống như vậy bởi vì, với hệ thống tệp ext4, bạn không thể thêm nhiều inodes hơn mà không cần cài đặt lại hệ thống tệp.
Để xem kích thước của khối đĩa trên hệ thống tệp của bạn, bạn có thể sử dụng blockdev
ra lệnh với --getbsz
(lấy kích thước khối) tùy chọn:
sudo blockdev --getbsz / dev / sda
Kích thước khối là 4096 byte.
Hãy sử dụng -B
(kích thước khối) để chỉ định kích thước khối 4096 byte và kiểm tra việc sử dụng đĩa thông thường:
df -B 4096 / dev / sda1
Kết quả này cho chúng ta thấy:
- Hệ thống tập tin: Hệ thống tệp mà chúng tôi đang báo cáo.
- Khối 4K: Tổng số khối 4 KB trong hệ thống tệp này.
- Đã sử dụng: Có bao nhiêu khối 4K đang được sử dụng.
- Có sẵn: Số khối 4 KB còn lại có sẵn để sử dụng.
- Sử dụng%: Phần trăm khối 4 KB đã được sử dụng.
- Gắn trên: Điểm gắn kết cho hệ thống tệp này.
Trong ví dụ của chúng tôi, lưu trữ tệp (và lưu trữ các inodes và cấu trúc thư mục) đã sử dụng 28% dung lượng trên hệ thống tệp này, với chi phí bằng 10% inodes, vì vậy chúng tôi đang ở trong tình trạng tốt.
Siêu dữ liệu Inode
Để xem số inode của một tệp, chúng ta có thể sử dụng ls
với -Tôi
(inode) tùy chọn:
ls -i geek.txt
Số inode cho tệp này là 1441801, vì vậy inode này giữ siêu dữ liệu cho tệp này và theo truyền thống, các con trỏ đến khối đĩa nơi tệp nằm trên ổ cứng. Nếu tệp bị phân mảnh, rất lớn hoặc cả hai, một số khối mà inode trỏ tới có thể giữ thêm con trỏ tới các khối đĩa khác. Và một số khối đĩa khác cũng có thể chứa các con trỏ đến một tập hợp khối đĩa khác. Điều này khắc phục được vấn đề của inode là một kích thước cố định và có thể chứa một số lượng con trỏ hữu hạn đến các khối đĩa.
Phương pháp đó đã được thay thế bằng một lược đồ mới sử dụng "các phạm vi". Chúng ghi lại khối bắt đầu và khối kết thúc của mỗi tập hợp các khối liền kề được sử dụng để lưu trữ tệp. Nếu tệp không bị phân mảnh, bạn chỉ phải lưu trữ khối đầu tiên và độ dài tệp. Nếu tệp bị phân mảnh, bạn phải lưu trữ khối đầu tiên và khối cuối cùng của mỗi phần của tệp. Phương pháp này (rõ ràng) hiệu quả hơn.
Nếu bạn muốn xem liệu hệ thống tệp của mình có sử dụng con trỏ hoặc vùng mở rộng của khối đĩa hay không, bạn có thể xem bên trong một inode. Để làm như vậy, chúng tôi sẽ sử dụng gỡ lỗi
ra lệnh với -R
(yêu cầu) tùy chọn và chuyển nó vào inode của tệp quan tâm. Điều này yêu cầugỡ lỗi
để sử dụng lệnh “stat” bên trong của nó để hiển thị nội dung của inode. Bởi vì số inode chỉ là duy nhất trong một hệ thống tệp, chúng tôi cũng phải cho biết gỡ lỗi
hệ thống tệp mà inode nằm trên đó.
Đây là lệnh ví dụ này sẽ trông như thế nào:
sudo debugfs -R "stat" / dev / sda1
Như hình dưới đây, gỡ lỗi
lệnh trích xuất thông tin từ inode và trình bày nó cho chúng tôi trong ít hơn
:
Chúng tôi được hiển thị thông tin sau:
- Inode: Số inode mà chúng tôi đang xem xét.
- Kiểu: Đây là một tệp thông thường, không phải là một thư mục hoặc liên kết tượng trưng.
- Chế độ: Quyền của tệp trong hệ bát phân.
- Cờ: Các chỉ số đại diện cho các tính năng hoặc chức năng khác nhau. 0x80000 là cờ "mở rộng" (thêm thông tin về điều này bên dưới).
- Thế hệ: Hệ thống tệp mạng (NFS) sử dụng tính năng này khi ai đó truy cập hệ thống tệp từ xa qua kết nối mạng như thể chúng được gắn trên máy cục bộ. Các số inode và thế hệ được sử dụng như một dạng xử lý tệp.
- Phiên bản: Phiên bản inode.
- Người dùng: Chủ sở hữu của tệp.
- Nhóm: Chủ sở hữu nhóm của tệp.
- Dự án: Luôn luôn là số không.
- Kích thước: Kích thước của tệp.
- Tệp ACL: Danh sách kiểm soát quyền truy cập tệp. Chúng được thiết kế để cho phép bạn cấp quyền truy cập có kiểm soát cho những người không thuộc nhóm chủ sở hữu.
- Liên kết: Số lượng liên kết cứng đến tệp.
- Blockcount: Dung lượng ổ cứng được phân bổ cho tệp này, được tính theo khối 512 byte. Tệp của chúng tôi đã được phân bổ tám trong số này, có dung lượng 4.096 byte. Vì vậy, tệp 98 byte của chúng tôi nằm trong một khối đĩa 4.096 byte duy nhất.
- Miếng: Tệp này không bị phân mảnh. (Đây là một cờ lỗi thời.)
- Ctime: Thời gian tệp được tạo.
- Một thời gian: Thời gian mà tệp này được truy cập lần cuối.
- Mtime: Thời gian mà tệp này được sửa đổi lần cuối.
- Crtime: Thời gian tệp được tạo.
- Kích thước của các trường inode bổ sung: Hệ thống tệp ext4 giới thiệu khả năng cấp phát inode lớn hơn trên đĩa tại thời điểm định dạng. Giá trị này là số byte phụ mà inode đang sử dụng. Không gian bổ sung này cũng có thể được sử dụng để đáp ứng các yêu cầu trong tương lai đối với nhân mới hoặc để lưu trữ các thuộc tính mở rộng.
- Inode tổng kiểm tra: Một tổng kiểm tra cho inode này, giúp bạn có thể phát hiện ra inode có bị hỏng hay không.
- Phạm vi: Nếu các phần mở rộng đang được sử dụng (theo mặc định là trên ext4), thì siêu dữ liệu liên quan đến việc sử dụng khối đĩa của tệp có hai số cho biết khối bắt đầu và khối kết thúc của mỗi phần của tệp bị phân mảnh. Điều này hiệu quả hơn việc lưu trữ mọi khối đĩa được chiếm bởi mỗi phần của tệp. Chúng tôi có một mức độ bởi vì tệp nhỏ của chúng tôi nằm trong một khối đĩa tại phần bù khối này.
Tên tệp ở đâu?
Hiện chúng tôi có rất nhiều thông tin về tệp, nhưng như bạn có thể nhận thấy, chúng tôi không nhận được tên tệp. Đây là lúc cấu trúc thư mục phát huy tác dụng. Trong Linux, giống như một tệp, một thư mục có một inode. Tuy nhiên, thay vì trỏ đến khối đĩa chứa dữ liệu tệp, inode thư mục trỏ đến khối đĩa chứa cấu trúc thư mục.
So với inode, cấu trúc thư mục chứa một lượng thông tin hạn chế về tệp. Nó chỉ chứa số inode, tên và độ dài của tên.
Inode và cấu trúc thư mục chứa mọi thứ bạn (hoặc một ứng dụng) cần biết về một tệp hoặc thư mục. Cấu trúc thư mục nằm trong một khối đĩa thư mục, vì vậy chúng ta biết thư mục chứa tệp. Cấu trúc thư mục cho chúng ta tên tệp và số inode. Inode cho chúng ta biết mọi thứ khác về tệp, bao gồm dấu thời gian, quyền và nơi tìm dữ liệu tệp trong hệ thống tệp.
Inodes thư mục
Bạn có thể xem số inode của một thư mục dễ dàng như bạn có thể xem chúng cho các tệp.
Trong ví dụ sau, chúng tôi sẽ sử dụng ls
với -l
(định dạng dài), -Tôi
(inode), và -d
(thư mục) tùy chọn và xem xét công việc
danh mục:
ls -lid công việc /
Bởi vì chúng tôi đã sử dụng -d
(thư mục) tùy chọn,ls
báo cáo trên chính thư mục, không phải nội dung của nó. Inode cho thư mục này là 1443016.
Để lặp lại điều đó cho Trang Chủ
thư mục, chúng tôi nhập như sau:
ls -lid ~
Inode cho Trang Chủ
thư mục là 1447510 và công việc
thư mục nằm trong thư mục chính. Bây giờ, hãy xem nội dung của công việc
danh mục. Thay cho-d
(thư mục), chúng tôi sẽ sử dụng -a
(tất cả) tùy chọn. Thao tác này sẽ hiển thị cho chúng ta các mục thư mục thường bị ẩn.
Chúng tôi gõ như sau:
ls -lia làm việc /
Bởi vì chúng tôi đã sử dụng -a
(tất cả), các mục nhập dấu một (.) và dấu chấm kép (..) được hiển thị. Các mục nhập này đại diện cho chính thư mục (dấu chấm đơn) và thư mục mẹ của nó (dấu chấm kép.)
Nếu bạn nhìn vào số inode cho mục nhập một chấm, bạn sẽ thấy rằng đó là 1443016 — chính số inode mà chúng tôi nhận được khi chúng tôi phát hiện ra số inode cho công việc
danh mục. Ngoài ra, số inode cho mục nhập dấu chấm đôi giống với số inode cho Trang Chủ
danh mục.
Đó là lý do tại sao bạn có thể sử dụng cd ..
lệnh để di chuyển lên một cấp trong cây thư mục. Tương tự như vậy, khi bạn đặt trước tên ứng dụng hoặc tập lệnh bằng./
, bạn cho trình bao biết nơi khởi chạy ứng dụng hoặc tập lệnh.
Inodes và liên kết
Như chúng tôi đã trình bày, ba thành phần bắt buộc phải có để có một tệp được định dạng tốt và có thể truy cập được trong hệ thống tệp: tệp, cấu trúc thư mục và inode. Tệp là dữ liệu được lưu trữ trên ổ cứng, cấu trúc thư mục chứa tên của tệp và số inode của nó, inode chứa tất cả siêu dữ liệu cho tệp.
Các liên kết tượng trưng là các mục nhập hệ thống tệp trông giống như tệp, nhưng chúng thực sự là lối tắt trỏ đến tệp hoặc thư mục hiện có. Hãy xem cách họ quản lý điều này và cách ba yếu tố được sử dụng để đạt được điều này.
Giả sử chúng ta có một thư mục chứa hai tệp trong đó: một tệp là tập lệnh và tệp kia là ứng dụng, như được hiển thị bên dưới.
Chúng ta có thể sử dụng lệnh ln và lệnh -S
(Symbol) để tạo một liên kết mềm đến tệp script, như sau:
ls -s my_script geek.sh
Chúng tôi đã tạo một liên kết đến my_script.sh
gọi là geek.sh
. Chúng ta có thể gõ như sau và sử dụngls
để xem hai tệp kịch bản:
ls -li * .sh
Mục nhập cho geek.sh
xuất hiện với màu xanh lam. Ký tự đầu tiên của các cờ quyền là "l" cho liên kết và->
chỉ tới my_script.sh
. Tất cả những điều này chỉ ra rằng geek.sh
là một liên kết.
Như bạn có thể mong đợi, hai tệp script có số inode khác nhau. Tuy nhiên, điều có thể ngạc nhiên hơn là liên kết mềm, geek.sh
, không có quyền người dùng giống như tệp tập lệnh gốc. Trên thực tế, các quyền đối vớigeek.sh
tự do hơn nhiều — tất cả người dùng đều có đầy đủ quyền.
Cấu trúc thư mục cho geek.sh
chứa tên của liên kết và inode của nó. Khi bạn cố gắng sử dụng liên kết, inode của nó được tham chiếu, giống như một tệp thông thường. Inode liên kết sẽ trỏ đến một khối đĩa, nhưng thay vì chứa dữ liệu nội dung tệp, khối đĩa chứa tên của tệp gốc. Hệ thống tệp chuyển hướng đến tệp gốc.
Chúng tôi sẽ xóa tệp gốc và xem điều gì sẽ xảy ra khi chúng tôi nhập thông tin sau để xem nội dung củageek.sh
:
rm my_script.sh
mèo geek.sh
Liên kết tượng trưng bị hỏng và chuyển hướng không thành công.
Bây giờ chúng ta gõ như sau để tạo một liên kết cứng đến tệp ứng dụng:
Trong ứng dụng geek-app đặc biệt
Để xem các inodes cho hai tệp này, chúng tôi nhập như sau:
ls -li
Cả hai đều trông giống như các tệp thông thường. Không có gì geek-app
cho biết đó là một liên kết theo cách ls
danh sách cho geek.sh
đã làm. Thêm,geek-app
có quyền người dùng giống như tệp gốc. Tuy nhiên, điều có thể gây ngạc nhiên là cả hai ứng dụng đều có cùng số inode: 1441797.
Mục nhập thư mục cho geek-app
chứa tên “geek-app” và số inode, nhưng nó giống với số inode của tệp gốc. Vì vậy, chúng tôi có hai mục nhập hệ thống tệp với các tên khác nhau, cả hai đều trỏ đến cùng một inode. Trên thực tế, bất kỳ số lượng mục nào cũng có thể trỏ đến cùng một inode.
Chúng tôi sẽ nhập nội dung sau và sử dụng chỉ số
chương trình để xem tệp đích:
ứng dụng đặc biệt của thống kê
Chúng tôi thấy rằng hai liên kết cứng trỏ đến tệp này. Điều này được lưu trữ trong inode.
Trong ví dụ sau, chúng tôi xóa tệp gốc và cố gắng sử dụng liên kết có mật khẩu an toàn, bí mật:
ứng dụng đặc biệt rm
./geek-app correcthorsebatterystaple
Đáng ngạc nhiên là ứng dụng chạy như mong đợi, nhưng làm thế nào? Nó hoạt động vì khi bạn xóa một tệp, inode sẽ được sử dụng lại miễn phí. Cấu trúc thư mục được đánh dấu là có số inode bằng 0 và các khối đĩa sau đó sẵn sàng cho một tệp khác được lưu trữ trong không gian đó.
Tuy nhiên, nếu số liên kết cứng đến inode lớn hơn một, thì số liên kết cứng sẽ giảm đi một và số inode của cấu trúc thư mục của tệp bị xóa được đặt thành 0. Nội dung tệp trên ổ cứng và inode vẫn có sẵn cho các liên kết cứng hiện có.
Chúng tôi sẽ nhập thông tin sau và sử dụng thống kê một lần nữa — lần này vào geek-app
:
stat geek-app
Các chi tiết này được lấy từ cùng một inode (1441797) như trước chỉ số
chỉ huy. Số lượng liên kết đã giảm đi một.
Bởi vì chúng tôi đi đến một liên kết cố định tới inode này, nếu chúng tôi xóaứng dụng geek
, nó sẽ thực sự xóa tệp. Hệ thống tệp sẽ giải phóng inode và đánh dấu cấu trúc thư mục bằng inode bằng không. Sau đó, một tệp mới có thể ghi đè lên phần lưu trữ dữ liệu trên ổ cứng.
LIÊN QUAN:Cách sử dụng lệnh stat trên Linux
Inode Overhead
đó là một hệ thống gọn gàng, nhưng có những chi phí chung. Để đọc một tệp, hệ thống tệp phải thực hiện tất cả những việc sau:
- Tìm cấu trúc thư mục phù hợp
- Đọc số inode
- Tìm inode phù hợp
- Đọc thông tin inode
- Thực hiện theo các liên kết inode hoặc các phạm vi đến các khối đĩa có liên quan
- Đọc dữ liệu tệp
Một chút nhảy xung quanh là cần thiết nếu dữ liệu không liền nhau.
Hãy tưởng tượng công việc phải được thực hiện chols
để thực hiện một danh sách tệp định dạng dài gồm nhiều tệp. Có rất nhiều hoạt động qua lại chỉ dành cho ls
để có được thông tin nó cần để tạo ra đầu ra của nó.
Tất nhiên, tăng tốc độ truy cập hệ thống tệp là lý do tại sao Linux cố gắng thực hiện càng nhiều bộ nhớ đệm tệp trước càng tốt. Điều này giúp ích rất nhiều, nhưng đôi khi — cũng như với bất kỳ hệ thống tệp nào — chi phí chung có thể trở nên rõ ràng.
Bây giờ bạn sẽ biết tại sao.