/src/e2fsprogs/lib/ext2fs/alloc_stats.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * alloc_stats.c --- Update allocation statistics for ext2fs |
3 | | * |
4 | | * Copyright (C) 2001 Theodore Ts'o. |
5 | | * |
6 | | * %Begin-Header% |
7 | | * This file may be redistributed under the terms of the GNU Library |
8 | | * General Public License, version 2. |
9 | | * %End-Header% |
10 | | */ |
11 | | |
12 | | #include "config.h" |
13 | | #include <stdio.h> |
14 | | |
15 | | #include "ext2_fs.h" |
16 | | #include "ext2fs.h" |
17 | | |
18 | | void ext2fs_inode_alloc_stats2(ext2_filsys fs, ext2_ino_t ino, |
19 | | int inuse, int isdir) |
20 | 0 | { |
21 | 0 | int group = ext2fs_group_of_ino(fs, ino); |
22 | |
|
23 | 0 | if (ino > fs->super->s_inodes_count) { |
24 | 0 | #ifndef OMIT_COM_ERR |
25 | 0 | com_err("ext2fs_inode_alloc_stats2", 0, |
26 | 0 | "Illegal inode number: %lu", (unsigned long) ino); |
27 | 0 | #endif |
28 | 0 | return; |
29 | 0 | } |
30 | 0 | if (inuse > 0) |
31 | 0 | ext2fs_mark_inode_bitmap2(fs->inode_map, ino); |
32 | 0 | else |
33 | 0 | ext2fs_unmark_inode_bitmap2(fs->inode_map, ino); |
34 | 0 | ext2fs_bg_free_inodes_count_set(fs, group, ext2fs_bg_free_inodes_count(fs, group) - inuse); |
35 | 0 | if (isdir) |
36 | 0 | ext2fs_bg_used_dirs_count_set(fs, group, ext2fs_bg_used_dirs_count(fs, group) + inuse); |
37 | | |
38 | | /* We don't strictly need to be clearing the uninit flag if inuse < 0 |
39 | | * (i.e. freeing inodes) but it also means something is bad. */ |
40 | 0 | ext2fs_bg_flags_clear(fs, group, EXT2_BG_INODE_UNINIT); |
41 | 0 | if (ext2fs_has_group_desc_csum(fs)) { |
42 | 0 | ext2_ino_t first_unused_inode = fs->super->s_inodes_per_group - |
43 | 0 | ext2fs_bg_itable_unused(fs, group) + |
44 | 0 | group * fs->super->s_inodes_per_group + 1; |
45 | |
|
46 | 0 | if (ino >= first_unused_inode) |
47 | 0 | ext2fs_bg_itable_unused_set(fs, group, group * fs->super->s_inodes_per_group + fs->super->s_inodes_per_group - ino); |
48 | 0 | ext2fs_group_desc_csum_set(fs, group); |
49 | 0 | } |
50 | |
|
51 | 0 | fs->super->s_free_inodes_count -= inuse; |
52 | 0 | ext2fs_mark_super_dirty(fs); |
53 | 0 | ext2fs_mark_ib_dirty(fs); |
54 | 0 | } |
55 | | |
56 | | void ext2fs_inode_alloc_stats(ext2_filsys fs, ext2_ino_t ino, int inuse) |
57 | 0 | { |
58 | 0 | ext2fs_inode_alloc_stats2(fs, ino, inuse, 0); |
59 | 0 | } |
60 | | |
61 | | void ext2fs_block_alloc_stats2(ext2_filsys fs, blk64_t blk, int inuse) |
62 | 0 | { |
63 | 0 | int group = ext2fs_group_of_blk2(fs, blk); |
64 | |
|
65 | 0 | if (blk < fs->super->s_first_data_block || |
66 | 0 | blk >= ext2fs_blocks_count(fs->super)) { |
67 | 0 | #ifndef OMIT_COM_ERR |
68 | 0 | com_err("ext2fs_block_alloc_stats", 0, |
69 | 0 | "Illegal block number: %lu", (unsigned long) blk); |
70 | 0 | #endif |
71 | 0 | return; |
72 | 0 | } |
73 | 0 | if (inuse > 0) |
74 | 0 | ext2fs_mark_block_bitmap2(fs->block_map, blk); |
75 | 0 | else |
76 | 0 | ext2fs_unmark_block_bitmap2(fs->block_map, blk); |
77 | 0 | ext2fs_bg_free_blocks_count_set(fs, group, ext2fs_bg_free_blocks_count(fs, group) - inuse); |
78 | 0 | ext2fs_bg_flags_clear(fs, group, EXT2_BG_BLOCK_UNINIT); |
79 | 0 | ext2fs_group_desc_csum_set(fs, group); |
80 | |
|
81 | 0 | ext2fs_free_blocks_count_add(fs->super, |
82 | 0 | -inuse * (blk64_t) EXT2FS_CLUSTER_RATIO(fs)); |
83 | 0 | ext2fs_mark_super_dirty(fs); |
84 | 0 | ext2fs_mark_bb_dirty(fs); |
85 | 0 | if (fs->block_alloc_stats) |
86 | 0 | (fs->block_alloc_stats)(fs, (blk64_t) blk, inuse); |
87 | 0 | } |
88 | | |
89 | | void ext2fs_block_alloc_stats(ext2_filsys fs, blk_t blk, int inuse) |
90 | 0 | { |
91 | 0 | ext2fs_block_alloc_stats2(fs, blk, inuse); |
92 | 0 | } |
93 | | |
94 | | void ext2fs_set_block_alloc_stats_callback(ext2_filsys fs, |
95 | | void (*func)(ext2_filsys fs, |
96 | | blk64_t blk, |
97 | | int inuse), |
98 | | void (**old)(ext2_filsys fs, |
99 | | blk64_t blk, |
100 | | int inuse)) |
101 | 0 | { |
102 | 0 | if (!fs || fs->magic != EXT2_ET_MAGIC_EXT2FS_FILSYS) |
103 | 0 | return; |
104 | 0 | if (old) |
105 | 0 | *old = fs->block_alloc_stats; |
106 | |
|
107 | 0 | fs->block_alloc_stats = func; |
108 | 0 | } |
109 | | |
110 | | void ext2fs_block_alloc_stats_range(ext2_filsys fs, blk64_t blk, |
111 | | blk_t num, int inuse) |
112 | 0 | { |
113 | 0 | #ifndef OMIT_COM_ERR |
114 | 0 | if (blk + num > ext2fs_blocks_count(fs->super)) { |
115 | 0 | com_err("ext2fs_block_alloc_stats_range", 0, |
116 | 0 | "Illegal block range: %llu (%u) ", |
117 | 0 | (unsigned long long) blk, num); |
118 | 0 | return; |
119 | 0 | } |
120 | 0 | #endif |
121 | 0 | if (inuse == 0) |
122 | 0 | return; |
123 | 0 | if (inuse > 0) { |
124 | 0 | ext2fs_mark_block_bitmap_range2(fs->block_map, blk, num); |
125 | 0 | inuse = 1; |
126 | 0 | } else { |
127 | 0 | ext2fs_unmark_block_bitmap_range2(fs->block_map, blk, num); |
128 | 0 | inuse = -1; |
129 | 0 | } |
130 | 0 | while (num) { |
131 | 0 | int group = ext2fs_group_of_blk2(fs, blk); |
132 | 0 | blk64_t last_blk = ext2fs_group_last_block2(fs, group); |
133 | 0 | blk64_t n = num; |
134 | |
|
135 | 0 | if (blk + num > last_blk) |
136 | 0 | n = last_blk - blk + 1; |
137 | |
|
138 | 0 | ext2fs_bg_free_blocks_count_set(fs, group, |
139 | 0 | ext2fs_bg_free_blocks_count(fs, group) - |
140 | 0 | inuse*n/EXT2FS_CLUSTER_RATIO(fs)); |
141 | 0 | ext2fs_bg_flags_clear(fs, group, EXT2_BG_BLOCK_UNINIT); |
142 | 0 | ext2fs_group_desc_csum_set(fs, group); |
143 | 0 | ext2fs_free_blocks_count_add(fs->super, -inuse * (blk64_t) n); |
144 | 0 | blk += n; |
145 | 0 | num -= n; |
146 | 0 | } |
147 | 0 | ext2fs_mark_super_dirty(fs); |
148 | 0 | ext2fs_mark_bb_dirty(fs); |
149 | 0 | if (fs->block_alloc_stats_range) |
150 | 0 | (fs->block_alloc_stats_range)(fs, blk, num, inuse); |
151 | 0 | } |
152 | | |
153 | | void ext2fs_set_block_alloc_stats_range_callback(ext2_filsys fs, |
154 | | void (*func)(ext2_filsys fs, blk64_t blk, |
155 | | blk_t num, int inuse), |
156 | | void (**old)(ext2_filsys fs, blk64_t blk, |
157 | | blk_t num, int inuse)) |
158 | 0 | { |
159 | 0 | if (!fs || fs->magic != EXT2_ET_MAGIC_EXT2FS_FILSYS) |
160 | 0 | return; |
161 | 0 | if (old) |
162 | 0 | *old = fs->block_alloc_stats_range; |
163 | |
|
164 | 0 | fs->block_alloc_stats_range = func; |
165 | 0 | } |