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>