description: _ product_versions: Linux linux-260-test8-efs changelog: _ URL: _ requires: _ conflicts: _ maintainer: _ patch_name: efs_blocksize3d.patch author: Randy.Dunlap patch_version: 2003-10-26.21:56:06 diffstat:= diff -Naurp ./fs/efs/dir.c~blocksize ./fs/efs/dir.c --- ./fs/efs/dir.c~blocksize 2003-10-17 14:43:20.000000000 -0700 +++ ./fs/efs/dir.c 2003-10-26 21:47:35.000000000 -0800 @@ -19,10 +19,12 @@ struct inode_operations efs_dir_inode_op .lookup = efs_lookup, }; -static int efs_readdir(struct file *filp, void *dirent, filldir_t filldir) { +static int efs_readdir(struct file *filp, void *dirent, filldir_t filldir) +{ struct inode *inode = filp->f_dentry->d_inode; struct buffer_head *bh; - + char *blockbuf; + unsigned long blockbuf_offset; struct efs_dir *dirblock; struct efs_dentry *dirslot; efs_ino_t inodenum; @@ -44,14 +46,15 @@ static int efs_readdir(struct file *filp /* look at all blocks */ while (block < inode->i_blocks) { /* read the dir block */ - bh = sb_bread(inode->i_sb, efs_bmap(inode, block)); + bh = efs_bread(inode->i_sb, efs_bmap(inode, block), &blockbuf_offset); if (!bh) { printk(KERN_ERR "EFS: readdir(): failed to read dir block %d\n", block); break; } - dirblock = (struct efs_dir *) bh->b_data; + blockbuf = bh->b_data + blockbuf_offset; + dirblock = (struct efs_dir *) blockbuf; if (be16_to_cpu(dirblock->magic) != EFS_DIRBLK_MAGIC) { printk(KERN_ERR "EFS: readdir(): invalid directory block\n"); @@ -65,8 +68,11 @@ static int efs_readdir(struct file *filp continue; } - dirslot = (struct efs_dentry *) (((char *) bh->b_data) + EFS_SLOTAT(dirblock, slot)); + dirslot = (struct efs_dentry *) (blockbuf + + EFS_SLOTAT(dirblock, slot)); + printk(KERN_DEBUG "efs_readdir: dirslot ptr=%p for slot %d\n", + dirslot, slot); inodenum = be32_to_cpu(dirslot->inode); namelen = dirslot->namelen; nameptr = dirslot->name; @@ -110,4 +116,3 @@ out: unlock_kernel(); return 0; } - diff -Naurp ./fs/efs/file.c~blocksize ./fs/efs/file.c --- ./fs/efs/file.c~blocksize 2003-10-17 14:43:15.000000000 -0700 +++ ./fs/efs/file.c 2003-10-22 19:31:04.000000000 -0700 @@ -22,8 +22,8 @@ int efs_get_block(struct inode *inode, s /* * i have no idea why this happens as often as it does */ - printk(KERN_WARNING "EFS: bmap(): block %d >= %ld (filesize %ld)\n", - block, + printk(KERN_WARNING "EFS: bmap(): block %llu >= %ld (filesize %llu)\n", + (unsigned long long)iblock, inode->i_blocks, inode->i_size); #endif @@ -35,8 +35,8 @@ int efs_get_block(struct inode *inode, s return 0; } -int efs_bmap(struct inode *inode, efs_block_t block) { - +int efs_bmap(struct inode *inode, efs_block_t block) +{ if (block < 0) { printk(KERN_WARNING "EFS: bmap(): block < 0\n"); return 0; @@ -48,8 +48,8 @@ int efs_bmap(struct inode *inode, efs_bl /* * i have no idea why this happens as often as it does */ - printk(KERN_WARNING "EFS: bmap(): block %d >= %ld (filesize %ld)\n", - block, + printk(KERN_WARNING "EFS: bmap(): block %ld >= %ld (filesize %llu)\n", + (long)block, inode->i_blocks, inode->i_size); #endif diff -Naurp ./fs/efs/inode.c~blocksize ./fs/efs/inode.c --- ./fs/efs/inode.c~blocksize 2003-10-17 14:43:03.000000000 -0700 +++ ./fs/efs/inode.c 2003-10-26 20:12:14.000000000 -0800 @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -53,6 +54,8 @@ void efs_read_inode(struct inode *inode) dev_t device; u32 rdev; struct buffer_head *bh; + char *blockbuf; + unsigned long blockbuf_offset; struct efs_sb_info *sb = SUPER_INFO(inode->i_sb); struct efs_inode_info *in = INODE_INFO(inode); efs_block_t block, offset; @@ -81,13 +84,14 @@ void efs_read_inode(struct inode *inode) (EFS_BLOCKSIZE / sizeof(struct efs_dinode))) * sizeof(struct efs_dinode); - bh = sb_bread(inode->i_sb, block); + bh = efs_bread(inode->i_sb, block, &blockbuf_offset); if (!bh) { printk(KERN_WARNING "EFS: bread() failed at block %d\n", block); goto read_inode_error; } - efs_inode = (struct efs_dinode *) (bh->b_data + offset); + blockbuf = bh->b_data + blockbuf_offset; + efs_inode = (struct efs_dinode *) (blockbuf + offset); inode->i_mode = be16_to_cpu(efs_inode->di_mode); inode->i_nlink = be16_to_cpu(efs_inode->di_nlink); @@ -191,11 +195,13 @@ efs_extent_check(efs_extent *ptr, efs_bl } } -efs_block_t efs_map_block(struct inode *inode, efs_block_t block) { +efs_block_t efs_map_block(struct inode *inode, efs_block_t block) +{ struct efs_sb_info *sb = SUPER_INFO(inode->i_sb); struct efs_inode_info *in = INODE_INFO(inode); struct buffer_head *bh = NULL; - + char *blockbuf = NULL; + unsigned long blockbuf_offset; int cur, last, first = 1; int ibase, ioffset, dirext, direxts, indext, indexts; efs_block_t iblock, result = 0, lastblock = 0; @@ -271,11 +277,12 @@ efs_block_t efs_map_block(struct inode * if (first || lastblock != iblock) { if (bh) brelse(bh); - bh = sb_bread(inode->i_sb, iblock); + bh = efs_bread(inode->i_sb, iblock, &blockbuf_offset); if (!bh) { printk(KERN_ERR "EFS: bread() failed at block %d\n", iblock); return 0; } + blockbuf = bh->b_data + blockbuf_offset; #ifdef DEBUG printk(KERN_DEBUG "EFS: map_block(): read indirect extent block %d\n", iblock); #endif @@ -283,7 +290,7 @@ efs_block_t efs_map_block(struct inode * lastblock = iblock; } - exts = (efs_extent *) bh->b_data; + exts = (efs_extent *) blockbuf; extent_copy(&(exts[ioffset]), &ext); @@ -304,4 +311,21 @@ efs_block_t efs_map_block(struct inode * return 0; } +struct buffer_head *efs_bread(struct super_block *sb, + sector_t block, unsigned long *blockbuf_offset) +{ + struct efs_sb_info *sinfo = SUPER_INFO(sb); + unsigned blocking = sinfo->blocking; + sector_t phys_sector; + + if (blocking <= 1) { + *blockbuf_offset = 0; + return sb_bread(sb, block); + } + + phys_sector = block; + *blockbuf_offset = sector_div(phys_sector, blocking) * EFS_BLOCKSIZE; + return sb_bread(sb, phys_sector); +} + MODULE_LICENSE("GPL"); diff -Naurp ./fs/efs/namei.c~blocksize ./fs/efs/namei.c --- ./fs/efs/namei.c~blocksize 2003-10-17 14:43:20.000000000 -0700 +++ ./fs/efs/namei.c 2003-10-22 20:53:03.000000000 -0700 @@ -12,8 +12,9 @@ #include static efs_ino_t efs_find_entry(struct inode *inode, const char *name, int len) { - struct buffer_head *bh; - + struct buffer_head *bh; + char *blockbuf; + unsigned long blockbuf_offset; int slot, namelen; char *nameptr; struct efs_dir *dirblock; @@ -26,13 +27,14 @@ static efs_ino_t efs_find_entry(struct i for(block = 0; block < inode->i_blocks; block++) { - bh = sb_bread(inode->i_sb, efs_bmap(inode, block)); + bh = efs_bread(inode->i_sb, efs_bmap(inode, block), &blockbuf_offset); if (!bh) { printk(KERN_ERR "EFS: find_entry(): failed to read dir block %d\n", block); return 0; } - dirblock = (struct efs_dir *) bh->b_data; + blockbuf = bh->b_data + blockbuf_offset; + dirblock = (struct efs_dir *) blockbuf; if (be16_to_cpu(dirblock->magic) != EFS_DIRBLK_MAGIC) { printk(KERN_ERR "EFS: find_entry(): invalid directory block\n"); @@ -41,7 +43,7 @@ static efs_ino_t efs_find_entry(struct i } for(slot = 0; slot < dirblock->slots; slot++) { - dirslot = (struct efs_dentry *) (((char *) bh->b_data) + EFS_SLOTAT(dirblock, slot)); + dirslot = (struct efs_dentry *) (blockbuf + EFS_SLOTAT(dirblock, slot)); namelen = dirslot->namelen; nameptr = dirslot->name; @@ -74,4 +76,3 @@ struct dentry *efs_lookup(struct inode * d_add(dentry, inode); return NULL; } - diff -Naurp ./fs/efs/super.c~blocksize ./fs/efs/super.c --- ./fs/efs/super.c~blocksize 2003-10-17 14:43:25.000000000 -0700 +++ ./fs/efs/super.c 2003-10-22 21:00:26.000000000 -0700 @@ -210,6 +210,9 @@ int efs_fill_super(struct super_block *s { struct efs_sb_info *sb; struct buffer_head *bh; + char *blockbuf; + unsigned long blockbuf_offset; + unsigned long blocksize; sb = kmalloc(sizeof(struct efs_sb_info), GFP_KERNEL); if (!sb) @@ -217,40 +220,49 @@ int efs_fill_super(struct super_block *s s->s_fs_info = sb; memset(sb, 0, sizeof(struct efs_sb_info)); - s->s_magic = EFS_SUPER_MAGIC; - if (!sb_set_blocksize(s, EFS_BLOCKSIZE)) { - printk(KERN_ERR "EFS: device does not support %d byte blocks\n", - EFS_BLOCKSIZE); - goto out_no_fs_ul; - } - + s->s_magic = EFS_SUPER_MAGIC; + sb->blocking = 1; + for (blocksize = EFS_BLOCKSIZE; blocksize <= 4 * EFS_BLOCKSIZE; + blocksize += blocksize, sb->blocking += sb->blocking) { + if (!sb_set_blocksize(s, blocksize)) + printk(KERN_ERR "EFS: device does not support %ld byte blocks\n", + blocksize); + else + goto efs_have_blocksize; + } + goto out_no_fs_ul; + +efs_have_blocksize: + printk(KERN_DEBUG "EFS: using blocksize = %ld, blocking factor = %d\n", + blocksize, sb->blocking); /* read the vh (volume header) block */ - bh = sb_bread(s, 0); - + bh = efs_bread(s, 0, &blockbuf_offset); if (!bh) { printk(KERN_ERR "EFS: cannot read volume header\n"); goto out_no_fs_ul; } + blockbuf = bh->b_data + blockbuf_offset; /* * if this returns zero then we didn't find any partition table. * this isn't (yet) an error - just assume for the moment that * the device is valid and go on to search for a superblock. */ - sb->fs_start = efs_validate_vh((struct volume_header *) bh->b_data); + sb->fs_start = efs_validate_vh((struct volume_header *) blockbuf); brelse(bh); if (sb->fs_start == -1) { goto out_no_fs_ul; } - bh = sb_bread(s, sb->fs_start + EFS_SUPER); + bh = efs_bread(s, sb->fs_start + EFS_SUPER, &blockbuf_offset); if (!bh) { printk(KERN_ERR "EFS: cannot read superblock\n"); goto out_no_fs_ul; } - - if (efs_validate_super(sb, (struct efs_super *) bh->b_data)) { + blockbuf = bh->b_data + blockbuf_offset; + + if (efs_validate_super(sb, (struct efs_super *) blockbuf)) { #ifdef DEBUG printk(KERN_WARNING "EFS: invalid superblock at block %u\n", sb->fs_start + EFS_SUPER); #endif @@ -301,4 +313,3 @@ int efs_statfs(struct super_block *s, st return 0; } - diff -Naurp ./fs/efs/symlink.c~blocksize ./fs/efs/symlink.c --- ./fs/efs/symlink.c~blocksize 2003-10-17 14:43:16.000000000 -0700 +++ ./fs/efs/symlink.c 2003-10-22 20:55:20.000000000 -0700 @@ -16,6 +16,8 @@ static int efs_symlink_readpage(struct f { char *link = kmap(page); struct buffer_head * bh; + char *blockbuf; + unsigned long blockbuf_offset; struct inode * inode = page->mapping->host; efs_block_t size = inode->i_size; int err; @@ -27,16 +29,18 @@ static int efs_symlink_readpage(struct f lock_kernel(); /* read first 512 bytes of link target */ err = -EIO; - bh = sb_bread(inode->i_sb, efs_bmap(inode, 0)); + bh = efs_bread(inode->i_sb, efs_bmap(inode, 0), &blockbuf_offset); if (!bh) goto fail; - memcpy(link, bh->b_data, (size > EFS_BLOCKSIZE) ? EFS_BLOCKSIZE : size); + blockbuf = bh->b_data + blockbuf_offset; + memcpy(link, blockbuf, (size > EFS_BLOCKSIZE) ? EFS_BLOCKSIZE : size); brelse(bh); if (size > EFS_BLOCKSIZE) { - bh = sb_bread(inode->i_sb, efs_bmap(inode, 1)); + bh = efs_bread(inode->i_sb, efs_bmap(inode, 1), &blockbuf_offset); if (!bh) goto fail; - memcpy(link + EFS_BLOCKSIZE, bh->b_data, size - EFS_BLOCKSIZE); + blockbuf = bh->b_data + blockbuf_offset; + memcpy(link + EFS_BLOCKSIZE, blockbuf, size - EFS_BLOCKSIZE); brelse(bh); } link[size] = '\0'; diff -Naurp ./include/linux/efs_fs.h~blocksize ./include/linux/efs_fs.h --- ./include/linux/efs_fs.h~blocksize 2003-10-17 14:43:04.000000000 -0700 +++ ./include/linux/efs_fs.h 2003-10-22 19:30:27.000000000 -0700 @@ -10,6 +10,7 @@ #define __EFS_FS_H__ #define EFS_VERSION "1.0a" +#define DEBUG 1 /* rddunlap */ static const char cprt[] = "EFS: "EFS_VERSION" - (c) 1999 Al Smith "; @@ -48,5 +49,7 @@ extern efs_block_t efs_map_block(struct extern struct dentry *efs_lookup(struct inode *, struct dentry *, struct nameidata *); extern int efs_bmap(struct inode *, int); +extern struct buffer_head *efs_bread(struct super_block *sb, + sector_t block, unsigned long *bh_offset); #endif /* __EFS_FS_H__ */ diff -Naurp ./include/linux/efs_fs_sb.h~blocksize ./include/linux/efs_fs_sb.h --- ./include/linux/efs_fs_sb.h~blocksize 2003-10-17 14:43:20.000000000 -0700 +++ ./include/linux/efs_fs_sb.h 2003-10-21 20:48:22.000000000 -0700 @@ -56,6 +56,7 @@ struct efs_sb_info { int32_t inode_free; /* # of free inodes */ short inode_blocks; /* # of blocks used for inodes in every grp */ short total_groups; /* # of groups */ + int32_t blocking; /* number of logical blocks per physical block */ }; #endif /* __EFS_FS_SB_H__ */