1: /*
   2:  * Copyright (c) 1982, 1986, 1989, 1993
   3:  *	The Regents of the University of California.  All rights reserved.
   4:  * (c) UNIX System Laboratories, Inc.
   5:  * All or some portions of this file are derived from material licensed
   6:  * to the University of California by American Telephone and Telegraph
   7:  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
   8:  * the permission of UNIX System Laboratories, Inc.
   9:  *
  10:  * Redistribution and use in source and binary forms, with or without
  11:  * modification, are permitted provided that the following conditions
  12:  * are met:
  13:  * 1. Redistributions of source code must retain the above copyright
  14:  *    notice, this list of conditions and the following disclaimer.
  15:  * 2. Redistributions in binary form must reproduce the above copyright
  16:  *    notice, this list of conditions and the following disclaimer in the
  17:  *    documentation and/or other materials provided with the distribution.
  18:  * 3. All advertising materials mentioning features or use of this software
  19:  *    must display the following acknowledgement:
  20:  *	This product includes software developed by the University of
  21:  *	California, Berkeley and its contributors.
  22:  * 4. Neither the name of the University nor the names of its contributors
  23:  *    may be used to endorse or promote products derived from this software
  24:  *    without specific prior written permission.
  25:  *
  26:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  27:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  28:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  29:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  30:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  31:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  32:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  33:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  34:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  35:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  36:  * SUCH DAMAGE.
  37:  *
  38:  *	@(#)vfs_vnops.c	8.14.4 (2.11BSD) 1999/9/13
  39:  */
  40: 
  41: #include <sys/param.h>
  42: #include <sys/file.h>
  43: #include <sys/user.h>
  44: #include <sys/namei.h>
  45: #include <sys/inode.h>
  46: #include <sys/stat.h>
  47: 
  48: /*
  49:  * 2.11BSD does not have "vnodes", having instead only old fashioned "inodes".
  50:  * The routine names (i.e. vn_open) were retained since the functions them-
  51:  * selves were ported over with minimal change.  Retaining the 4.4 function
  52:  * names also makes it easier to follow the logic flow when reading the 4.4
  53:  * sources.  Also, changing the names from vn_* to in_* could have caused
  54:  * confusion with the networking routines since 'in_' and 'ip_' are frequently
  55:  * used in the networking code.
  56:  *
  57:  * The tab spacing has been altered to be (to me) more readable.
  58: */
  59: 
  60: /*
  61:  * Common code for vnode open operations.
  62:  * Check permissions, and call the VOP_OPEN (openi for 2.11) or VOP_CREATE
  63:  * (maknode) routine.
  64:  */
  65: vn_open(ndp, fmode, cmode)
  66:     register struct nameidata *ndp;
  67:     int fmode, cmode;
  68:     {
  69:     register struct inode *ip;
  70:     register int error;
  71: 
  72:     if  (fmode & O_CREAT)
  73:         {
  74:         if  ((fmode & O_EXCL) == 0)
  75:             ndp->ni_nameiop |= (CREATE|FOLLOW);
  76:         else
  77:             ndp->ni_nameiop= CREATE;
  78:         ip = namei(ndp);
  79:         if  (ip == NULL)
  80:             {
  81:             if  (u.u_error)
  82:                 goto retuerr;
  83:             ip = maknode(cmode, ndp);
  84:             if  (ip == NULL)
  85:                 goto retuerr;
  86:             fmode &= ~O_TRUNC;
  87:             }
  88:         else
  89:             {
  90:             if  (fmode & O_EXCL)
  91:                 {
  92:                 error = EEXIST;
  93:                 goto bad;
  94:                 }
  95:             fmode &= ~O_CREAT;
  96:             }
  97:         }
  98:     else
  99:         {
 100:         ndp->ni_nameiop = LOOKUP | FOLLOW;
 101:         ip = namei(ndp);
 102:         if  (ip == NULL)
 103:             goto retuerr;
 104:         }
 105:     if  ((ip->i_mode & IFMT) == IFSOCK)
 106:         {
 107:         error = EOPNOTSUPP;
 108:         goto bad;
 109:         }
 110:     if  ((ip->i_flags & APPEND) && (fmode&(FWRITE|O_APPEND)) == FWRITE)
 111:         {
 112:         error = EPERM;
 113:         goto bad;
 114:         }
 115:     if  ((fmode & O_CREAT) == 0)
 116:         {
 117:         if  (fmode & FREAD)
 118:             {
 119:             if  (access(ip, IREAD))
 120:                 {
 121:                 error = u.u_error;  /* XXX */
 122:                 goto bad;
 123:                 }
 124:             }
 125:         if  (fmode & (FWRITE | O_TRUNC))
 126:             {
 127:             if  ((ip->i_mode & IFMT) == IFDIR)
 128:                 {
 129:                 error = EISDIR;
 130:                 goto bad;
 131:                 }
 132:             if  (access(ip, IWRITE))
 133:                 {
 134:                 error = u.u_error;
 135:                 goto bad;
 136:                 }
 137:             }
 138:         }
 139:     if  (fmode & O_TRUNC)
 140:         itrunc(ip, (off_t)0, fmode & O_FSYNC ? IO_SYNC : 0);
 141: /*
 142:  * 4.4 returns the vnode locked from vn_open which means that each caller
 143:  * has to go and unlock it.
 144:  *
 145:  * 2.11 returns the inode unlocked (for now).
 146: */
 147:     iunlock(ip);        /* because namei returns a locked inode */
 148:     if  (setjmp(&u.u_qsave))
 149:         {
 150:         error = EINTR;  /* opens are not restarted after signals */
 151:         goto lbad;
 152:         }
 153:     if  (error = openi(ip, fmode))
 154:         goto lbad;
 155:     return(0);
 156: /*
 157:  * Gratuitous lock but it does (correctly) implement the earlier behaviour of
 158:  * copen (it also avoids a panic in iput).
 159: */
 160: 
 161: lbad:
 162:     ilock(ip);
 163: 
 164: bad:
 165: /*
 166:  * Do NOT do an 'ilock' here - this tag is to be used only when the inode is
 167:  * locked (i.e. from namei).
 168: */
 169:     iput(ip);
 170:     return(error);
 171: retuerr:
 172:     return(u.u_error);  /* XXX - Bletch */
 173:     }
 174: 
 175: /*
 176:  * Inode close call.  Pipes and sockets do NOT enter here.  This routine is
 177:  * used by the kernel to close files it opened for itself (see kern_acct.c
 178:  * for a good example of this).  The kernel does not create sockets or pipes
 179:  * on its own behalf.
 180:  *
 181:  * The difference between this routine and vn_closefile below is that vn_close
 182:  * takes an "inode *" as a first argument and is passed the flags by the caller
 183:  * while vn_closefile (called from the closef routine for DTYPE_INODE inodes)
 184:  * takes a "file *" and extracts the flags from the file structure.
 185:  */
 186: vn_close(ip, flags)
 187:     register struct inode *ip;
 188:     int flags;
 189:     {
 190:     register int error;
 191: 
 192:     error = closei(ip, flags);
 193:     irele(ip);          /* assumes inode is unlocked */
 194:     return(error);
 195:     }
 196: 
 197: /*
 198:  * File table inode close routine.  This is called from 'closef()' via the
 199:  * "Fops" table (the 'inodeops' entry).
 200:  *
 201:  * NOTE: pipes are a special case of inode and have their own 'pipe_close'
 202:  * entry in the 'pipeops' table. See sys_pipe.c for pipe_close().
 203:  *
 204:  * In 4.4BSD this routine called vn_close() but since 2.11 does not do the
 205:  * writecheck counting we can skip the overhead of nesting another level down
 206:  * and call closei() and irele() ourself.
 207:  */
 208: vn_closefile(fp)
 209:     register struct file *fp;
 210:     {
 211:     register struct inode *ip = (struct inode *)fp->f_data;
 212: 
 213: /*
 214:  * Need to clear the inode pointer in the file structure so that the
 215:  * inode is not seen during the scan for aliases of character or block
 216:  * devices in closei().
 217: */
 218:     fp->f_data = (caddr_t)0;    /* XXX */
 219:     irele(ip);
 220:     return(closei(ip, fp->f_flag));
 221:     }

Defined functions

vn_close defined in line 186; never used
vn_closefile defined in line 208; used 2 times
vn_open defined in line 65; used 1 times
Last modified: 1999-09-14
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 86
Valid CSS Valid XHTML 1.0 Strict