2009-08-28 1 views
7

Tôi tự hỏi làm thế nào lệnh stat tính toán các khối của một tập tin. Tôi đọc số article, nó cho biết:Lệnh stat tính các khối của một tệp như thế nào?

Giá trị st_blocks cho kích thước tệp trong khối 512 byte. (Điều này có thể nhỏ hơn st_size/512, ví dụ: khi tệp có lỗ.) Giá trị st_blksize cho phép khối "ưa thích" cho hệ thống tệp I/O hiệu quả. (Việc ghi vào một tập tin trong các đoạn nhỏ hơn có thể gây ra việc đọc-sửa-viết lại không hiệu quả.)

nhưng tôi không thể xác minh nó trong bài kiểm tra của mình.

hệ thống tệp của tôi là ext3.

các dumpe2fs -h/dev/sda3 cho thấy:

... 
First block: 0 
Block size: 4096 
Fragment size: 4096 
... 

sau đó tôi chạy

[email protected]:~/Desktop$ stat Email 
File: `Email' 
Size: 965 Blocks: 8 IO Block: 4096 regular file 
Device: 80ah/2058d Inode: 746095 Links: 1 
Access: (0644/-rw-r--r--) Uid: (1000/ kent) Gid: (1000/ kent) 
Access: 2009-08-11 21:36:36.000000000 +0200 
Modify: 2009-08-11 21:36:35.000000000 +0200 
Change: 2009-08-11 21:36:35.000000000 +0200 

Nếu Blocks đây có nghĩa là: có bao nhiêu 512bytes khối, số lượng nên 2 không 8. Tôi nghĩ rằng, các khối từ hệ thống tập tin (khối io) là 4k. Nếu fs sẽ nhận được các tập tin Email, nó sẽ lấy tối thiểu 4k từ đĩa (8 x 512bytes khối), có nghĩa là 965/512 + 6 = 8. Tôi không chắc chắn nếu đoán là chính xác.

một thử nghiệm:

[email protected]:~/Desktop$ stat wxPython-demo-2.8.10.1.tar.bz2 
File: `wxPython-demo-2.8.10.1.tar.bz2' 
Size: 3605257 Blocks: 7056 IO Block: 4096 regular file 
Device: 80ah/2058d Inode: 746210 Links: 1 
Access: (0644/-rw-r--r--) Uid: (1000/ kent) Gid: (1000/ kent) 
Access: 2009-08-12 21:45:45.000000000 +0200 
Modify: 2009-08-12 21:43:46.000000000 +0200 
Change: 2009-08-12 21:43:46.000000000 +0200 


3605257/512=7041.xx = 7042 

sau tôi đoán ở trên, đây sẽ là 7042 + 6 = 7048. nhưng kết quả cho thấy stat 7056.

Và một ví dụ khác từ internet tại http://www.computerhope.com/unix/stat.htm. Tôi sao chép ví dụ ở cuối trang tại đây:

