Ext4

**Hệ thống file nhật ký ext4** hoặc **Hệ thống file mở rộng thứ tư** là một hệ thống file nhật ký cho Linux, được phát triển như là sự kế thừa cho ext3. Đây là hệ thống file mặc định cho hầu hết các bản phân phối Linux.

## Lịch sử
ext4 ban đầu là một loạt các phần mở rộng tương thích ngược với ext3, nhiều phần mở rộng ban đầu được phát triển bởi Cluster File Systems cho hệ thống file Luster giữa năm 2003 và 2006, nhằm mở rộng giới hạn lưu trữ và thêm các cải tiến hiệu suất khác. Tuy nhiên, các nhà phát triển nhân Linux khác phản đối việc chấp nhận các phần mở rộng cho, và đề nghị fork mã nguồn của ext3, đổi tên nó thành ext4, và thực hiện tất cả sự phát triển đó, mà không ảnh hưởng đến người dùng ext3 hiện tại. Đề xuất này đã được chấp nhận và vào ngày 28 tháng 6 năm 2006, Theodore Ts'o, người duy trì ext3, đã công bố kế hoạch phát triển mới cho ext4.

Phiên bản phát triển sơ bộ của ext4 đã được đưa vào phiên bản 2.6.19  của nhân Linux. Ngày 11 tháng 10 năm 2008, các bản vá đánh dấu ext4 là mã ổn định đã được hợp nhất trong kho lưu trữ mã nguồn Linux 2.6.28, biểu thị sự kết thúc của giai đoạn phát triển và khuyến nghị áp dụng ext4. Kernel 2.6.28, chứa hệ thống file ext4, cuối cùng đã được phát hành ngày 25 tháng 12 năm 2008 Ngày 15 tháng 1 năm 2010, Google đã thông báo rằng họ sẽ nâng cấp cơ sở hạ tầng lưu trữ của mình từ ext2 lên ext4. Ngày 14 tháng 12 năm 2010, Google cũng tuyên bố sẽ sử dụng ext4, thay vì YAFFS, trên Android 2.3.

## Tính năng, đặc điểm

; Hệ thống file lớn
: Hệ thống file ext4 hỗ trợ các phân vùng có kích thước lên tới 1 exbibyte (EiB) và các file đơn lẻ có kích thước tới 16 tebibytes (TiB) với block size 4 KiB tiêu chuẩn. Giới hạn kích thước file, thư mục và kích thước hệ thống file tối đa tăng theo tỉ lệ với block size hệ thống file lên đến kích thước block 64 KiB tối đa có sẵn trên CPU ARM và PowerPC/Power ISA.
; Extents
: Extents thay thế sơ đồ ánh xạ block truyền thống được sử dụng bởi ext2 và ext3. Một extent là một chuỗi các blocks vật lý liền kề nhau, cải thiện hiệu suất với file lớn và giảm phân mảnh. Một extent đơn trong ext4 có thể ánh xạ tới 128 MiB không gian tiếp giáp với block size 4 KiB. Có thể có bốn phạm vi được lưu trữ trực tiếp trong inode. Khi có nhiều hơn bốn phạm vi cho một file, phần còn lại của các phạm vi được lập chỉ mục trong một cây.
; Tương thích ngược
: ext4 tương thích ngược với ext3 và ext2, làm cho nó có thể mount ext3 và ext2 giống như ext4.Điều này sẽ cải thiện hiệu suất một chút, bởi vì một số tính năng mới của việc triển khai ext4 cũng có thể được sử dụng với ext3 và ext2, chẳng hạn như thuật toán phân bổ block mới, mà không ảnh hưởng đến định dạng trên đĩa.
: ext3 tương thích một phần với ext4. Thực tế, ext4 sẽ không mount như một hệ thống file ext3, trừ khi một số tính năng mới bị vô hiệu hóa khi tạo nó, chẳng hạn như `^extent`, `^flex_bg`, `^huge_file`, `^uninit_bg`, `^dir_nlink`, và `^extra_isize`.
; Phân bổ trước liên tục
: ext4 có thể phân bổ trước dung lượng trên đĩa cho một file. Để làm điều này trên hầu hết các hệ thống file, các số 0 sẽ được ghi vào file khi được tạo. ITrong ext4 (và một số hệ thống file khác ví dụ như XFS) `fallocate()`, một lời gọi hệ thống mới trong nhân Linux, có thể được dùng. Không gian được phân bổ sẽ được đảm bảo và có khả năng tiếp giáp nhau. Tình huống này có các ứng dụng cho truyền phát trực tuyến và cơ sở dữ liệu.
; Phân bổ trễ
: ext4 sử dụng một kỹ thuật hiệu suất được gọi là allocate-on-flush, còn được gọi là *phân bổ trễ* Đó là, ext4 trì hoãn phân bổ block cho đến khi dữ liệu được ghi vào đĩa. Ngược lại, một số hệ thống file phân bổ các block ngay lập tức, ngay khi dữ liệu được đưa vào cache. Phân bổ trễ sẽ cải thiện hiệu suất và giảm phân mảnh bằng cách phân bổ hiệu quả lượng dữ liệu lớn hơn tại một thời điểm.
; Không giới hạn số lượng thu mục con
: Ext4 không giới hạn số lượng thư mục con trong một thư mục, ngoại trừ bởi giới hạn kích thước vốn có của chính thư mục đó (trong ext3 một thư mục có tối đa 32000 thư mục con). Để cho phép các thư mục lớn hơn và tiếp tục hoạt động, ext4 trong Linux 2.6.23 trở lên, kích hoạt mảng HTree (một phiên bản đặc biệt của B-tree) theo mặc định, cho phép các thư mục được lưu trữ trong khoảng 10-12 triệu mục trong mục lục 2-level HTree và và giới hạn kích thước thư mục 2GB cho kích thước block 4 KiB, tùy thuộc vào độ dài tên file. Trong Linux 4.12 trở lên tính năng `largedir` kích hoạt một 3-level HTree và kích cỡ thư mục trên 2GB, cho phép khoảng 6 tỷ mục trong một thư mục.
; Kiểm tra nhật ký
: ext4 dùng checksums trong nhật ký để cải thiện độ tin cậy, vì nhật ký là một trong những file được sử dụng nhiều nhất của đĩa. Tính năng này có một lợi ích phụ: nó có thể tránh sự chờ đợi I/O của đĩa trong quá trình ghi nhật ký, cải thiện hiệu suất một chút. Kiểm tra nhật ký được lấy cảm hứng từ một bài báo nghiên cứu từ  University of Wisconsin, có tên là *IRON File Systems* (cụ thể, phần 6, được gọi là "kiểm tra giao dịch"), với các sửa đổi trong việc thực hiện các giao dịch hỗn hợp được thực hiện bởi hệ thống file IRON (ban đầu được đề xuất bởi Sam Naghreezeh trong hội nghị thượng đỉnh RedHat).
; Kiểm tra siêu dữ liệu
: Từ Linux kernel 3.16.
; Faster file system checking
: Trong ext4 các nhóm block và các phần của bảng chưa được phân bổ được đánh dấu. Việc này cho phép e2fsck bỏ qua chúng hoàn toàn và giảm đáng kể thời gian kiểm tra hệ thống file. Linux 2.6.24 triển khai tính năng này.

