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 --- |