| 305 | } |
| 306 | |
| 307 | static void |
| 308 | vfs_mountroot_shuffle(struct thread *td, struct mount *mpdevfs) |
| 309 | { |
| 310 | struct nameidata nd; |
| 311 | struct mount *mporoot, *mpnroot; |
| 312 | struct vnode *vp, *vporoot, *vpdevfs; |
| 313 | char *fspath; |
| 314 | int error; |
| 315 | |
| 316 | mpnroot = TAILQ_NEXT(mpdevfs, mnt_list); |
| 317 | |
| 318 | /* Shuffle the mountlist. */ |
| 319 | mtx_lock(&mountlist_mtx); |
| 320 | mporoot = TAILQ_FIRST(&mountlist); |
| 321 | TAILQ_REMOVE(&mountlist, mpdevfs, mnt_list); |
| 322 | if (mporoot != mpdevfs) { |
| 323 | TAILQ_REMOVE(&mountlist, mpnroot, mnt_list); |
| 324 | TAILQ_INSERT_HEAD(&mountlist, mpnroot, mnt_list); |
| 325 | } |
| 326 | TAILQ_INSERT_TAIL(&mountlist, mpdevfs, mnt_list); |
| 327 | mtx_unlock(&mountlist_mtx); |
| 328 | |
| 329 | cache_purgevfs(mporoot); |
| 330 | if (mporoot != mpdevfs) |
| 331 | cache_purgevfs(mpdevfs); |
| 332 | |
| 333 | if (VFS_ROOT(mporoot, LK_EXCLUSIVE, &vporoot)) |
| 334 | panic("vfs_mountroot_shuffle: Cannot find root vnode"); |
| 335 | |
| 336 | VI_LOCK(vporoot); |
| 337 | vporoot->v_iflag &= ~VI_MOUNT; |
| 338 | vn_irflag_unset_locked(vporoot, VIRF_MOUNTPOINT); |
| 339 | vporoot->v_mountedhere = NULL; |
| 340 | VI_UNLOCK(vporoot); |
| 341 | mporoot->mnt_flag &= ~MNT_ROOTFS; |
| 342 | mporoot->mnt_vnodecovered = NULL; |
| 343 | vput(vporoot); |
| 344 | |
| 345 | /* Set up the new rootvnode, and purge the cache */ |
| 346 | mpnroot->mnt_vnodecovered = NULL; |
| 347 | set_rootvnode(); |
| 348 | cache_purgevfs(rootvnode->v_mount); |
| 349 | |
| 350 | if (mporoot != mpdevfs) { |
| 351 | /* Remount old root under /.mount or /mnt */ |
| 352 | fspath = "/.mount"; |
| 353 | NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, |
| 354 | fspath, td); |
| 355 | error = namei(&nd); |
| 356 | if (error) { |
| 357 | NDFREE(&nd, NDF_ONLY_PNBUF); |
| 358 | fspath = "/mnt"; |
| 359 | NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, |
| 360 | fspath, td); |
| 361 | error = namei(&nd); |
| 362 | } |
| 363 | if (!error) { |
| 364 | vp = nd.ni_vp; |
no test coverage detected