; Phân bổ đa block 
: Khi ext3 nối vào một file, nó gọi bộ cấp phát block, một lần cho mỗi block. Do đó, nếu có nhiều trình ghi đồng thời, các file có thể dễ dàng bị phân mảnh trên đĩa. Tuy nhiên, ext4 sử dụng phân bổ trễ cho phép nó lưu đệm dữ liệu và phân bổ các nhóm block. Do đó, bộ cấp phát đa block có thể đưa ra các lựa chọn tốt hơn về việc phân bổ các file liên tục trên đĩa. Bộ cấp phát đa block cũng có thể được sử dụng khi các file được mở ở chế độ O_DIRECT. Tính năng này không ảnh hưởng đến định dạng đĩa. 
; Cải thiện dấu thời gian 
: Khi máy tính trở nên nhanh hơn nói chung và khi Linux trở nên được sử dụng nhiều hơn cho các ứng dụng quan trọng, thì độ chi tiết của dấu thời gian dựa trên giây trở nên không đủ. Để giải quyết điều này, ext4 cung cấp dấu thời gian được đo bằng nano giây. Ngoài ra, 2 bit của trường dấu thời gian mở rộng được thêm vào các bit quan trọng nhất của trường giây của dấu thời gian để trì hoãn sự cố năm 2038 cho bổ sung 408 năm.  
: ext4 cũng bổ sung hỗ trợ cho dấu thời gian tạo giờ. Nhưng, như Theodore Ts'o chỉ ra, trong khi thật dễ dàng để thêm một trường ngày tạo thêm vào trong inode (như vậy, về mặt kỹ thuật cho phép hỗ trợ cho các dấu thời gian trong ext4), nó là khó khăn hơn để sửa đổi hoặc bổ sung cần thiết lời gọi hệ thống, như stat() (có thể sẽ yêu cầu một phiên bản mới) và các thư viện khác nhau phụ thuộc vào chúng (như glibc). Những thay đổi này sẽ yêu cầu sự phối hợp của nhiều dự án. Do đó, ngày tạo được lưu trữ bởi ext4 hiện chỉ khả dụng cho các chương trình người dùng trên Linux thông qua API `statx()`.
; Mã hóa trong suốt 
: Hỗ trợ mã hóa trong suốt đã được thêm vào Linux kernel 4.1 vào tháng 6 năm 2015.

