diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c index 1d41ce477df5..59cb76e05160 100644 --- a/fs/bfs/inode.c +++ b/fs/bfs/inode.c @@ -38,6 +38,7 @@ struct inode *bfs_iget(struct super_block *sb, unsigned long ino) struct inode *inode; struct buffer_head *bh; int block, off; + u32 eoff, sblock, eblock, blocks; inode = iget_locked(sb, ino); if (!inode) @@ -79,8 +80,20 @@ struct inode *bfs_iget(struct super_block *sb, unsigned long ino) i_uid_write(inode, le32_to_cpu(di->i_uid)); i_gid_write(inode, le32_to_cpu(di->i_gid)); set_nlink(inode, le32_to_cpu(di->i_nlink)); - inode->i_size = BFS_FILESIZE(di); - inode->i_blocks = BFS_FILEBLOCKS(di); + eoff = le32_to_cpu(di->i_eoffset); + sblock = le32_to_cpu(di->i_sblock); + eblock = le32_to_cpu(di->i_eblock); + blocks = sblock == 0 ? 0 : (eblock - sblock + 1); + inode->i_blocks = blocks; + /* For directories, 0xFFFFFFFF on-disk means "unused" */ + if (S_ISDIR(inode->i_mode) && eoff == U32_MAX) + inode->i_size = blocks * BFS_BSIZE; + else + if (sblock == 0) + inode->i_size = 0; + else + inode->i_size = (eoff + 1) - (sblock * BFS_BSIZE); + inode_set_atime(inode, le32_to_cpu(di->i_atime), 0); inode_set_mtime(inode, le32_to_cpu(di->i_mtime), 0); inode_set_ctime(inode, le32_to_cpu(di->i_ctime), 0);