Subversion Repositories Kolibri OS

Rev

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