Currently reading udf files > 2 GB is busted due to truncation
in the kernel.  Also reading a UDF file can return more data
than present in the file due to a failure to check the number
of bytes being requested with the number of bytes left in the
file.  Both problems are addressed by the enclosed patch.

-- John Wehle
------------------8<------------------------8<------------------------
*** fs/udf/udf_vnops.c.ORIGINAL	Sat Oct  2 01:48:04 2004
--- fs/udf/udf_vnops.c	Tue Jan 11 03:12:38 2005
*************** static int udf_strategy(struct vop_strat
*** 65,72 ****
  static int udf_bmap(struct vop_bmap_args *);
  static int udf_lookup(struct vop_cachedlookup_args *);
  static int udf_reclaim(struct vop_reclaim_args *);
! static int udf_readatoffset(struct udf_node *, int *, int, struct buf **, uint8_t **);
! static int udf_bmap_internal(struct udf_node *, uint32_t, daddr_t *, uint32_t *);
  
  vop_t **udf_vnodeop_p;
  static struct vnodeopv_entry_desc udf_vnodeop_entries[] = {
--- 65,72 ----
  static int udf_bmap(struct vop_bmap_args *);
  static int udf_lookup(struct vop_cachedlookup_args *);
  static int udf_reclaim(struct vop_reclaim_args *);
! static int udf_readatoffset(struct udf_node *, int *, off_t, struct buf **, uint8_t **);
! static int udf_bmap_internal(struct udf_node *, off_t, daddr_t *, uint32_t *);
  
  vop_t **udf_vnodeop_p;
  static struct vnodeopv_entry_desc udf_vnodeop_entries[] = {
*************** udf_read(struct vop_read_args *a)
*** 407,414 ****
  	struct udf_node *node = VTON(vp);
  	struct buf *bp;
  	uint8_t *data;
  	int error = 0;
! 	int size, fsize, offset;
  
  	if (uio->uio_offset < 0)
  		return (EINVAL);
--- 407,415 ----
  	struct udf_node *node = VTON(vp);
  	struct buf *bp;
  	uint8_t *data;
+ 	off_t fsize, offset;
  	int error = 0;
! 	int size;
  
  	if (uio->uio_offset < 0)
  		return (EINVAL);
*************** udf_read(struct vop_read_args *a)
*** 417,423 ****
  
  	while (uio->uio_offset < fsize && uio->uio_resid > 0) {
  		offset = uio->uio_offset;
! 		size = uio->uio_resid;
  		error = udf_readatoffset(node, &size, offset, &bp, &data);
  		if (error == 0)
  			error = uiomove(data, size, uio);
--- 418,424 ----
  
  	while (uio->uio_offset < fsize && uio->uio_resid > 0) {
  		offset = uio->uio_offset;
! 		size = min (uio->uio_resid, fsize - uio->uio_offset);
  		error = udf_readatoffset(node, &size, offset, &bp, &data);
  		if (error == 0)
  			error = uiomove(data, size, uio);
*************** udf_reclaim(struct vop_reclaim_args *a)
*** 1060,1066 ****
   *
   */
  static int
! udf_readatoffset(struct udf_node *node, int *size, int offset, struct buf **bp, uint8_t **data)
  {
  	struct udf_mnt *udfmp;
  	struct file_entry *fentry = NULL;
--- 1061,1067 ----
   *
   */
  static int
! udf_readatoffset(struct udf_node *node, int *size, off_t offset, struct buf **bp, uint8_t **data)
  {
  	struct udf_mnt *udfmp;
  	struct file_entry *fentry = NULL;
*************** udf_readatoffset(struct udf_node *node, 
*** 1107,1113 ****
   * block.
   */
  static int
! udf_bmap_internal(struct udf_node *node, uint32_t offset, daddr_t *sector, uint32_t *max_size)
  {
  	struct udf_mnt *udfmp;
  	struct file_entry *fentry;
--- 1108,1114 ----
   * block.
   */
  static int
! udf_bmap_internal(struct udf_node *node, off_t offset, daddr_t *sector, uint32_t *max_size)
  {
  	struct udf_mnt *udfmp;
  	struct file_entry *fentry;
-------------------------------------------------------------------------
|   Feith Systems  |   Voice: 1-215-646-8000  |  Email: john@feith.com  |
|    John Wehle    |     Fax: 1-215-540-5495  |                         |
-------------------------------------------------------------------------

