Re: [PATCH][BUG] ext4: dx_map_entry cannot support over 64KB block size

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

[Index of Archives]     [Reiser Filesystem Development]     [Ceph FS]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux FS]     [Yosemite National Park]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Device Mapper]     [Linux Media]

  Powered by Linux