aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorEvgeniy Dushistov <dushistov@mail.ru>2006-06-25 05:47:20 -0700
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-25 10:01:01 -0700
commit6ef4d6bf86a82965896eaa1a189177239ec2bbab (patch)
tree3217c5601d8cf6701f8783ec776aa96d0dd75d4a /include
parent[PATCH] ufs: right block allocation (diff)
downloadlinux-dev-6ef4d6bf86a82965896eaa1a189177239ec2bbab.tar.xz
linux-dev-6ef4d6bf86a82965896eaa1a189177239ec2bbab.zip
[PATCH] ufs: change block number on the fly
First of all some necessary notes about UFS by it self: To avoid waste of disk space the tail of file consists not from blocks (which is ordinary big enough, 16K usually), it consists from fragments(which is ordinary 2K). When file is growing its tail occupy 1 fragment, 2 fragments... At some stage decision to allocate whole block is made and all fragments are moved to one block. How this situation was handled before: ufs_prepare_write ->block_prepare_write ->ufs_getfrag_block ->... ->ufs_new_fragments: bh = sb_bread bh->b_blocknr = result + i; mark_buffer_dirty (bh); This is wrong solution, because: - it didn't take into consideration that there is another cache: "inode page cache" - because of sb_getblk uses not b_blocknr, (it uses page->index) to find certain block, this breaks sb_getblk. How this situation is handled now: we go though all "page inode cache", if there are no such page in cache we load it into cache, and change b_blocknr. Signed-off-by: Evgeniy Dushistov <dushistov@mail.ru> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'include')
-rw-r--r--include/linux/ufs_fs.h3
1 files changed, 2 insertions, 1 deletions
diff --git a/include/linux/ufs_fs.h b/include/linux/ufs_fs.h
index 86b5b4271b5a..ed5053f5cd71 100644
--- a/include/linux/ufs_fs.h
+++ b/include/linux/ufs_fs.h
@@ -875,7 +875,8 @@ struct ufs_super_block_third {
/* balloc.c */
extern void ufs_free_fragments (struct inode *, unsigned, unsigned);
extern void ufs_free_blocks (struct inode *, unsigned, unsigned);
-extern unsigned ufs_new_fragments (struct inode *, __fs32 *, unsigned, unsigned, unsigned, int *);
+extern unsigned ufs_new_fragments(struct inode *, __fs32 *, unsigned, unsigned,
+ unsigned, int *, struct page *);
/* cylinder.c */
extern struct ufs_cg_private_info * ufs_load_cylinder (struct super_block *, unsigned);