alloc.c revision 21c84b71e205b5ab13f14343da5645dcc985856d
1/* 2 * alloc.c --- allocate new inodes, blocks for ext2fs 3 * 4 * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o. 5 * 6 * %Begin-Header% 7 * This file may be redistributed under the terms of the GNU Public 8 * License. 9 * %End-Header% 10 * 11 */ 12 13#include <stdio.h> 14#include <unistd.h> 15#include <stdlib.h> 16#include <time.h> 17#include <sys/stat.h> 18#include <sys/types.h> 19#if HAVE_ERRNO_H 20#include <errno.h> 21#endif 22 23#include <linux/ext2_fs.h> 24 25#include "ext2fs.h" 26 27/* 28 * Right now, just search forward from the parent directory's block 29 * group to find the next free inode. 30 * 31 * Should have a special policy for directories. 32 */ 33errcode_t ext2fs_new_inode(ext2_filsys fs, ino_t dir, int mode, 34 ext2fs_inode_bitmap map, ino_t *ret) 35{ 36 int dir_group = 0; 37 ino_t i; 38 ino_t start_inode; 39 40 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); 41 42 if (!map) 43 map = fs->inode_map; 44 if (!map) 45 return EXT2_ET_NO_INODE_BITMAP; 46 47 if (dir > 0) 48 dir_group = (dir - 1) / EXT2_INODES_PER_GROUP(fs->super); 49 50 start_inode = (dir_group * EXT2_INODES_PER_GROUP(fs->super)) + 1; 51 if (start_inode < EXT2_FIRST_INODE(fs->super)) 52 start_inode = EXT2_FIRST_INODE(fs->super); 53 i = start_inode; 54 55 do { 56 if (!ext2fs_test_inode_bitmap(map, i)) 57 break; 58 i++; 59 if (i > fs->super->s_inodes_count) 60 i = EXT2_FIRST_INODE(fs->super); 61 } while (i != start_inode); 62 63 if (ext2fs_test_inode_bitmap(map, i)) 64 return ENOSPC; 65 *ret = i; 66 return 0; 67} 68 69/* 70 * Stupid algorithm --- we now just search forward starting from the 71 * goal. Should put in a smarter one someday.... 72 */ 73errcode_t ext2fs_new_block(ext2_filsys fs, blk_t goal, 74 ext2fs_block_bitmap map, blk_t *ret) 75{ 76 blk_t i = goal; 77 78 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); 79 80 if (!map) 81 map = fs->block_map; 82 if (!map) 83 return EXT2_ET_NO_BLOCK_BITMAP; 84 if (!i) 85 i = fs->super->s_first_data_block; 86 do { 87 if (!ext2fs_test_block_bitmap(map, i)) { 88 *ret = i; 89 return 0; 90 } 91 i++; 92 if (i >= fs->super->s_blocks_count) 93 i = fs->super->s_first_data_block; 94 } while (i != goal); 95 return ENOSPC; 96} 97 98errcode_t ext2fs_get_free_blocks(ext2_filsys fs, blk_t start, blk_t finish, 99 int num, ext2fs_block_bitmap map, blk_t *ret) 100{ 101 blk_t b = start; 102 103 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); 104 105 if (!map) 106 map = fs->block_map; 107 if (!map) 108 return EXT2_ET_NO_BLOCK_BITMAP; 109 if (!b) 110 b = fs->super->s_first_data_block; 111 if (!finish) 112 finish = start; 113 if (!num) 114 num = 1; 115 do { 116 if (b+num-1 > fs->super->s_blocks_count) 117 b = fs->super->s_first_data_block; 118 if (ext2fs_fast_test_block_bitmap_range(map, b, num)) { 119 *ret = b; 120 return 0; 121 } 122 b++; 123 } while (b != finish); 124 return ENOSPC; 125} 126 127