alloc_stats.c revision 543547a52a20cb7e69d74921b2f691078fd55d83
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) 308bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o ext2fs_mark_inode_bitmap(fs->inode_map, ino); 318bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o else 328bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o ext2fs_unmark_inode_bitmap(fs->inode_map, ino); 338bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o fs->group_desc[group].bg_free_inodes_count -= inuse; 347f961d424b1ba527e835d01ad24e0e4c3f4088c5Theodore Ts'o if (isdir) 357f961d424b1ba527e835d01ad24e0e4c3f4088c5Theodore Ts'o fs->group_desc[group].bg_used_dirs_count += 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. */ 395711ed297b1a3d94086256b5b3b891d4f77b21caTheodore Ts'o fs->group_desc[group].bg_flags &= ~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 - 43d4f34d41be97e23db07d5ed606fcc1a26f5a3c76Jose R. Santos fs->group_desc[group].bg_itable_unused + 44d4f34d41be97e23db07d5ed606fcc1a26f5a3c76Jose R. Santos group * fs->super->s_inodes_per_group + 1; 45d4f34d41be97e23db07d5ed606fcc1a26f5a3c76Jose R. Santos 46d4f34d41be97e23db07d5ed606fcc1a26f5a3c76Jose R. Santos if (ino >= first_unused_inode) 47d4f34d41be97e23db07d5ed606fcc1a26f5a3c76Jose R. Santos fs->group_desc[group].bg_itable_unused = 48d4f34d41be97e23db07d5ed606fcc1a26f5a3c76Jose R. Santos group * fs->super->s_inodes_per_group + 49d4f34d41be97e23db07d5ed606fcc1a26f5a3c76Jose R. Santos fs->super->s_inodes_per_group - ino; 50d4f34d41be97e23db07d5ed606fcc1a26f5a3c76Jose R. Santos ext2fs_group_desc_csum_set(fs, group); 51d4f34d41be97e23db07d5ed606fcc1a26f5a3c76Jose R. Santos } 52d4f34d41be97e23db07d5ed606fcc1a26f5a3c76Jose R. Santos 538bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o fs->super->s_free_inodes_count -= inuse; 548bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o ext2fs_mark_super_dirty(fs); 558bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o ext2fs_mark_ib_dirty(fs); 568bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o} 578bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o 587f961d424b1ba527e835d01ad24e0e4c3f4088c5Theodore Ts'ovoid ext2fs_inode_alloc_stats(ext2_filsys fs, ext2_ino_t ino, int inuse) 597f961d424b1ba527e835d01ad24e0e4c3f4088c5Theodore Ts'o{ 607f961d424b1ba527e835d01ad24e0e4c3f4088c5Theodore Ts'o ext2fs_inode_alloc_stats2(fs, ino, inuse, 0); 617f961d424b1ba527e835d01ad24e0e4c3f4088c5Theodore Ts'o} 627f961d424b1ba527e835d01ad24e0e4c3f4088c5Theodore Ts'o 638bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'ovoid ext2fs_block_alloc_stats(ext2_filsys fs, blk_t blk, int inuse) 648bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o{ 658bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o int group = ext2fs_group_of_blk(fs, blk); 668bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o 67cf4e06d665e53ec7a5af67c9104e7278777a8488Theodore Ts'o#ifndef OMIT_COM_ERR 68cf4e06d665e53ec7a5af67c9104e7278777a8488Theodore Ts'o if (blk >= fs->super->s_blocks_count) { 6946d6f84ebe3cfdd703f40a56f9904c04d10cc138Theodore Ts'o com_err("ext2fs_block_alloc_stats", 0, 7046d6f84ebe3cfdd703f40a56f9904c04d10cc138Theodore Ts'o "Illegal block number: %lu", (unsigned long) blk); 71cf4e06d665e53ec7a5af67c9104e7278777a8488Theodore Ts'o return; 72cf4e06d665e53ec7a5af67c9104e7278777a8488Theodore Ts'o } 73cf4e06d665e53ec7a5af67c9104e7278777a8488Theodore Ts'o#endif 748bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o if (inuse > 0) 758bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o ext2fs_mark_block_bitmap(fs->block_map, blk); 768bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o else 778bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o ext2fs_unmark_block_bitmap(fs->block_map, blk); 788bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o fs->group_desc[group].bg_free_blocks_count -= inuse; 79d4f34d41be97e23db07d5ed606fcc1a26f5a3c76Jose R. Santos fs->group_desc[group].bg_flags &= ~EXT2_BG_BLOCK_UNINIT; 80d4f34d41be97e23db07d5ed606fcc1a26f5a3c76Jose R. Santos ext2fs_group_desc_csum_set(fs, group); 81d4f34d41be97e23db07d5ed606fcc1a26f5a3c76Jose R. Santos 828bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o fs->super->s_free_blocks_count -= inuse; 838bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o ext2fs_mark_super_dirty(fs); 848bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o ext2fs_mark_bb_dirty(fs); 85f5c562e2324a8950d659ebfc8db4356121d6104eTheodore Ts'o if (fs->block_alloc_stats) 86f5c562e2324a8950d659ebfc8db4356121d6104eTheodore Ts'o (fs->block_alloc_stats)(fs, (blk64_t) blk, inuse); 87f5c562e2324a8950d659ebfc8db4356121d6104eTheodore Ts'o} 88f5c562e2324a8950d659ebfc8db4356121d6104eTheodore Ts'o 89efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'ovoid ext2fs_set_block_alloc_stats_callback(ext2_filsys fs, 90f5c562e2324a8950d659ebfc8db4356121d6104eTheodore Ts'o void (*func)(ext2_filsys fs, 91f5c562e2324a8950d659ebfc8db4356121d6104eTheodore Ts'o blk64_t blk, 92f5c562e2324a8950d659ebfc8db4356121d6104eTheodore Ts'o int inuse), 93f5c562e2324a8950d659ebfc8db4356121d6104eTheodore Ts'o void (**old)(ext2_filsys fs, 94f5c562e2324a8950d659ebfc8db4356121d6104eTheodore Ts'o blk64_t blk, 95f5c562e2324a8950d659ebfc8db4356121d6104eTheodore Ts'o int inuse)) 96f5c562e2324a8950d659ebfc8db4356121d6104eTheodore Ts'o{ 97f5c562e2324a8950d659ebfc8db4356121d6104eTheodore Ts'o if (!fs || fs->magic != EXT2_ET_MAGIC_EXT2FS_FILSYS) 98f5c562e2324a8950d659ebfc8db4356121d6104eTheodore Ts'o return; 99f5c562e2324a8950d659ebfc8db4356121d6104eTheodore Ts'o if (old) 100f5c562e2324a8950d659ebfc8db4356121d6104eTheodore Ts'o *old = fs->block_alloc_stats; 101f5c562e2324a8950d659ebfc8db4356121d6104eTheodore Ts'o 102f5c562e2324a8950d659ebfc8db4356121d6104eTheodore Ts'o fs->block_alloc_stats = func; 1038bd0c95908baa3af706b9e731daff9472bec74c9Theodore Ts'o} 104