From nobody@FreeBSD.org  Sun Oct 30 19:02:11 2005
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 430F416A41F
	for <freebsd-gnats-submit@FreeBSD.org>; Sun, 30 Oct 2005 19:02:11 +0000 (GMT)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [216.136.204.117])
	by mx1.FreeBSD.org (Postfix) with ESMTP id E799A43D5E
	for <freebsd-gnats-submit@FreeBSD.org>; Sun, 30 Oct 2005 19:02:10 +0000 (GMT)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.13.1/8.13.1) with ESMTP id j9UJ2ATd075067
	for <freebsd-gnats-submit@FreeBSD.org>; Sun, 30 Oct 2005 19:02:10 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.13.1/8.13.1/Submit) id j9UJ2Apr075066;
	Sun, 30 Oct 2005 19:02:10 GMT
	(envelope-from nobody)
Message-Id: <200510301902.j9UJ2Apr075066@www.freebsd.org>
Date: Sun, 30 Oct 2005 19:02:10 GMT
From: "Arno J. Klaassen" <arno@heho.snv.jussieu.fr>
To: freebsd-gnats-submit@FreeBSD.org
Subject: getdents syscall fails for devfs on amd64 linuxalator
X-Send-Pr-Version: www-2.3

>Number:         88249
>Category:       kern
>Synopsis:       getdents syscall fails for devfs on amd64 linuxalator
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    dwhite
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sun Oct 30 19:10:18 GMT 2005
>Closed-Date:    Sat Apr 15 06:59:54 GMT 2006
>Last-Modified:  Sat Apr 15 06:59:54 GMT 2006
>Originator:     Arno J. Klaassen
>Release:        RELENG_6
>Organization:
INSERM U472
>Environment:
FreeBSD demo 6.0-RC1 FreeBSD 6.0-RC1 #1: Sat Oct 29 17:04:50 CEST 2005     toor@demo:/files/amd64/obj/files/bsd/src6/sys/D470K  amd64
>Description:
Calling getdents() on /dev from within linux emulation panics with 'kmem_malloc: entry not found or misaligned' :


#0  doadump () at /files/bsd/src6/sys/kern/kern_shutdown.c:234
#1  0xffffffff8030c10b in boot (howto=260)
    at /files/bsd/src6/sys/kern/kern_shutdown.c:399
#2  0xffffffff8030c5de in panic (
    fmt=0xffffffff805cdea8 "kmem_malloc: entry not found or misaligned")
    at /files/bsd/src6/sys/kern/kern_shutdown.c:555
#3  0xffffffff804ed2cf in kmem_malloc (map=0xffffff003e0b0160, size=0,
    flags=258) at /files/bsd/src6/sys/vm/vm_kern.c:382
#4  0xffffffff804e00a2 in page_alloc (zone=0x0, bytes=0,
    pflag=0xffffffffa7aa15e7 "\002\200e?", wait=258)
    at /files/bsd/src6/sys/vm/uma_core.c:957
#5  0xffffffff804e3bbb in uma_large_malloc (size=0, wait=258)
    at /files/bsd/src6/sys/vm/uma_core.c:2711
#6  0xffffffff802fc503 in malloc (size=0, mtp=0xffffffff80706880, flags=258)
    at /files/bsd/src6/sys/kern/kern_malloc.c:327
#7  0xffffffff802fc6fe in realloc (addr=0x0, size=18446744073709549576,
    mtp=0xffffffff80706880, flags=258)
    at /files/bsd/src6/sys/kern/kern_malloc.c:416
#8  0xffffffff80398412 in vfs_read_dirent (ap=0xffffffffa7aa1790,
    dp=0xffffff003d44f898, off=0) at /files/bsd/src6/sys/kern/vfs_subr.c:3877
#9  0xffffffff80290f56 in devfs_readdir (ap=0xffffffffa7aa1790)
    at /files/bsd/src6/sys/fs/devfs/devfs_vnops.c:828
#10 0xffffffff805815ec in VOP_READDIR_APV (vop=0xffffffff806fc480,
    a=0xffffffffa7aa1790) at vnode_if.c:1427
