blob: 0bc637dbd2e65a9ce5e30661ffed2571a187ba8c [file] [log] [blame]
Theodore Ts'o3839e651997-04-26 13:21:57 +00001/*
2 * alloc.c --- allocate new inodes, blocks for ext2fs
3 *
Theodore Ts'o21c84b71997-04-29 16:15:03 +00004 * 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 *
Theodore Ts'o3839e651997-04-26 13:21:57 +000011 */
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>
Theodore Ts'o50e1e101997-04-26 13:58:21 +000019#if HAVE_ERRNO_H
20#include <errno.h>
21#endif
Theodore Ts'o3839e651997-04-26 13:21:57 +000022
Theodore Ts'o3839e651997-04-26 13:21:57 +000023#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 */
Theodore Ts'of3db3561997-04-26 13:34:30 +000033errcode_t ext2fs_new_inode(ext2_filsys fs, ino_t dir, int mode,
34 ext2fs_inode_bitmap map, ino_t *ret)
Theodore Ts'o3839e651997-04-26 13:21:57 +000035{
36 int dir_group = 0;
37 ino_t i;
38 ino_t start_inode;
39
Theodore Ts'of3db3561997-04-26 13:34:30 +000040 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
41
Theodore Ts'o3839e651997-04-26 13:21:57 +000042 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;
Theodore Ts'o7f88b041997-04-26 14:48:50 +000051 if (start_inode < EXT2_FIRST_INODE(fs->super))
52 start_inode = EXT2_FIRST_INODE(fs->super);
Theodore Ts'o3839e651997-04-26 13:21:57 +000053 i = start_inode;
Theodore Ts'o3839e651997-04-26 13:21:57 +000054
55 do {
Theodore Ts'of3db3561997-04-26 13:34:30 +000056 if (!ext2fs_test_inode_bitmap(map, i))
Theodore Ts'o3839e651997-04-26 13:21:57 +000057 break;
58 i++;
59 if (i > fs->super->s_inodes_count)
Theodore Ts'o7f88b041997-04-26 14:48:50 +000060 i = EXT2_FIRST_INODE(fs->super);
Theodore Ts'o3839e651997-04-26 13:21:57 +000061 } while (i != start_inode);
62
Theodore Ts'of3db3561997-04-26 13:34:30 +000063 if (ext2fs_test_inode_bitmap(map, i))
Theodore Ts'o3839e651997-04-26 13:21:57 +000064 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 */
Theodore Ts'of3db3561997-04-26 13:34:30 +000073errcode_t ext2fs_new_block(ext2_filsys fs, blk_t goal,
74 ext2fs_block_bitmap map, blk_t *ret)
Theodore Ts'o3839e651997-04-26 13:21:57 +000075{
76 blk_t i = goal;
77
Theodore Ts'of3db3561997-04-26 13:34:30 +000078 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
79
Theodore Ts'o3839e651997-04-26 13:21:57 +000080 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 {
Theodore Ts'of3db3561997-04-26 13:34:30 +000087 if (!ext2fs_test_block_bitmap(map, i)) {
Theodore Ts'o3839e651997-04-26 13:21:57 +000088 *ret = i;
89 return 0;
90 }
91 i++;
Theodore Ts'o21c84b71997-04-29 16:15:03 +000092 if (i >= fs->super->s_blocks_count)
Theodore Ts'o3839e651997-04-26 13:21:57 +000093 i = fs->super->s_first_data_block;
94 } while (i != goal);
95 return ENOSPC;
96}
97
Theodore Ts'o3839e651997-04-26 13:21:57 +000098errcode_t ext2fs_get_free_blocks(ext2_filsys fs, blk_t start, blk_t finish,
Theodore Ts'of3db3561997-04-26 13:34:30 +000099 int num, ext2fs_block_bitmap map, blk_t *ret)
Theodore Ts'o3839e651997-04-26 13:21:57 +0000100{
101 blk_t b = start;
102
Theodore Ts'of3db3561997-04-26 13:34:30 +0000103 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
104
Theodore Ts'o3839e651997-04-26 13:21:57 +0000105 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 {
Theodore Ts'o21c84b71997-04-29 16:15:03 +0000116 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)) {
Theodore Ts'o3839e651997-04-26 13:21:57 +0000119 *ret = b;
120 return 0;
121 }
122 b++;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000123 } while (b != finish);
124 return ENOSPC;
125}
126