| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: smbfs_vfsops.c,v 1.87 2008/12/17 20:51:35 cegger Exp $ */ | | 1 | /* $NetBSD: smbfs_vfsops.c,v 1.88 2009/07/02 16:17:52 njoly Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 2000-2001, Boris Popov | | 4 | * Copyright (c) 2000-2001, Boris Popov |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
| @@ -25,27 +25,27 @@ | | | @@ -25,27 +25,27 @@ |
25 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | | 25 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | | 26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | | 27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
28 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 28 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | | 29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
32 | * SUCH DAMAGE. | | 32 | * SUCH DAMAGE. |
33 | * | | 33 | * |
34 | * FreeBSD: src/sys/fs/smbfs/smbfs_vfsops.c,v 1.5 2001/12/13 13:08:34 sheldonh Exp | | 34 | * FreeBSD: src/sys/fs/smbfs/smbfs_vfsops.c,v 1.5 2001/12/13 13:08:34 sheldonh Exp |
35 | */ | | 35 | */ |
36 | | | 36 | |
37 | #include <sys/cdefs.h> | | 37 | #include <sys/cdefs.h> |
38 | __KERNEL_RCSID(0, "$NetBSD: smbfs_vfsops.c,v 1.87 2008/12/17 20:51:35 cegger Exp $"); | | 38 | __KERNEL_RCSID(0, "$NetBSD: smbfs_vfsops.c,v 1.88 2009/07/02 16:17:52 njoly Exp $"); |
39 | | | 39 | |
40 | #include <sys/param.h> | | 40 | #include <sys/param.h> |
41 | #include <sys/systm.h> | | 41 | #include <sys/systm.h> |
42 | #include <sys/proc.h> | | 42 | #include <sys/proc.h> |
43 | #include <sys/buf.h> | | 43 | #include <sys/buf.h> |
44 | #include <sys/kernel.h> | | 44 | #include <sys/kernel.h> |
45 | #include <sys/dirent.h> | | 45 | #include <sys/dirent.h> |
46 | #include <sys/sysctl.h> | | 46 | #include <sys/sysctl.h> |
47 | #include <sys/vnode.h> | | 47 | #include <sys/vnode.h> |
48 | #include <sys/mount.h> | | 48 | #include <sys/mount.h> |
49 | #include <sys/stat.h> | | 49 | #include <sys/stat.h> |
50 | #include <sys/malloc.h> | | 50 | #include <sys/malloc.h> |
51 | #include <sys/kauth.h> | | 51 | #include <sys/kauth.h> |
| @@ -221,59 +221,62 @@ smbfs_mount(struct mount *mp, const char | | | @@ -221,59 +221,62 @@ smbfs_mount(struct mount *mp, const char |
221 | "//%s@%s/%s", vcp->vc_username, vcp->vc_srvname, ssp->ss_name); | | 221 | "//%s@%s/%s", vcp->vc_username, vcp->vc_srvname, ssp->ss_name); |
222 | | | 222 | |
223 | vfs_getnewfsid(mp); | | 223 | vfs_getnewfsid(mp); |
224 | return (0); | | 224 | return (0); |
225 | } | | 225 | } |
226 | | | 226 | |
227 | /* Unmount the filesystem described by mp. */ | | 227 | /* Unmount the filesystem described by mp. */ |
228 | int | | 228 | int |
229 | smbfs_unmount(struct mount *mp, int mntflags) | | 229 | smbfs_unmount(struct mount *mp, int mntflags) |
230 | { | | 230 | { |
231 | struct lwp *l = curlwp; | | 231 | struct lwp *l = curlwp; |
232 | struct smbmount *smp = VFSTOSMBFS(mp); | | 232 | struct smbmount *smp = VFSTOSMBFS(mp); |
233 | struct smb_cred scred; | | 233 | struct smb_cred scred; |
| | | 234 | struct vnode *smbfs_rootvp = SMBTOV(smp->sm_root); |
234 | int error, flags; | | 235 | int error, flags; |
235 | | | 236 | |
236 | SMBVDEBUG("smbfs_unmount: flags=%04x\n", mntflags); | | 237 | SMBVDEBUG("smbfs_unmount: flags=%04x\n", mntflags); |
237 | flags = 0; | | 238 | flags = 0; |
238 | if (mntflags & MNT_FORCE) | | 239 | if (mntflags & MNT_FORCE) |
239 | flags |= FORCECLOSE; | | 240 | flags |= FORCECLOSE; |
240 | /* Drop the extra reference to root vnode. */ | | 241 | |
241 | if (smp->sm_root) { | | 242 | if (smbfs_rootvp->v_usecount > 1 && (mntflags & MNT_FORCE) == 0) |
242 | vrele(SMBTOV(smp->sm_root)); | | 243 | return EBUSY; |
243 | smp->sm_root = NULL; | | | |
244 | } | | | |
245 | | | 244 | |
246 | /* Flush all vnodes. | | 245 | /* Flush all vnodes. |
247 | * Keep trying to flush the vnode list for the mount while | | 246 | * Keep trying to flush the vnode list for the mount while |
248 | * some are still busy and we are making progress towards | | 247 | * some are still busy and we are making progress towards |
249 | * making them not busy. This is needed because smbfs vnodes | | 248 | * making them not busy. This is needed because smbfs vnodes |
250 | * reference their parent directory but may appear after their | | 249 | * reference their parent directory but may appear after their |
251 | * parent in the list; one pass over the vnode list is not | | 250 | * parent in the list; one pass over the vnode list is not |
252 | * sufficient in this case. */ | | 251 | * sufficient in this case. */ |
253 | do { | | 252 | do { |
254 | smp->sm_didrele = 0; | | 253 | smp->sm_didrele = 0; |
255 | error = vflush(mp, NULLVP, flags); | | 254 | error = vflush(mp, smbfs_rootvp, flags); |
256 | } while (error == EBUSY && smp->sm_didrele != 0); | | 255 | } while (error == EBUSY && smp->sm_didrele != 0); |
| | | 256 | if (error) |
| | | 257 | return error; |
| | | 258 | |
| | | 259 | vgone(smbfs_rootvp); |
257 | | | 260 | |
258 | smb_makescred(&scred, l, l->l_cred); | | 261 | smb_makescred(&scred, l, l->l_cred); |
259 | smb_share_lock(smp->sm_share); | | 262 | smb_share_lock(smp->sm_share); |
260 | smb_share_put(smp->sm_share, &scred); | | 263 | smb_share_put(smp->sm_share, &scred); |
261 | mp->mnt_data = NULL; | | 264 | mp->mnt_data = NULL; |
262 | | | 265 | |
263 | hashdone(smp->sm_hash, HASH_LIST, smp->sm_hashlen); | | 266 | hashdone(smp->sm_hash, HASH_LIST, smp->sm_hashlen); |
264 | mutex_destroy(&smp->sm_hashlock); | | 267 | mutex_destroy(&smp->sm_hashlock); |
265 | free(smp, M_SMBFSDATA); | | 268 | free(smp, M_SMBFSDATA); |
266 | return error; | | 269 | return 0; |
267 | } | | 270 | } |
268 | | | 271 | |
269 | /* | | 272 | /* |
270 | * Get root vnode of the smbfs filesystem, and store it in sm_root. | | 273 | * Get root vnode of the smbfs filesystem, and store it in sm_root. |
271 | */ | | 274 | */ |
272 | static int | | 275 | static int |
273 | smbfs_setroot(struct mount *mp) | | 276 | smbfs_setroot(struct mount *mp) |
274 | { | | 277 | { |
275 | struct smbmount *smp = VFSTOSMBFS(mp); | | 278 | struct smbmount *smp = VFSTOSMBFS(mp); |
276 | struct vnode *vp; | | 279 | struct vnode *vp; |
277 | struct smbfattr fattr; | | 280 | struct smbfattr fattr; |
278 | struct lwp *l = curlwp; | | 281 | struct lwp *l = curlwp; |
279 | kauth_cred_t cred = l->l_cred; | | 282 | kauth_cred_t cred = l->l_cred; |