Subversion Repositories Kolibri OS

Rev

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

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