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 mount's vnode list; one pass over the
list is not sufficient in this case.

This stops attempts to unmount idle smbfs mounts failing with EBUSY.
This commit is contained in:
Tim J. Robbins 2002-12-13 23:44:00 +00:00
parent 96ac3c4b16
commit 578dcf0c31
3 changed files with 19 additions and 2 deletions

View File

@ -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))

View File

@ -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");

View File

@ -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);