Date: Wed, 2 Jul 1997 04:29:18 -0700 (PDT) From: yamagata@nwgpc.kek.jp To: freebsd-gnats-submit@FreeBSD.ORG Subject: kern/4011: GNU grep on CDROM causes panic Message-ID: <199707021129.EAA29117@hub.freebsd.org> Resent-Message-ID: <199707021130.EAA29169@hub.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 4011
>Category: kern
>Synopsis: GNU grep on CDROM causes panic
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: freebsd-bugs
>State: open
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Wed Jul 2 04:30:00 PDT 1997
>Last-Modified:
>Originator: yamagata
>Organization:
KEK , Tsukuba , Japan
>Release: 2.2.1-RELEASE
>Environment:
FreeBSD kekhw2.kek.jp 2.2.1-RELEASE FreeBSD 2.2.1-RELEASE #1: Tue Jun 17 12:04:24 JST 1997
>Description:
When GNU grep (maked with option -DHAVE_WORKING_MMAP=1) access files on CDROM,
system will panic, saying "locking against myself".
MSDOS FS seems to have same problem.
>How-To-Repeat:
1) make GNU grep by typing just only "./configure ; make". configure will set the option "-DHAVE_WORKING_MMAP=1".
2) apply grep to files on CDROM, "./grep xxx /cdrom/*"
3) system will panic
if set the option HAVE_WORKING_MMAP 0, panic will not happen.
>Fix:
apply this patch, but this is for FreeBSD-2.1.5.
this patch is contributed by Okamura Yoshihito <okamura@bardot.rim.or.jp>
*** cd9660_node.c.orig Wed Jun 12 12:41:35 1996
--- cd9660_node.c Sun Nov 17 17:36:34 1996
*************** iso_ilock(ip)
*** 420,428 ****
{
while (ip->i_flag & ILOCKED) {
ip->i_flag |= IWANT;
- if (ip->i_spare0 == curproc->p_pid)
- panic("locking against myself");
ip->i_spare1 = curproc->p_pid;
(void) tsleep((caddr_t)ip, PINOD, "isoilk", 0);
}
--- 420,435 ----
{
while (ip->i_flag & ILOCKED) {
+ if (ip->i_spare0 == curproc->p_pid) {
+ if((ip->i_flag & IRECURSE) == 0)
+ panic("locking against myself");
+ else {
+ ++ip->i_lockcount;
+ return(0);
+ }
+
+ }
ip->i_flag |= IWANT;
ip->i_spare1 = curproc->p_pid;
(void) tsleep((caddr_t)ip, PINOD, "isoilk", 0);
}
*************** iso_iunlock(ip)
*** 440,449 ****
register struct iso_node *ip;
{
if ((ip->i_flag & ILOCKED) == 0)
vprint("iso_iunlock: unlocked inode", ITOV(ip));
ip->i_spare0 = 0;
! ip->i_flag &= ~ILOCKED;
if (ip->i_flag&IWANT) {
ip->i_flag &= ~IWANT;
wakeup((caddr_t)ip);
--- 447,460 ----
register struct iso_node *ip;
{
+ if(ip->i_lockcount > 0) {
+ --ip->i_lockcount;
+ return(0);
+ }
if ((ip->i_flag & ILOCKED) == 0)
vprint("iso_iunlock: unlocked inode", ITOV(ip));
ip->i_spare0 = 0;
! ip->i_flag &= ~(ILOCKED|IRECURSE);
if (ip->i_flag&IWANT) {
ip->i_flag &= ~IWANT;
wakeup((caddr_t)ip);
*** cd9660_node.h.orig Fri Mar 17 03:12:16 1995
--- cd9660_node.h Sun Nov 17 17:11:29 1996
*************** struct iso_node {
*** 95,100 ****
--- 95,101 ----
long iso_start; /* actual start of data of file (may be different */
/* from iso_extent, if file has extended attributes) */
ISO_RRIP_INODE inode;
+ int i_lockcount; /* Process lock count (recursion) */
};
#define i_forw i_chain[0]
*************** struct iso_node {
*** 104,109 ****
--- 105,111 ----
#define ILOCKED 0x0001 /* inode is locked */
#define IWANT 0x0002 /* some process waiting on lock */
#define IACC 0x0020 /* inode access time to be updated */
+ #define IRECURSE 0x0400 /* Recursion expected */
#define VTOI(vp) ((struct iso_node *)(vp)->v_data)
#define ITOV(ip) ((ip)->i_vnode)
*** cd9660_vnops.c.org Wed Jun 26 03:30:21 1996
--- cd9660_vnops.c Sun Nov 17 17:14:38 1996
*************** cd9660_read(ap)
*** 331,337 ****
--- 331,341 ----
return (error);
}
+ if (uio->uio_segflg != UIO_NOCOPY)
+ ip->i_flag |= IRECURSE;
error = uiomove(bp->b_un.b_addr + on, (int)n, uio);
+ if (uio->uio_segflg != UIO_NOCOPY)
+ ip->i_flag &= ~IRECURSE;
brelse(bp);
} while (error == 0 && uio->uio_resid > 0 && n != 0);
return (error);
*** denode.h.org Tue May 30 17:07:32 1995
--- denode.h Sun Nov 17 17:48:48 1996
*************** struct denode {
*** 159,164 ****
--- 159,165 ----
u_short de_StartCluster; /* starting cluster of file */
u_long de_FileSize; /* size of file in bytes */
struct fatcache de_fc[FC_SIZE]; /* fat cache */
+ int de_lockcount; /* Process lock count (recursion) */
};
/*
*************** struct denode {
*** 169,174 ****
--- 170,176 ----
#define DE_UPDATE 0x0004 /* modification time update request */
#define DE_MODIFIED 0x0080 /* denode has been modified, but DE_UPDATE
* isn't set */
+ #define DE_RECURSE 0x0400 /* Recursion expected */
/*
* Transfer directory entries between internal and external form.
*** msdosfs_vnops.c.org Wed Jul 3 03:40:22 1996
--- msdosfs_vnops.c Sun Nov 17 17:56:08 1996
*************** msdosfs_read(ap)
*** 535,541 ****
--- 535,545 ----
brelse(bp);
return error;
}
+ if (uio->uio_segflg != UIO_NOCOPY)
+ dep->de_flag |= DE_RECURSE;
error = uiomove(bp->b_data + on, (int) n, uio);
+ if (uio->uio_segflg != UIO_NOCOPY)
+ dep->de_flag &= ~DE_RECURSE;
/*
* If we have read everything from this block or have read
* to end of file then we are done with this block. Mark
*************** msdosfs_write(ap)
*** 728,734 ****
--- 732,742 ----
/*
* Copy the data from user space into the buf header.
*/
+ if (uio->uio_segflg != UIO_NOCOPY)
+ dep->de_flag |= DE_RECURSE;
error = uiomove(bp->b_data + croffset, n, uio);
+ if (uio->uio_segflg != UIO_NOCOPY)
+ dep->de_flag &= ~DE_RECURSE;
/*
* If they want this synchronous then write it and wait for
*************** msdosfs_lock(ap)
*** 1757,1765 ****
struct denode *dep = VTODE(ap->a_vp);
while (dep->de_flag & DE_LOCKED) {
dep->de_flag |= DE_WANTED;
- if (dep->de_lockholder == curproc->p_pid)
- panic("msdosfs_lock: locking against myself");
dep->de_lockwaiter = curproc->p_pid;
(void) tsleep((caddr_t) dep, PINOD, "msdlck", 0);
}
--- 1765,1779 ----
struct denode *dep = VTODE(ap->a_vp);
while (dep->de_flag & DE_LOCKED) {
+ if (dep->de_lockholder == curproc->p_pid) {
+ if ((dep->de_flag & DE_RECURSE) == 0)
+ panic("msdosfs_lock: locking against myself");
+ else {
+ ++dep->de_lockcount;
+ return 0;
+ }
+ }
dep->de_flag |= DE_WANTED;
dep->de_lockwaiter = curproc->p_pid;
(void) tsleep((caddr_t) dep, PINOD, "msdlck", 0);
}
*************** msdosfs_unlock(ap)
*** 1777,1786 ****
{
struct denode *dep = VTODE(ap->a_vp);
if (!(dep->de_flag & DE_LOCKED))
panic("msdosfs_unlock: denode not locked");
dep->de_lockholder = 0;
! dep->de_flag &= ~DE_LOCKED;
if (dep->de_flag & DE_WANTED) {
dep->de_flag &= ~DE_WANTED;
wakeup((caddr_t) dep);
--- 1791,1804 ----
{
struct denode *dep = VTODE(ap->a_vp);
+ if(dep->de_lockcount > 0) {
+ --dep->de_lockcount;
+ return 0;
+ }
if (!(dep->de_flag & DE_LOCKED))
panic("msdosfs_unlock: denode not locked");
dep->de_lockholder = 0;
! dep->de_flag &= ~(DE_LOCKED|DE_RECURSE);
if (dep->de_flag & DE_WANTED) {
dep->de_flag &= ~DE_WANTED;
wakeup((caddr_t) dep);
>Audit-Trail:
>Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199707021129.EAA29117>
