2007-09-20 14:32:16

by Jan Kara

[permalink] [raw]
Subject: Avoid rec_len overflow with 64KB block size

Hello,

when converting ext4 directories to pagecache I just came over
Takashi's patch preventing overflowing of rec_len. Looking over the
patch - can't we do it more elegantly by using say 0xffff instead of 64K
and perform conversion (using some helper) at the moment we read / store
rec_len? That would be IMHO more transparent than current approach (at
least it took me some time to understand what's going on with the
current patch when I was looking at the code)...

Honza

--
Jan Kara <[email protected]>
SuSE CR Labs


2007-09-20 16:17:24

by Jan Kara

[permalink] [raw]
Subject: Re: Avoid rec_len overflow with 64KB block size

> when converting ext4 directories to pagecache I just came over
> Takashi's patch preventing overflowing of rec_len. Looking over the
> patch - can't we do it more elegantly by using say 0xffff instead of 64K
> and perform conversion (using some helper) at the moment we read / store
> rec_len? That would be IMHO more transparent than current approach (at
> least it took me some time to understand what's going on with the
> current patch when I was looking at the code)...
Attached is a patch that does this for ext4. If you like this
approach, I can cook up a similar patch for ext2 / ext3.

Honza
--
Jan Kara <[email protected]>
SuSE CR Labs


Attachments:
(No filename) (657.00 B)
ext4-2.6.23-rc6-ext4_64k_blocksize.diff (11.41 kB)
Download all attachments

2007-09-20 18:18:24

by Andreas Dilger

[permalink] [raw]
Subject: Re: Avoid rec_len overflow with 64KB block size

On Sep 20, 2007 18:17 +0200, Jan Kara wrote:
> > when converting ext4 directories to pagecache I just came over
> > Takashi's patch preventing overflowing of rec_len. Looking over the
> > patch - can't we do it more elegantly by using say 0xffff instead of 64K
> > and perform conversion (using some helper) at the moment we read / store
> > rec_len? That would be IMHO more transparent than current approach (at
> > least it took me some time to understand what's going on with the
> > current patch when I was looking at the code)...
>
> Attached is a patch that does this for ext4. If you like this
> approach, I can cook up a similar patch for ext2 / ext3.

Yes, I think this is much cleaner to avoid all the conditionals in the
code.

> With 64KB blocksize, a directory entry can have size 64KB which does not fit
> into 16 bits we have for entry lenght. So we store 0xffff instead and convert
> value when read from / written to disk. The patch also converts some places
> to use ext4_next_entry() when we are changing them anyway.
>
> const char * error_msg = NULL;
> - const int rlen = le16_to_cpu(de->rec_len);
> + const int rlen = ext4_get_rec_len(le16_to_cpu(de->rec_len));

Maybe we should wrap the le16_to_cpu() into ext4_get_rec_len() itself,
making the parameter just be "__le16 rec_len"? We appear to have
le16_to_cpu() at every callsite.

Likewise for ext4_store_rec_len() it should do the cpu_to_le16() internally
and return an __le16. It should maybe be called ext4_set_rec_len() to be
a more natural pairing?

This also needs a patch for e2fsprogs, while I'm not sure the old patch did
(has anyone ever checked this?) We could still consider making
EXT4_DIR_MAX_REC_LEN as in Takashi's patch, but keep the cleanups here.


Cheers, Andreas
--
Andreas Dilger
Principal Software Engineer
Cluster File Systems, Inc.

2007-09-21 13:38:05

by Jan Kara

[permalink] [raw]
Subject: Re: Avoid rec_len overflow with 64KB block size

> On Sep 20, 2007 18:17 +0200, Jan Kara wrote:
> > With 64KB blocksize, a directory entry can have size 64KB which does not fit
> > into 16 bits we have for entry lenght. So we store 0xffff instead and convert
> > value when read from / written to disk. The patch also converts some places
> > to use ext4_next_entry() when we are changing them anyway.
> >
> > const char * error_msg = NULL;
> > - const int rlen = le16_to_cpu(de->rec_len);
> > + const int rlen = ext4_get_rec_len(le16_to_cpu(de->rec_len));
>
> Maybe we should wrap the le16_to_cpu() into ext4_get_rec_len() itself,
> making the parameter just be "__le16 rec_len"? We appear to have
> le16_to_cpu() at every callsite.
Yes, we do and I was also thinking about wrapping this up. The only
think I don't like about this is that the endianity conversion is then
hidden.

> Likewise for ext4_store_rec_len() it should do the cpu_to_le16() internally
> and return an __le16. It should maybe be called ext4_set_rec_len() to be
> a more natural pairing?
Yes. Actually, I'd find names like "ext4_rec_len_to_disk" and
"ext4_rec_len_from_disk" more explanative but I guess it's already too
long...

> This also needs a patch for e2fsprogs, while I'm not sure the old patch did
> (has anyone ever checked this?) We could still consider making
> EXT4_DIR_MAX_REC_LEN as in Takashi's patch, but keep the cleanups here.
I don't mind whether EXT4_DIR_MAX_REC_LEN is 1<<16-1 or 1<<16-4 :).
But e2fsprogs need to be updated in either case as both values were invalid
originally...

Honza
--
Jan Kara <[email protected]>
SuSE CR Labs