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
|