Re: generic_file_llseek() broken?

From: Andreas Dilger (adilger@turbolabs.com)
Date: Thu Nov 15 2001 - 16:09:17 EST


On Nov 15, 2001 10:38 +0100, Helge Hafting wrote:
> > On Nov 15, 2001 02:47 +0100, David Gomez wrote:
> > > I did 'dd if=/dev/zero of=test bs=1024k seek=2G' in a 10Gb ide disk, and
> > > guess what ?
> > >
> > > $ ls -l test
> > > -rw-r--r-- 1 huma huma 2251799813685248 Nov 15 02:39 test
> > > $ ls -lh test
> > > -rw-r--r-- 1 huma huma 2.0P Nov 15 02:39 test
> >
> > No, that in itself is fine - it is a sparse file, with a single 1MB block
> > at 2PB offset. If you were to "du" this file, it would say 1MB of allocated
> > space. The problem is that this _should_ be impossible to create on ext2,
> > because the write would be way past the allowed file size limit.
> >
> > > After that, i unmounted the partition and did an fsck, lots of errors and
> > > several files corrupted that fsck ask me to delete because some inodes had
> > > illegal blocks.
> >
> > That is really bad, I don't know how it would happen. Maybe there is
> > overflow internal to ext2, which causes it to write elsewhere in the fs?
> > When was the last time (previous to this problem) you fsck'd this fs?
>
> If he's _allowed_ to create a sparse file with impossible offset - what
> happens to the file's index blocks? I guess that's where something
> overflowed.

I think the problem is not coming from the llseek+write, but maybe from
ftruncate? Strace doesn't show any writes for me (only failed llseek +
lots of reads), yet when trying to create files > 4TB I get "block > big"
and > 8TB I get "block < 0" messages, which come from ext2_block_to_path().

In a couple of places (iblock, offsets) we are using an int/long to
store the block counts, don't know why we want to use a signed value
here instead of an unsigned (long). Looks like changing block numbers
to be unsigned longs goes into the guts of getblk and such. Ugh.

Maybe also sys_truncate should disallow truncating to a size larger
than s_maxbytes. Al? For now, returning EOVERFLOW from do_truncate()
when (length > inode->i_sb->s_maxbytes) should be OK.

Cheers, Andreas

--
Andreas Dilger
http://sourceforge.net/projects/ext2resize/
http://www-mddsp.enel.ucalgary.ca/People/adilger/

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Thu Nov 15 2001 - 21:00:44 EST