aboutsummaryrefslogtreecommitdiff
path: root/fs/bfs
diff options
context:
space:
mode:
authorAl Viro2005-10-04 17:48:44 +0100
committerLinus Torvalds2005-10-04 13:22:01 -0700
commitc2b513dfbb04d7c94cca145172cfeb91f7683e54 (patch)
tree8d022fdb4b7c44b940f8b09f2e568c044cadc27c /fs/bfs
parentce0fe7e70a0ad11097a3773e9f3f0de3d859edf0 (diff)
[PATCH] bfs iget() abuses
bfs_fill_super() walks the inode table to get the bitmap of free inodes and collect stats. It has no business using iget() for that - it's a lot of extra work, extra icache pollution and more complex code. Switched to walking the damn thing directly. Note: that also allows to kill ->i_dsk_ino in there - separate patch if Tigran can confirm that this field can be zero only for deleted inodes (i.e. something that could only be found during that scan and not by normal lookups). Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/bfs')
-rw-r--r--fs/bfs/inode.c42
1 files changed, 30 insertions, 12 deletions
diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c
index 868af0f224fb..3af6c73c5b5a 100644
--- a/fs/bfs/inode.c
+++ b/fs/bfs/inode.c
@@ -362,23 +362,41 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent)
info->si_lf_eblk = 0;
info->si_lf_sblk = 0;
info->si_lf_ioff = 0;
+ bh = NULL;
for (i=BFS_ROOT_INO; i<=info->si_lasti; i++) {
- inode = iget(s,i);
- if (BFS_I(inode)->i_dsk_ino == 0)
+ struct bfs_inode *di;
+ int block = (i - BFS_ROOT_INO)/BFS_INODES_PER_BLOCK + 1;
+ int off = (i - BFS_ROOT_INO) % BFS_INODES_PER_BLOCK;
+ unsigned long sblock, eblock;
+
+ if (!off) {
+ brelse(bh);
+ bh = sb_bread(s, block);
+ }
+
+ if (!bh)
+ continue;
+
+ di = (struct bfs_inode *)bh->b_data + off;
+
+ if (!di->i_ino) {
info->si_freei++;
- else {
- set_bit(i, info->si_imap);
- info->si_freeb -= inode->i_blocks;
- if (BFS_I(inode)->i_eblock > info->si_lf_eblk) {
- info->si_lf_eblk = BFS_I(inode)->i_eblock;
- info->si_lf_sblk = BFS_I(inode)->i_sblock;
- info->si_lf_ioff = BFS_INO2OFF(i);
- }
+ continue;
+ }
+ set_bit(i, info->si_imap);
+ info->si_freeb -= BFS_FILEBLOCKS(di);
+
+ sblock = le32_to_cpu(di->i_sblock);
+ eblock = le32_to_cpu(di->i_eblock);
+ if (eblock > info->si_lf_eblk) {
+ info->si_lf_eblk = eblock;
+ info->si_lf_sblk = sblock;
+ info->si_lf_ioff = BFS_INO2OFF(i);
}
- iput(inode);
}
+ brelse(bh);
if (!(s->s_flags & MS_RDONLY)) {
- mark_buffer_dirty(bh);
+ mark_buffer_dirty(info->si_sbh);
s->s_dirt = 1;
}
dump_imap("read_super", s);