Date: Tue, 11 Jan 2005 06:27:15 -0500 (EST) From: John Wehle <john@feith.com> To: freebsd-fs@freebsd.org Subject: FreeBSD 5.3 Patch to fix udf large files and reading past EOF Message-ID: <200501111127.j0BBRFY9017163@jwlab.FEITH.COM>
next in thread | raw e-mail | index | archive | help
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 | |
-------------------------------------------------------------------------
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200501111127.j0BBRFY9017163>
