xfs
[Top] [All Lists]

Re: [LNX-XFS] Re: [LNX-XFS] Re: large file problems with 2.4.25-pre4

To: Eric Sandeen <sandeen@xxxxxxx>
Subject: Re: [LNX-XFS] Re: [LNX-XFS] Re: large file problems with 2.4.25-pre4
From: Kelsey Cummings <kgc@xxxxxxxxx>
Date: Tue, 13 Jan 2004 11:40:02 -0800
Cc: Nathan Scott <nathans@xxxxxxx>, Steve Lord <lord@xxxxxxx>, linux-xfs@xxxxxxxxxxx
In-reply-to: <1074022226.20422.23.camel@xxxxxxxxxxxxxxxxxxxxxx>
References: <20040112233619.GF98119@xxxxxxxxx> <20040113003039.GB969@frodo> <20040113005150.GL98119@xxxxxxxxx> <4003539F.8030207@xxxxxxx> <20040113024639.GA1205@frodo> <20040113184702.GW98119@xxxxxxxxx> <1074022226.20422.23.camel@xxxxxxxxxxxxxxxxxxxxxx>
Sender: linux-xfs-bounce@xxxxxxxxxxx
User-agent: Mutt/1.4.1i
I'll let you know how it goes.  Thanks!

On Tue, Jan 13, 2004 at 01:30:26PM -0600, Eric Sandeen wrote:
> Here's the patch which I am on the verge of checking in, if you'd like
> to test it with default mkfs values again, that'd be great.
> 
> Depending on what your xfs tree looks like, you might need to change
> "linux-2.4" paths to just "linux" and references to "xfs_buf.[ch]" to
> "page_buf.[ch]" or so, to make it apply.  Pathnames & file names have
> been swizzled a little bit lately.
> 
> -Eric
> 
> -- 
> Eric Sandeen      [C]XFS for Linux   http://oss.sgi.com/projects/xfs
> sandeen@xxxxxxx   SGI, Inc.          651-683-3102