## Hạn chế
Năm 2008, nhà phát triển chính của hệ thống file ext3 và ext4, Theodore Ts'o, đã tuyên bố rằng mặc dù ext4 có các tính năng được cải thiện, nhưng nó không phải là một bước tiến lớn, nó sử dụng công nghệ cũ và là một điểm dừng. Ts'o tin rằng Btrfs là hướng tốt hơn bởi vì "nó mang lại sự cải thiện về khả năng mở rộng, độ tin cậy và dễ quản lý". Btrfs cũng có "một số ý tưởng thiết kế tương tự mà reiser3/4 đã có". Tuy nhiên, ext4 đã tiếp tục đạt được các tính năng mới như mã hóa file và kiểm siêu dữ liệu.

Hệ thống file ext4 không xem trọng thuộc tính file "xóa an toàn", được cho là gây ra việc ghi đè các file khi xóa. Một bản vá để thực hiện xóa an toàn đã được đề xuất vào năm 2011, nhưng không giải quyết được vấn đề dữ liệu nhạy cảm kết thúc trong hệ thống file nhật ký.

## Phân bổ trễ và mất dữ liệu tiềm năng
Do phân trễ làm thay đổi hành vi mà các lập trình viên đã dựa vào ext3, tính năng này gây ra một số rủi ro mất dữ liệu bổ sung trong trường hợp hệ thống gặp sự cố hoặc mất điện trước khi tất cả dữ liệu được ghi vào đĩa. Do đó, ext4 trong các phiên bản kernel 2.6.30 trở lên sẽ tự động xử lý các trường hợp này như ext3.

Kịch bản điển hình trong đó điều này có thể xảy ra là một chương trình thay thế nội dung của file mà không buộc ghi vào đĩa bằng fsync. Có hai cách phổ biến để thay thế nội dung của file trên các hệ thống Unix:

* `fd=open("file", O_TRUNC); write(fd, data); close(fd);`

: Trong trường hợp này, một file hiện có bị cắt ngắn tại thời điểm mở (do cờ `O_TRUNC`), sau đó dữ liệu mới được ghi ra. Vì việc ghi có thể mất một thời gian, có thể mất cơ hội ngay cả với ext3, nhưng thường rất nhỏ. Tuy nhiên, vì ext4 có thể trì hoãn việc ghi dữ liệu file trong một thời gian dài, cơ hội này lớn hơn nhiều. 
: Có một số vấn đề có thể phát sinh: 
:# Nếu việc ghi không thành công (có thể do điều kiện lỗi trong chương trình ghi hoặc do các điều kiện bên ngoài như đĩa đầy), thì cả phiên bản gốc *và* phiên bản mới của file sẽ bị mất và file có thể bị hỏng vì chỉ một phần của nó đã được ghi. 
:# Nếu các tiến trình khác truy cập file trong khi nó đang được ghi, chúng sẽ thấy một phiên bản bị hỏng. 
:# Nếu các tiến trình khác mở file và không mong đợi nội dung của nó thay đổi, các tiến trình đó có thể bị crash. Một ví dụ đáng chú ý là một file thư viện dùng chung được ánh xạ vào các chương trình đang chạy. 
: Do những vấn đề này, thường thì câu lệnh sau được ưa thích hơn so với câu trên:

* `fd=open("file.new"); write(fd, data); close(fd); rename("file.new", "file");`

: Một file tạm mới ("file.new") được tạo, ban đầu chứa nội dung mới. Sau đó, file mới được đổi tên trên file cũ. Việc thay thế các file bằng lời gọi `rename()` được đảm bảo là nguyên tử theo tiêu chuẩn POSIX - tức là file cũ vẫn còn hoặc bị ghi đè bằng file mới. Vì chế độ ghi nhật ký "được đặt hàng" mặc định của ext3 đảm bảo dữ liệu file được ghi trên đĩa trước siêu dữ liệu, kỹ thuật này đảm bảo rằng nội dung file cũ hoặc mới sẽ tồn tại trên đĩa. Phân bổ trễ của ext4 phá vỡ kỳ vọng này, vì việc ghi file có thể bị trễ trong một thời gian dài và việc đổi tên thường được thực hiện trước khi *nội dung* file mới đến đĩa.

