handles new uba stuff and fix page freeing problem
[unix-history] / usr / src / sys / kern / vfs_vnops.c
index d2d2619..a817582 100644 (file)
@@ -1,4 +1,4 @@
-/*     vfs_vnops.c     3.2     %G%     */
+/*     vfs_vnops.c     4.20    82/01/25        */
 
 #include "../h/param.h"
 #include "../h/systm.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
 #include "../h/inode.h"
 #include "../h/reg.h"
 #include "../h/acct.h"
 #include "../h/inode.h"
 #include "../h/reg.h"
 #include "../h/acct.h"
+#include "../h/mount.h"
+#include "../h/socket.h"
+#include "../h/socketvar.h"
+#include "../h/proc.h"
 
 /*
 
 /*
- * Convert a user supplied
- * file descriptor into a pointer
- * to a file structure.
- * Only task is to check range
- * of the descriptor.
+ * Convert a user supplied file descriptor into a pointer
+ * to a file structure.  Only task is to check range of the descriptor.
+ * Critical paths should use the GETF macro, defined in inline.h.
  */
 struct file *
 getf(f)
  */
 struct file *
 getf(f)
-register int f;
+       register int f;
 {
        register struct file *fp;
 
 {
        register struct file *fp;
 
-       if(0 <= f && f < NOFILE) {
-               fp = u.u_ofile[f];
-               if(fp != NULL)
-                       return(fp);
+       if ((unsigned)f >= NOFILE || (fp = u.u_ofile[f]) == NULL) {
+               u.u_error = EBADF;
+               return (NULL);
        }
        }
-       u.u_error = EBADF;
-       return(NULL);
+       return (fp);
 }
 
 /*
 }
 
 /*
@@ -43,88 +43,101 @@ register int f;
  * Decrement reference count on the inode following
  * removal to the referencing file structure.
  * Call device handler on last close.
  * Decrement reference count on the inode following
  * removal to the referencing file structure.
  * Call device handler on last close.
+ * Nouser indicates that the user isn't available to present
+ * errors to.
  */
  */
-closef(fp)
-register struct file *fp;
+closef(fp, nouser)
+       register struct file *fp;
 {
        register struct inode *ip;
 {
        register struct inode *ip;
+       register struct mount *mp;
        int flag, mode;
        dev_t dev;
        register int (*cfunc)();
        int flag, mode;
        dev_t dev;
        register int (*cfunc)();
-       struct chan *cp;
 
 
-       if(fp == NULL)
+       if (fp == NULL)
                return;
        if (fp->f_count > 1) {
                fp->f_count--;
                return;
        }
                return;
        if (fp->f_count > 1) {
                fp->f_count--;
                return;
        }
-       ip = fp->f_inode;
        flag = fp->f_flag;
        flag = fp->f_flag;
-       cp = fp->f_un.f_chan;
-       dev = (dev_t)ip->i_un.i_rdev;
-       mode = ip->i_mode;
-
-       plock(ip);
-       fp->f_count = 0;
-       if(flag & FPIPE) {
-               ip->i_mode &= ~(IREAD|IWRITE);
-               wakeup((caddr_t)ip+1);
-               wakeup((caddr_t)ip+2);
+       if (flag & FSOCKET) {
+               u.u_error = 0;                  /* XXX */
+               soclose(fp->f_socket, nouser);
+               if (nouser == 0 && u.u_error)
+                       return;
+               fp->f_socket = 0;
+               fp->f_count = 0;
+               return;
        }
        }
+       ip = fp->f_inode;
+       dev = (dev_t)ip->i_un.i_rdev;
+       mode = ip->i_mode & IFMT;
+       ilock(ip);
        iput(ip);
        iput(ip);
+       fp->f_count = 0;
 
 
-       switch(mode&IFMT) {
+       switch (mode) {
 
        case IFCHR:
 
        case IFCHR:
-       case IFMPC:
                cfunc = cdevsw[major(dev)].d_close;
                break;
 
        case IFBLK:
                cfunc = cdevsw[major(dev)].d_close;
                break;
 
        case IFBLK:
-       case IFMPB:
+               /*
+                * We don't want to really close the device if it is mounted
+                */
+               for (mp = mount; mp < &mount[NMOUNT]; mp++)
+                       if (mp->m_bufp != NULL && mp->m_dev == dev)
+                               return;
                cfunc = bdevsw[major(dev)].d_close;
                break;
                cfunc = bdevsw[major(dev)].d_close;
                break;
+
        default:
                return;
        }
        default:
                return;
        }
-
-       if (flag & FMP)
-               goto call;
-
-       for(fp=file; fp < &file[NFILE]; fp++)
-               if (fp->f_count && fp->f_inode==ip)
+       for (fp = file; fp < fileNFILE; fp++) {
+               if (fp->f_flag & FSOCKET)
+                       continue;
+               if (fp->f_count && (ip = fp->f_inode) &&
+                   ip->i_un.i_rdev == dev && (ip->i_mode&IFMT) == mode)
                        return;
                        return;
-
-call:
-       (*cfunc)(dev, flag, cp);
+       }
+       if (mode == IFBLK) {
+               /*
+                * On last close of a block device (that isn't mounted)
+                * we must invalidate any in core blocks
+                */
+               bflush(dev);
+               binval(dev);
+       }
+       (*cfunc)(dev, flag, fp);
 }
 
 /*
 }
 
 /*
- * openi called to allow handler
+ * Openi called to allow handler
  * of special files to initialize and
  * validate before actual IO.
  */
 openi(ip, rw)
  * of special files to initialize and
  * validate before actual IO.
  */
 openi(ip, rw)
-register struct inode *ip;
+       register struct inode *ip;
 {
        dev_t dev;
        register unsigned int maj;
 
        dev = (dev_t)ip->i_un.i_rdev;
        maj = major(dev);
 {
        dev_t dev;
        register unsigned int maj;
 
        dev = (dev_t)ip->i_un.i_rdev;
        maj = major(dev);
-       switch(ip->i_mode&IFMT) {
+       switch (ip->i_mode&IFMT) {
 
        case IFCHR:
 
        case IFCHR:
-       case IFMPC:
-               if(maj >= nchrdev)
+               if (maj >= nchrdev)
                        goto bad;
                (*cdevsw[maj].d_open)(dev, rw);
                break;
 
        case IFBLK:
                        goto bad;
                (*cdevsw[maj].d_open)(dev, rw);
                break;
 
        case IFBLK:
-       case IFMPB:
-               if(maj >= nblkdev)
+               if (maj >= nblkdev)
                        goto bad;
                (*bdevsw[maj].d_open)(dev, rw);
        }
                        goto bad;
                (*bdevsw[maj].d_open)(dev, rw);
        }
@@ -148,35 +161,35 @@ bad:
  * permissions.
  */
 access(ip, mode)
  * permissions.
  */
 access(ip, mode)
-register struct inode *ip;
+       register struct inode *ip;
+       int mode;
 {
        register m;
 
        m = mode;
 {
        register m;
 
        m = mode;
-       if(m == IWRITE) {
-               if(getfs(ip->i_dev)->s_ronly != 0) {
+       if (m == IWRITE) {
+               if (getfs(ip->i_dev)->s_ronly != 0) {
                        u.u_error = EROFS;
                        u.u_error = EROFS;
-                       return(1);
+                       return (1);
                }
                if (ip->i_flag&ITEXT)           /* try to free text */
                        xrele(ip);
                }
                if (ip->i_flag&ITEXT)           /* try to free text */
                        xrele(ip);
-               if(ip->i_flag & ITEXT) {
+               if (ip->i_flag & ITEXT) {
                        u.u_error = ETXTBSY;
                        u.u_error = ETXTBSY;
-                       return(1);
+                       return (1);
                }
        }
                }
        }
-       if(u.u_uid == 0)
-               return(0);
-       if(u.u_uid != ip->i_uid) {
+       if (u.u_uid == 0)
+               return (0);
+       if (u.u_uid != ip->i_uid) {
                m >>= 3;
                m >>= 3;
-               if(u.u_gid != ip->i_gid)
+               if (u.u_gid != ip->i_gid)
                        m >>= 3;
        }
                        m >>= 3;
        }
-       if((ip->i_mode&m) != 0)
-               return(0);
-
+       if ((ip->i_mode&m) != 0)
+               return (0);
        u.u_error = EACCES;
        u.u_error = EACCES;
-       return(1);
+       return (1);
 }
 
 /*
 }
 
 /*
@@ -193,14 +206,14 @@ owner()
        register struct inode *ip;
 
        ip = namei(uchar, 0);
        register struct inode *ip;
 
        ip = namei(uchar, 0);
-       if(ip == NULL)
-               return(NULL);
-       if(u.u_uid == ip->i_uid)
-               return(ip);
-       if(suser())
-               return(ip);
+       if (ip == NULL)
+               return (NULL);
+       if (u.u_uid == ip->i_uid)
+               return (ip);
+       if (suser())
+               return (ip);
        iput(ip);
        iput(ip);
-       return(NULL);
+       return (NULL);
 }
 
 /*
 }
 
 /*
@@ -210,12 +223,12 @@ owner()
 suser()
 {
 
 suser()
 {
 
-       if(u.u_uid == 0) {
+       if (u.u_uid == 0) {
                u.u_acflag |= ASU;
                u.u_acflag |= ASU;
-               return(1);
+               return (1);
        }
        u.u_error = EPERM;
        }
        u.u_error = EPERM;
-       return(0);
+       return (0);
 }
 
 /*
 }
 
 /*
@@ -225,24 +238,22 @@ ufalloc()
 {
        register i;
 
 {
        register i;
 
-       for(i=0; i<NOFILE; i++)
-               if(u.u_ofile[i] == NULL) {
+       for (i=0; i<NOFILE; i++)
+               if (u.u_ofile[i] == NULL) {
                        u.u_r.r_val1 = i;
                        u.u_pofile[i] = 0;
                        u.u_r.r_val1 = i;
                        u.u_pofile[i] = 0;
-                       return(i);
+                       return (i);
                }
        u.u_error = EMFILE;
                }
        u.u_error = EMFILE;
-       return(-1);
+       return (-1);
 }
 
 }
 
+struct file *lastf;
 /*
  * Allocate a user file descriptor
  * and a file structure.
  * Initialize the descriptor
  * to point at the file structure.
 /*
  * Allocate a user file descriptor
  * and a file structure.
  * Initialize the descriptor
  * to point at the file structure.
- *
- * no file -- if there are no available
- *     file structures.
  */
 struct file *
 falloc()
  */
 struct file *
 falloc()
@@ -251,16 +262,24 @@ falloc()
        register i;
 
        i = ufalloc();
        register i;
 
        i = ufalloc();
-       if(i < 0)
-               return(NULL);
-       for(fp = &file[0]; fp < &file[NFILE]; fp++)
-               if(fp->f_count == 0) {
-                       u.u_ofile[i] = fp;
-                       fp->f_count++;
-                       fp->f_un.f_offset = 0;
-                       return(fp);
-               }
-       printf("no file\n");
+       if (i < 0)
+               return (NULL);
+       if (lastf == 0)
+               lastf = file;
+       for (fp = lastf; fp < fileNFILE; fp++)
+               if (fp->f_count == 0)
+                       goto slot;
+       for (fp = file; fp < lastf; fp++)
+               if (fp->f_count == 0)
+                       goto slot;
+       tablefull("file");
        u.u_error = ENFILE;
        u.u_error = ENFILE;
-       return(NULL);
+       return (NULL);
+slot:
+       u.u_ofile[i] = fp;
+       fp->f_count++;
+       fp->f_offset = 0;
+       fp->f_inode = 0;
+       lastf = fp + 1;
+       return (fp);
 }
 }