From nobody@FreeBSD.org  Sun Nov 23 13:36:10 2008
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 5C4C6106567E
	for <freebsd-gnats-submit@FreeBSD.org>; Sun, 23 Nov 2008 13:36:10 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21])
	by mx1.freebsd.org (Postfix) with ESMTP id 51EFA8FC1F
	for <freebsd-gnats-submit@FreeBSD.org>; Sun, 23 Nov 2008 13:36:10 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.14.3/8.14.3) with ESMTP id mANDaAh8056765
	for <freebsd-gnats-submit@FreeBSD.org>; Sun, 23 Nov 2008 13:36:10 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.14.3/8.14.3/Submit) id mANDaANo056764;
	Sun, 23 Nov 2008 13:36:10 GMT
	(envelope-from nobody)
Message-Id: <200811231336.mANDaANo056764@www.freebsd.org>
Date: Sun, 23 Nov 2008 13:36:10 GMT
From: Paul <onemda@gmail.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: udf panic: getblk: size(67584) > MAXBSIZE(65536)
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         129084
>Category:       kern
>Synopsis:       [udf] [panic] [lor] udf panic: getblk: size(67584) > MAXBSIZE(65536)
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-fs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sun Nov 23 13:40:05 UTC 2008
>Closed-Date:    Mon Mar 23 13:34:41 UTC 2009
>Last-Modified:  Mon Mar 23 13:34:41 UTC 2009
>Originator:     Paul
>Release:        FreeBSD 8-0 CURRENT
>Organization:
>Environment:
FreeBSD dhcppc1 8.0-CURRENT FreeBSD 8.0-CURRENT #5: Sat Nov 22 15:17:29 CET 2008     root@:/usr/src/obj/usr/src/sys/KERNEL  i386
>Description:
Head of textdump:

db:0:kdb.enter.panic>  run lockinfo
db:1:lockinfo> show locks
db:1:locks>  show alllocks
Process 864 (python) thread 0xc4866240 (100085)
db:1:alllocks>  show lockedvnods
Locked vnodes
db:0:kdb.enter.panic>  show pcpu
cpuid        = 1
curthread    = 0xc4866240: pid 864 "initial thread"
curpcb       = 0xc3b61d90
fpcurthread  = none
idlethread   = 0xc3d2ad80: pid 10 "idle: cpu1"
APIC ID      = 1
currentldt   = 0x50
spin locks held:
db:0:kdb.enter.panic>  bt
Tracing pid 864 tid 100085 td 0xc4866240
kdb_enter(c069b2ff,c069b2ff,c06a5f73,c3b61968,1,...) at kdb_enter+0x3a
panic(c06a5f73,10800,10000,c06869a6,c3b619d0,...) at panic+0x131
getblk(c4f08648,424,0,10800,0,...) at getblk+0x2d
breadn(c4f08648,424,0,10800,0,...) at breadn+0x44
bread(c4f08648,424,0,10800,0,...) at bread+0x4c
udf_readatoffset(1a18,0,c5183038,c518303c,0,...) at udf_readatoffset+0xbb
udf_getfid(c4f02200,c06a034f,527,c06a87d5,c3b61c24,...) at udf_getfid+0x1ca
udf_readdir(c3b61c24,0,c4f05a78,0,c3b61c5c,...) at udf_readdir+0xdc
VOP_READDIR_APV(c517f280,c3b61c24,c06a87d5,ff3,1a18,...) at VOP_READDIR_APV+0xa0
kern_getdirentries(c4866240,46,2844c000,1000,c3b61c78,...) at kern_getdirentries+0x1bd
getdirentries(c4866240,c3b61cf8,10,c06a1dd7,c06cfe00,...) at getdirentries+0x31
syscall(c3b61d38) at syscall+0x261
Xint0x80_syscall() at Xint0x80_syscall+0x20
--- syscall (196, FreeBSD ELF32, getdirentries), eip = 0x28251e4b, esp = 0xbfbfdcbc, ebp = 0xbfbfdce8 ---

End of dmesg:
lock order reversal:
 1st 0xc4f06488 udf (udf) @ /usr/src/sys/kern/vfs_subr.c:2053
 2nd 0xd7d9d490 bufwait (bufwait) @ /usr/src/sys/kern/vfs_bio.c:2443
 3rd 0xc4f057ac udf (udf) @ /usr/src/sys/modules/udf/../../fs/udf/udf_vfsops.c:616
