svn commit: r190052 - in stable/7/sys: . fs/udf

Andriy Gapon avg at FreeBSD.org
Thu Mar 19 07:12:09 PDT 2009


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, &sector, &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);


More information about the svn-src-stable-7 mailing list