Sử dụng `fsync()` thường xuyên hơn để giảm rủi ro cho ext4 có thể dẫn đến các hình phạt về hiệu năng đối với các hệ thống file ext3 được gắn cờ `data=ordered` (mặc định trên hầu hết các bản phân phối Linux). Cho rằng cả hai hệ thống file sẽ được sử dụng trong một thời gian, điều này làm phức tạp vấn đề cho các nhà phát triển ứng dụng người dùng cuối. Đáp lại, ext4 trong nhân Linux 2.6.30 và mới hơn phát hiện sự xuất hiện của các trường hợp phổ biến này và buộc các file phải được phân bổ ngay lập tức. Với một phí tổn nhỏ trong hiệu suất, điều này cung cấp ngữ nghĩa tương tự như chế độ được đặt hàng ext3 và tăng khả năng một trong hai phiên bản của file sẽ sống sót sau sự cố. Hành vi mới này được kích hoạt theo mặc định, nhưng có thể bị vô hiệu hóa với tùy chọn gắn kết "noauto_da_alloc".

Các bản vá mới đã trở thành một phần của kernel dòng chính 2.6.30, nhưng các bản phân phối khác nhau đã chọn backport chúng thành 2.6.28 hoặc 2.6.29.

Các bản vá này hoàn toàn không ngăn chặn mất dữ liệu tiềm năng hoặc trợ giúp với các file mới. Cách duy nhất để an toàn là viết và sử dụng phần mềm thực hiện `fsync()` khi cần. Các vấn đề về hiệu năng có thể được giảm thiểu bằng cách hạn chế ghi đĩa quan trọng cần `fsync()` xảy ra ít thường xuyên hơn.

## Triển khai

Linux kernel Virtual File System là một hệ thống con hoặc lớp bên trong kernel Linux. Đó là kết quả của nỗ lực rất nghiêm túc để tích hợp nhiều hệ thống file vào một cấu trúc đơn có trật tự. Ý tưởng chính, bắt nguồn từ công việc tiên phong được thực hiện bởi các nhân viên của Sun Microsystems vào năm 1986, là trừu tượng hóa một phần của hệ thống file phổ biến cho tất cả các hệ thống file và đặt mã đó vào một lớp riêng gọi hệ thống tập tin cụ thể để thực sự quản lý dữ liệu.

Tất cả các lời gọi hệ thống liên quan đến các file (hoặc file giả) được chuyển đến Linux kernel Virtual File System để xử lý ban đầu. Các lời gọi này, đến từ các quy trình của người dùng, là các lời gọi POSIX tiêu chuẩn, chẳng hạn như `open`, `read`, `write`, `lseek`, v.v.

### Khả năng tương thích với Windows và Macintosh
ext4 chưa có nhiều hỗ trợ như ext2 và ext3 trên các hệ điều hành không phải Linux. ext2 và ext3 có các trình điều khiển ổn định như Ext2IFS, chưa có sẵn cho ext4. Có thể tạo các hệ thống file ext4 tương thích bằng cách vô hiệu hóa tính năng phạm vi và đôi khi chỉ định kích thước inode. Một tùy chọn khác để sử dụng ext4 trong Windows là sử dụng Ext2Fsd, trình điều khiển nguồn mở hỗ trợ ghi trong phân vùng ext4 với ghi nhật ký hạn chế. Cũng có thể xem và sao chép các file từ ext4 sang Windows, ngay cả khi đã bật tính năng mở rộng, với phần mềm Ext2Read. Gần đây, Paragon đã phát hành sản phẩm thương mại ExtFS for Windows, cho phép khả năng đọc/ghi cho ext2/3/4.

macOS có đầy đủ khả năng đọc/ghi ext2/3/4  thông qua phần mềm Paragon ExtFS, là một sản phẩm thương mại. Phần mềm miễn phí như ext4fuse chỉ hỗ trợ chỉ đọc với chức năng hạn chế.

## Xem thêm

* Btrfs 
* So sánh hệ thống file 
* Ext2Fsd 
* JFS 
* Danh sách các hệ thống file 
* Reiser4 
* XFS 
* ZFS 
* NTFS

## Chú thích

## Liên kết ngoài

* Theodore Ts'o's discussion on ext4, ngày 29 tháng 6 năm 2006
* "ext4 online defragmentation"  (materials from Ottawa Linux Symposium 2007)
* "The new ext4 filesystem: current status and future plans" (materials from Ottawa Linux Symposium 2007)
* Kernel Log: Ext4 completes development phase as interim step to btrfs, ngày 17 tháng 10 năm 2008
* "Ext4 block and inode allocator improvements"  (materials from Ottawa Linux Symposium 2008)
* "Ext4: The Next Generation of Ext2/3 Filesystem"
* Ext4 (and Ext2/Ext3) Wiki
* Ext4 wiki at kernelnewbies.org
* Native Windows port of Ext4 and other FS in CROSSMETA
* Ext2read A windows application to read/copy ext2/ext3/ext4 files with extent and LVM2 support.
* Ext2Fsd Open source ext2/ext3/ext4 read/write file system driver for Windows. ext4 is supported from version 0.50 onwards
* Ext4fuse Open source read-only ext4 driver for FUSE. (Supports Mac OS X 10.5 and later, using  MacFuse)