> 
> ===========================================================================
> Index: linux-2.4/xfs_aops.c
> ===========================================================================
> 
> --- /usr/tmp/TmpDir.10141-0/linux-2.4/xfs_aops.c_1.64 2004-01-12 
> 23:44:25.000000000 -0600
> +++ linux-2.4/xfs_aops.c      2004-01-12 21:52:57.000000000 -0600
> @@ -374,8 +374,9 @@
>       offset <<= PAGE_CACHE_SHIFT;
>       offset += p_offset;
>  
> -     pb = pagebuf_lookup(iomapp->iomap_target,
> -                         iomapp->iomap_offset, iomapp->iomap_bsize, 0);
> +     /* get an "empty" pagebuf to manage IO completion
> +      * Proper values will be set before returning */
> +     pb = pagebuf_lookup(iomapp->iomap_target, 0, 0, 0);
>       if (!pb)
>               return -EAGAIN;
>  
> @@ -438,6 +439,13 @@
>                       nblocks += bs;
>                       atomic_add(bs, &pb->pb_io_remaining);
>                       convert_page(inode, page, iomapp, pb, startio, all_bh);
> +                     /* stop if we've found enough blocks that the 
> +                      * corresponding byte count won't fit in our ulong
> +                      * pagebuf length (max 128 blocks could be returned
> +                      * from probe_unwritten_page - 64k page / 512b blocks)
> +                      */
> +                     if ((nblocks + 128) > (ULONG_MAX >> block_bits))
> +                             goto enough;
>               }
>  
>               if (tindex == tlast &&
> @@ -448,16 +456,20 @@
>                               nblocks += bs;
>                               atomic_add(bs, &pb->pb_io_remaining);
>                               convert_page(inode, page, iomapp, pb, startio, 
> all_bh);
> +                             if ((nblocks + 128) > (ULONG_MAX >> block_bits))
> +                                     goto enough;
>                       }
>               }
>       }
>  
> +enough:
>       size = nblocks;         /* NB: using 64bit number here */
>       size <<= block_bits;    /* convert fsb's to byte range */
>  
>       XFS_BUF_DATAIO(pb);
>       XFS_BUF_ASYNC(pb);
>       XFS_BUF_SET_SIZE(pb, size);
> +     XFS_BUF_SET_COUNT(pb, size);
>       XFS_BUF_SET_OFFSET(pb, offset);
>       XFS_BUF_SET_FSPRIVATE(pb, LINVFS_GET_VP(inode));
>       XFS_BUF_SET_IODONE_FUNC(pb, linvfs_unwritten_convert);
> @@ -1127,10 +1139,14 @@
>       int                     error = 0;
>       int                     pb_flags, map_flags, pg_index = 0;
>       size_t                  length, total;
> -     loff_t                  offset;
> -     size_t                  map_size, size;
> +     loff_t                  offset, map_size;
> +     size_t                  size;
>       vnode_t                 *vp = LINVFS_GET_VP(inode);
>  
> +     /* Note - although the iomap could have a 64-bit size,
> +      * kiobuf->length is only an int, so the min(map_size, length)
> +      * test will keep us from overflowing the pagebuf size_t size.
> +      */
>       total = length = iobuf->length;
>       offset = blocknr;
>       offset <<= inode->i_blkbits;
> @@ -1147,7 +1163,7 @@
>               BUG_ON(iomap.iomap_flags & IOMAP_DELAY);
>  
>               map_size = iomap.iomap_bsize - iomap.iomap_delta;
> -             size = min(map_size, length);
> +             size = (size_t)min(map_size, (loff_t)length);
>  
>               if ((iomap.iomap_flags & IOMAP_HOLE) ||
>                   ((iomap.iomap_flags & IOMAP_UNWRITTEN) && rw == READ)) {
> 
> ===========================================================================
> Index: linux-2.6/xfs_aops.c
> ===========================================================================
> 
> --- /usr/tmp/TmpDir.10141-0/linux-2.6/xfs_aops.c_1.56 2004-01-12 
> 23:44:25.000000000 -0600
> +++ linux-2.6/xfs_aops.c      2004-01-12 23:36:05.000000000 -0600
> @@ -407,8 +407,10 @@
>       offset <<= PAGE_CACHE_SHIFT;
>       offset += p_offset;
>  
> -     pb = pagebuf_lookup(iomapp->iomap_target,
> -                         iomapp->iomap_offset, iomapp->iomap_bsize, 0);
> +     /* get an "empty" pagebuf to manage IO completion
> +      * Proper values will be set before returning */
> +     pb = pagebuf_lookup(iomapp->iomap_target, 0, 0, 0);
> +
>       if (!pb)
>               return -EAGAIN;
>  
> @@ -471,6 +473,13 @@
>                       nblocks += bs;
>                       atomic_add(bs, &pb->pb_io_remaining);
>                       convert_page(inode, page, iomapp, pb, startio, all_bh);
> +                     /* stop if we've found enough blocks that the 
> +                      * corresponding byte count won't fit in the
> +                      * pagebuf length (max 128 blocks could be returned
> +                      * from probe_unwritten_page: 64k page / 512b blocks)
> +                      */
> +                     if ((nblocks + 128) > (ULONG_MAX >> block_bits))
> +                             goto enough;
>               }
>  
>               if (tindex == tlast &&
> @@ -481,16 +490,20 @@
>                               nblocks += bs;
>                               atomic_add(bs, &pb->pb_io_remaining);
>                               convert_page(inode, page, iomapp, pb, startio, 
> all_bh);
> +                             if ((nblocks + 128) > (ULONG_MAX >> block_bits))
> +                                     goto enough;
>                       }
>               }
>       }
>  
> +enough:
>       size = nblocks;         /* NB: using 64bit number here */
>       size <<= block_bits;    /* convert fsb's to byte range */
>  
>       XFS_BUF_DATAIO(pb);
>       XFS_BUF_ASYNC(pb);
>       XFS_BUF_SET_SIZE(pb, size);
> +     XFS_BUF_SET_COUNT(pb, size);
>       XFS_BUF_SET_OFFSET(pb, offset);
>       XFS_BUF_SET_FSPRIVATE(pb, LINVFS_GET_VP(inode));
>       XFS_BUF_SET_IODONE_FUNC(pb, linvfs_unwritten_convert);
> @@ -925,8 +938,10 @@
>       }
>  
>       if (blocks) {
> -             size = (iomap.iomap_bsize - iomap.iomap_delta); 
> -             bh_result->b_size = min_t(ssize_t, size, blocks << 
> inode->i_blkbits);
> +             loff_t iosize;
> +             iosize = (iomap.iomap_bsize - iomap.iomap_delta);
> +             bh_result->b_size =
> +                 (ssize_t)min(iosize, (loff_t)(blocks << inode->i_blkbits));
>       }
>  
>       return 0;
> 
> ===========================================================================
> Index: xfs_iomap.h
> ===========================================================================
> 
> --- /usr/tmp/TmpDir.10141-0/xfs_iomap.h_1.1   2004-01-12 23:44:25.000000000 
> -0600
> +++ xfs_iomap.h       2004-01-05 23:05:32.000000000 -0600
> @@ -66,27 +66,26 @@
>  /*
>   * xfs_iomap_t:  File system I/O map
>   *
> - * The iomap_bn, iomap_offset and iomap_length fields are expressed in disk 
> blocks.
> - * The iomap_length field specifies the size of the underlying backing store
> - * for the particular mapping.
> + * The iomap_bn field is expressed in 512-byte blocks, and is where the 
> + * mapping starts on disk.
>   *
> - * The iomap_bsize, iomap_size and iomap_delta fields are in bytes and 
> indicate
> - * the size of the mapping, the number of bytes that are valid to access
> - * (read or write), and the offset into the mapping, given the offset
> - * supplied to the file I/O map routine.  iomap_delta is the offset of the
> - * desired data from the beginning of the mapping.
> + * The iomap_offset, iomap_bsize and iomap_delta fields are in bytes.
> + * iomap_offset is the offset of the mapping in the file itself.
> + * iomap_bsize is the size of the mapping,  iomap_delta is the 
> + * desired data's offset into the mapping, given the offset supplied 
> + * to the file I/O map routine.
>   *
>   * When a request is made to read beyond the logical end of the object,
> - * iomap_size may be set to 0, but iomap_offset and iomap_length should be 
> set to
> - * the actual amount of underlying storage that has been allocated, if any.
> + * iomap_size may be set to 0, but iomap_offset and iomap_length should be 
> set
> + * to the actual amount of underlying storage that has been allocated, if 
> any.
>   */
>  
>  typedef struct xfs_iomap {
> -     xfs_daddr_t             iomap_bn;
> +     xfs_daddr_t             iomap_bn;       /* first 512b blk of mapping */
>       xfs_buftarg_t           *iomap_target;
> -     loff_t                  iomap_offset;
> -     size_t                  iomap_delta;
> -     size_t                  iomap_bsize;
> +     loff_t                  iomap_offset;   /* offset of mapping, bytes */
> +     loff_t                  iomap_bsize;    /* size of mapping, bytes */
> +     size_t                  iomap_delta;    /* offset into mapping, bytes */
>       iomap_flags_t           iomap_flags;
>  } xfs_iomap_t;
>  
> 
> ===========================================================================
> Index: xfsidbg.c
> ===========================================================================
> 
> --- /usr/tmp/TmpDir.10141-0/xfsidbg.c_1.250   2004-01-12 23:44:25.000000000 
> -0600
> +++ xfsidbg.c 2004-01-05 23:15:44.000000000 -0600
> @@ -2610,9 +2610,9 @@
>           (diag = kdb_getarea(iomap, addr)))
>  
>       kdb_printf("iomap_t at 0x%lx\n", addr);
> -     kdb_printf("  iomap_bn 0x%llx iomap_offset 0x%Lx iomap_delta 0x%lx 
> iomap_bsize 0x%lx\n",
> +     kdb_printf("  iomap_bn 0x%llx iomap_offset 0x%Lx iomap_delta 0x%lx 
> iomap_bsize 0x%llx\n",
>               (long long) iomap.iomap_bn, iomap.iomap_offset,
> -             (unsigned long) iomap.iomap_delta, (unsigned long) 
> iomap.iomap_bsize);
> +             (unsigned long)iomap.iomap_delta, (long long)iomap.iomap_bsize);
>  
>       kdb_printf("  iomap_flags %s\n", map_flags(iomap.iomap_flags, 
> iomap_flag_vals));
>  


-- 
Kelsey Cummings - kgc@xxxxxxxxx           sonic.net, inc.
System Administrator                      2260 Apollo Way
707.522.1000 (Voice)                      Santa Rosa, CA 95407
707.547.2199 (Fax)                        http://www.sonic.net/
Fingerprint = D5F9 667F 5D32 7347 0B79  8DB7 2B42 86B6 4E2C 3896


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