Subversion Repositories Kolibri OS

Rev

Rev 4429 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Contains ext2 structures, and macros.                        ;;
  4. ;;                                                              ;;
  5. ;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
  6. ;; Distributed under terms of the GNU General Public License    ;;
  7. ;;                                                              ;;
  8. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  9.  
  10. $Revision: 4891 $
  11.  
  12.  
  13. ; Future jobs for driver, in order of preference:
  14. ;     * clean up existing extents support.
  15. ;     * add b-tree directories support.
  16. ;     * add long file support.
  17. ;     * add journal support.
  18. ;     * add minor features that come with ext3/4.
  19.  
  20. ; Recommended move to some kernel-wide bitmap handling code (with a bit of abstraction, of course).
  21.  
  22. ;---------------------------------------------------------------------
  23. ; Clears a bit.
  24. ; Input:        eax = index into bitmap.
  25. ;               [EXTFS.ext2_save_block] = address of bitmap.
  26. ;               ebp = address of EXTFS.
  27. ; Output:       Bit cleared.
  28. ;               eax = non-zero, if already cleared.
  29. ;---------------------------------------------------------------------
  30. bitmap_clear_bit:
  31.         push    ebx ecx edx
  32.  
  33.         xor     edx, edx
  34.         mov     ecx, 8
  35.         div     ecx
  36.  
  37.         add     eax, [ebp + EXTFS.ext2_save_block]
  38.        
  39.         ; Get the mask.
  40.         mov     ebx, 1
  41.         mov     ecx, edx
  42.         shl     ebx, cl
  43.  
  44.         test    [eax], ebx
  45.         jz      .cleared
  46.  
  47.         not     ebx
  48.         and     [eax], ebx
  49.  
  50.         xor     eax, eax
  51.     .return:
  52.         pop     edx ecx ebx
  53.         ret
  54.  
  55.     ; Already cleared.
  56.     .cleared:
  57.         xor     eax, eax
  58.         not     eax
  59.         jmp     .return
  60.  
  61. ;---------------------------------------------------------------------
  62. ; Finds free bit in the bitmap.
  63. ; Input:        ecx = number of bits in the bitmap.
  64. ;               [EXTFS.ext2_save_block] = address of bitmap.
  65. ;               ebp = address of EXTFS.
  66. ; Output:       eax = index of free bit in the bitmap; marked set.
  67. ;                     0xFFFFFFFF if no free bit found.
  68. ;---------------------------------------------------------------------
  69. ext2_find_free_bit:
  70. bitmap_find_free_bit:
  71.         push    esi ebx ecx edx
  72.         mov     esi, [ebp + EXTFS.ext2_save_block]
  73.  
  74.         ; Get total DWORDS in eax; total bits in last dword, if any, in edx.
  75.         xor     edx, edx
  76.         mov     eax, ecx
  77.         mov     ecx, 32
  78.         div     ecx
  79.  
  80.         mov     ecx, eax
  81.         xor     eax, eax
  82.         push    edx
  83.  
  84.         test    ecx, ecx
  85.         jz      .last_bits
  86.  
  87.     ; Check in the DWORDS.
  88.     .dwords:
  89.         mov     ebx, [esi]
  90.         not     ebx
  91.  
  92.         bsf     edx, ebx
  93.  
  94.         ; If 0, then the original value would be 0xFFFFFFFF, hence no free bits.
  95.         jz      @F
  96.  
  97.         ; We found the value. Let's return with it.
  98.         add     esp, 4
  99.  
  100.         add     eax, edx
  101.         jmp     .return
  102.        
  103.     @@:
  104.         add     esi, 4
  105.         add     eax, 32
  106.         loop    .dwords
  107.  
  108.     .last_bits:
  109.         ; Check in the last few bits.
  110.         pop     ecx
  111.         test    ecx, ecx
  112.         jz      @F
  113.        
  114.         mov     ebx, [esi]
  115.         not     ebx
  116.         bsf     ebx, edx
  117.  
  118.         ; If 0, no free bits.
  119.         jz      @F
  120.  
  121.         ; If free bit is greater than the last known bit, then error.
  122.         cmp     edx, ecx
  123.         jg      @F
  124.  
  125.         add     eax, edx
  126.         jmp     .return
  127.  
  128.     @@:
  129.         ; Didn't find any free bits.
  130.         xor     eax, eax
  131.         not     eax
  132.         jmp     @F
  133.  
  134.     .return:
  135.         mov     ecx, edx
  136.         mov     edx, 1
  137.         shl     edx, cl
  138.         or      [esi], edx
  139.  
  140.     @@:
  141.         pop     edx ecx ebx esi
  142.         ret
  143.  
  144. ; Recommended move to some kernel-wide string handling code.
  145. ;---------------------------------------------------------------------
  146. ; Find the length of a string.
  147. ; Input:        esi = source.
  148. ; Output:       length in ecx
  149. ;---------------------------------------------------------------------
  150. strlen:
  151.         push    eax esi
  152.         xor     ecx, ecx
  153.  
  154.     @@:
  155.         lodsb
  156.         test    al, al
  157.         jz      .ret
  158.  
  159.         inc     ecx
  160.         jmp     @B
  161.  
  162.     .ret:
  163.         pop     esi eax
  164.         ret
  165.  
  166. ;---------------------------------------------------------------------
  167. ; Convert UTF-8 string to ASCII-string (codepage 866)
  168. ; Input:        esi = source.
  169. ;               edi = buffer.
  170. ;               ecx = length of source.
  171. ; Output:       destroys eax, esi, edi
  172. ;---------------------------------------------------------------------
  173. utf8_to_cp866:
  174.         ; Check for zero-length string.
  175.         jecxz   .return
  176.  
  177.     .start:
  178.         lodsw
  179.         cmp     al, 0x80
  180.         jb      .ascii
  181.  
  182.         xchg    al, ah                                  ; Big-endian.
  183.         cmp     ax, 0xd080
  184.         jz      .yo1
  185.  
  186.         cmp     ax, 0xd191
  187.         jz      .yo2
  188.  
  189.         cmp     ax, 0xd090
  190.         jb      .unk
  191.  
  192.         cmp     ax, 0xd180
  193.         jb      .rus1
  194.  
  195.         cmp     ax, 0xd190
  196.         jb      .rus2
  197.  
  198.     .unk:
  199.         mov     al, '_'
  200.         jmp     .doit
  201.  
  202.     .yo1:
  203.         mov     al, 0xf0                                ; Ё capital.
  204.         jmp     .doit
  205.  
  206.     .yo2:
  207.         mov     al, 0xf1                                ; ё small.
  208.         jmp     .doit
  209.  
  210.     .rus1:
  211.         sub     ax, 0xd090 - 0x80
  212.         jmp     .doit
  213.  
  214.     .rus2:
  215.         sub     ax, 0xd18f - 0xEF
  216.    
  217.     .doit:
  218.         stosb
  219.         sub     ecx, 2
  220.         ja      .start
  221.         ret
  222.  
  223.     .ascii:
  224.         stosb
  225.         dec     esi
  226.         dec     ecx
  227.         jnz     .start
  228.  
  229.     .return:
  230.         ret
  231.  
  232. ; Recommended move to some kernel-wide time handling code.
  233.  
  234. ; Total cumulative seconds till each month.
  235. cumulative_seconds_in_month:
  236.         .january:       dd 0 * (60 * 60 * 24)
  237.         .february:      dd 31 * (60 * 60 * 24)
  238.         .march:         dd 59 * (60 * 60 * 24)
  239.         .april:         dd 90 * (60 * 60 * 24)
  240.         .may:           dd 120 * (60 * 60 * 24)
  241.         .june:          dd 151 * (60 * 60 * 24)
  242.         .july:          dd 181 * (60 * 60 * 24)
  243.         .august:        dd 212 * (60 * 60 * 24)
  244.         .september:     dd 243 * (60 * 60 * 24)
  245.         .october:       dd 273 * (60 * 60 * 24)
  246.         .november:      dd 304 * (60 * 60 * 24)
  247.         .december:      dd 334 * (60 * 60 * 24)
  248.  
  249. current_bdfe_time:
  250.         dd 0
  251. current_bdfe_date:
  252.         dd 0
  253.  
  254. ;---------------------------------------------------------------------
  255. ; Stores current unix time.
  256. ; Input:        edi = buffer to output Unix time.
  257. ;---------------------------------------------------------------------
  258. current_unix_time:
  259.         push    eax esi
  260.         mov     esi, current_bdfe_time
  261.        
  262.         ; Just a small observation:
  263.         ; The CMOS is a pretty bad source to get time from. One shouldn't rely on it,
  264.         ; since it messes up the time by tiny bits. Of course, this is all technical,
  265.         ; but one can look it up on the osdev wiki. What is better is to get the time
  266.         ; from CMOS during boot, then update system time using a more accurate timer.
  267.         ; I'll probably add that after the Summer of Code, so TODO! TODO! TODO!.
  268.  
  269.         ; Get time from CMOS.
  270.         ; Seconds.
  271.         mov     al, 0x00
  272.         out     0x70, al
  273.         in      al, 0x71
  274.         call    bcd2bin
  275.         mov     [esi + 0], al
  276.  
  277.         ; Minute.
  278.         mov     al, 0x02
  279.         out     0x70, al
  280.         in      al, 0x71
  281.         call    bcd2bin
  282.         mov     [esi + 1], al
  283.  
  284.         ; Hour.
  285.         mov     al, 0x04
  286.         out     0x70, al
  287.         in      al, 0x71
  288.         call    bcd2bin
  289.         mov     [esi + 2], al
  290.  
  291.         ; Get date.
  292.  
  293.         ; Day.
  294.         mov     al, 0x7
  295.         out     0x70, al
  296.         in      al, 0x71
  297.         call    bcd2bin
  298.         mov     [esi + 4], al
  299.  
  300.         ; Month.
  301.         mov     al, 0x8
  302.         out     0x70, al
  303.         in      al, 0x71
  304.         call    bcd2bin
  305.         mov     [esi + 5], al
  306.  
  307.         ; Year.
  308.         mov     al, 0x9
  309.         out     0x70, al
  310.         in      al, 0x71
  311.         call    bcd2bin
  312.         add     ax, 2000        ; CMOS only returns last two digits.
  313.                                 ; Note that everywhere in KolibriOS this is used.
  314.                                 ; This is hacky, since the RTC can be incorrectly set
  315.                                 ; to something before 2000.
  316.         mov     [esi + 6], ax
  317.  
  318.         call    bdfe_to_unix_time
  319.         pop     esi eax
  320.         ret
  321.  
  322. ;---------------------------------------------------------------------
  323. ; Convert time+date from BDFE to Unix time.
  324. ; Input:        esi = pointer to BDFE time+date.
  325. ;               edi = buffer to output Unix time.
  326. ;---------------------------------------------------------------------
  327. bdfe_to_unix_time:
  328.         push    eax ebx ecx edx
  329.         mov     dword[edi], 0x00000000
  330.      
  331.         ; The minimum representable time is 1901-12-13.
  332.         cmp     word[esi + 6], 1901
  333.         jb      .ret
  334.         jg      .max
  335.  
  336.         cmp     byte[esi + 5], 12
  337.         jb      .ret
  338.  
  339.         cmp     byte[esi + 4], 13
  340.         jbe     .ret
  341.         jg      .convert
  342.  
  343.     ; Check if it is more than the maximum representable time.
  344.     .max:
  345.         ; The maximum representable time is 2038-01-19.
  346.         cmp     word[esi + 6], 2038
  347.         jg      .ret
  348.         jb      .convert
  349.  
  350.         cmp     byte[esi + 5], 1
  351.         jg      .ret
  352.  
  353.         cmp     byte[esi + 4], 19
  354.         jge     .ret
  355.  
  356.     ; Convert the time.
  357.     .convert:
  358.         ; Get if current year is leap year in ECX.
  359.         xor     ecx, ecx
  360.         mov     ebx, 4
  361.         xor     edx, edx
  362.  
  363.         cmp     word[esi + 6], 1970
  364.         jb      .negative
  365.  
  366.         movzx   eax, word[esi + 6]              ; Year.
  367.         cmp     byte[esi + 5], 3                ; If the month is less than March, than that year doesn't matter.
  368.         jge     @F
  369.  
  370.         test    eax, 3
  371.         ; Not a leap year.
  372.         jnz     @F
  373.  
  374.         inc     ecx
  375.     @@:
  376.         ; Number of leap years between two years = ((end date - 1)/4) - (1970/4)
  377.         dec     eax
  378.         div     ebx
  379.         sub     eax, 1970/4
  380.  
  381.         ; EAX is the number of leap years.
  382.         add     eax, ecx
  383.         mov     ecx, (60 * 60 * 24)             ; Seconds in a day.
  384.         mul     ecx
  385.  
  386.         ; Account for leap years, i.e., one day extra for each.
  387.         add     [edi], eax
  388.  
  389.         ; Get total days in EAX.
  390.         movzx   eax, byte[esi + 4]
  391.         dec     eax
  392.         mul     ecx
  393.  
  394.         ; Account for days.
  395.         add     [edi], eax
  396.  
  397.         ; Account for month.
  398.         movzx   eax, byte[esi + 5]
  399.         dec     eax
  400.         mov     eax, [cumulative_seconds_in_month + (eax * 4)]
  401.         add     [edi], eax
  402.  
  403.         ; Account for year.
  404.         movzx   eax, word[esi + 6]
  405.         sub     eax, 1970
  406.         mov     ecx, (60 * 60 * 24) * 365       ; Seconds in a year.
  407.         mul     ecx
  408.         add     [edi], eax
  409.  
  410.         ; Seconds.
  411.         movzx   eax, byte[esi + 0]
  412.         add     [edi], eax        
  413.  
  414.         ; Minutes.
  415.         movzx   eax, byte[esi + 1]
  416.         mov     ecx, 60
  417.         mul     ecx
  418.         add     [edi], eax
  419.  
  420.         ; Hours.
  421.         movzx   eax, byte[esi + 2]
  422.         mov     ecx, (60 * 60)
  423.         mul     ecx
  424.         add     [edi], eax  
  425.  
  426.     ; The time wanted is before the epoch; handle it here.
  427.     .negative:
  428.         ; TODO.
  429.  
  430.     .ret:
  431.         pop     edx ecx ebx eax
  432.         ret
  433.  
  434. ; Recommended move to some kernel-wide alloc handling code.
  435. macro KERNEL_ALLOC store, label
  436. {
  437.         call    kernel_alloc
  438.         mov     store, eax
  439.         test    eax, eax    
  440.         jz      label  
  441. }
  442.  
  443. macro KERNEL_FREE data, label
  444. {
  445.         cmp     data, 0
  446.         jz      label
  447.         push    data
  448.         call    kernel_free
  449. }
  450.  
  451. struct EXTFS PARTITION
  452.         lock MUTEX
  453.         partition_flags                dd ?
  454.         log_block_size                 dd ?
  455.         block_size                     dd ?
  456.         count_block_in_block           dd ?
  457.         blocks_per_group               dd ?
  458.         global_desc_table              dd ?
  459.         root_inode                     dd ?         ; Pointer to root inode in memory.
  460.         inode_size                     dd ?
  461.         count_pointer_in_block         dd ?         ; (block_size / 4)
  462.         count_pointer_in_block_square  dd ?         ; (block_size / 4)**2
  463.         ext2_save_block                dd ?         ; Block for 1 global procedure.
  464.         ext2_temp_block                dd ?         ; Block for small procedures.
  465.         ext2_save_inode                dd ?         ; inode for global procedures.
  466.         ext2_temp_inode                dd ?         ; inode for small procedures.
  467.         groups_count                   dd ?
  468.         superblock                     rd 1024/4
  469. ends
  470.  
  471. ; EXT2 revisions.
  472. EXT2_GOOD_OLD_REV    = 0
  473.  
  474. ; For fs_type.
  475. FS_TYPE_UNDEFINED    = 0
  476. FS_TYPE_EXT          = 2
  477.  
  478. ; Some set inodes.
  479. EXT2_BAD_INO         = 1
  480. EXT2_ROOT_INO        = 2
  481. EXT2_ACL_IDX_INO     = 3
  482. EXT2_ACL_DATA_INO    = 4
  483. EXT2_BOOT_LOADER_INO = 5
  484. EXT2_UNDEL_DIR_INO   = 6
  485.  
  486. ; EXT2_SUPER_MAGIC.
  487. EXT2_SUPER_MAGIC     = 0xEF53
  488. EXT2_VALID_FS        = 1
  489.  
  490. ; Flags defining i_mode values.
  491. EXT2_S_IFMT          = 0xF000           ; Mask for file type.
  492.  
  493. EXT2_S_IFREG         = 0x8000           ; Regular file.
  494. EXT2_S_IFDIR         = 0x4000           ; Directory.
  495.  
  496. EXT2_S_IRUSR         = 0x0100           ; User read
  497. EXT2_S_IWUSR         = 0x0080           ; User write
  498. EXT2_S_IXUSR         = 0x0040           ; User execute
  499. EXT2_S_IRGRP         = 0x0020           ; Group read
  500. EXT2_S_IWGRP         = 0x0010           ; Group write
  501. EXT2_S_IXGRP         = 0x0008           ; Group execute
  502. EXT2_S_IROTH         = 0x0004           ; Others read
  503. EXT2_S_IWOTH         = 0x0002           ; Others write
  504. EXT2_S_IXOTH         = 0x0001           ; Others execute
  505.  
  506. PERMISSIONS          = EXT2_S_IRUSR or EXT2_S_IWUSR \
  507.                        or EXT2_S_IRGRP or EXT2_S_IWGRP \
  508.                        or EXT2_S_IROTH or EXT2_S_IWOTH
  509.  
  510. ; File type defining values in directory entry.
  511. EXT2_FT_REG_FILE     = 1                ; Regular file.
  512. EXT2_FT_DIR          = 2                ; Directory.
  513.  
  514. ; Flags used by KolibriOS.
  515. FS_FT_HIDDEN         = 2
  516. FS_FT_DIR            = 0x10             ; Directory.
  517.  
  518. ; ext2 partition flags.
  519. EXT2_RO              = 0x01
  520.  
  521. FS_FT_ASCII          = 0                ; Name in ASCII.
  522. FS_FT_UNICODE        = 1                ; Name in Unicode.
  523.  
  524. EXT2_FEATURE_INCOMPAT_FILETYPE = 0x0002 ; Have file type in directory entry.
  525. EXT4_FEATURE_INCOMPAT_EXTENTS  = 0x0040 ; Extents.
  526. EXT4_FEATURE_INCOMPAT_FLEX_BG  = 0x0200 ; Flexible block groups.
  527.  
  528. EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER = 0x0001 ; Sparse Superblock
  529. EXT2_FEATURE_RO_COMPAT_LARGE_FILE   = 0x0002 ; Large file support (64-bit file size)
  530.  
  531. ; Implemented ext[2,3,4] features.
  532. EXT4_FEATURE_INCOMPAT_SUPP = EXT2_FEATURE_INCOMPAT_FILETYPE \
  533.                              or EXT4_FEATURE_INCOMPAT_EXTENTS \
  534.                              or EXT4_FEATURE_INCOMPAT_FLEX_BG
  535.  
  536. ; Implemented features which otherwise require "read-only" mount.
  537. EXT2_FEATURE_RO_COMPAT_SUPP = EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER \
  538.                               or EXT2_FEATURE_RO_COMPAT_LARGE_FILE
  539.  
  540. ; ext4 features not support for write.
  541. EXT4_FEATURE_INCOMPAT_W_NOT_SUPP = EXT4_FEATURE_INCOMPAT_EXTENTS \
  542.                                    or EXT4_FEATURE_INCOMPAT_FLEX_BG
  543.  
  544. ; Flags specified in i_flags.
  545. EXT2_EXTENTS_FL      = 0x00080000       ; Extents.
  546.  
  547. struct  EXT2_INODE_STRUC
  548.         i_mode          dw ?
  549.         i_uid           dw ?
  550.         i_size          dd ?
  551.         i_atime         dd ?
  552.         i_ctime         dd ?
  553.         i_mtime         dd ?
  554.         i_dtime         dd ?
  555.         i_gid           dw ?
  556.         i_links_count   dw ?
  557.         i_blocks        dd ?
  558.         i_flags         dd ?
  559.         i_osd1          dd ?
  560.         i_block         rd 15
  561.         i_generation    dd ?
  562.         i_file_acl      dd ?
  563.         i_dir_acl       dd ?
  564.         i_faddr         dd ?
  565.         i_osd2          dd ?        ; 12 bytes.
  566. ends
  567.  
  568. struct  EXT2_DIR_STRUC
  569.         inode           dd ?
  570.         rec_len         dw ?
  571.         name_len        db ?
  572.         file_type       db ?
  573.         name            db ?         ; 255 (max) bytes.
  574. ends
  575.  
  576. struct  EXT2_BLOCK_GROUP_DESC
  577.         block_bitmap            dd ?         ; +0
  578.         inode_bitmap            dd ?         ; +4
  579.         inode_table             dd ?         ; +8
  580.         free_blocks_count       dw ?         ; +12
  581.         free_inodes_count       dw ?         ; +14
  582.         used_dirs_count         dw ?         ; +16
  583.         pad                     dw ?         ; +18
  584.         reserved                rb 12        ; +20
  585. ends
  586.  
  587. struct  EXT2_SB_STRUC
  588.         inodes_count            dd ?         ; +0
  589.         blocks_count            dd ?         ; +4
  590.         r_block_count           dd ?         ; +8
  591.         free_block_count        dd ?         ; +12
  592.         free_inodes_count       dd ?         ; +16
  593.         first_data_block        dd ?         ; +20
  594.         log_block_size          dd ?         ; +24
  595.         log_frag_size           dd ?         ; +28
  596.         blocks_per_group        dd ?         ; +32
  597.         frags_per_group         dd ?         ; +36
  598.         inodes_per_group        dd ?         ; +40
  599.         mtime                   dd ?         ; +44
  600.         wtime                   dd ?         ; +48
  601.         mnt_count               dw ?         ; +52
  602.         max_mnt_count           dw ?         ; +54
  603.         magic                   dw ?         ; +56
  604.         state                   dw ?         ; +58
  605.         errors                  dw ?         ; +60
  606.         minor_rev_level         dw ?         ; +62
  607.         lastcheck               dd ?         ; +64
  608.         check_intervals         dd ?         ; +68
  609.         creator_os              dd ?         ; +72
  610.         rev_level               dd ?         ; +76
  611.         def_resuid              dw ?         ; +80
  612.         def_resgid              dw ?         ; +82
  613.         first_ino               dd ?         ; +84
  614.         inode_size              dw ?         ; +88
  615.         block_group_nr          dw ?         ; +90
  616.         feature_compat          dd ?         ; +92
  617.         feature_incompat        dd ?         ; +96
  618.         feature_ro_compat       dd ?         ; +100
  619.         uuid                    rb 16        ; +104
  620.         volume_name             rb 16        ; +120
  621.         last_mounted            rb 64        ; +136
  622.         algo_bitmap             dd ?         ; +200
  623.         prealloc_blocks         db ?         ; +204
  624.         preallock_dir_blocks    db ?         ; +205
  625.         reserved_gdt_blocks     dw ?         ; +206
  626.         journal_uuid            rb 16        ; +208
  627.         journal_inum            dd ?         ; +224
  628.         journal_dev             dd ?         ; +228
  629.         last_orphan             dd ?         ; +232
  630.         hash_seed               rd 4         ; +236
  631.         def_hash_version        db ?         ; +252
  632.         reserved                rb 3         ; +253 (reserved)
  633.         default_mount_options   dd ?         ; +256
  634.         first_meta_bg           dd ?         ; +260
  635.         mkfs_time               dd ?         ; +264
  636.         jnl_blocks              rd 17        ; +268
  637.         blocks_count_hi         dd ?         ; +336
  638.         r_blocks_count_hi       dd ?         ; +340
  639.         free_blocks_count_hi    dd ?         ; +344
  640.         min_extra_isize         dw ?         ; +348
  641.         want_extra_isize        dw ?         ; +350
  642.         flags                   dd ?         ; +352
  643.         raid_stride             dw ?         ; +356
  644.         mmp_interval            dw ?         ; +358
  645.         mmp_block               dq ?         ; +360
  646.         raid_stripe_width       dd ?         ; +368
  647.         log_groups_per_flex     db ?         ; +372
  648. ends
  649.  
  650. ; Header block extents.
  651. struct EXT4_EXTENT_HEADER
  652.         eh_magic        dw ?    ; Magic value of 0xF30A, for ext4.
  653.         eh_entries      dw ?    ; Number of blocks covered by the extent.
  654.         eh_max          dw ?    ; Capacity of entries.
  655.         eh_depth        dw ?    ; Tree depth (if 0, extents in the array are not extent indexes)
  656.         eh_generation   dd ?    ; ???
  657. ends
  658.  
  659. ; Extent.
  660. struct EXT4_EXTENT
  661.         ee_block        dd ?    ; First logical block extent covers.
  662.         ee_len          dw ?    ; Number of blocks covered by extent.
  663.         ee_start_hi     dw ?    ; Upper 16 bits of 48-bit address (unused in KOS)
  664.         ee_start_lo     dd ?    ; Lower 32 bits of 48-bit address.
  665. ends
  666.  
  667. ; Index on-disk structure; pointer to block of extents/indexes.
  668. struct EXT4_EXTENT_IDX
  669.         ei_block        dd ?    ; Covers logical blocks from here.
  670.         ei_leaf_lo      dd ?    ; Lower 32-bits of pointer to the physical block of the next level.
  671.         ei_leaf_hi      dw ?    ; Higher 16-bits (unused in KOS).
  672.         ei_unused       dw ?    ; Reserved.
  673. ends