1 /* This files manages inodes allocation and deallocation.
3 * The entry points into this file are:
4 * alloc_inode: allocate a new, unused inode.
5 * free_inode: mark an inode as available for a new file.
7 * Created (alloc_inode/free_inode/wipe_inode are from MFS):
8 * June 2010 (Evgeniy Ivanov)
14 #include <minix/com.h>
15 #include <minix/u64.h>
22 static bit_t
alloc_inode_bit(struct super_block
*sp
, struct inode
24 static void free_inode_bit(struct super_block
*sp
, bit_t bit_returned
,
26 static void wipe_inode(struct inode
*rip
);
29 /*===========================================================================*
31 *===========================================================================*/
32 struct inode
*alloc_inode(struct inode
*parent
, mode_t bits
)
34 /* Allocate a free inode on parent's dev, and return a pointer to it. */
36 register struct inode
*rip
;
37 register struct super_block
*sp
;
40 static int print_oos_msg
= 1;
42 sp
= get_super(parent
->i_dev
); /* get pointer to super_block */
43 if (sp
->s_rd_only
) { /* can't allocate an inode on a read only device. */
48 /* Acquire an inode from the bit map. */
49 b
= alloc_inode_bit(sp
, parent
, (bits
& I_TYPE
) == I_DIRECTORY
);
53 ext2_debug("Out of i-nodes on device %d/%d\n",
54 major(sp
->s_dev
), minor(sp
->s_dev
));
55 print_oos_msg
= 0; /* Don't repeat message */
60 inumb
= (int) b
; /* be careful not to pass unshort as param */
62 /* Try to acquire a slot in the inode table. */
63 if ((rip
= get_inode(NO_DEV
, inumb
)) == NULL
) {
64 /* No inode table slots available. Free the inode just allocated. */
65 free_inode_bit(sp
, b
, (bits
& I_TYPE
) == I_DIRECTORY
);
67 /* An inode slot is available. Put the inode just allocated into it. */
68 rip
->i_mode
= bits
; /* set up RWX bits */
69 rip
->i_links_count
= NO_LINK
; /* initial no links */
70 rip
->i_uid
= caller_uid
; /* file's uid is owner's */
71 rip
->i_gid
= caller_gid
; /* ditto group id */
72 rip
->i_dev
= parent
->i_dev
; /* mark which device it is on */
73 rip
->i_sp
= sp
; /* pointer to super block */
75 /* Fields not cleared already are cleared in wipe_inode(). They have
76 * been put there because truncate() needs to clear the same fields if
77 * the file happens to be open while being truncated. It saves space
78 * not to repeat the code twice.
87 /*===========================================================================*
89 *===========================================================================*/
91 register struct inode
*rip
/* inode to free */
94 /* Return an inode to the pool of unallocated inodes. */
95 register struct super_block
*sp
;
96 dev_t dev
= rip
->i_dev
;
98 u16_t mode
= rip
->i_mode
;
100 /* Locate the appropriate super_block. */
103 if (b
<= NO_ENTRY
|| b
> sp
->s_inodes_count
)
105 free_inode_bit(sp
, b
, (mode
& I_TYPE
) == I_DIRECTORY
);
107 rip
->i_mode
= I_NOT_ALLOC
; /* clear I_TYPE field */
111 static int find_group_dir(struct super_block
*sp
);
112 static int find_group_hashalloc(struct super_block
*sp
, struct inode
114 static int find_group_any(struct super_block
*sp
);
115 static int find_group_orlov(struct super_block
*sp
, struct inode
119 /*===========================================================================*
121 *===========================================================================*/
122 static bit_t
alloc_inode_bit(sp
, parent
, is_dir
)
123 struct super_block
*sp
; /* the filesystem to allocate from */
124 struct inode
*parent
; /* parent of newly allocated inode */
125 int is_dir
; /* inode will be a directory if it is TRUE */
128 ino_t inumber
= NO_BIT
;
131 struct group_desc
*gd
;
134 panic("can't alloc inode on read-only filesys.");
137 group
= find_group_any(sp
);
141 group
= find_group_orlov(sp
, parent
);
143 group
= find_group_dir(sp
);
146 group
= find_group_hashalloc(sp
, parent
);
149 /* Check if we have a group where to allocate an inode */
151 return(NO_BIT
); /* no bit could be allocated */
153 gd
= get_group_desc(group
);
155 panic("can't get group_desc to alloc block");
157 /* find_group_* should always return either a group with
158 * a free inode slot or -1, which we checked earlier.
160 ASSERT(gd
->free_inodes_count
);
162 bp
= get_block(sp
->s_dev
, gd
->inode_bitmap
, NORMAL
);
163 bit
= setbit(b_bitmap(bp
), sp
->s_inodes_per_group
, 0);
164 ASSERT(bit
!= -1); /* group definitly contains free inode */
166 inumber
= group
* sp
->s_inodes_per_group
+ bit
+ 1;
168 /* Extra checks before real allocation.
169 * Only major bug can cause problems. Since setbit changed
170 * bp->b_bitmap there is no way to recover from this bug.
171 * Should never happen.
173 if (inumber
> sp
->s_inodes_count
) {
174 panic("ext2: allocator returned inum greater, than\
175 total number of inodes.\n");
178 if (inumber
< EXT2_FIRST_INO(sp
)) {
179 panic("ext2: allocator tryed to use reserved inode.\n");
183 put_block(bp
, MAP_BLOCK
);
185 gd
->free_inodes_count
--;
186 sp
->s_free_inodes_count
--;
188 gd
->used_dirs_count
++;
189 sp
->s_dirs_counter
++;
192 group_descriptors_dirty
= 1;
194 /* Almost the same as previous 'group' ASSERT */
195 ASSERT(inumber
!= NO_BIT
);
200 /*===========================================================================*
202 *===========================================================================*/
203 static void free_inode_bit(struct super_block
*sp
, bit_t bit_returned
,
206 /* Return an inode by turning off its bitmap bit. */
207 int group
; /* group number of bit_returned */
208 int bit
; /* bit_returned number within its group */
210 struct group_desc
*gd
;
213 panic("can't free bit on read-only filesys.");
215 /* At first search group, to which bit_returned belongs to
216 * and figure out in what word bit is stored.
218 if (bit_returned
> sp
->s_inodes_count
||
219 bit_returned
< EXT2_FIRST_INO(sp
))
220 panic("trying to free inode %d beyond inodes scope.", bit_returned
);
222 group
= (bit_returned
- 1) / sp
->s_inodes_per_group
;
223 bit
= (bit_returned
- 1) % sp
->s_inodes_per_group
; /* index in bitmap */
225 gd
= get_group_desc(group
);
227 panic("can't get group_desc to alloc block");
229 bp
= get_block(sp
->s_dev
, gd
->inode_bitmap
, NORMAL
);
231 if (unsetbit(b_bitmap(bp
), bit
))
232 panic("Tried to free unused inode", bit_returned
);
235 put_block(bp
, MAP_BLOCK
);
237 gd
->free_inodes_count
++;
238 sp
->s_free_inodes_count
++;
241 gd
->used_dirs_count
--;
242 sp
->s_dirs_counter
--;
245 group_descriptors_dirty
= 1;
247 if (group
< sp
->s_igsearch
)
248 sp
->s_igsearch
= group
;
252 /* it's implemented very close to the linux' find_group_dir() */
253 static int find_group_dir(struct super_block
*sp
)
255 int avefreei
= sp
->s_free_inodes_count
/ sp
->s_groups_count
;
256 struct group_desc
*gd
, *best_gd
= NULL
;
257 int group
, best_group
= -1;
259 for (group
= 0; group
< sp
->s_groups_count
; ++group
) {
260 gd
= get_group_desc(group
);
262 panic("can't get group_desc to alloc inode");
263 if (gd
->free_inodes_count
== 0)
265 if (gd
->free_inodes_count
< avefreei
)
268 gd
->free_blocks_count
> best_gd
->free_blocks_count
) {
274 return best_group
; /* group or -1 */
278 /* Analog of ffs_hashalloc() from *BSD.
279 * 1) Check parent's for free inodes and blocks.
280 * 2) Quadradically rehash on the group number.
281 * 3) Make a linear search for free inode.
283 static int find_group_hashalloc(struct super_block
*sp
, struct inode
*parent
)
285 int ngroups
= sp
->s_groups_count
;
286 struct group_desc
*gd
;
288 int parent_group
= (parent
->i_num
- 1) / sp
->s_inodes_per_group
;
290 /* Try to place new inode in its parent group */
291 gd
= get_group_desc(parent_group
);
293 panic("can't get group_desc to alloc inode");
294 if (gd
->free_inodes_count
&& gd
->free_blocks_count
)
297 /* We can't allocate inode in the parent's group.
298 * Now we will try to place it in another blockgroup.
299 * The main idea is still to keep files from the same
300 * directory together and use different blockgroups for
301 * files from another directory, which lives in the same
302 * blockgroup as our parent.
303 * Thus we will spread things on the disk.
305 group
= (parent_group
+ parent
->i_num
) % ngroups
;
307 /* Make quadratic probing to find a group with free inodes and blocks. */
308 for (i
= 1; i
< ngroups
; i
<<= 1) {
310 if (group
>= ngroups
)
312 gd
= get_group_desc(group
);
314 panic("can't get group_desc to alloc inode");
315 if (gd
->free_inodes_count
&& gd
->free_blocks_count
)
319 /* Still no group for new inode, try linear search.
320 * Also check parent again (but for free inodes only).
322 group
= parent_group
;
323 for (i
= 0; i
< ngroups
; i
++, group
++) {
324 if (group
>= ngroups
)
326 gd
= get_group_desc(group
);
328 panic("can't get group_desc to alloc inode");
329 if (gd
->free_inodes_count
)
337 /* Find first group which has free inode slot.
338 * This is similar to what MFS does.
340 static int find_group_any(struct super_block
*sp
)
342 int ngroups
= sp
->s_groups_count
;
343 struct group_desc
*gd
;
344 int group
= sp
->s_igsearch
;
346 for (; group
< ngroups
; group
++) {
347 gd
= get_group_desc(group
);
349 panic("can't get group_desc to alloc inode");
350 if (gd
->free_inodes_count
) {
351 sp
->s_igsearch
= group
;
360 /* We try to spread first-level directories (i.e. directories in the root
361 * or in the directory marked as TOPDIR).
362 * If there are blockgroups with counts for blocks and inodes less than average
363 * we return a group with lowest directory count. Otherwise we either
364 * return a group with good free inodes and blocks counts or just a group
367 * For other directories we try to find a 'good' group, we consider a group as
368 * a 'good' if it has enough blocks and inodes (greater than min_blocks and
372 static int find_group_orlov(struct super_block
*sp
, struct inode
*parent
)
374 int avefreei
= sp
->s_free_inodes_count
/ sp
->s_groups_count
;
375 int avefreeb
= sp
->s_free_blocks_count
/ sp
->s_groups_count
;
378 int fallback_group
= -1; /* Group with at least 1 free inode */
379 struct group_desc
*gd
;
382 if (parent
->i_num
== ROOT_INODE
||
383 parent
->i_flags
& EXT2_TOPDIR_FL
) {
385 int best_avefree_group
= -1; /* Best value of avefreei/avefreeb */
386 int best_ndir
= sp
->s_inodes_per_group
;
388 group
= (unsigned int)random();
389 for (i
= 0; i
< sp
->s_groups_count
; i
++, group
++) {
390 if (group
>= sp
->s_groups_count
)
392 gd
= get_group_desc(group
);
394 panic("can't get group_desc to alloc inode");
395 if (gd
->free_inodes_count
== 0)
398 fallback_group
= group
;
400 if (gd
->free_inodes_count
< avefreei
||
401 gd
->free_blocks_count
< avefreeb
)
404 best_avefree_group
= group
;
406 if (gd
->used_dirs_count
>= best_ndir
)
408 best_ndir
= gd
->used_dirs_count
;
413 if (best_avefree_group
>= 0)
414 return best_avefree_group
;
415 return fallback_group
;
417 int parent_group
= (parent
->i_num
- 1) / sp
->s_inodes_per_group
;
418 /* 2 is kind of random thing for now,
419 * but performance results are still good.
421 int min_blocks
= avefreeb
/ 2;
422 int min_inodes
= avefreei
/ 2;
424 group
= parent_group
;
425 for (i
= 0; i
< sp
->s_groups_count
; i
++, group
++) {
426 if (group
>= sp
->s_groups_count
)
428 gd
= get_group_desc(group
);
430 panic("can't get group_desc to alloc inode");
431 if (gd
->free_inodes_count
== 0)
434 fallback_group
= group
;
436 if (gd
->free_inodes_count
>= min_inodes
&&
437 gd
->free_blocks_count
>= min_blocks
)
440 return fallback_group
;
447 /*===========================================================================*
449 *===========================================================================*/
450 static void wipe_inode(
451 register struct inode
*rip
/* the inode to be erased */
454 /* Erase some fields in the inode. This function is called from alloc_inode()
455 * when a new inode is to be allocated, and from truncate(), when an existing
456 * inode is to be truncated.
462 rip
->i_update
= ATIME
| CTIME
| MTIME
; /* update all times later */
465 rip
->i_generation
= 0;
470 for (i
= 0; i
< EXT2_N_BLOCKS
; i
++)
471 rip
->i_block
[i
] = NO_BLOCK
;
472 rip
->i_block
[0] = NO_BLOCK
;
474 rip
->i_dirt
= IN_DIRTY
;