KDB: stack backtrace:
db_trace_self_wrapper(c069e457,c3b61824,c04e7a2f,4,c0699b7b,...) at db_trace_self_wrapper+0x26
kdb_backtrace(4,c0699b7b,c3cb7538,c3cb9d08,c3b61880,...) at kdb_backtrace+0x29
_witness_debugger(c06a1124,c4f057ac,c517e9dc,c3cb9d08,c517e956,...) at _witness_debugger+0x1e
witness_checkorder(c4f057ac,9,c517e956,268,0,...) at witness_checkorder+0x811
__lockmgr_args(c4f057ac,80000,0,0,0,...) at __lockmgr_args+0x762
udf_vget(c4990280,c1,80000,c3b619bc,0,...) at udf_vget+0x137
udf_lookup(c3b619fc,c4f06430,c3b61bb4,c4f06430,c3b61a1c,...) at udf_lookup+0x26c
VOP_CACHEDLOOKUP_APV(c517f280,c3b619fc,c3b61bb4,c3b61ba0,c06fa3e0,...) at VOP_CACHEDLOOKUP_APV+0xa0
vfs_cache_lookup(c3b61a7c,c3b61a7c,0,200000,c4f06430,...) at vfs_cache_lookup+0xc3
VOP_LOOKUP_APV(c517f280,c3b61a7c,c06a6e55,2cc,c3b61ba0,...) at VOP_LOOKUP_APV+0xaa
lookup(c3b61b88,0,c06a6e55,ec,c41fe42c,...) at lookup+0x507
namei(c3b61b88,c04e780b,c06b6dc4,c06a0b67,3,...) at namei+0x45b
kern_statat(c4866240,0,ffffff9c,28307450,0,...) at kern_statat+0x66
kern_stat(c4866240,28307450,0,c3b61c1c,44f,...) at kern_stat+0x36
stat(c4866240,c3b61cf8,8,c06a259b,c06cfd40,...) at stat+0x2b
syscall(c3b61d38) at syscall+0x261
Xint0x80_syscall() at Xint0x80_syscall+0x20
--- syscall (188, FreeBSD ELF32, stat), eip = 0x2825c34b, esp = 0xbfbfe0bc, ebp = 0xbfbfe158 ---
uiomove returned -1
uiomove returned -1
uiomove returned -1
uiomove returned -1
uiomove returned -1
panic: getblk: size(67584) > MAXBSIZE(65536)

cpuid = 1
KDB: enter: panic
exclusive lockmgr udf (udf) r = 0 (0xc4f05ad0) locked @ /usr/src/sys/kern/vfs_syscalls.c:4083
exclusive sleep mutex Giant (Giant) r = 0 (0xc0710cf0) locked @ /usr/src/sys/kern/vfs_syscalls.c:4068
exclusive lockmgr udf (udf) r = 0 (0xc4f05ad0) locked @ /usr/src/sys/kern/vfs_syscalls.c:4083
exclusive sleep mutex Giant (Giant) r = 0 (0xc0710cf0) locked @ /usr/src/sys/kern/vfs_syscalls.c:4068

0xc4f05a78: tag udf, type VDIR
    usecount 1, writecount 0, refcount 1 mountedhere 0
    flags ()
    v_object 0xc50b907c ref 0 pages 0
     lock type udf: EXCL by thread 0xc4866240 (pid 864)

>How-To-Repeat:
# create 3GB udf file system with multiple files and directories with mkisofs.
# mdconfig -f /path/to/udf.iso
# mount_udf /dev/md0 /mnt

Try to read files and dirs on udf fs with threaded application like cplay(python script) : /usr/ports/audio/cplay

# cplay /mnt/*
>Fix:


>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->freebsd-fs 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Sun Nov 23 18:01:23 UTC 2008 
Responsible-Changed-Why:  
Over to maintainer(s). 

http://www.freebsd.org/cgi/query-pr.cgi?pr=129084 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/129084: commit references a PR
Date: Thu, 26 Feb 2009 18:58:59 +0000 (UTC)

 Author: avg
 Date: Thu Feb 26 18:58:41 2009
 New Revision: 189082
 URL: http://svn.freebsd.org/changeset/base/189082
 
 Log:
   udf_readatoffset: read through directory vnode, do not read > MAXBSIZE
   
   Currently bread()-ing through device vnode with
   (1) VMIO enabled,
   (2) bo_bsize != DEV_BSIZE
   (3) more than 1 block
   results in data being incorrectly cached.
   So instead a more common approach of using a vnode belonging to fs is now
   employed.
   Also, prevent attempt to bread more than MAXBSIZE bytes because of
   adjustments made to account for offset that doesn't start on block
   boundary.
   Add expanded comments to explain the calculations.
   Also drop unused inline function while here.
   
   PR: kern/120967
   PR: kern/129084
   
   Reviewed by: scottl, kib
   Approved by: jhb (mentor)
 
 Modified:
   head/sys/fs/udf/udf.h
   head/sys/fs/udf/udf_vfsops.c
   head/sys/fs/udf/udf_vnops.c
 
 Modified: head/sys/fs/udf/udf.h
 ==============================================================================
 --- head/sys/fs/udf/udf.h	Thu Feb 26 18:55:55 2009	(r189081)
 +++ head/sys/fs/udf/udf.h	Thu Feb 26 18:58:41 2009	(r189082)
 @@ -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: head/sys/fs/udf/udf_vfsops.c
 ==============================================================================
 --- head/sys/fs/udf/udf_vfsops.c	Thu Feb 26 18:55:55 2009	(r189081)
 +++ head/sys/fs/udf/udf_vfsops.c	Thu Feb 26 18:58:41 2009	(r189082)
 @@ -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;
  	}
 @@ -794,7 +794,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: head/sys/fs/udf/udf_vnops.c
 ==============================================================================
 --- head/sys/fs/udf/udf_vnops.c	Thu Feb 26 18:55:55 2009	(r189081)
 +++ head/sys/fs/udf/udf_vnops.c	Thu Feb 26 18:58:41 2009	(r189082)
 @@ -1296,16 +1296,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) {
  		/*
 @@ -1323,9 +1327,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);
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: open->closed 
State-Changed-By: gavin 
State-Changed-When: Mon Mar 23 13:34:07 UTC 2009 
State-Changed-Why:  
This has been fixed and merged to 7.x (confirmed by avg on IRC) 

http://www.freebsd.org/cgi/query-pr.cgi?pr=129084 
>Unformatted:
