kern/93905: [possible patch] fdescfs vop_lookup and parent vnode locking

Kostik Belousov kostikbel at gmail.com
Mon Feb 27 08:10:13 PST 2006


>Number:         93905
>Category:       kern
>Synopsis:       [possible patch] fdescfs vop_lookup and parent vnode locking
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Feb 27 16:10:11 GMT 2006
>Closed-Date:
>Last-Modified:
>Originator:     Kostik Belousov
>Release:        6-STABLE
>Organization:
-
>Environment:
FreeBSD deviant.kiev.zoral.com.ua 6.1-PRERELEASE FreeBSD 6.1-PRERELEASE #3: Mon Feb 20 13:48:25 EET 2006     root at deviant.kiev.zoral.com.ua:/usr/obj/usr/src/sys/DEVIANT  i386

>Description:
> Is it correct that filesystem-specific vop_lookup is expected to              
> take the directory vnode (dvp) locked, and shall return with dvp locked ?     
> vnode_if.src specifies this behaviour as dependent on the flags in the cnp    
> arguments. My reading of the sources suggest that the statement in the first  
> sentence is true, and note from vnode_if.src applies to                       
> sys/kern/vfs_lookup.c:lookup() procedure itself.                              
>                                                                               
> If it is true, the fdescfs break this rule, dropping the lock on the dvp. See 
> sys/fs/fdescfs/fdesc_vnops.c, line 196. As result, having fdescfs mounted,    
> most accesses to files on it cause warning from the lockmgr,
> lockmgr: thread XXX unlocking unheld lock

> I did testing with the attached patch
> and do not see the warnings anymore. The system does not deadlock.
>How-To-Repeat:
mount the fdescfs on /dev/fd and do find /dev/fd on the kernel compiled
with INVARIANTS
>Fix:
Index: sys/fs/fdescfs/fdesc_vnops.c                                           
===================================================================           
RCS file: /usr/local/arch/ncvs/src/sys/fs/fdescfs/fdesc_vnops.c,v             
retrieving revision 1.100                                                     
diff -u -r1.100 fdesc_vnops.c                                                 
--- sys/fs/fdescfs/fdesc_vnops.c      10 Aug 2005 07:08:14 -0000      1.100   
+++ sys/fs/fdescfs/fdesc_vnops.c      3 Feb 2006 14:35:11 -0000               
@@ -193,11 +193,9 @@                                                          
              goto bad;                                                       
      }                                                                       
                                                                              
-     VOP_UNLOCK(dvp, 0, td);                                                 
      if (cnp->cn_namelen == 1 && *pname == '.') {                            
              *vpp = dvp;                                                     
              VREF(dvp);                                                      
-             vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, td);                      
              return (0);                                                     
      }                                                                       
                                                                              
@@ -228,12 +226,12 @@                                                         
      if (error)                                                              
              goto bad;                                                       
      VTOFDESC(fvp)->fd_fd = fd;                                              
-     vn_lock(fvp, LK_EXCLUSIVE | LK_RETRY, td);                              
+     if (fvp != dvp)                                                         
+             vn_lock(fvp, LK_EXCLUSIVE | LK_RETRY, td);                      
      *vpp = fvp;                                                             
      return (0);                                                             
                                                                              
 bad:                                                                         
-     vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, td);                              
      *vpp = NULL;                                                            
      return (error);                                                         
 }                                                                            
>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list