On Tue, Dec 20, 2011 at 01:33:37AM +0100, Mike Belopuhov wrote:
> this is an improved diff that addresses the problem with forced
> unmount of the ntfs filesystem in situations like the one described
> here:  http://marc.info/?l=openbsd-bugs&m=132257956328474&w=2
> 
> ntfs keeps a bunch of vnodes opened and marked as VSYSTEM including
> the mount point: it's usecount is 1 and it is incremented if you do
> "cd /mnt".  when you pull out a usb stick and ntfs_unmount is called
> it flushes all but system vnodes and then checks if system vnodes'
> usecount is not more than 1 (somebody is using a vnode).  in case
> this is not true (and it's not true for the mount point since shell
> process is holding that vnode) it returns EBUSY.
> 
> the only thing is ntfs is a read-only filesystem so there's no
> real reason to not to succeed and "forceclose" all the vnodes.
> 
> the following change makes it respect the MNT_FORCE flag and proceed
> even if there's someone holding a vnode.  also it silences the
> ntfs_reclaim (like ufs_reclaim is silenced by the prtactive).
> 
> it might not be a perfect diff, but it improves the situation by
> a vast margin and still reports fs as being busy when unmount is
> not forced (e.g. you run umount(1)).
> 
> comments/ok?

I don't use NTFS, but this makes sense to me. ok krw@.

.... Ken

> 
> Index: ntfs/ntfs_vfsops.c
> ===================================================================
> RCS file: /cvs/src/sys/ntfs/ntfs_vfsops.c,v
> retrieving revision 1.27
> diff -u -p -r1.27 ntfs_vfsops.c
> --- ntfs/ntfs_vfsops.c        4 Jul 2011 20:35:35 -0000       1.27
> +++ ntfs/ntfs_vfsops.c        20 Dec 2011 00:12:06 -0000
> @@ -547,10 +547,12 @@ ntfs_unmount( 
>               return (error);
>       }
>  
> -     /* Check if only system vnodes are rest */
> -     for(i=0;i<NTFS_SYSNODESNUM;i++)
> -              if((ntmp->ntm_sysvn[i]) && 
> -                 (ntmp->ntm_sysvn[i]->v_usecount > 1)) return (EBUSY);
> +     /* Check if system vnodes are still referenced */
> +     for(i=0;i<NTFS_SYSNODESNUM;i++) {
> +             if(((mntflags & MNT_FORCE) == 0) && (ntmp->ntm_sysvn[i] &&
> +                 ntmp->ntm_sysvn[i]->v_usecount > 1))
> +                     return (EBUSY);
> +     }
>  
>       /* Dereference all system vnodes */
>       for(i=0;i<NTFS_SYSNODESNUM;i++)
> Index: ntfs/ntfs_vnops.c
> ===================================================================
> RCS file: /cvs/src/sys/ntfs/ntfs_vnops.c,v
> retrieving revision 1.24
> diff -u -p -r1.24 ntfs_vnops.c
> --- ntfs/ntfs_vnops.c 4 Jul 2011 20:35:35 -0000       1.24
> +++ ntfs/ntfs_vnops.c 20 Dec 2011 00:12:06 -0000
> @@ -72,7 +72,7 @@ static int  ntfs_bmap(void *);
>  static int   ntfs_fsync(void *);
>  static int   ntfs_pathconf(void *);
>  
> -int  ntfs_prtactive = 1;     /* 1 => print out reclaim of active vnodes */
> +int  ntfs_prtactive = 0;     /* 1 => print out reclaim of active vnodes */
>  
>  /*
>   * This is a noop, simply returning what one has been given.

Reply via email to