File: `index.htm' 
Size: 17137 Blocks: 40 IO Block: 8192 regular file 
Device: 8h/8d Inode: 23161443 Links: 1 
Access: (0644/-rw-r--r--) Uid: (17433/comphope) Gid: (32/ www) 
Access: 2007-04-03 09:20:18.000000000 -0600 
Modify: 2007-04-01 23:13:05.000000000 -0600 
Change: 2007-04-02 16:36:21.000000000 -0600 

Trong ví dụ này, FS chặn là 8k. Tôi cho rằng số khối nên là 16xN, nhưng nó là 40. bị mất ...

bất cứ ai có thể giải thích, làm thế nào để tính toán các khối?

Cảm ơn!

Trả lời

15

Công cụ dòng lệnh stat sử dụng các chức năng stat/fstat v.v., trả về dữ liệu trong cấu trúc stat. Thành viên st_blocks của cấu trúc stat trả về:

Tổng số khối vật lý có kích thước 512 byte thực sự được phân bổ trên đĩa. Trường này không được định nghĩa cho các tệp đặc biệt của ký tự đặc biệt hoặc khối.

Vì vậy, đối với ví dụ "Email" của bạn, với kích thước 965 và khối đếm 8, nó chỉ ra rằng 8 * 512 = 4096 byte được phân bổ trên đĩa. Lý do nó không phải là 2 là hệ thống tập tin trên đĩa không phân bổ không gian trong các đơn vị 512, nó rõ ràng phân bổ chúng trong đơn vị 4096. (Và đơn vị phân bổ có thể khác nhau tùy thuộc vào kích thước tập tin và hệ thống tập tin tinh tế. đơn vị phân bổ.)

Tương tự, ví dụ wxPython, nó chỉ ra rằng 7056 * 512 byte hoặc 3612672 byte được phân bổ trên đĩa vật lý. Bạn có được ý tưởng.

Kích thước khối IO là "gợi ý về kích thước đơn vị 'tốt nhất' cho hoạt động I/O" - thường là đơn vị phân bổ trên đĩa vật lý. Đừng nhầm lẫn giữa khối IO và khối mà stat sử dụng để biểu thị kích thước vật lý; các khối cho kích thước vật lý luôn là 512 byte.

Cập nhật dựa trên nhận xét:

Như tôi đã nói, st_blocks là cách hệ điều hành chỉ ra bao nhiêu không gian được sử dụng bởi các tập tin trên đĩa. Các đơn vị phân bổ thực tế trên đĩa là sự lựa chọn của hệ thống tệp. Ví dụ, ZFS có thể có khối phân bổ có kích thước biến, ngay cả trong cùng một tệp, vì cách phân bổ khối: tệp bắt đầu có kích thước khối nhỏ và kích thước khối tiếp tục tăng cho đến khi đạt đến một điểm cụ thể. Nếu tập tin sau đó bị cắt bớt, nó có thể sẽ giữ kích thước khối cũ. Vì vậy, dựa trên lịch sử của tập tin, nó có thể có nhiều kích thước khối có thể. Vì vậy, cho một kích thước tập tin nó không phải là luôn luôn rõ ràng lý do tại sao nó có một kích thước vật lý cụ thể.

dụ bê tông: trên hộp Solaris của tôi, với một hệ thống tập tin ZFS, tôi có thể tạo ra một tập tin rất ngắn:

$ echo foo > test 
$ stat test 
    Size: 4    Blocks: 2   IO Block: 512 regular file 
(irrelevant details omitted) 

OK, file nhỏ, 2 khối, sử dụng đĩa vật lý là 1024 cho tập tin này.

$ dd if=/dev/zero of=test2 bs=8192 count=4 
$ stat test2 
    Size: 32768   Blocks: 65   IO Block: 32768 regular file 

OK, bây giờ chúng ta thấy mức sử dụng đĩa vật lý là 32.5K và kích thước khối IO là 32K. sau đó tôi sao chép nó vào test3 và cắt ngắn test3 tập tin này trong một biên tập viên:

$ cp test2 test3 
$ joe -hex test3 
$ stat test3 
    Size: 4    Blocks: 65   IO Block: 32768 regular file 

Vâng bây giờ, đây là một tập tin với 4 byte trong nó - giống như test - nhưng nó sử dụng 32.5K vật lý trên đĩa, vì cách hệ thống tệp ZFS phân bổ không gian. Kích thước khối tăng khi tệp lớn hơn, nhưng chúng không giảm khi tệp nhỏ hơn. (Và có, điều này có thể dẫn đến không gian lãng phí đáng kể tùy thuộc vào loại tệp và thao tác tệp bạn thực hiện trên ZFS, đó là lý do tại sao nó cho phép bạn đặt kích thước khối tối đa trên cơ sở từng tệp và thay đổi động.)

Hy vọng rằng bạn nên đánh giá cao rằng không nhất thiết phải có mối quan hệ đơn giản giữa kích thước tệp và mức sử dụng đĩa vật lý. Ngay cả ở trên, không rõ lý do tại sao 32,5K byte là cần thiết để lưu trữ một tệp có kích thước chính xác 32K - có vẻ như ZFS thường cần thêm 512 byte để lưu trữ thêm. Có lẽ nó đang sử dụng lưu trữ cho tổng kiểm tra, số lượng tham chiếu, trạng thái giao dịch - sổ sách kế toán hệ thống. Bằng cách bao gồm các tính năng bổ sung này trong kích thước tệp vật lý được chỉ định, có vẻ như ZFS đang cố gắng không đánh lừa người dùng về chi phí vật lý của tệp. Điều đó không có nghĩa là nó là tầm thường để đảo ngược kỹ sư tính toán mà không biết các chi tiết thân mật về việc triển khai hệ thống tệp cơ bản.

+0

Đồng ý. 'st_blocks' chỉ được gọi là vì lý do lịch sử. Đừng nghĩ về nó như là các khối, nhưng là số lượng không gian đĩa được sử dụng bởi các tập tin, trong các đơn vị của 512 byte. 512 byte là một đơn vị thuận tiện vì nó là đơn vị phân bổ nhỏ nhất mà bất kỳ ai sử dụng. – mark4o

+0

Cảm ơn bạn đã giải thích. gần như rõ ràng. nhưng vẫn có câu hỏi. tôi không chắc chắn nếu nó là sự hiểu biết chính xác: st_blocks = (kích thước khối IO/512) * (số lượng IO chặn tệp được sử dụng). Ví dụ email có thể được giải thích bằng cách này: (4096/512) * 1 = 8 wxpython một không. vì tệp đã sử dụng 881 khối IO và (4096/512) * 881 = 7048 không phải 7056. và ví dụ cuối cùng không phải là: 40 thậm chí có thể không được chia chính xác cho 16 (8192/512) .. là "512byte" cho tất cả hệ thống giống nhau không? cảm ơn – Kent