Deleted Added
full compact
vfs_mount.c (138696) vfs_mount.c (138835)
1/*
2 * Copyright (c) 1999-2004 Poul-Henning Kamp
3 * Copyright (c) 1999 Michael Smith
4 * Copyright (c) 1989, 1993
5 * The Regents of the University of California. All rights reserved.
6 * (c) UNIX System Laboratories, Inc.
7 * All or some portions of this file are derived from material licensed
8 * to the University of California by American Telephone and Telegraph

--- 21 unchanged lines hidden (view full) ---

30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#include <sys/cdefs.h>
1/*
2 * Copyright (c) 1999-2004 Poul-Henning Kamp
3 * Copyright (c) 1999 Michael Smith
4 * Copyright (c) 1989, 1993
5 * The Regents of the University of California. All rights reserved.
6 * (c) UNIX System Laboratories, Inc.
7 * All or some portions of this file are derived from material licensed
8 * to the University of California by American Telephone and Telegraph

--- 21 unchanged lines hidden (view full) ---

30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#include <sys/cdefs.h>
38__FBSDID("$FreeBSD: head/sys/kern/vfs_mount.c 138696 2004-12-11 22:13:02Z phk $");
38__FBSDID("$FreeBSD: head/sys/kern/vfs_mount.c 138835 2004-12-14 08:23:18Z phk $");
39
40#include <sys/param.h>
41#include <sys/conf.h>
42#include <sys/cons.h>
43#include <sys/jail.h>
44#include <sys/kernel.h>
45#include <sys/mac.h>
46#include <sys/malloc.h>

--- 21 unchanged lines hidden (view full) ---

68
69#ifdef DDB
70#include <ddb/ddb.h>
71#endif
72
73#define ROOTNAME "root_device"
74#define VFS_MOUNTARG_SIZE_MAX (1024 * 64)
75
39
40#include <sys/param.h>
41#include <sys/conf.h>
42#include <sys/cons.h>
43#include <sys/jail.h>
44#include <sys/kernel.h>
45#include <sys/mac.h>
46#include <sys/malloc.h>

--- 21 unchanged lines hidden (view full) ---

68
69#ifdef DDB
70#include <ddb/ddb.h>
71#endif
72
73#define ROOTNAME "root_device"
74#define VFS_MOUNTARG_SIZE_MAX (1024 * 64)
75
76static void checkdirs(struct vnode *olddp, struct vnode *newdp);
77static void gets(char *cp);
78static int vfs_domount(struct thread *td, const char *fstype,
79 char *fspath, int fsflags, void *fsdata);
80static int vfs_mount_alloc(struct vnode *dvp, struct vfsconf *vfsp,
81 const char *fspath, struct thread *td, struct mount **mpp);
82static int vfs_mountroot_ask(void);
83static int vfs_mountroot_try(const char *mountfrom);
84static int vfs_donmount(struct thread *td, int fsflags,

--- 694 unchanged lines hidden (view full) ---

779 VI_UNLOCK(vp);
780 vp->v_mountedhere = mp;
781 mtx_lock(&mountlist_mtx);
782 TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list);
783 mtx_unlock(&mountlist_mtx);
784 vfs_event_signal(NULL, VQ_MOUNT, 0);
785 if (VFS_ROOT(mp, &newdp, td))
786 panic("mount: lost mount");
76static void gets(char *cp);
77static int vfs_domount(struct thread *td, const char *fstype,
78 char *fspath, int fsflags, void *fsdata);
79static int vfs_mount_alloc(struct vnode *dvp, struct vfsconf *vfsp,
80 const char *fspath, struct thread *td, struct mount **mpp);
81static int vfs_mountroot_ask(void);
82static int vfs_mountroot_try(const char *mountfrom);
83static int vfs_donmount(struct thread *td, int fsflags,

--- 694 unchanged lines hidden (view full) ---

778 VI_UNLOCK(vp);
779 vp->v_mountedhere = mp;
780 mtx_lock(&mountlist_mtx);
781 TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list);
782 mtx_unlock(&mountlist_mtx);
783 vfs_event_signal(NULL, VQ_MOUNT, 0);
784 if (VFS_ROOT(mp, &newdp, td))
785 panic("mount: lost mount");
787 checkdirs(vp, newdp);
786 mountcheckdirs(vp, newdp);
788 vput(newdp);
789 VOP_UNLOCK(vp, 0, td);
790 if ((mp->mnt_flag & MNT_RDONLY) == 0)
791 error = vfs_allocate_syncvnode(mp);
792 vfs_unbusy(mp, td);
793 if (error || (error = VFS_START(mp, 0, td)) != 0)
794 vrele(vp);
795 } else {
796 VI_LOCK(vp);
797 vp->v_iflag &= ~VI_MOUNT;
798 VI_UNLOCK(vp);
799 vfs_mount_destroy(mp, td);
800 vput(vp);
801 }
802 return (error);
803}
804
805/*
787 vput(newdp);
788 VOP_UNLOCK(vp, 0, td);
789 if ((mp->mnt_flag & MNT_RDONLY) == 0)
790 error = vfs_allocate_syncvnode(mp);
791 vfs_unbusy(mp, td);
792 if (error || (error = VFS_START(mp, 0, td)) != 0)
793 vrele(vp);
794 } else {
795 VI_LOCK(vp);
796 vp->v_iflag &= ~VI_MOUNT;
797 VI_UNLOCK(vp);
798 vfs_mount_destroy(mp, td);
799 vput(vp);
800 }
801 return (error);
802}
803
804/*
806 * Scan all active processes to see if any of them have a current
807 * or root directory of `olddp'. If so, replace them with the new
808 * mount point.
809 */
810static void
811checkdirs(olddp, newdp)
812 struct vnode *olddp, *newdp;
813{
814 struct filedesc *fdp;
815 struct proc *p;
816 int nrele;
817
818 if (vrefcnt(olddp) == 1)
819 return;
820 sx_slock(&allproc_lock);
821 LIST_FOREACH(p, &allproc, p_list) {
822 mtx_lock(&fdesc_mtx);
823 fdp = p->p_fd;
824 if (fdp == NULL) {
825 mtx_unlock(&fdesc_mtx);
826 continue;
827 }
828 nrele = 0;
829 FILEDESC_LOCK_FAST(fdp);
830 if (fdp->fd_cdir == olddp) {
831 vref(newdp);
832 fdp->fd_cdir = newdp;
833 nrele++;
834 }
835 if (fdp->fd_rdir == olddp) {
836 vref(newdp);
837 fdp->fd_rdir = newdp;
838 nrele++;
839 }
840 FILEDESC_UNLOCK_FAST(fdp);
841 mtx_unlock(&fdesc_mtx);
842 while (nrele--)
843 vrele(olddp);
844 }
845 sx_sunlock(&allproc_lock);
846 if (rootvnode == olddp) {
847 vrele(rootvnode);
848 vref(newdp);
849 rootvnode = newdp;
850 }
851}
852
853/*
854 * ---------------------------------------------------------------------
855 * Unmount a filesystem.
856 *
857 * Note: unmount takes a path to the vnode mounted on as argument,
858 * not special file (as before).
859 */
860#ifndef _SYS_SYSPROTO_H_
861struct unmount_args {

--- 124 unchanged lines hidden (view full) ---

986 vrele(mp->mnt_syncer);
987 /*
988 * For forced unmounts, move process cdir/rdir refs on the fs root
989 * vnode to the covered vnode. For non-forced unmounts we want
990 * such references to cause an EBUSY error.
991 */
992 if ((flags & MNT_FORCE) && VFS_ROOT(mp, &fsrootvp, td) == 0) {
993 if (mp->mnt_vnodecovered != NULL)
805 * ---------------------------------------------------------------------
806 * Unmount a filesystem.
807 *
808 * Note: unmount takes a path to the vnode mounted on as argument,
809 * not special file (as before).
810 */
811#ifndef _SYS_SYSPROTO_H_
812struct unmount_args {

--- 124 unchanged lines hidden (view full) ---

937 vrele(mp->mnt_syncer);
938 /*
939 * For forced unmounts, move process cdir/rdir refs on the fs root
940 * vnode to the covered vnode. For non-forced unmounts we want
941 * such references to cause an EBUSY error.
942 */
943 if ((flags & MNT_FORCE) && VFS_ROOT(mp, &fsrootvp, td) == 0) {
944 if (mp->mnt_vnodecovered != NULL)
994 checkdirs(fsrootvp, mp->mnt_vnodecovered);
945 mountcheckdirs(fsrootvp, mp->mnt_vnodecovered);
995 if (fsrootvp == rootvnode) {
996 vrele(rootvnode);
997 rootvnode = NULL;
998 }
999 vput(fsrootvp);
1000 }
1001 if (((mp->mnt_flag & MNT_RDONLY) ||
1002 (error = VFS_SYNC(mp, MNT_WAIT, td->td_ucred, td)) == 0) ||
1003 (flags & MNT_FORCE)) {
1004 error = VFS_UNMOUNT(mp, flags, td);
1005 }
1006 vn_finished_write(mp);
1007 if (error) {
1008 /* Undo cdir/rdir and rootvnode changes made above. */
1009 if ((flags & MNT_FORCE) && VFS_ROOT(mp, &fsrootvp, td) == 0) {
1010 if (mp->mnt_vnodecovered != NULL)
946 if (fsrootvp == rootvnode) {
947 vrele(rootvnode);
948 rootvnode = NULL;
949 }
950 vput(fsrootvp);
951 }
952 if (((mp->mnt_flag & MNT_RDONLY) ||
953 (error = VFS_SYNC(mp, MNT_WAIT, td->td_ucred, td)) == 0) ||
954 (flags & MNT_FORCE)) {
955 error = VFS_UNMOUNT(mp, flags, td);
956 }
957 vn_finished_write(mp);
958 if (error) {
959 /* Undo cdir/rdir and rootvnode changes made above. */
960 if ((flags & MNT_FORCE) && VFS_ROOT(mp, &fsrootvp, td) == 0) {
961 if (mp->mnt_vnodecovered != NULL)
1011 checkdirs(mp->mnt_vnodecovered, fsrootvp);
962 mountcheckdirs(mp->mnt_vnodecovered, fsrootvp);
1012 if (rootvnode == NULL) {
1013 rootvnode = fsrootvp;
1014 vref(rootvnode);
1015 }
1016 vput(fsrootvp);
1017 }
1018 if ((mp->mnt_flag & MNT_RDONLY) == 0 && mp->mnt_syncer == NULL)
1019 (void) vfs_allocate_syncvnode(mp);

--- 784 unchanged lines hidden ---
963 if (rootvnode == NULL) {
964 rootvnode = fsrootvp;
965 vref(rootvnode);
966 }
967 vput(fsrootvp);
968 }
969 if ((mp->mnt_flag & MNT_RDONLY) == 0 && mp->mnt_syncer == NULL)
970 (void) vfs_allocate_syncvnode(mp);

--- 784 unchanged lines hidden ---