On Jun 05, 2009 16:50 +0900, Toshiyuki Okajima wrote: > From: Toshiyuki Okajima <toshi.okajima@xxxxxxxxxxxxxx> > > The dx_map_entry structure doesn't support over 64KB block size by current > usage of its member("offs"). Because "offs" treats an offset of copies of > the ext4_dir_entry_2 structure as is. This member size is 16 bits. But real > offset for over 64KB(256KB) block size needs 18 bits. However, real offset > keeps 4 byte boundary, so lower 2 bits is not used. > > Therefore, we do the following to fix this limitation: > For "store": > we divide the real offset by 4 and then store this result to "offs" > member. > For "use": > we multiply "offs" member by 4 and then use this result > as real offset. This patch unfortunately doesn't address all of the issues related to blocksize > 64kB. There are a number of other places where there are limits related to > 64kB blocksize like ext4_dir_entry_2 itself having only a "__u16 rec_len", so without changing the on-disk format it is not possible to have > 64kB blocksize. You would only notice this if you create a large enough directory. It might be possible to force very large directory blocks to have multiple directory entries (max size 65536 bytes using the helpers ext4_rec_len_{to,from}_disk() to convert 0xffff -> 0x10000). The dx_map_entry you are changing is only an in-memory structure, so changing it to use an int doesn't matter, but without changing the on-disk structures it is not useful. > Signed-off-by: Toshiyuki Okajima <toshi.okajima@xxxxxxxxxxxxxx> > --- > fs/ext4/namei.c | 5 +++-- > 1 file changed, 3 insertions(+), 2 deletions(-) > > --- linux-2.6.30-rc6/fs/ext4/namei.c.orig 2009-05-26 01:35:09.000000000 +0900 > +++ linux-2.6.30-rc6/fs/ext4/namei.c 2009-06-06 00:05:51.000000000 +0900 > @@ -750,7 +750,7 @@ static int dx_make_map(struct ext4_dir_e > ext4fs_dirhash(de->name, de->name_len, &h); > map_tail--; > map_tail->hash = h.hash; > - map_tail->offs = (u16) ((char *) de - base); > + map_tail->offs = ((char *) de - base)>>2; > map_tail->size = le16_to_cpu(de->rec_len); > count++; > cond_resched(); > @@ -1148,7 +1148,8 @@ dx_move_dirents(char *from, char *to, st > unsigned rec_len = 0; > > while (count--) { > - struct ext4_dir_entry_2 *de = (struct ext4_dir_entry_2 *) (from + map->offs); > + struct ext4_dir_entry_2 *de = (struct ext4_dir_entry_2 *) > + (from + (map->offs<<2)); > rec_len = EXT4_DIR_REC_LEN(de->name_len); > memcpy (to, de, rec_len); > ((struct ext4_dir_entry_2 *) to)->rec_len = Cheers, Andreas -- Andreas Dilger Sr. Staff Engineer, Lustre Group Sun Microsystems of Canada, Inc. -- To unsubscribe from this list: send the line "unsubscribe linux-ext4" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html