Subversion Repositories Kolibri OS

Rev

Rev 4429 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Contains common resource allocation + freeing code.          ;;
  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. ;---------------------------------------------------------------------
  14. ; Frees a resource (block/inode).
  15. ; Input:        eax = resource ID.
  16. ;               edi = function pointer of ext2_bg_*_bitmap form, to
  17. ;                     get bitmap of resource.
  18. ;               ecx = 0, block; 1, inode.
  19. ;               ebp = pointer to EXTFS.
  20. ; Output:       Block marked as free in block group.
  21. ;               eax = error code.
  22. ;---------------------------------------------------------------------
  23. ext2_resource_free:
  24.         push    ebx edx esi
  25.  
  26.         ; Get block group.
  27.         sub     eax, [ebp + EXTFS.superblock + EXT2_SB_STRUC.first_data_block]
  28.         xor     edx, edx
  29.         div     [ebp + EXTFS.superblock + EXT2_SB_STRUC.blocks_per_group]
  30.         push    eax edx
  31.  
  32.         call    edi
  33.         test    eax, eax
  34.         jz      .fail
  35.         mov     esi, eax
  36.  
  37.         ; Read the bitmap.
  38.         mov     eax, ebx
  39.         mov     edx, eax
  40.         mov     ebx, [ebp + EXTFS.ext2_save_block]
  41.         call    ext2_block_read
  42.         test    eax, eax
  43.         jnz     .fail
  44.  
  45.         pop     eax
  46.         ; Mark bit free.
  47.         call    bitmap_clear_bit
  48.         test    eax, eax
  49.         jz      @F
  50.  
  51.         ; No need to save anything.
  52.         xor     eax, eax
  53.  
  54.         add     esp, 4
  55.         jmp     .return
  56.  
  57.     @@:
  58.         mov     eax, edx
  59.         mov     ebx, [ebp + EXTFS.ext2_save_block]
  60.         call    ext2_block_write
  61.         test    eax, eax
  62.         jnz     .fail
  63.  
  64.         ; Read the descriptor.
  65.         mov     eax, [esp]
  66.         call    ext2_bg_read_desc
  67.         test    eax, eax
  68.         jz      .fail_bg_desc_read
  69.  
  70.         lea     eax, [eax + EXT2_BLOCK_GROUP_DESC.free_blocks_count]
  71.         shl     ecx, 1
  72.         add     eax, ecx
  73.         inc     word[eax]
  74.  
  75.         lea     eax, [ebp + EXTFS.superblock + EXT2_SB_STRUC.free_block_count]
  76.         shl     ecx, 1
  77.         add     eax, ecx
  78.         inc     dword[eax]
  79.  
  80.         pop     eax
  81.         call    ext2_bg_write_desc
  82.  
  83.     .return:
  84.         pop     esi edx ebx
  85.         ret
  86.  
  87.     .fail:
  88.         add     esp, 4
  89.     .fail_bg_desc_read:
  90.         add     esp, 4
  91.         xor     eax, eax
  92.         not     eax
  93.         jmp     .return
  94.  
  95. ;---------------------------------------------------------------------
  96. ; Allocates a resource.
  97. ; Input:        eax = inode ID for "preference".
  98. ;               ebp = pointer to EXTFS.
  99. ;               [esp + 4], func pointer to ext2_bg_*_bitmap
  100. ;               [esp + 8], pointer to free_*_count in SB.
  101. ;               [esp + 12], *_per_group
  102. ;               [esp + 16], offset to free_*_count in bg descriptor.
  103. ;               [esp + 20], *_count
  104. ; Output:       Resource marked as set in block group.
  105. ;               eax = error code.
  106. ;               ebx = resource ID.
  107. ;---------------------------------------------------------------------
  108. ext2_resource_alloc:
  109.         ; Block allocation is a pretty serious area, since bad allocation
  110.         ; can lead to fragmentation. Thus, the best way to allocate that
  111.         ; comes to mind is to allocate around an inode as much as possible.
  112.         ; On the other hand, this isn't about a single inode/file/directory,
  113.         ; and focusing just around the preferred inode would lead to
  114.         ; congestion. Thus, after much thought, the chosen allocation algorithm
  115.         ; is to search forward, then backward.
  116.         push    ecx edx esi edi
  117.  
  118.         cmp     dword[esp + 16 + 8], 0
  119.         jnz     @F
  120.  
  121.         ; No free blocks.
  122.         xor     eax, eax
  123.         not     eax
  124.         pop     edi esi edx ecx
  125.         ret     20
  126.  
  127.     @@:
  128.         ; Calculate which block group the preferred inode belongs to.
  129.         dec     eax
  130.         xor     edx, edx
  131.        
  132.         ; EAX = block group.
  133.         div     [ebp + EXTFS.superblock + EXT2_SB_STRUC.inodes_per_group]
  134.         push    eax
  135.         push    eax
  136.  
  137.         mov     edi, .forward
  138.  
  139.     .test_block_group:
  140.         call    dword[esp + 16 + 8 + 4]
  141.         test    eax, eax
  142.         jz      .fail
  143.         mov     esi, eax
  144.  
  145.         mov     eax, ebx
  146.         mov     edx, eax
  147.         mov     ebx, [ebp + EXTFS.ext2_save_block]
  148.         call    ext2_block_read
  149.         test    eax, eax
  150.         jnz     .fail
  151.  
  152.         mov     ecx, [esp + 16 + 8 + 12]
  153.         call    ext2_find_free_bit
  154.         cmp     eax, 0xFFFFFFFF
  155.         jne     @F
  156.  
  157.         mov     eax, edi
  158.         jmp     eax
  159.  
  160.     @@:
  161.         mov     ecx, eax
  162.  
  163.         mov     eax, edx
  164.         mov     ebx, [ebp + EXTFS.ext2_save_block]
  165.         call    ext2_block_write
  166.         test    eax, eax
  167.         jnz     .fail
  168.  
  169.         ; ecx: the index of the matched entry.
  170.         ; [esp]: block group where we found.
  171.         ; [esp + 4]: starting block group.
  172.         ; esi: block group descriptor.
  173.         mov     eax, [esp]                             ; Index of block group in which we found.
  174.         mul     dword[esp + 16 + 8 + 12]
  175.         add     eax, ecx
  176.         mov     ebx, eax
  177.  
  178.         mov     eax, [esp + 16 + 8 + 8]
  179.         dec     dword[eax]
  180.  
  181.         mov     eax, esi
  182.         add     eax, [esp + 16 + 8 + 16]
  183.         dec     word[eax]
  184.  
  185.         pop     eax
  186.         call    ext2_bg_write_desc
  187.  
  188.         add     esp, 4
  189.         jmp     .return
  190.  
  191.     ; Continue forward.
  192.     .forward:        
  193.         inc     dword[esp]
  194.         mov     eax, [esp]
  195.         mul     dword[esp + 16 + 8 + 12]
  196.         cmp     eax, [esp + 16 + 8 + 20]
  197.         jbe     @F
  198.  
  199.         ; We need to go backward.
  200.         mov     eax, [esp + 4]
  201.         mov     [esp], eax
  202.         mov     edi, .backward
  203.         jmp     .backward
  204.  
  205.     @@:
  206.         mov     eax, [esp]
  207.         jmp     .test_block_group
  208.  
  209.     ; Continue backward.
  210.     .backward:
  211.         cmp     dword[esp], 0
  212.         je      .fail
  213.  
  214.         dec     dword[esp]
  215.         mov     eax, [esp]
  216.         jmp     .test_block_group
  217.  
  218.     .return:
  219.         pop     edi esi edx ecx
  220.         ret     20
  221.  
  222.     .fail:
  223.         add     esp, 8
  224.         xor     eax, eax
  225.         not     eax
  226.         jmp     .return