diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c index 1d41ce477df5..d18383d04c71 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 = (eblock >= sblock) ? (eblock - sblock + 1) : 0; + inode->i_blocks = blocks; + /* For directories, 0xFFFFFFFF on-disk means "unused" */ + if (S_ISDIR(inode->i_mode) && eoff == U32_MAX) + inode->i_size = (loff_t)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);