Date: Thu, 19 Mar 2009 14:12:07 +0000 (UTC) From: Andriy Gapon <avg@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org Subject: svn commit: r190052 - in stable/7/sys: . fs/udf Message-ID: <200903191412.n2JEC721064320@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: avg Date: Thu Mar 19 14:12:07 2009 New Revision: 190052 URL: http://svn.freebsd.org/changeset/base/190052 Log: MFC 189082: udf_readatoffset: read through directory vnode, do not read > MAXBSIZE Approved by: jhb (mentor) Modified: stable/7/sys/ (props changed) stable/7/sys/fs/udf/udf.h stable/7/sys/fs/udf/udf_vfsops.c stable/7/sys/fs/udf/udf_vnops.c Modified: stable/7/sys/fs/udf/udf.h ============================================================================== --- stable/7/sys/fs/udf/udf.h Thu Mar 19 14:11:03 2009 (r190051) +++ stable/7/sys/fs/udf/udf.h Thu Mar 19 14:12:07 2009 (r190052) @@ -95,27 +95,12 @@ struct ifid { MALLOC_DECLARE(M_UDFFENTRY); static __inline int -udf_readlblks(struct udf_mnt *udfmp, int sector, int size, struct buf **bp) +udf_readdevblks(struct udf_mnt *udfmp, int sector, int size, struct buf **bp) { return (RDSECTOR(udfmp->im_devvp, sector, (size + udfmp->bmask) & ~udfmp->bmask, bp)); } -static __inline int -udf_readalblks(struct udf_mnt *udfmp, int lsector, int size, struct buf **bp) -{ - daddr_t rablock, lblk; - int rasize; - - lblk = (lsector + udfmp->part_start) << (udfmp->bshift - DEV_BSHIFT); - rablock = (lblk + 1) << udfmp->bshift; - rasize = size; - - return (breadn(udfmp->im_devvp, lblk, - (size + udfmp->bmask) & ~udfmp->bmask, - &rablock, &rasize, 1, NOCRED, bp)); -} - /* * Produce a suitable file number from an ICB. The passed in ICB is expected * to be in little endian (meaning that it hasn't been swapped for big Modified: stable/7/sys/fs/udf/udf_vfsops.c ============================================================================== --- stable/7/sys/fs/udf/udf_vfsops.c Thu Mar 19 14:11:03 2009 (r190051) +++ stable/7/sys/fs/udf/udf_vfsops.c Thu Mar 19 14:12:07 2009 (r190052) @@ -476,7 +476,7 @@ udf_mountfs(struct vnode *devvp, struct */ sector = le32toh(udfmp->root_icb.loc.lb_num) + udfmp->part_start; size = le32toh(udfmp->root_icb.len); - if ((error = udf_readlblks(udfmp, sector, size, &bp)) != 0) { + if ((error = udf_readdevblks(udfmp, sector, size, &bp)) != 0) { printf("Cannot read sector %d\n", sector); goto bail; } @@ -795,7 +795,7 @@ udf_find_partmaps(struct udf_mnt *udfmp, * XXX If reading the first Sparing Table fails, should look * for another table. */ - if ((error = udf_readlblks(udfmp, le32toh(pms->st_loc[0]), + if ((error = udf_readdevblks(udfmp, le32toh(pms->st_loc[0]), le32toh(pms->st_size), &bp)) != 0) { if (bp != NULL) brelse(bp); Modified: stable/7/sys/fs/udf/udf_vnops.c ============================================================================== --- stable/7/sys/fs/udf/udf_vnops.c Thu Mar 19 14:11:03 2009 (r190051) +++ stable/7/sys/fs/udf/udf_vnops.c Thu Mar 19 14:12:07 2009 (r190052) @@ -1282,16 +1282,20 @@ 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; + struct udf_mnt *udfmp = node->udfmp; + struct vnode *vp = node->i_vnode; + struct file_entry *fentry; struct buf *bp1; uint32_t max_size; daddr_t sector; + off_t off; + int adj_size; int error; - udfmp = node->udfmp; - - *bp = NULL; + /* + * This call is made *not* only to detect UDF_INVALID_BMAP case, + * max_size is used as an ad-hoc read-ahead hint for "normal" case. + */ error = udf_bmap_internal(node, offset, §or, &max_size); if (error == UDF_INVALID_BMAP) { /* @@ -1309,9 +1313,18 @@ udf_readatoffset(struct udf_node *node, /* Adjust the size so that it is within range */ if (*size == 0 || *size > max_size) *size = max_size; - *size = min(*size, MAXBSIZE); - if ((error = udf_readlblks(udfmp, sector, *size + (offset & udfmp->bmask), bp))) { + /* + * Because we will read starting at block boundary, we need to adjust + * how much we need to read so that all promised data is in. + * Also, we can't promise to read more than MAXBSIZE bytes starting + * from block boundary, so adjust what we promise too. + */ + off = blkoff(udfmp, offset); + *size = min(*size, MAXBSIZE - off); + adj_size = (*size + off + udfmp->bmask) & ~udfmp->bmask; + *bp = NULL; + if ((error = bread(vp, lblkno(udfmp, offset), adj_size, NOCRED, bp))) { printf("warning: udf_readlblks returned error %d\n", error); /* note: *bp may be non-NULL */ return (error);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200903191412.n2JEC721064320>