blob: adec36369a8c1e6c9313f203d378e77105a02f9d [file] [log] [blame]
Theodore Ts'o8bd0c952002-01-03 03:29:19 -05001/*
2 * alloc_stats.c --- Update allocation statistics for ext2fs
3 *
4 * Copyright (C) 2001 Theodore Ts'o.
5 *
6 * %Begin-Header%
Theodore Ts'o543547a2010-05-17 21:31:56 -04007 * This file may be redistributed under the terms of the GNU Library
8 * General Public License, version 2.
Theodore Ts'o8bd0c952002-01-03 03:29:19 -05009 * %End-Header%
Theodore Ts'o8bd0c952002-01-03 03:29:19 -050010 */
11
Theodore Ts'od1154eb2011-09-18 17:34:37 -040012#include "config.h"
Theodore Ts'o8bd0c952002-01-03 03:29:19 -050013#include <stdio.h>
14
15#include "ext2_fs.h"
16#include "ext2fs.h"
17
Theodore Ts'o7f961d42002-02-03 01:28:52 -050018void ext2fs_inode_alloc_stats2(ext2_filsys fs, ext2_ino_t ino,
19 int inuse, int isdir)
Theodore Ts'o8bd0c952002-01-03 03:29:19 -050020{
21 int group = ext2fs_group_of_ino(fs, ino);
22
Theodore Ts'ocf4e06d2009-01-22 16:01:38 -050023#ifndef OMIT_COM_ERR
24 if (ino > fs->super->s_inodes_count) {
25 com_err("ext2fs_inode_alloc_stats2", 0,
Theodore Ts'o46d6f842009-04-22 15:07:00 -040026 "Illegal inode number: %lu", (unsigned long) ino);
Theodore Ts'ocf4e06d2009-01-22 16:01:38 -050027 return;
28 }
29#endif
Theodore Ts'o8bd0c952002-01-03 03:29:19 -050030 if (inuse > 0)
Valerie Aurora Henson8f82ef92009-08-05 00:27:10 -040031 ext2fs_mark_inode_bitmap2(fs->inode_map, ino);
Theodore Ts'o8bd0c952002-01-03 03:29:19 -050032 else
Valerie Aurora Henson8f82ef92009-08-05 00:27:10 -040033 ext2fs_unmark_inode_bitmap2(fs->inode_map, ino);
Valerie Aurora Hensond7cca6b2009-10-25 21:43:47 -040034 ext2fs_bg_free_inodes_count_set(fs, group, ext2fs_bg_free_inodes_count(fs, group) - inuse);
Theodore Ts'o7f961d42002-02-03 01:28:52 -050035 if (isdir)
Valerie Aurora Hensond7cca6b2009-10-25 21:43:47 -040036 ext2fs_bg_used_dirs_count_set(fs, group, ext2fs_bg_used_dirs_count(fs, group) + inuse);
Jose R. Santosd4f34d42007-10-21 21:03:25 -050037
Theodore Ts'o5711ed22008-04-21 01:29:01 -040038 /* We don't strictly need to be clearing the uninit flag if inuse < 0
Jose R. Santosd4f34d42007-10-21 21:03:25 -050039 * (i.e. freeing inodes) but it also means something is bad. */
Eric Sandeene633b582009-10-25 21:41:32 -040040 ext2fs_bg_flags_clear(fs, group, EXT2_BG_INODE_UNINIT);
Jose R. Santosd4f34d42007-10-21 21:03:25 -050041 if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
42 EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) {
43 ext2_ino_t first_unused_inode = fs->super->s_inodes_per_group -
Valerie Aurora Hensond7cca6b2009-10-25 21:43:47 -040044 ext2fs_bg_itable_unused(fs, group) +
Jose R. Santosd4f34d42007-10-21 21:03:25 -050045 group * fs->super->s_inodes_per_group + 1;
46
47 if (ino >= first_unused_inode)
Valerie Aurora Hensond7cca6b2009-10-25 21:43:47 -040048 ext2fs_bg_itable_unused_set(fs, group, group * fs->super->s_inodes_per_group + fs->super->s_inodes_per_group - ino);
Jose R. Santosd4f34d42007-10-21 21:03:25 -050049 ext2fs_group_desc_csum_set(fs, group);
50 }
51
Theodore Ts'o8bd0c952002-01-03 03:29:19 -050052 fs->super->s_free_inodes_count -= inuse;
53 ext2fs_mark_super_dirty(fs);
54 ext2fs_mark_ib_dirty(fs);
55}
56
Theodore Ts'o7f961d42002-02-03 01:28:52 -050057void ext2fs_inode_alloc_stats(ext2_filsys fs, ext2_ino_t ino, int inuse)
58{
59 ext2fs_inode_alloc_stats2(fs, ino, inuse, 0);
60}
61
Jose R. Santose8328e32009-06-01 16:15:40 -040062void ext2fs_block_alloc_stats2(ext2_filsys fs, blk64_t blk, int inuse)
Theodore Ts'o8bd0c952002-01-03 03:29:19 -050063{
Jose R. Santose8328e32009-06-01 16:15:40 -040064 int group = ext2fs_group_of_blk2(fs, blk);
Theodore Ts'o8bd0c952002-01-03 03:29:19 -050065
Theodore Ts'ocf4e06d2009-01-22 16:01:38 -050066#ifndef OMIT_COM_ERR
Valerie Aurora Henson4efbac62009-09-07 20:46:34 -040067 if (blk >= ext2fs_blocks_count(fs->super)) {
Theodore Ts'o46d6f842009-04-22 15:07:00 -040068 com_err("ext2fs_block_alloc_stats", 0,
69 "Illegal block number: %lu", (unsigned long) blk);
Theodore Ts'ocf4e06d2009-01-22 16:01:38 -050070 return;
71 }
72#endif
Theodore Ts'o8bd0c952002-01-03 03:29:19 -050073 if (inuse > 0)
Valerie Aurora Henson8f82ef92009-08-05 00:27:10 -040074 ext2fs_mark_block_bitmap2(fs->block_map, blk);
Theodore Ts'o8bd0c952002-01-03 03:29:19 -050075 else
Valerie Aurora Henson8f82ef92009-08-05 00:27:10 -040076 ext2fs_unmark_block_bitmap2(fs->block_map, blk);
Valerie Aurora Hensond7cca6b2009-10-25 21:43:47 -040077 ext2fs_bg_free_blocks_count_set(fs, group, ext2fs_bg_free_blocks_count(fs, group) - inuse);
Eric Sandeene633b582009-10-25 21:41:32 -040078 ext2fs_bg_flags_clear(fs, group, EXT2_BG_BLOCK_UNINIT);
Jose R. Santosd4f34d42007-10-21 21:03:25 -050079 ext2fs_group_desc_csum_set(fs, group);
80
Theodore Ts'ob98d3e82011-07-07 13:54:39 -040081 ext2fs_free_blocks_count_add(fs->super,
82 -inuse * EXT2FS_CLUSTER_RATIO(fs));
Theodore Ts'o8bd0c952002-01-03 03:29:19 -050083 ext2fs_mark_super_dirty(fs);
84 ext2fs_mark_bb_dirty(fs);
Theodore Ts'of5c562e2008-06-02 17:21:37 -040085 if (fs->block_alloc_stats)
86 (fs->block_alloc_stats)(fs, (blk64_t) blk, inuse);
87}
88
Jose R. Santose8328e32009-06-01 16:15:40 -040089void ext2fs_block_alloc_stats(ext2_filsys fs, blk_t blk, int inuse)
90{
91 ext2fs_block_alloc_stats2(fs, blk, inuse);
92}
93
Theodore Ts'oefc6f622008-08-27 23:07:54 -040094void ext2fs_set_block_alloc_stats_callback(ext2_filsys fs,
Theodore Ts'of5c562e2008-06-02 17:21:37 -040095 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{
102 if (!fs || fs->magic != EXT2_ET_MAGIC_EXT2FS_FILSYS)
103 return;
104 if (old)
105 *old = fs->block_alloc_stats;
106
107 fs->block_alloc_stats = func;
Theodore Ts'o8bd0c952002-01-03 03:29:19 -0500108}