aboutsummaryrefslogtreecommitdiff
path: root/sys/fs
diff options
context:
space:
mode:
authorTim J. Robbins <tjr@FreeBSD.org>2002-12-13 23:44:00 +0000
committerTim J. Robbins <tjr@FreeBSD.org>2002-12-13 23:44:00 +0000
commit578dcf0c31d1fedc367d72d5e1ae03b31ba6fe2e (patch)
tree1a77f7c23d2fdcb275bbf718a62e17855b8f3b9e /sys/fs
parent96ac3c4b1688d96289c56231ce34812ae0afb72a (diff)
downloadsrc-578dcf0c31d1fedc367d72d5e1ae03b31ba6fe2e.tar.gz
src-578dcf0c31d1fedc367d72d5e1ae03b31ba6fe2e.zip
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.
Notes
Notes: svn path=/head/; revision=107842
Diffstat (limited to 'sys/fs')
-rw-r--r--sys/fs/smbfs/smbfs.h1
-rw-r--r--sys/fs/smbfs/smbfs_node.c5
-rw-r--r--sys/fs/smbfs/smbfs_vfsops.c15
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);