diff options
Diffstat (limited to 'sys/fs')
-rw-r--r-- | sys/fs/smbfs/smbfs.h | 1 | ||||
-rw-r--r-- | sys/fs/smbfs/smbfs_node.c | 5 | ||||
-rw-r--r-- | sys/fs/smbfs/smbfs_vfsops.c | 15 |
3 files changed, 19 insertions, 2 deletions
diff --git a/sys/fs/smbfs/smbfs.h b/sys/fs/smbfs/smbfs.h index b6f97bec7047..50487916826f 100644 --- a/sys/fs/smbfs/smbfs.h +++ b/sys/fs/smbfs/smbfs.h @@ -89,6 +89,7 @@ struct smbmount { struct lock sm_hashlock; LIST_HEAD(smbnode_hashhead, smbnode) *sm_hash; u_long sm_hashlen; + int sm_didrele; }; #define VFSTOSMBFS(mp) ((struct smbmount *)((mp)->mnt_data)) diff --git a/sys/fs/smbfs/smbfs_node.c b/sys/fs/smbfs/smbfs_node.c index 7f17967d43fe..0feadd0eec12 100644 --- a/sys/fs/smbfs/smbfs_node.c +++ b/sys/fs/smbfs/smbfs_node.c @@ -322,6 +322,11 @@ smbfs_reclaim(ap) if (dvp->v_usecount >= 1) { VI_UNLOCK(dvp); vrele(dvp); + /* + * Indicate that we released something; see comment + * in smbfs_unmount(). + */ + smp->sm_didrele = 1; } else { VI_UNLOCK(dvp); SMBERROR("BUG: negative use count for parent!\n"); diff --git a/sys/fs/smbfs/smbfs_vfsops.c b/sys/fs/smbfs/smbfs_vfsops.c index 8dba8c84a525..db0bc8418a50 100644 --- a/sys/fs/smbfs/smbfs_vfsops.c +++ b/sys/fs/smbfs/smbfs_vfsops.c @@ -243,8 +243,19 @@ smbfs_unmount(struct mount *mp, int mntflags, struct thread *td) flags = 0; if (mntflags & MNT_FORCE) flags |= FORCECLOSE; - /* There is 1 extra root vnode reference from smbfs_mount(). */ - error = vflush(mp, 1, flags); + /* + * Keep trying to flush the vnode list for the mount while + * some are still busy and we are making progress towards + * making them not busy. This is needed because smbfs vnodes + * reference their parent directory but may appear after their + * parent in the list; one pass over the vnode list is not + * sufficient in this case. + */ + do { + smp->sm_didrele = 0; + /* There is 1 extra root vnode reference from smbfs_mount(). */ + error = vflush(mp, 1, flags); + } while (error == EBUSY && smp->sm_didrele != 0); if (error) return error; smb_makescred(&scred, td, td->td_ucred); |