18bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o/* 28bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o * alloc_stats.c --- Update allocation statistics for ext2fs 38bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o * 48bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o * Copyright (C) 2001 Theodore Ts'o. 58bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o * 68bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o * %Begin-Header% 7543547a52a20cb7e69d74921b2f691078fd55d83Theodore Ts'o * This file may be redistributed under the terms of the GNU Library 8543547a52a20cb7e69d74921b2f691078fd55d83Theodore Ts'o * General Public License, version 2. 98bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o * %End-Header% 108bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o */ 118bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o 128bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o#include <stdio.h> 138bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o 148bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o#include "ext2_fs.h" 158bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o#include "ext2fs.h" 168bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o 177f961d424b1ba527e835d01ad24e0e4c3f4088c5Theodore Ts'ovoid ext2fs_inode_alloc_stats2(ext2_filsys fs, ext2_ino_t ino, 187f961d424b1ba527e835d01ad24e0e4c3f4088c5Theodore Ts'o int inuse, int isdir) 198bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o{ 208bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o int group = ext2fs_group_of_ino(fs, ino); 218bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o 22cf4e06d665e53ec7a5af67c9104e7278777a8488Theodore Ts'o#ifndef OMIT_COM_ERR 23cf4e06d665e53ec7a5af67c9104e7278777a8488Theodore Ts'o if (ino > fs->super->s_inodes_count) { 24cf4e06d665e53ec7a5af67c9104e7278777a8488Theodore Ts'o com_err("ext2fs_inode_alloc_stats2", 0, 2546d6f84ebe3cfdd703f40a56f9904c04d10cc138Theodore Ts'o "Illegal inode number: %lu", (unsigned long) ino); 26cf4e06d665e53ec7a5af67c9104e7278777a8488Theodore Ts'o return; 27cf4e06d665e53ec7a5af67c9104e7278777a8488Theodore Ts'o } 28cf4e06d665e53ec7a5af67c9104e7278777a8488Theodore Ts'o#endif 298bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o if (inuse > 0) 30e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_mark_inode_bitmap2(fs->inode_map, ino); 318bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o else 32e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_unmark_inode_bitmap2(fs->inode_map, ino); 33e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_bg_free_inodes_count_set(fs, group, ext2fs_bg_free_inodes_count(fs, group) - inuse); 347f961d424b1ba527e835d01ad24e0e4c3f4088c5Theodore Ts'o if (isdir) 35e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_bg_used_dirs_count_set(fs, group, ext2fs_bg_used_dirs_count(fs, group) + inuse); 36d4f34d41be97e23db07d5ed606fcc1a26f5a3c76Jose R. Santos 375711ed297b1a3d94086256b5b3b891d4f77b21caTheodore Ts'o /* We don't strictly need to be clearing the uninit flag if inuse < 0 38d4f34d41be97e23db07d5ed606fcc1a26f5a3c76Jose R. Santos * (i.e. freeing inodes) but it also means something is bad. */ 39e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_bg_flags_clear(fs, group, EXT2_BG_INODE_UNINIT); 40d4f34d41be97e23db07d5ed606fcc1a26f5a3c76Jose R. Santos if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super, 41d4f34d41be97e23db07d5ed606fcc1a26f5a3c76Jose R. Santos EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) { 42d4f34d41be97e23db07d5ed606fcc1a26f5a3c76Jose R. Santos ext2_ino_t first_unused_inode = fs->super->s_inodes_per_group - 43e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_bg_itable_unused(fs, group) + 44d4f34d41be97e23db07d5ed606fcc1a26f5a3c76Jose R. Santos group * fs->super->s_inodes_per_group + 1; 45d4f34d41be97e23db07d5ed606fcc1a26f5a3c76Jose R. Santos 46d4f34d41be97e23db07d5ed606fcc1a26f5a3c76Jose R. Santos if (ino >= first_unused_inode) 47e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_bg_itable_unused_set(fs, group, group * fs->super->s_inodes_per_group + fs->super->s_inodes_per_group - ino); 48d4f34d41be97e23db07d5ed606fcc1a26f5a3c76Jose R. Santos ext2fs_group_desc_csum_set(fs, group); 49d4f34d41be97e23db07d5ed606fcc1a26f5a3c76Jose R. Santos } 50d4f34d41be97e23db07d5ed606fcc1a26f5a3c76Jose R. Santos 518bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o fs->super->s_free_inodes_count -= inuse; 528bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o ext2fs_mark_super_dirty(fs); 538bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o ext2fs_mark_ib_dirty(fs); 548bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o} 558bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o 567f961d424b1ba527e835d01ad24e0e4c3f4088c5Theodore Ts'ovoid ext2fs_inode_alloc_stats(ext2_filsys fs, ext2_ino_t ino, int inuse) 577f961d424b1ba527e835d01ad24e0e4c3f4088c5Theodore Ts'o{ 587f961d424b1ba527e835d01ad24e0e4c3f4088c5Theodore Ts'o ext2fs_inode_alloc_stats2(fs, ino, inuse, 0); 597f961d424b1ba527e835d01ad24e0e4c3f4088c5Theodore Ts'o} 607f961d424b1ba527e835d01ad24e0e4c3f4088c5Theodore Ts'o 61e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallvoid ext2fs_block_alloc_stats2(ext2_filsys fs, blk64_t blk, int inuse) 628bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o{ 63e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall int group = ext2fs_group_of_blk2(fs, blk); 648bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o 65cf4e06d665e53ec7a5af67c9104e7278777a8488Theodore Ts'o#ifndef OMIT_COM_ERR 66e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (blk >= ext2fs_blocks_count(fs->super)) { 6746d6f84ebe3cfdd703f40a56f9904c04d10cc138Theodore Ts'o com_err("ext2fs_block_alloc_stats", 0, 6846d6f84ebe3cfdd703f40a56f9904c04d10cc138Theodore Ts'o "Illegal block number: %lu", (unsigned long) blk); 69cf4e06d665e53ec7a5af67c9104e7278777a8488Theodore Ts'o return; 70cf4e06d665e53ec7a5af67c9104e7278777a8488Theodore Ts'o } 71cf4e06d665e53ec7a5af67c9104e7278777a8488Theodore Ts'o#endif 728bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o if (inuse > 0) 73e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_mark_block_bitmap2(fs->block_map, blk); 748bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o else 75e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_unmark_block_bitmap2(fs->block_map, blk); 76e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_bg_free_blocks_count_set(fs, group, ext2fs_bg_free_blocks_count(fs, group) - inuse); 77e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_bg_flags_clear(fs, group, EXT2_BG_BLOCK_UNINIT); 78d4f34d41be97e23db07d5ed606fcc1a26f5a3c76Jose R. Santos ext2fs_group_desc_csum_set(fs, group); 79d4f34d41be97e23db07d5ed606fcc1a26f5a3c76Jose R. Santos 80e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_free_blocks_count_add(fs->super, 81e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall -inuse * EXT2FS_CLUSTER_RATIO(fs)); 828bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o ext2fs_mark_super_dirty(fs); 838bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o ext2fs_mark_bb_dirty(fs); 84f5c562e2324a8950d659ebfc8db4356121d6104eTheodore Ts'o if (fs->block_alloc_stats) 85f5c562e2324a8950d659ebfc8db4356121d6104eTheodore Ts'o (fs->block_alloc_stats)(fs, (blk64_t) blk, inuse); 86f5c562e2324a8950d659ebfc8db4356121d6104eTheodore Ts'o} 87f5c562e2324a8950d659ebfc8db4356121d6104eTheodore Ts'o 88e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallvoid ext2fs_block_alloc_stats(ext2_filsys fs, blk_t blk, int inuse) 89e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall{ 90e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_block_alloc_stats2(fs, blk, inuse); 91e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall} 92e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 93efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'ovoid ext2fs_set_block_alloc_stats_callback(ext2_filsys fs, 94f5c562e2324a8950d659ebfc8db4356121d6104eTheodore Ts'o void (*func)(ext2_filsys fs, 95f5c562e2324a8950d659ebfc8db4356121d6104eTheodore Ts'o blk64_t blk, 96f5c562e2324a8950d659ebfc8db4356121d6104eTheodore Ts'o int inuse), 97f5c562e2324a8950d659ebfc8db4356121d6104eTheodore Ts'o void (**old)(ext2_filsys fs, 98f5c562e2324a8950d659ebfc8db4356121d6104eTheodore Ts'o blk64_t blk, 99f5c562e2324a8950d659ebfc8db4356121d6104eTheodore Ts'o int inuse)) 100f5c562e2324a8950d659ebfc8db4356121d6104eTheodore Ts'o{ 101f5c562e2324a8950d659ebfc8db4356121d6104eTheodore Ts'o if (!fs || fs->magic != EXT2_ET_MAGIC_EXT2FS_FILSYS) 102f5c562e2324a8950d659ebfc8db4356121d6104eTheodore Ts'o return; 103f5c562e2324a8950d659ebfc8db4356121d6104eTheodore Ts'o if (old) 104f5c562e2324a8950d659ebfc8db4356121d6104eTheodore Ts'o *old = fs->block_alloc_stats; 105f5c562e2324a8950d659ebfc8db4356121d6104eTheodore Ts'o 106f5c562e2324a8950d659ebfc8db4356121d6104eTheodore Ts'o fs->block_alloc_stats = func; 1078bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o} 108