xfs
[Top] [All Lists]

Re: fseeko64() suspended FIXED

To: yxy_oversea <yxy_oversea@xxxxxxxxxxx>
Subject: Re: fseeko64() suspended FIXED
From: Eric Sandeen <sandeen@xxxxxxx>
Date: Mon, 06 Nov 2000 14:15:12 -0600
Cc: linux-xfs@xxxxxxxxxxx
References: <OE659T3TGJ2TUSzbAUf00000024@xxxxxxxxxxx>
Sender: owner-linux-xfs@xxxxxxxxxxx
Found the problem:

In page_buf_io.c, on line 710, we have:

rounded_isize = (inode->i_size + rounding - 1) & mask;

However, this overflows for file sizes > 32 bits.  Types are:

inode->i_size:  loff_t (__kernel_off_t, long long)
rounded_isize:  size_t (u int)
rounding:       u_int
mask:           u_int

This overflow eventually caused the size of the read to be very wrong.

This should fix it (it has been checked in):

================

--- linux/fs/pagebuf/page_buf_io.c.orig  Mon Nov  6 11:28:31 2000
+++ linux/fs/pagebuf/page_buf_io.c       Mon Nov  6 11:37:59 2000
@@ -692,11 +692,11 @@
        int maps_returned, map_entry;
        unsigned long chunksize, map_size, size, readahead;
        int     direct = filp->f_flags & O_DIRECT;
-       unsigned int    rounding, mask;
-       size_t rounded_isize;
-
+       unsigned long   rounding;
+       loff_t          mask, rounded_isize;
+        
        rounding = direct ? inode->i_sb->s_blocksize : PAGE_CACHE_SIZE;
-       mask = ~(rounding - 1);
+       mask = ~(loff_t)(rounding - 1);
 
        /*
         * while we have data to do, get a bunch of mapping for this

================

I also changed "rounding" to unsigned long because it's possibly
assigned from inode->i_sb->s_blocksize, which is an unsigned long.

-Eric

<Prev in Thread] Current Thread [Next in Thread>