#11 0xffffffff8056f559 in VOP_READDIR (vp=0xffffff0002a2d000,
    uio=0xffffffffa7aa1ab0, cred=0xffffff0034ea7300,
    eofflag=0xffffffffa7aa1854, ncookies=0xffffffffa7aa1834,
    cookies=0xffffffffa7aa1840) at vnode_if.h:747
#12 0xffffffff8056efe6 in getdents_common (td=0xffffff0030440000,
    args=0xffffffffa7aa1b90, is64bit=1)
    at /files/bsd/src6/sys/compat/linux/linux_file.c:328
#13 0xffffffff8056f612 in linux_getdents64 (td=0xffffff0030440000,
    args=0xffffffffa7aa1b90)
    at /files/bsd/src6/sys/compat/linux/linux_file.c:476
#14 0xffffffff80564f54 in ia32_syscall (frame=
      {tf_rdi = 3, tf_rsi = 0, tf_rdx = 4096, tf_rcx = 134533232, tf_r8 = 0, tf_r9 = 0, tf_rax = 220, tf_rbx = 3, tf_rbp = 4294957720, tf_r10 = 0, tf_r11 = 0, tf_r12 = 0, tf_r13 = 0, tf_r14 = 0, tf_r15 = 0, tf_trapno = 12, tf_addr = 134537332, tf_flags = 0, tf_err = 2, tf_rip = 672148537, tf_cs = 27, tf_rflags = 582, tf_rsp = 4294957644, tf_ss = 35})
    at /files/bsd/src6/sys/amd64/ia32/ia32_syscall.c:186
#15 0xffffffff8050c1ad in Xint0x80_syscall () at ia32_exception.S:64

>How-To-Repeat:
open a shell '/compat/linux/bin/bash' and try 'tty' or 'ls /dev/'
>Fix:

>Release-Note:
>Audit-Trail:

From: "Arno J. Klaassen" <arno@heho.snv.jussieu.fr>
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: amd64/88249: getdents syscall fails for devfs on amd64 linuxalator
Date: Thu, 3 Nov 2005 17:17:16 +0100 (MET)

 Work around :
 
 cd /compat/linux/
 mkdir dev
 cd dev
 touch tty
 touch ctty
 

From: "Devon O'Dell" <dodell@offmyserver.com>
To: freebsd-gnats-submit@FreeBSD.org,
        "Arno J. Klaassen" <arno@heho.snv.jussieu.fr>
Cc:  
Subject: Re: amd64/88249: getdents syscall fails for devfs on amd64 linuxalator
Date: Fri, 4 Nov 2005 20:27:40 -0800

 --pf9I7BMVVzbSWLtt
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: inline
 
 I tested this issue and had the same result in FreeBSD 7-CURRENT/amd64.
 The attached patch fixes the issue, but I'm not sure if it is the
 correct solution. I'm sort of unfamiliar with the codepath leading up
 to the fix.
 
 Can someone please look at this?
 
 --Devon
 
 example:
 > /compat/linux/bin/bash
 bash-2.05b$ tty
 /dev/ttyp3
 bash-2.05b$ ls /dev
 acd0     ata         dsp0.1    io      net4     stderr      ttyv1  ttyvd
 acd0t01  audio0.0    dspW0.0   kbd0    network  stdin       ttyv2  ttyve
 acpi     audio0.1    dspW0.1   klog    nfs4     stdout      ttyv3  ttyvf
 ad4      console     dspr0.1   kmem    nfslock  sysmouse    ttyv4  ukbd0
 ad4s1    consolectl  dumpdev   log     null     ttyd0       ttyv5  ums0
 ad4s1a   ctty        fd        mdctl   pci      ttyd0.init  ttyv6  urandom
 ad4s1b   cuad0       fido      mem     ptyp0    ttyd0.lock  ttyv7  usb
 ad4s1c   cuad0.init  fw0       mixer0  ptyp1    ttyp0       ttyv8  usb0
 ad4s1d   cuad0.lock  fw0.0     net     ptyp2    ttyp1       ttyv9  usb1
 ad4s1e   devctl      fwmem0    net1    ptyp3    ttyp2       ttyva  xpt0
 ad4s1f   devstat     fwmem0.0  net2    random   ttyp3       ttyvb  zero
 ad4s2    dsp0.0      geom.ctl  net3    sndstat  ttyv0       ttyvc
 bash-2.05b$ uname -a
 Linux skik.dtrace.internal.sitetronics.com 2.4.2 FreeBSD 7.0-CURRENT #0: Fri Nov  4 20:11:34 PST 2005 i686 i686 i386 GNU/Linux
 
 
 --pf9I7BMVVzbSWLtt
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: attachment; filename="linux_getdents_panic.patch"
 
 --- sys/kern/vfs_subr.c	Mon Oct 31 07:41:25 2005
 +++ sys/kern/vfs_subr.c	Fri Nov  4 20:22:47 2005
 @@ -3873,7 +3873,7 @@
  		}
  		return (error);
  	}
 -	if (ap->a_ncookies == NULL)
 +	if (ap->a_ncookies == NULL || *ap->a_cookies == NULL)
  		return (0);
  	*ap->a_cookies = realloc(*ap->a_cookies,
  	    (*ap->a_ncookies + 1) * sizeof(u_long), M_TEMP, M_WAITOK | M_ZERO);
 
 --pf9I7BMVVzbSWLtt--

