From d67a03ebbca3b5847c14fed1901f509520a476d2 Mon Sep 17 00:00:00 2001 From: Bill Joy Date: Wed, 9 Apr 1980 23:04:33 -0800 Subject: [PATCH] date and time created 80/04/09 16:04:33 by bill SCCS-vsn: sys/kern/vfs_syscalls.c 3.1 SCCS-vsn: sys/ufs/ffs/ffs_vnops.c 3.1 SCCS-vsn: sys/ufs/ffs/ufs_vnops.c 3.1 SCCS-vsn: sys/ufs/lfs/lfs_vnops.c 3.1 SCCS-vsn: sys/ufs/ufs/ufs_vnops.c 3.1 --- usr/src/sys/kern/vfs_syscalls.c | 267 ++++++++++++++++++++++++++++++++ usr/src/sys/ufs/ffs/ffs_vnops.c | 267 ++++++++++++++++++++++++++++++++ usr/src/sys/ufs/ffs/ufs_vnops.c | 267 ++++++++++++++++++++++++++++++++ usr/src/sys/ufs/lfs/lfs_vnops.c | 267 ++++++++++++++++++++++++++++++++ usr/src/sys/ufs/ufs/ufs_vnops.c | 267 ++++++++++++++++++++++++++++++++ 5 files changed, 1335 insertions(+) create mode 100644 usr/src/sys/kern/vfs_syscalls.c create mode 100644 usr/src/sys/ufs/ffs/ffs_vnops.c create mode 100644 usr/src/sys/ufs/ffs/ufs_vnops.c create mode 100644 usr/src/sys/ufs/lfs/lfs_vnops.c create mode 100644 usr/src/sys/ufs/ufs/ufs_vnops.c diff --git a/usr/src/sys/kern/vfs_syscalls.c b/usr/src/sys/kern/vfs_syscalls.c new file mode 100644 index 0000000000..b9b8217b48 --- /dev/null +++ b/usr/src/sys/kern/vfs_syscalls.c @@ -0,0 +1,267 @@ +/* vfs_syscalls.c 3.1 %H% */ + +#include "../h/param.h" +#include "../h/systm.h" +#include "../h/mount.h" +#include "../h/ino.h" +#include "../h/reg.h" +#include "../h/buf.h" +#include "../h/filsys.h" +#include "../h/dir.h" +#include "../h/user.h" +#include "../h/inode.h" +#include "../h/file.h" +#include "../h/conf.h" +#include "../h/stat.h" + +/* + * the fstat system call. + */ +fstat() +{ + register struct file *fp; + register struct a { + int fdes; + struct stat *sb; + } *uap; + + uap = (struct a *)u.u_ap; + fp = getf(uap->fdes); + if(fp == NULL) + return; + stat1(fp->f_inode, uap->sb, fp->f_flag&FPIPE? fp->f_un.f_offset: 0); +} + +/* + * the stat system call. + */ +stat() +{ + register struct inode *ip; + register struct a { + char *fname; + struct stat *sb; + } *uap; + + uap = (struct a *)u.u_ap; + ip = namei(uchar, 0); + if(ip == NULL) + return; + stat1(ip, uap->sb, (off_t)0); + iput(ip); +} + +/* + * The basic routine for fstat and stat: + * get the inode and pass appropriate parts back. + */ +stat1(ip, ub, pipeadj) +register struct inode *ip; +struct stat *ub; +off_t pipeadj; +{ + register struct dinode *dp; + register struct buf *bp; + struct stat ds; + + iupdat(ip, &time, &time); + /* + * first copy from inode table + */ + ds.st_dev = ip->i_dev; + ds.st_ino = ip->i_number; + ds.st_mode = ip->i_mode; + ds.st_nlink = ip->i_nlink; + ds.st_uid = ip->i_uid; + ds.st_gid = ip->i_gid; + ds.st_rdev = (dev_t)ip->i_un.i_rdev; + ds.st_size = ip->i_size - pipeadj; + /* + * next the dates in the disk + */ + bp = bread(ip->i_dev, itod(ip->i_number)); + dp = bp->b_un.b_dino; + dp += itoo(ip->i_number); + ds.st_atime = dp->di_atime; + ds.st_mtime = dp->di_mtime; + ds.st_ctime = dp->di_ctime; + brelse(bp); + if (copyout((caddr_t)&ds, (caddr_t)ub, sizeof(ds)) < 0) + u.u_error = EFAULT; +} + +/* + * the dup system call. + */ +dup() +{ + register struct file *fp; + register struct a { + int fdes; + int fdes2; + } *uap; + register i, m; + + uap = (struct a *)u.u_ap; + m = uap->fdes & ~077; + uap->fdes &= 077; + fp = getf(uap->fdes); + if(fp == NULL) + return; + if ((m&0100) == 0) { + if ((i = ufalloc()) < 0) + return; + } else { + i = uap->fdes2; + if (i<0 || i>=NOFILE) { + u.u_error = EBADF; + return; + } + if (u.u_vrpages[i]) { + u.u_error = ETXTBSY; + return; + } + u.u_r.r_val1 = i; + } + if (i!=uap->fdes) { + if (u.u_ofile[i]!=NULL) + closef(u.u_ofile[i]); + u.u_ofile[i] = fp; + fp->f_count++; + } +} + +/* + * the mount system call. + */ +smount() +{ + dev_t dev; + register struct inode *ip; + register struct mount *mp; + struct mount *smp; + register struct filsys *fp; + struct buf *bp; + register struct a { + char *fspec; + char *freg; + int ronly; + } *uap; + + uap = (struct a *)u.u_ap; + dev = getmdev(); + if(u.u_error) + return; + u.u_dirp = (caddr_t)uap->freg; + ip = namei(uchar, 0); + if(ip == NULL) + return; + if(ip->i_count!=1 || (ip->i_mode&(IFBLK&IFCHR))!=0) + goto out; + smp = NULL; + for(mp = &mount[0]; mp < &mount[NMOUNT]; mp++) { + if(mp->m_bufp != NULL) { + if(dev == mp->m_dev) + goto out; + } else + if(smp == NULL) + smp = mp; + } + mp = smp; + if(mp == NULL) + goto out; + (*bdevsw[major(dev)].d_open)(dev, !uap->ronly); + if(u.u_error) + goto out; + bp = bread(dev, SUPERB); + if(u.u_error) { + brelse(bp); + goto out1; + } + mp->m_inodp = ip; + mp->m_dev = dev; + mp->m_bufp = geteblk(); + bcopy((caddr_t)bp->b_un.b_addr, mp->m_bufp->b_un.b_addr, BSIZE); + fp = mp->m_bufp->b_un.b_filsys; + fp->s_ilock = 0; + fp->s_flock = 0; + fp->s_ronly = uap->ronly & 1; + fp->s_nbehind = 0; + fp->s_lasti = 1; + brelse(bp); + ip->i_flag |= IMOUNT; + prele(ip); + return; + +out: + u.u_error = EBUSY; +out1: + iput(ip); +} + +/* + * the umount system call. + */ +sumount() +{ + dev_t dev; + register struct inode *ip; + register struct mount *mp; + struct buf *bp; + register struct a { + char *fspec; + }; + + dev = getmdev(); + if(u.u_error) + return; + xumount(dev); /* remove unused sticky files from text table */ + update(); + for(mp = &mount[0]; mp < &mount[NMOUNT]; mp++) + if(mp->m_bufp != NULL && dev == mp->m_dev) + goto found; + u.u_error = EINVAL; + return; + +found: + for(ip = &inode[0]; ip < &inode[NINODE]; ip++) + if(ip->i_number != 0 && dev == ip->i_dev) { + u.u_error = EBUSY; + return; + } + (*bdevsw[major(dev)].d_close)(dev, 0); + ip = mp->m_inodp; + ip->i_flag &= ~IMOUNT; + plock(ip); + iput(ip); + bp = mp->m_bufp; + mp->m_bufp = NULL; + brelse(bp); +} + +/* + * Common code for mount and umount. + * Check that the user's argument is a reasonable + * thing on which to mount, and return the device number if so. + */ +dev_t +getmdev() +{ + dev_t dev; + register struct inode *ip; + +#ifdef UCB + if (!suser()) + return(NODEV); +#endif + ip = namei(uchar, 0); + if(ip == NULL) + return(NODEV); + if((ip->i_mode&IFMT) != IFBLK) + u.u_error = ENOTBLK; + dev = (dev_t)ip->i_un.i_rdev; + if(major(dev) >= nblkdev) + u.u_error = ENXIO; + iput(ip); + return(dev); +} diff --git a/usr/src/sys/ufs/ffs/ffs_vnops.c b/usr/src/sys/ufs/ffs/ffs_vnops.c new file mode 100644 index 0000000000..5868ae60f8 --- /dev/null +++ b/usr/src/sys/ufs/ffs/ffs_vnops.c @@ -0,0 +1,267 @@ +/* ffs_vnops.c 3.1 %H% */ + +#include "../h/param.h" +#include "../h/systm.h" +#include "../h/mount.h" +#include "../h/ino.h" +#include "../h/reg.h" +#include "../h/buf.h" +#include "../h/filsys.h" +#include "../h/dir.h" +#include "../h/user.h" +#include "../h/inode.h" +#include "../h/file.h" +#include "../h/conf.h" +#include "../h/stat.h" + +/* + * the fstat system call. + */ +fstat() +{ + register struct file *fp; + register struct a { + int fdes; + struct stat *sb; + } *uap; + + uap = (struct a *)u.u_ap; + fp = getf(uap->fdes); + if(fp == NULL) + return; + stat1(fp->f_inode, uap->sb, fp->f_flag&FPIPE? fp->f_un.f_offset: 0); +} + +/* + * the stat system call. + */ +stat() +{ + register struct inode *ip; + register struct a { + char *fname; + struct stat *sb; + } *uap; + + uap = (struct a *)u.u_ap; + ip = namei(uchar, 0); + if(ip == NULL) + return; + stat1(ip, uap->sb, (off_t)0); + iput(ip); +} + +/* + * The basic routine for fstat and stat: + * get the inode and pass appropriate parts back. + */ +stat1(ip, ub, pipeadj) +register struct inode *ip; +struct stat *ub; +off_t pipeadj; +{ + register struct dinode *dp; + register struct buf *bp; + struct stat ds; + + iupdat(ip, &time, &time); + /* + * first copy from inode table + */ + ds.st_dev = ip->i_dev; + ds.st_ino = ip->i_number; + ds.st_mode = ip->i_mode; + ds.st_nlink = ip->i_nlink; + ds.st_uid = ip->i_uid; + ds.st_gid = ip->i_gid; + ds.st_rdev = (dev_t)ip->i_un.i_rdev; + ds.st_size = ip->i_size - pipeadj; + /* + * next the dates in the disk + */ + bp = bread(ip->i_dev, itod(ip->i_number)); + dp = bp->b_un.b_dino; + dp += itoo(ip->i_number); + ds.st_atime = dp->di_atime; + ds.st_mtime = dp->di_mtime; + ds.st_ctime = dp->di_ctime; + brelse(bp); + if (copyout((caddr_t)&ds, (caddr_t)ub, sizeof(ds)) < 0) + u.u_error = EFAULT; +} + +/* + * the dup system call. + */ +dup() +{ + register struct file *fp; + register struct a { + int fdes; + int fdes2; + } *uap; + register i, m; + + uap = (struct a *)u.u_ap; + m = uap->fdes & ~077; + uap->fdes &= 077; + fp = getf(uap->fdes); + if(fp == NULL) + return; + if ((m&0100) == 0) { + if ((i = ufalloc()) < 0) + return; + } else { + i = uap->fdes2; + if (i<0 || i>=NOFILE) { + u.u_error = EBADF; + return; + } + if (u.u_vrpages[i]) { + u.u_error = ETXTBSY; + return; + } + u.u_r.r_val1 = i; + } + if (i!=uap->fdes) { + if (u.u_ofile[i]!=NULL) + closef(u.u_ofile[i]); + u.u_ofile[i] = fp; + fp->f_count++; + } +} + +/* + * the mount system call. + */ +smount() +{ + dev_t dev; + register struct inode *ip; + register struct mount *mp; + struct mount *smp; + register struct filsys *fp; + struct buf *bp; + register struct a { + char *fspec; + char *freg; + int ronly; + } *uap; + + uap = (struct a *)u.u_ap; + dev = getmdev(); + if(u.u_error) + return; + u.u_dirp = (caddr_t)uap->freg; + ip = namei(uchar, 0); + if(ip == NULL) + return; + if(ip->i_count!=1 || (ip->i_mode&(IFBLK&IFCHR))!=0) + goto out; + smp = NULL; + for(mp = &mount[0]; mp < &mount[NMOUNT]; mp++) { + if(mp->m_bufp != NULL) { + if(dev == mp->m_dev) + goto out; + } else + if(smp == NULL) + smp = mp; + } + mp = smp; + if(mp == NULL) + goto out; + (*bdevsw[major(dev)].d_open)(dev, !uap->ronly); + if(u.u_error) + goto out; + bp = bread(dev, SUPERB); + if(u.u_error) { + brelse(bp); + goto out1; + } + mp->m_inodp = ip; + mp->m_dev = dev; + mp->m_bufp = geteblk(); + bcopy((caddr_t)bp->b_un.b_addr, mp->m_bufp->b_un.b_addr, BSIZE); + fp = mp->m_bufp->b_un.b_filsys; + fp->s_ilock = 0; + fp->s_flock = 0; + fp->s_ronly = uap->ronly & 1; + fp->s_nbehind = 0; + fp->s_lasti = 1; + brelse(bp); + ip->i_flag |= IMOUNT; + prele(ip); + return; + +out: + u.u_error = EBUSY; +out1: + iput(ip); +} + +/* + * the umount system call. + */ +sumount() +{ + dev_t dev; + register struct inode *ip; + register struct mount *mp; + struct buf *bp; + register struct a { + char *fspec; + }; + + dev = getmdev(); + if(u.u_error) + return; + xumount(dev); /* remove unused sticky files from text table */ + update(); + for(mp = &mount[0]; mp < &mount[NMOUNT]; mp++) + if(mp->m_bufp != NULL && dev == mp->m_dev) + goto found; + u.u_error = EINVAL; + return; + +found: + for(ip = &inode[0]; ip < &inode[NINODE]; ip++) + if(ip->i_number != 0 && dev == ip->i_dev) { + u.u_error = EBUSY; + return; + } + (*bdevsw[major(dev)].d_close)(dev, 0); + ip = mp->m_inodp; + ip->i_flag &= ~IMOUNT; + plock(ip); + iput(ip); + bp = mp->m_bufp; + mp->m_bufp = NULL; + brelse(bp); +} + +/* + * Common code for mount and umount. + * Check that the user's argument is a reasonable + * thing on which to mount, and return the device number if so. + */ +dev_t +getmdev() +{ + dev_t dev; + register struct inode *ip; + +#ifdef UCB + if (!suser()) + return(NODEV); +#endif + ip = namei(uchar, 0); + if(ip == NULL) + return(NODEV); + if((ip->i_mode&IFMT) != IFBLK) + u.u_error = ENOTBLK; + dev = (dev_t)ip->i_un.i_rdev; + if(major(dev) >= nblkdev) + u.u_error = ENXIO; + iput(ip); + return(dev); +} diff --git a/usr/src/sys/ufs/ffs/ufs_vnops.c b/usr/src/sys/ufs/ffs/ufs_vnops.c new file mode 100644 index 0000000000..7483dec46a --- /dev/null +++ b/usr/src/sys/ufs/ffs/ufs_vnops.c @@ -0,0 +1,267 @@ +/* ufs_vnops.c 3.1 %H% */ + +#include "../h/param.h" +#include "../h/systm.h" +#include "../h/mount.h" +#include "../h/ino.h" +#include "../h/reg.h" +#include "../h/buf.h" +#include "../h/filsys.h" +#include "../h/dir.h" +#include "../h/user.h" +#include "../h/inode.h" +#include "../h/file.h" +#include "../h/conf.h" +#include "../h/stat.h" + +/* + * the fstat system call. + */ +fstat() +{ + register struct file *fp; + register struct a { + int fdes; + struct stat *sb; + } *uap; + + uap = (struct a *)u.u_ap; + fp = getf(uap->fdes); + if(fp == NULL) + return; + stat1(fp->f_inode, uap->sb, fp->f_flag&FPIPE? fp->f_un.f_offset: 0); +} + +/* + * the stat system call. + */ +stat() +{ + register struct inode *ip; + register struct a { + char *fname; + struct stat *sb; + } *uap; + + uap = (struct a *)u.u_ap; + ip = namei(uchar, 0); + if(ip == NULL) + return; + stat1(ip, uap->sb, (off_t)0); + iput(ip); +} + +/* + * The basic routine for fstat and stat: + * get the inode and pass appropriate parts back. + */ +stat1(ip, ub, pipeadj) +register struct inode *ip; +struct stat *ub; +off_t pipeadj; +{ + register struct dinode *dp; + register struct buf *bp; + struct stat ds; + + iupdat(ip, &time, &time); + /* + * first copy from inode table + */ + ds.st_dev = ip->i_dev; + ds.st_ino = ip->i_number; + ds.st_mode = ip->i_mode; + ds.st_nlink = ip->i_nlink; + ds.st_uid = ip->i_uid; + ds.st_gid = ip->i_gid; + ds.st_rdev = (dev_t)ip->i_un.i_rdev; + ds.st_size = ip->i_size - pipeadj; + /* + * next the dates in the disk + */ + bp = bread(ip->i_dev, itod(ip->i_number)); + dp = bp->b_un.b_dino; + dp += itoo(ip->i_number); + ds.st_atime = dp->di_atime; + ds.st_mtime = dp->di_mtime; + ds.st_ctime = dp->di_ctime; + brelse(bp); + if (copyout((caddr_t)&ds, (caddr_t)ub, sizeof(ds)) < 0) + u.u_error = EFAULT; +} + +/* + * the dup system call. + */ +dup() +{ + register struct file *fp; + register struct a { + int fdes; + int fdes2; + } *uap; + register i, m; + + uap = (struct a *)u.u_ap; + m = uap->fdes & ~077; + uap->fdes &= 077; + fp = getf(uap->fdes); + if(fp == NULL) + return; + if ((m&0100) == 0) { + if ((i = ufalloc()) < 0) + return; + } else { + i = uap->fdes2; + if (i<0 || i>=NOFILE) { + u.u_error = EBADF; + return; + } + if (u.u_vrpages[i]) { + u.u_error = ETXTBSY; + return; + } + u.u_r.r_val1 = i; + } + if (i!=uap->fdes) { + if (u.u_ofile[i]!=NULL) + closef(u.u_ofile[i]); + u.u_ofile[i] = fp; + fp->f_count++; + } +} + +/* + * the mount system call. + */ +smount() +{ + dev_t dev; + register struct inode *ip; + register struct mount *mp; + struct mount *smp; + register struct filsys *fp; + struct buf *bp; + register struct a { + char *fspec; + char *freg; + int ronly; + } *uap; + + uap = (struct a *)u.u_ap; + dev = getmdev(); + if(u.u_error) + return; + u.u_dirp = (caddr_t)uap->freg; + ip = namei(uchar, 0); + if(ip == NULL) + return; + if(ip->i_count!=1 || (ip->i_mode&(IFBLK&IFCHR))!=0) + goto out; + smp = NULL; + for(mp = &mount[0]; mp < &mount[NMOUNT]; mp++) { + if(mp->m_bufp != NULL) { + if(dev == mp->m_dev) + goto out; + } else + if(smp == NULL) + smp = mp; + } + mp = smp; + if(mp == NULL) + goto out; + (*bdevsw[major(dev)].d_open)(dev, !uap->ronly); + if(u.u_error) + goto out; + bp = bread(dev, SUPERB); + if(u.u_error) { + brelse(bp); + goto out1; + } + mp->m_inodp = ip; + mp->m_dev = dev; + mp->m_bufp = geteblk(); + bcopy((caddr_t)bp->b_un.b_addr, mp->m_bufp->b_un.b_addr, BSIZE); + fp = mp->m_bufp->b_un.b_filsys; + fp->s_ilock = 0; + fp->s_flock = 0; + fp->s_ronly = uap->ronly & 1; + fp->s_nbehind = 0; + fp->s_lasti = 1; + brelse(bp); + ip->i_flag |= IMOUNT; + prele(ip); + return; + +out: + u.u_error = EBUSY; +out1: + iput(ip); +} + +/* + * the umount system call. + */ +sumount() +{ + dev_t dev; + register struct inode *ip; + register struct mount *mp; + struct buf *bp; + register struct a { + char *fspec; + }; + + dev = getmdev(); + if(u.u_error) + return; + xumount(dev); /* remove unused sticky files from text table */ + update(); + for(mp = &mount[0]; mp < &mount[NMOUNT]; mp++) + if(mp->m_bufp != NULL && dev == mp->m_dev) + goto found; + u.u_error = EINVAL; + return; + +found: + for(ip = &inode[0]; ip < &inode[NINODE]; ip++) + if(ip->i_number != 0 && dev == ip->i_dev) { + u.u_error = EBUSY; + return; + } + (*bdevsw[major(dev)].d_close)(dev, 0); + ip = mp->m_inodp; + ip->i_flag &= ~IMOUNT; + plock(ip); + iput(ip); + bp = mp->m_bufp; + mp->m_bufp = NULL; + brelse(bp); +} + +/* + * Common code for mount and umount. + * Check that the user's argument is a reasonable + * thing on which to mount, and return the device number if so. + */ +dev_t +getmdev() +{ + dev_t dev; + register struct inode *ip; + +#ifdef UCB + if (!suser()) + return(NODEV); +#endif + ip = namei(uchar, 0); + if(ip == NULL) + return(NODEV); + if((ip->i_mode&IFMT) != IFBLK) + u.u_error = ENOTBLK; + dev = (dev_t)ip->i_un.i_rdev; + if(major(dev) >= nblkdev) + u.u_error = ENXIO; + iput(ip); + return(dev); +} diff --git a/usr/src/sys/ufs/lfs/lfs_vnops.c b/usr/src/sys/ufs/lfs/lfs_vnops.c new file mode 100644 index 0000000000..fd6c2ba12b --- /dev/null +++ b/usr/src/sys/ufs/lfs/lfs_vnops.c @@ -0,0 +1,267 @@ +/* lfs_vnops.c 3.1 %H% */ + +#include "../h/param.h" +#include "../h/systm.h" +#include "../h/mount.h" +#include "../h/ino.h" +#include "../h/reg.h" +#include "../h/buf.h" +#include "../h/filsys.h" +#include "../h/dir.h" +#include "../h/user.h" +#include "../h/inode.h" +#include "../h/file.h" +#include "../h/conf.h" +#include "../h/stat.h" + +/* + * the fstat system call. + */ +fstat() +{ + register struct file *fp; + register struct a { + int fdes; + struct stat *sb; + } *uap; + + uap = (struct a *)u.u_ap; + fp = getf(uap->fdes); + if(fp == NULL) + return; + stat1(fp->f_inode, uap->sb, fp->f_flag&FPIPE? fp->f_un.f_offset: 0); +} + +/* + * the stat system call. + */ +stat() +{ + register struct inode *ip; + register struct a { + char *fname; + struct stat *sb; + } *uap; + + uap = (struct a *)u.u_ap; + ip = namei(uchar, 0); + if(ip == NULL) + return; + stat1(ip, uap->sb, (off_t)0); + iput(ip); +} + +/* + * The basic routine for fstat and stat: + * get the inode and pass appropriate parts back. + */ +stat1(ip, ub, pipeadj) +register struct inode *ip; +struct stat *ub; +off_t pipeadj; +{ + register struct dinode *dp; + register struct buf *bp; + struct stat ds; + + iupdat(ip, &time, &time); + /* + * first copy from inode table + */ + ds.st_dev = ip->i_dev; + ds.st_ino = ip->i_number; + ds.st_mode = ip->i_mode; + ds.st_nlink = ip->i_nlink; + ds.st_uid = ip->i_uid; + ds.st_gid = ip->i_gid; + ds.st_rdev = (dev_t)ip->i_un.i_rdev; + ds.st_size = ip->i_size - pipeadj; + /* + * next the dates in the disk + */ + bp = bread(ip->i_dev, itod(ip->i_number)); + dp = bp->b_un.b_dino; + dp += itoo(ip->i_number); + ds.st_atime = dp->di_atime; + ds.st_mtime = dp->di_mtime; + ds.st_ctime = dp->di_ctime; + brelse(bp); + if (copyout((caddr_t)&ds, (caddr_t)ub, sizeof(ds)) < 0) + u.u_error = EFAULT; +} + +/* + * the dup system call. + */ +dup() +{ + register struct file *fp; + register struct a { + int fdes; + int fdes2; + } *uap; + register i, m; + + uap = (struct a *)u.u_ap; + m = uap->fdes & ~077; + uap->fdes &= 077; + fp = getf(uap->fdes); + if(fp == NULL) + return; + if ((m&0100) == 0) { + if ((i = ufalloc()) < 0) + return; + } else { + i = uap->fdes2; + if (i<0 || i>=NOFILE) { + u.u_error = EBADF; + return; + } + if (u.u_vrpages[i]) { + u.u_error = ETXTBSY; + return; + } + u.u_r.r_val1 = i; + } + if (i!=uap->fdes) { + if (u.u_ofile[i]!=NULL) + closef(u.u_ofile[i]); + u.u_ofile[i] = fp; + fp->f_count++; + } +} + +/* + * the mount system call. + */ +smount() +{ + dev_t dev; + register struct inode *ip; + register struct mount *mp; + struct mount *smp; + register struct filsys *fp; + struct buf *bp; + register struct a { + char *fspec; + char *freg; + int ronly; + } *uap; + + uap = (struct a *)u.u_ap; + dev = getmdev(); + if(u.u_error) + return; + u.u_dirp = (caddr_t)uap->freg; + ip = namei(uchar, 0); + if(ip == NULL) + return; + if(ip->i_count!=1 || (ip->i_mode&(IFBLK&IFCHR))!=0) + goto out; + smp = NULL; + for(mp = &mount[0]; mp < &mount[NMOUNT]; mp++) { + if(mp->m_bufp != NULL) { + if(dev == mp->m_dev) + goto out; + } else + if(smp == NULL) + smp = mp; + } + mp = smp; + if(mp == NULL) + goto out; + (*bdevsw[major(dev)].d_open)(dev, !uap->ronly); + if(u.u_error) + goto out; + bp = bread(dev, SUPERB); + if(u.u_error) { + brelse(bp); + goto out1; + } + mp->m_inodp = ip; + mp->m_dev = dev; + mp->m_bufp = geteblk(); + bcopy((caddr_t)bp->b_un.b_addr, mp->m_bufp->b_un.b_addr, BSIZE); + fp = mp->m_bufp->b_un.b_filsys; + fp->s_ilock = 0; + fp->s_flock = 0; + fp->s_ronly = uap->ronly & 1; + fp->s_nbehind = 0; + fp->s_lasti = 1; + brelse(bp); + ip->i_flag |= IMOUNT; + prele(ip); + return; + +out: + u.u_error = EBUSY; +out1: + iput(ip); +} + +/* + * the umount system call. + */ +sumount() +{ + dev_t dev; + register struct inode *ip; + register struct mount *mp; + struct buf *bp; + register struct a { + char *fspec; + }; + + dev = getmdev(); + if(u.u_error) + return; + xumount(dev); /* remove unused sticky files from text table */ + update(); + for(mp = &mount[0]; mp < &mount[NMOUNT]; mp++) + if(mp->m_bufp != NULL && dev == mp->m_dev) + goto found; + u.u_error = EINVAL; + return; + +found: + for(ip = &inode[0]; ip < &inode[NINODE]; ip++) + if(ip->i_number != 0 && dev == ip->i_dev) { + u.u_error = EBUSY; + return; + } + (*bdevsw[major(dev)].d_close)(dev, 0); + ip = mp->m_inodp; + ip->i_flag &= ~IMOUNT; + plock(ip); + iput(ip); + bp = mp->m_bufp; + mp->m_bufp = NULL; + brelse(bp); +} + +/* + * Common code for mount and umount. + * Check that the user's argument is a reasonable + * thing on which to mount, and return the device number if so. + */ +dev_t +getmdev() +{ + dev_t dev; + register struct inode *ip; + +#ifdef UCB + if (!suser()) + return(NODEV); +#endif + ip = namei(uchar, 0); + if(ip == NULL) + return(NODEV); + if((ip->i_mode&IFMT) != IFBLK) + u.u_error = ENOTBLK; + dev = (dev_t)ip->i_un.i_rdev; + if(major(dev) >= nblkdev) + u.u_error = ENXIO; + iput(ip); + return(dev); +} diff --git a/usr/src/sys/ufs/ufs/ufs_vnops.c b/usr/src/sys/ufs/ufs/ufs_vnops.c new file mode 100644 index 0000000000..7483dec46a --- /dev/null +++ b/usr/src/sys/ufs/ufs/ufs_vnops.c @@ -0,0 +1,267 @@ +/* ufs_vnops.c 3.1 %H% */ + +#include "../h/param.h" +#include "../h/systm.h" +#include "../h/mount.h" +#include "../h/ino.h" +#include "../h/reg.h" +#include "../h/buf.h" +#include "../h/filsys.h" +#include "../h/dir.h" +#include "../h/user.h" +#include "../h/inode.h" +#include "../h/file.h" +#include "../h/conf.h" +#include "../h/stat.h" + +/* + * the fstat system call. + */ +fstat() +{ + register struct file *fp; + register struct a { + int fdes; + struct stat *sb; + } *uap; + + uap = (struct a *)u.u_ap; + fp = getf(uap->fdes); + if(fp == NULL) + return; + stat1(fp->f_inode, uap->sb, fp->f_flag&FPIPE? fp->f_un.f_offset: 0); +} + +/* + * the stat system call. + */ +stat() +{ + register struct inode *ip; + register struct a { + char *fname; + struct stat *sb; + } *uap; + + uap = (struct a *)u.u_ap; + ip = namei(uchar, 0); + if(ip == NULL) + return; + stat1(ip, uap->sb, (off_t)0); + iput(ip); +} + +/* + * The basic routine for fstat and stat: + * get the inode and pass appropriate parts back. + */ +stat1(ip, ub, pipeadj) +register struct inode *ip; +struct stat *ub; +off_t pipeadj; +{ + register struct dinode *dp; + register struct buf *bp; + struct stat ds; + + iupdat(ip, &time, &time); + /* + * first copy from inode table + */ + ds.st_dev = ip->i_dev; + ds.st_ino = ip->i_number; + ds.st_mode = ip->i_mode; + ds.st_nlink = ip->i_nlink; + ds.st_uid = ip->i_uid; + ds.st_gid = ip->i_gid; + ds.st_rdev = (dev_t)ip->i_un.i_rdev; + ds.st_size = ip->i_size - pipeadj; + /* + * next the dates in the disk + */ + bp = bread(ip->i_dev, itod(ip->i_number)); + dp = bp->b_un.b_dino; + dp += itoo(ip->i_number); + ds.st_atime = dp->di_atime; + ds.st_mtime = dp->di_mtime; + ds.st_ctime = dp->di_ctime; + brelse(bp); + if (copyout((caddr_t)&ds, (caddr_t)ub, sizeof(ds)) < 0) + u.u_error = EFAULT; +} + +/* + * the dup system call. + */ +dup() +{ + register struct file *fp; + register struct a { + int fdes; + int fdes2; + } *uap; + register i, m; + + uap = (struct a *)u.u_ap; + m = uap->fdes & ~077; + uap->fdes &= 077; + fp = getf(uap->fdes); + if(fp == NULL) + return; + if ((m&0100) == 0) { + if ((i = ufalloc()) < 0) + return; + } else { + i = uap->fdes2; + if (i<0 || i>=NOFILE) { + u.u_error = EBADF; + return; + } + if (u.u_vrpages[i]) { + u.u_error = ETXTBSY; + return; + } + u.u_r.r_val1 = i; + } + if (i!=uap->fdes) { + if (u.u_ofile[i]!=NULL) + closef(u.u_ofile[i]); + u.u_ofile[i] = fp; + fp->f_count++; + } +} + +/* + * the mount system call. + */ +smount() +{ + dev_t dev; + register struct inode *ip; + register struct mount *mp; + struct mount *smp; + register struct filsys *fp; + struct buf *bp; + register struct a { + char *fspec; + char *freg; + int ronly; + } *uap; + + uap = (struct a *)u.u_ap; + dev = getmdev(); + if(u.u_error) + return; + u.u_dirp = (caddr_t)uap->freg; + ip = namei(uchar, 0); + if(ip == NULL) + return; + if(ip->i_count!=1 || (ip->i_mode&(IFBLK&IFCHR))!=0) + goto out; + smp = NULL; + for(mp = &mount[0]; mp < &mount[NMOUNT]; mp++) { + if(mp->m_bufp != NULL) { + if(dev == mp->m_dev) + goto out; + } else + if(smp == NULL) + smp = mp; + } + mp = smp; + if(mp == NULL) + goto out; + (*bdevsw[major(dev)].d_open)(dev, !uap->ronly); + if(u.u_error) + goto out; + bp = bread(dev, SUPERB); + if(u.u_error) { + brelse(bp); + goto out1; + } + mp->m_inodp = ip; + mp->m_dev = dev; + mp->m_bufp = geteblk(); + bcopy((caddr_t)bp->b_un.b_addr, mp->m_bufp->b_un.b_addr, BSIZE); + fp = mp->m_bufp->b_un.b_filsys; + fp->s_ilock = 0; + fp->s_flock = 0; + fp->s_ronly = uap->ronly & 1; + fp->s_nbehind = 0; + fp->s_lasti = 1; + brelse(bp); + ip->i_flag |= IMOUNT; + prele(ip); + return; + +out: + u.u_error = EBUSY; +out1: + iput(ip); +} + +/* + * the umount system call. + */ +sumount() +{ + dev_t dev; + register struct inode *ip; + register struct mount *mp; + struct buf *bp; + register struct a { + char *fspec; + }; + + dev = getmdev(); + if(u.u_error) + return; + xumount(dev); /* remove unused sticky files from text table */ + update(); + for(mp = &mount[0]; mp < &mount[NMOUNT]; mp++) + if(mp->m_bufp != NULL && dev == mp->m_dev) + goto found; + u.u_error = EINVAL; + return; + +found: + for(ip = &inode[0]; ip < &inode[NINODE]; ip++) + if(ip->i_number != 0 && dev == ip->i_dev) { + u.u_error = EBUSY; + return; + } + (*bdevsw[major(dev)].d_close)(dev, 0); + ip = mp->m_inodp; + ip->i_flag &= ~IMOUNT; + plock(ip); + iput(ip); + bp = mp->m_bufp; + mp->m_bufp = NULL; + brelse(bp); +} + +/* + * Common code for mount and umount. + * Check that the user's argument is a reasonable + * thing on which to mount, and return the device number if so. + */ +dev_t +getmdev() +{ + dev_t dev; + register struct inode *ip; + +#ifdef UCB + if (!suser()) + return(NODEV); +#endif + ip = namei(uchar, 0); + if(ip == NULL) + return(NODEV); + if((ip->i_mode&IFMT) != IFBLK) + u.u_error = ENOTBLK; + dev = (dev_t)ip->i_un.i_rdev; + if(major(dev) >= nblkdev) + u.u_error = ENXIO; + iput(ip); + return(dev); +} -- 2.20.1