diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/fs/nfsclient/nfs_clnfsiod.c | 8 | ||||
-rw-r--r-- | sys/fs/nfsclient/nfs_clvfsops.c | 13 | ||||
-rw-r--r-- | sys/nfsclient/nfs_nfsiod.c | 8 | ||||
-rw-r--r-- | sys/nfsclient/nfs_vfsops.c | 10 |
4 files changed, 37 insertions, 2 deletions
diff --git a/sys/fs/nfsclient/nfs_clnfsiod.c b/sys/fs/nfsclient/nfs_clnfsiod.c index 0f1810f..25ff694 100644 --- a/sys/fs/nfsclient/nfs_clnfsiod.c +++ b/sys/fs/nfsclient/nfs_clnfsiod.c @@ -304,6 +304,14 @@ nfssvc_iod(void *instance) } mtx_lock(&ncl_iod_mutex); /* + * Make sure the nmp hasn't been dismounted as soon as + * ncl_doio() completes for the last buffer. + */ + nmp = ncl_iodmount[myiod]; + if (nmp == NULL) + break; + + /* * If there are more than one iod on this mount, then defect * so that the iods can be shared out fairly between the mounts */ diff --git a/sys/fs/nfsclient/nfs_clvfsops.c b/sys/fs/nfsclient/nfs_clvfsops.c index 281ce44..b717210 100644 --- a/sys/fs/nfsclient/nfs_clvfsops.c +++ b/sys/fs/nfsclient/nfs_clvfsops.c @@ -81,6 +81,9 @@ extern struct timeval nfsboottime; extern struct nfsstats newnfsstats; extern int nfsrv_useacl; extern int nfscl_debuglevel; +extern enum nfsiod_state ncl_iodwant[NFS_MAXASYNCDAEMON]; +extern struct nfsmount *ncl_iodmount[NFS_MAXASYNCDAEMON]; +extern struct mtx ncl_iod_mutex; NFSCLSTATEMUTEX; MALLOC_DEFINE(M_NEWNFSREQ, "newnfsclient_req", "New NFS request header"); @@ -1472,7 +1475,7 @@ nfs_unmount(struct mount *mp, int mntflags) { struct thread *td; struct nfsmount *nmp; - int error, flags = 0, trycnt = 0; + int error, flags = 0, i, trycnt = 0; struct nfsclds *dsp, *tdsp; td = curthread; @@ -1508,6 +1511,14 @@ nfs_unmount(struct mount *mp, int mntflags) */ if ((mntflags & MNT_FORCE) == 0) nfscl_umount(nmp, td); + /* Make sure no nfsiods are assigned to this mount. */ + mtx_lock(&ncl_iod_mutex); + for (i = 0; i < NFS_MAXASYNCDAEMON; i++) + if (ncl_iodmount[i] == nmp) { + ncl_iodwant[i] = NFSIOD_AVAILABLE; + ncl_iodmount[i] = NULL; + } + mtx_unlock(&ncl_iod_mutex); newnfs_disconnect(&nmp->nm_sockreq); crfree(nmp->nm_sockreq.nr_cred); FREE(nmp->nm_nam, M_SONAME); diff --git a/sys/nfsclient/nfs_nfsiod.c b/sys/nfsclient/nfs_nfsiod.c index d34c205..2fb2c88 100644 --- a/sys/nfsclient/nfs_nfsiod.c +++ b/sys/nfsclient/nfs_nfsiod.c @@ -308,6 +308,14 @@ nfssvc_iod(void *instance) mtx_unlock(&Giant); mtx_lock(&nfs_iod_mtx); /* + * Make sure the nmp hasn't been dismounted as soon as + * nfs_doio() completes for the last buffer. + */ + nmp = nfs_iodmount[myiod]; + if (nmp == NULL) + break; + + /* * If there are more than one iod on this mount, then defect * so that the iods can be shared out fairly between the mounts */ diff --git a/sys/nfsclient/nfs_vfsops.c b/sys/nfsclient/nfs_vfsops.c index 6f00cf9..7a26aa2 100644 --- a/sys/nfsclient/nfs_vfsops.c +++ b/sys/nfsclient/nfs_vfsops.c @@ -1362,7 +1362,7 @@ static int nfs_unmount(struct mount *mp, int mntflags) { struct nfsmount *nmp; - int error, flags = 0; + int error, flags = 0, i; if (mntflags & MNT_FORCE) flags |= FORCECLOSE; @@ -1387,6 +1387,14 @@ nfs_unmount(struct mount *mp, int mntflags) /* * We are now committed to the unmount. */ + /* Make sure no nfsiods are assigned to this mount. */ + mtx_lock(&nfs_iod_mtx); + for (i = 0; i < NFS_MAXASYNCDAEMON; i++) + if (nfs_iodmount[i] == nmp) { + nfs_iodwant[i] = NFSIOD_AVAILABLE; + nfs_iodmount[i] = NULL; + } + mtx_unlock(&nfs_iod_mtx); nfs_disconnect(nmp); free(nmp->nm_nam, M_SONAME); |