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