date and time created 80/04/09 16:04:33 by bill
authorBill Joy <bill@ucbvax.Berkeley.EDU>
Thu, 10 Apr 1980 07:04:33 +0000 (23:04 -0800)
committerBill Joy <bill@ucbvax.Berkeley.EDU>
Thu, 10 Apr 1980 07:04:33 +0000 (23:04 -0800)
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 [new file with mode: 0644]
usr/src/sys/ufs/ffs/ffs_vnops.c [new file with mode: 0644]
usr/src/sys/ufs/ffs/ufs_vnops.c [new file with mode: 0644]
usr/src/sys/ufs/lfs/lfs_vnops.c [new file with mode: 0644]
usr/src/sys/ufs/ufs/ufs_vnops.c [new file with mode: 0644]

diff --git a/usr/src/sys/kern/vfs_syscalls.c b/usr/src/sys/kern/vfs_syscalls.c
new file mode 100644 (file)
index 0000000..b9b8217
--- /dev/null
@@ -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 (file)
index 0000000..5868ae6
--- /dev/null
@@ -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 (file)
index 0000000..7483dec
--- /dev/null
@@ -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 (file)
index 0000000..fd6c2ba
--- /dev/null
@@ -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 (file)
index 0000000..7483dec
--- /dev/null
@@ -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);
+}