From: "Devon O'Dell" <dodell@offmyserver.com>
To: freebsd-gnats-submit@FreeBSD.org,
        "Arno J. Klaassen" <arno@heho.snv.jussieu.fr>
Cc: scottl@FreeBSD.org
Subject: Re: amd64/88249: getdents syscall fails for devfs on amd64 linuxalator
Date: Mon, 7 Nov 2005 11:53:38 -0800

 --vtzGhvizbBRQ85DL
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: inline
 
 After much discussion on this issue with scottl@, I've come up with the
 following `quickfix' patch. While the previous patch does solve the
 issue, it does so in the wrong manner: vfs_subr.c:vfs_read_dirent() is
 not at fault here. The filesystem is expected to provide storage
 space for ap->a_cookies when ap->a_ncookies is non-NULL.
 
 In the case of the linuxulator, the linux_file.c:getdents_common() code
 requires the use of cookies. It is the filesystem's job to ensure that,
 when cookies are provided, space is allocated, as was previously
 mentioned. devfs.c:devfs_readdir() does not do this, and
 vfs_subr.c:vfs_read_dirent() expects this behavior.
 
 The long discussion ended up implying several things:
 
 a) There are bad things going on in each layer here:
    i)   linux_file.c:getdents_common has issues
    ii)  devfs.c:devfs_readdir() will need to support cookies at some 
         point
    iii) vfs_subr.c:vfs_read_dirent() should be used as a generic 
         procedure with multiple filesystems instead of having them all
         use various separate methods of allocating and determining
         cookie storage requirements, which results in a good bit of
         duplicated code.
 
 b) The issue isn't limited to amd64, so the PR should be migrated to
    kern/88249
 
 c) The issue is somewhat severe, so a fix that doesn't address the
    architectural problems (outlined in point a) should be committed
    while these architectural issues are further discussed and
    developed.
 
 d) The issue probably isn't limited to linuxulator, but to any
    filesystem that uses cookies and exports devfs. Thus, panics (or
    hangs) will probably occur for devfs being exported over AFS or NFS.
 
 The attached patch does two things:
 
 a) If we are provided with cookie information in devfs, we currently
    do not support this. This means we cannot export devfs over network
    mounts, which I don't view as a problem (but would be a cool
    feature).
 
 b) Do sanity checking in vfs_subr.c:vfs_read_dirent() to panic
    explicitly on the condition of ap->a_cookies being NULL with a
    non-NULL ap->a_ncookies. Since the API is well-defined enough,
    consumers should know to never subject the code to this condition.
 
 I'm currently working on the architectural issues outlined above and
 have been discussing them with scottl@ (extensively) and phk@ (briefly).
 
 Kind regards,
 
 Devon H. O'Dell
 
 --vtzGhvizbBRQ85DL
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: attachment; filename="devfs_cookie_quickfix.patch"
 
 diff -ur /sys/fs/devfs/devfs_vnops.c sys/fs/devfs/devfs_vnops.c
 --- /sys/fs/devfs/devfs_vnops.c	Mon Nov  7 11:47:53 2005
 +++ sys/fs/devfs/devfs_vnops.c	Mon Nov  7 10:53:09 2005
 @@ -797,6 +797,7 @@
  	struct devfs_dirent *de;
  	struct devfs_mount *dmp;
  	off_t off, oldoff;
 +	int *tmp_ncookies = NULL;
  
  	if (ap->a_vp->v_type != VDIR)
  		return (ENOTDIR);
 @@ -805,6 +806,22 @@
  	if (uio->uio_offset < 0)
  		return (EINVAL);
  
 +	/*
 +	 * XXX: This is a temporary hack to get around this filesystem not
 +	 * supporting cookies. We store the location of the ncookies pointer
 +	 * in a temporary variable before calling vfs_subr.c:vfs_read_dirent()
 +	 * and set the number of cookies to 0. We then set the pointer to
 +	 * NULL so that vfs_read_dirent doesn't try to call realloc() on 
 +	 * ap->a_cookies. Later in this function, we restore the ap->a_ncookies
 +	 * pointer to its original location before returning to the caller.
 +	 *
 +	 */
 +	if (ap->a_ncookies != NULL) {
 +		tmp_ncookies = ap->a_ncookies;
 +		*ap->a_ncookies = 0;
 +		ap->a_ncookies = NULL;
 +	}
 +
  	dmp = VFSTODEVFS(ap->a_vp->v_mount);
  	sx_xlock(&dmp->dm_lock);
  	devfs_populate(dmp);
 @@ -833,6 +850,14 @@
  	}
  	sx_xunlock(&dmp->dm_lock);
  	uio->uio_offset = off;
 +
 +	/*
 +	 * Restore ap->a_ncookies if it wasn't originally NULL in the first
 +	 * place.
 +	 */
 +	if (tmp_ncookies != NULL)
 +		ap->a_ncookies = tmp_ncookies;
 +
  	return (error);
  }
  
 diff -ur /sys/kern/vfs_subr.c sys/kern/vfs_subr.c
 --- /sys/kern/vfs_subr.c	Mon Nov  7 11:47:53 2005
 +++ sys/kern/vfs_subr.c	Mon Nov  7 11:47:33 2005
 @@ -3875,6 +3875,10 @@
  	}
  	if (ap->a_ncookies == NULL)
  		return (0);
 +
 +	KASSERT(ap->a_cookies,
 +	    ("NULL ap->a_cookies value with non-NULL ap->a_ncookies!"));
 +
  	*ap->a_cookies = realloc(*ap->a_cookies,
  	    (*ap->a_ncookies + 1) * sizeof(u_long), M_TEMP, M_WAITOK | M_ZERO);
  	(*ap->a_cookies)[*ap->a_ncookies] = off;
 
 --vtzGhvizbBRQ85DL--
Responsible-Changed-From-To: freebsd-amd64->dwhite 
Responsible-Changed-By: dwhite 
Responsible-Changed-When: Wed Nov 9 20:46:09 GMT 2005 
Responsible-Changed-Why:  
Take ownership and transfer to kern since this is in MI code 

http://www.freebsd.org/cgi/query-pr.cgi?pr=88249 
State-Changed-From-To: open->patched 
State-Changed-By: dwhite 
State-Changed-When: Wed Nov 9 22:04:06 GMT 2005 
State-Changed-Why:  
Fix applied to HEAD with 3 day MFC. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=88249 
State-Changed-From-To: patched->closed 
State-Changed-By: linimon 
State-Changed-When: Sat Apr 15 06:55:36 UTC 2006 
State-Changed-Why:  
Patch applied to RELENG_6 on Nov 12 21:21:27 2005.  RELENG_5 is not 
affected by this bug. 

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