Hi, > 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). This patch isn't one of the patches in order to support "blocksize > 64KB" with ext4. It only fixes dx_map_entry handling when we use "blocksize > 64KB". You know, ext4_rec_len_{to,from}_disk() has already supported "blocksize > 64KB". But dx_map_entry doesn't support "blocksize > 64KB" now. So, I have posted it to fix dx_map_entry handling on "blocksize > 64KB". I understand ext4_rec_len_{to,from}_disk() are useful for almost purpose of ext4_dir_entry_2 handling. But "offs" which is the member of dx_map_entry is exceptional. Because dx_map_entry must treat "0" value (offset = 0) but they cannot treat "0" value. ("0" is special value for them.) > unsigned int ext4_rec_len_from_disk(__le16 dlen, unsigned blocksize) > { > unsigned len = le16_to_cpu(dlen); > > if (len == EXT4_MAX_REC_LEN || len == 0) ^^^^^^^^^ > return blocksize; ^^^^^^^^^^^^^^^^^ > return (len & 65532) | ((len & 3) << 16); > } So, we cannot use them for "offs". Therefore I decided to use shift operations instead of them because it is easy implementation. [store] > > > + map_tail->offs = ((char *) de - base)>>2; [use] > > > + struct ext4_dir_entry_2 *de = (struct ext4_dir_entry_2 *) > > > + (from + (map->offs<<2)); Thanks, Toshiyuki Okajima -- 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