ChangeSet 1.2231.1.159, 2005/03/28 20:00:38-08:00, [EMAIL PROTECTED]

        [PATCH] ext2/3 file limits to avoid overflowing i_blocks
        
        As discussed before, we can overflow i_blocks in ext2/ext3 inodes by
        growing a file up to 2TB.  That gives us 2^32 sectors of data in the 
file;
        but once you add on the indirect tree and possible EA/ACL metadata,
        i_blocks will wrap beyond 2^32.  Consensus seemed to be that the best 
way
        to avoid this was simply to stop files getting so large that this was a
        problem in the first place; anything else would lead to complications 
if a
        sparse file tried to overflow that 2^32 sector limit while filling in
        holes.
        
        I wrote a small program to calculate the total indirect tree overhead 
for
        any given file size, and 0x1ff7fffe000 turned out to be the largest 
file we
        can get without the total i_blocks overflowing 2^32.
        
        But in testing, that *just* wrapped --- we need to limit the file to be 
one
        page smaller than that to deal with the possibility of an EA/ACL block
        being accounted against i_blocks.
        
        So this patch has been tested, at least on ext3, by letting a file grow
        densely to its maximum size permitted by the kernel; at 0x1ff7fffe000, 
stat
        shows the file to have wrapped back exactly to 0 st_blocks, but with the
        limit at 0x1ff7fffd000, du shows it occupying the expected 2TB-blocksize
        bytes.
        
        Signed-off-by: Stephen Tweedie <[EMAIL PROTECTED]>
        Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
        Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>



 ext2/super.c |   10 ++++++++--
 ext3/super.c |   10 ++++++++--
 2 files changed, 16 insertions(+), 4 deletions(-)


diff -Nru a/fs/ext2/super.c b/fs/ext2/super.c
--- a/fs/ext2/super.c   2005-03-28 21:41:31 -08:00
+++ b/fs/ext2/super.c   2005-03-28 21:41:31 -08:00
@@ -518,12 +518,18 @@
 static loff_t ext2_max_size(int bits)
 {
        loff_t res = EXT2_NDIR_BLOCKS;
+       /* This constant is calculated to be the largest file size for a
+        * dense, 4k-blocksize file such that the total number of
+        * sectors in the file, including data and all indirect blocks,
+        * does not exceed 2^32. */
+       const loff_t upper_limit = 0x1ff7fffd000LL;
+
        res += 1LL << (bits-2);
        res += 1LL << (2*(bits-2));
        res += 1LL << (3*(bits-2));
        res <<= bits;
-       if (res > (512LL << 32) - (1 << bits))
-               res = (512LL << 32) - (1 << bits);
+       if (res > upper_limit)
+               res = upper_limit;
        return res;
 }
 
diff -Nru a/fs/ext3/super.c b/fs/ext3/super.c
--- a/fs/ext3/super.c   2005-03-28 21:41:31 -08:00
+++ b/fs/ext3/super.c   2005-03-28 21:41:31 -08:00
@@ -1193,12 +1193,18 @@
 static loff_t ext3_max_size(int bits)
 {
        loff_t res = EXT3_NDIR_BLOCKS;
+       /* This constant is calculated to be the largest file size for a
+        * dense, 4k-blocksize file such that the total number of
+        * sectors in the file, including data and all indirect blocks,
+        * does not exceed 2^32. */
+       const loff_t upper_limit = 0x1ff7fffd000LL;
+
        res += 1LL << (bits-2);
        res += 1LL << (2*(bits-2));
        res += 1LL << (3*(bits-2));
        res <<= bits;
-       if (res > (512LL << 32) - (1 << bits))
-               res = (512LL << 32) - (1 << bits);
+       if (res > upper_limit)
+               res = upper_limit;
        return res;
 }
 
-
To unsubscribe from this list: send the line "unsubscribe bk-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to