[BACK]Return to vfs_syscalls.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / kern

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/sys/kern/vfs_syscalls.c between version 1.42 and 1.43

version 1.42, 1994/12/13 21:52:42 version 1.43, 1994/12/14 16:30:40
Line 37 
Line 37 
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.   * SUCH DAMAGE.
  *   *
  *      @(#)vfs_syscalls.c      8.15 (Berkeley) 6/4/94   *      @(#)vfs_syscalls.c      8.28 (Berkeley) 12/10/94
  */   */
   
 #include <sys/param.h>  #include <sys/param.h>
Line 84  mount(p, uap, retval)
Line 84  mount(p, uap, retval)
         int error, flag;          int error, flag;
         u_long fsindex;          u_long fsindex;
         char fstypename[MFSNAMELEN];          char fstypename[MFSNAMELEN];
           struct vattr va;
         struct nameidata nd;          struct nameidata nd;
   
         /*          /*
          * Must be super user  
          */  
         if (error = suser(p->p_ucred, &p->p_acflag))  
                 return (error);  
         /*  
          * Get vnode to be covered           * Get vnode to be covered
          */           */
         NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,          NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
Line 117  mount(p, uap, retval)
Line 113  mount(p, uap, retval)
                 }                  }
                 mp->mnt_flag |=                  mp->mnt_flag |=
                     SCARG(uap, flags) & (MNT_RELOAD | MNT_FORCE | MNT_UPDATE);                      SCARG(uap, flags) & (MNT_RELOAD | MNT_FORCE | MNT_UPDATE);
                   /*
                    * Only root, or the user that did the original mount is
                    * permitted to update it.
                    */
                   if (mp->mnt_stat.f_owner != p->p_ucred->cr_uid &&
                       (error = suser(p->p_ucred, &p->p_acflag))) {
                           vput(vp);
                           return (error);
                   }
                   /*
                    * Do not allow NFS export by non-root users. Silently
                    * enforce MNT_NOSUID and MNT_NODEV for non-root users.
                    */
                   if (p->p_ucred->cr_uid != 0) {
                           if (SCARG(uap, flags) & MNT_EXPORTED) {
                                   vput(vp);
                                   return (EPERM);
                           }
                           SCARG(uap, flags) |= MNT_NOSUID | MNT_NODEV;
                   }
                 VOP_UNLOCK(vp);                  VOP_UNLOCK(vp);
                 goto update;                  goto update;
         }          }
           /*
            * If the user is not root, ensure that they own the directory
            * onto which we are attempting to mount.
            */
           if ((error = VOP_GETATTR(vp, &va, p->p_ucred, p)) ||
               (va.va_uid != p->p_ucred->cr_uid &&
                (error = suser(p->p_ucred, &p->p_acflag)))) {
                   vput(vp);
                   return (error);
           }
           /*
            * Do not allow NFS export by non-root users. Silently
            * enforce MNT_NOSUID and MNT_NODEV for non-root users.
            */
           if (p->p_ucred->cr_uid != 0) {
                   if (SCARG(uap, flags) & MNT_EXPORTED) {
                           vput(vp);
                           return (EPERM);
                   }
                   SCARG(uap, flags) |= MNT_NOSUID | MNT_NODEV;
           }
         if (error = vinvalbuf(vp, V_SAVE, p->p_ucred, p, 0, 0))          if (error = vinvalbuf(vp, V_SAVE, p->p_ucred, p, 0, 0))
                 return (error);                  return (error);
         if (vp->v_type != VDIR) {          if (vp->v_type != VDIR) {
Line 142  mount(p, uap, retval)
Line 179  mount(p, uap, retval)
         if (fsindex >= nvfssw) {          if (fsindex >= nvfssw) {
 #ifdef COMPAT_09  #ifdef COMPAT_09
 check_num:  check_num:
                 fsindex = (unsigned long)SCARG(uap, type);                  fsindex = (u_long)SCARG(uap, type);
                 if (fsindex >= nvfssw || vfssw[fsindex] == NULL) {                  if (fsindex >= nvfssw || vfssw[fsindex] == NULL) {
                         vput(vp);                          vput(vp);
                         return (ENODEV);                          return (ENODEV);
Line 152  check_num:
Line 189  check_num:
                 return (ENODEV);                  return (ENODEV);
 #endif  #endif
         }          }
           if (vp->v_mountedhere != NULL) {
                   vput(vp);
                   return (EBUSY);
           }
   
         /*          /*
          * Allocate and initialize the file system.           * Allocate and initialize the file system.
Line 165  check_num:
Line 206  check_num:
                 vput(vp);                  vput(vp);
                 return (error);                  return (error);
         }          }
         if (vp->v_mountedhere != NULL) {  
                 vfs_unlock(mp);  
                 free((caddr_t)mp, M_MOUNT);  
                 vput(vp);  
                 return (EBUSY);  
         }  
         /* Do this early in case we block later. */          /* Do this early in case we block later. */
         vfssw[fsindex]->vfs_refcount++;          vfssw[fsindex]->vfs_refcount++;
         vp->v_mountedhere = mp;          vp->v_mountedhere = mp;
         mp->mnt_vnodecovered = vp;          mp->mnt_vnodecovered = vp;
           mp->mnt_stat.f_owner = p->p_ucred->cr_uid;
 update:  update:
         /*          /*
          * Set the mount level flags.           * Set the mount level flags.
Line 207  update:
Line 243  update:
         cache_purge(vp);          cache_purge(vp);
         if (!error) {          if (!error) {
                 TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list);                  TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list);
                   checkdirs(vp);
                 VOP_UNLOCK(vp);                  VOP_UNLOCK(vp);
                 vfs_unlock(mp);                  vfs_unlock(mp);
                 error = VFS_START(mp, 0, p);                  error = VFS_START(mp, 0, p);
Line 221  update:
Line 258  update:
 }  }
   
 /*  /*
    * Scan all active processes to see if any of them have a current
    * or root directory onto which the new filesystem has just been
    * mounted. If so, replace them with the new mount point.
    */
   checkdirs(olddp)
           struct vnode *olddp;
   {
           struct filedesc *fdp;
           struct vnode *newdp;
           struct proc *p;
   
           if (olddp->v_usecount == 1)
                   return;
           if (VFS_ROOT(olddp->v_mountedhere, &newdp))
                   panic("mount: lost mount");
           for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) {
                   fdp = p->p_fd;
                   if (fdp->fd_cdir == olddp) {
                           vrele(fdp->fd_cdir);
                           VREF(newdp);
                           fdp->fd_cdir = newdp;
                   }
                   if (fdp->fd_rdir == olddp) {
                           vrele(fdp->fd_rdir);
                           VREF(newdp);
                           fdp->fd_rdir = newdp;
                   }
           }
           if (rootvnode == olddp) {
                   vrele(rootvnode);
                   VREF(newdp);
                   rootvnode = newdp;
           }
           vput(newdp);
   }
   
   /*
  * Unmount a file system.   * Unmount a file system.
  *   *
  * Note: unmount takes a path to the vnode mounted on as argument,   * Note: unmount takes a path to the vnode mounted on as argument,
Line 245  unmount(p, uap, retval)
Line 319  unmount(p, uap, retval)
         if (error = namei(&nd))          if (error = namei(&nd))
                 return (error);                  return (error);
         vp = nd.ni_vp;          vp = nd.ni_vp;
           mp = vp->v_mount;
   
         /*          /*
          * Unless this is a user mount, then must           * Only root, or the user that did the original mount is
          * have suser privilege.           * permitted to unmount this filesystem.
          */           */
         if (((vp->v_mount->mnt_flag & MNT_USER) == 0) &&          if ((mp->mnt_stat.f_owner != p->p_ucred->cr_uid) &&
             (error = suser(p->p_ucred, &p->p_acflag))) {              (error = suser(p->p_ucred, &p->p_acflag))) {
                 vput(vp);                  vput(vp);
                 return (error);                  return (error);
Line 263  unmount(p, uap, retval)
Line 338  unmount(p, uap, retval)
                 vput(vp);                  vput(vp);
                 return (EINVAL);                  return (EINVAL);
         }          }
         mp = vp->v_mount;  
         vput(vp);          vput(vp);
         return (dounmount(mp, SCARG(uap, flags), p));          return (dounmount(mp, SCARG(uap, flags), p));
 }  }
Line 327  sync(p, uap, retval)
Line 401  sync(p, uap, retval)
         int asyncflag;          int asyncflag;
   
         for (mp = mountlist.tqh_first; mp != NULL; mp = nmp) {          for (mp = mountlist.tqh_first; mp != NULL; mp = nmp) {
                   /*
                    * Get the next pointer in case we hang on vfs_busy
                    * while we are being unmounted.
                    */
                 nmp = mp->mnt_list.tqe_next;                  nmp = mp->mnt_list.tqe_next;
                 /*                  /*
                  * The lock check below is to avoid races with mount                   * The lock check below is to avoid races with mount
Line 339  sync(p, uap, retval)
Line 417  sync(p, uap, retval)
                         VFS_SYNC(mp, MNT_NOWAIT, p->p_ucred, p);                          VFS_SYNC(mp, MNT_NOWAIT, p->p_ucred, p);
                         if (asyncflag)                          if (asyncflag)
                                 mp->mnt_flag |= MNT_ASYNC;                                  mp->mnt_flag |= MNT_ASYNC;
                         vfs_unbusy(mp);                          /*
                            * Get the next pointer again, as the next filesystem
                            * might have been unmounted while we were sync'ing.
                            */
                         nmp = mp->mnt_list.tqe_next;                          nmp = mp->mnt_list.tqe_next;
                           vfs_unbusy(mp);
                 }                  }
         }          }
 #ifdef DEBUG  #ifdef DEBUG
Line 491  fchdir(p, uap, retval)
Line 573  fchdir(p, uap, retval)
         register_t *retval;          register_t *retval;
 {  {
         register struct filedesc *fdp = p->p_fd;          register struct filedesc *fdp = p->p_fd;
         register struct vnode *vp;          struct vnode *vp, *tdp;
           struct mount *mp;
         struct file *fp;          struct file *fp;
         int error;          int error;
   
         if (error = getvnode(fdp, SCARG(uap, fd), &fp))          if (error = getvnode(fdp, SCARG(uap, fd), &fp))
                 return (error);                  return (error);
         vp = (struct vnode *)fp->f_data;          vp = (struct vnode *)fp->f_data;
           VREF(vp);
         VOP_LOCK(vp);          VOP_LOCK(vp);
         if (vp->v_type != VDIR)          if (vp->v_type != VDIR)
                 error = ENOTDIR;                  error = ENOTDIR;
         else          else
                 error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p);                  error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p);
           while (!error && (mp = vp->v_mountedhere) != NULL) {
                   if (mp->mnt_flag & MNT_MLOCK) {
                           mp->mnt_flag |= MNT_MWAIT;
                           sleep((caddr_t)mp, PVFS);
                           continue;
                   }
                   if (error = VFS_ROOT(mp, &tdp))
                           break;
                   vput(vp);
                   vp = tdp;
           }
         VOP_UNLOCK(vp);          VOP_UNLOCK(vp);
         if (error)          if (error) {
                   vrele(vp);
                 return (error);                  return (error);
         VREF(vp);          }
         vrele(fdp->fd_cdir);          vrele(fdp->fd_cdir);
         fdp->fd_cdir = vp;          fdp->fd_cdir = vp;
         return (0);          return (0);
Line 696  compat_43_creat(p, uap, retval)
Line 792  compat_43_creat(p, uap, retval)
                 syscallarg(char *) path;                  syscallarg(char *) path;
                 syscallarg(int) flags;                  syscallarg(int) flags;
                 syscallarg(int) mode;                  syscallarg(int) mode;
         } */ openuap;          } */ nuap;
   
         SCARG(&openuap, path) = SCARG(uap, path);          SCARG(&nuap, path) = SCARG(uap, path);
         SCARG(&openuap, mode) = SCARG(uap, mode);          SCARG(&nuap, mode) = SCARG(uap, mode);
         SCARG(&openuap, flags) = O_WRONLY | O_CREAT | O_TRUNC;          SCARG(&nuap, flags) = O_WRONLY | O_CREAT | O_TRUNC;
         return (open(p, &openuap, retval));          return (open(p, &nuap, retval));
 }  }
 #endif /* COMPAT_43 */  #endif /* COMPAT_43 */
   
Line 721  mknod(p, uap, retval)
Line 817  mknod(p, uap, retval)
         register struct vnode *vp;          register struct vnode *vp;
         struct vattr vattr;          struct vattr vattr;
         int error;          int error;
           int whiteout;
         struct nameidata nd;          struct nameidata nd;
   
         if (error = suser(p->p_ucred, &p->p_acflag))          if (error = suser(p->p_ucred, &p->p_acflag))
Line 729  mknod(p, uap, retval)
Line 826  mknod(p, uap, retval)
         if (error = namei(&nd))          if (error = namei(&nd))
                 return (error);                  return (error);
         vp = nd.ni_vp;          vp = nd.ni_vp;
         if (vp != NULL) {          if (vp != NULL)
                 error = EEXIST;                  error = EEXIST;
                 goto bad;          else {
                   VATTR_NULL(&vattr);
                   vattr.va_mode = (SCARG(uap, mode) & ALLPERMS) &~ p->p_fd->fd_cmask;
                   vattr.va_rdev = SCARG(uap, dev);
                   whiteout = 0;
   
                   switch (SCARG(uap, mode) & S_IFMT) {
                   case S_IFMT:    /* used by badsect to flag bad sectors */
                           vattr.va_type = VBAD;
                           break;
                   case S_IFCHR:
                           vattr.va_type = VCHR;
                           break;
                   case S_IFBLK:
                           vattr.va_type = VBLK;
                           break;
                   case S_IFWHT:
                           whiteout = 1;
                           break;
                   default:
                           error = EINVAL;
                           break;
                   }
         }          }
         VATTR_NULL(&vattr);          if (!error) {
         vattr.va_mode = (SCARG(uap, mode) & ALLPERMS) &~ p->p_fd->fd_cmask;                  VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
         vattr.va_rdev = SCARG(uap, dev);                  if (whiteout) {
                           error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, CREATE);
         switch (SCARG(uap, mode) & S_IFMT) {                          if (error)
         case S_IFMT:    /* used by badsect to flag bad sectors */                                  VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
                 vattr.va_type = VBAD;                          vput(nd.ni_dvp);
                 break;                  } else {
         case S_IFCHR:                          error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp,
                 vattr.va_type = VCHR;                                                  &nd.ni_cnd, &vattr);
                 break;                  }
         case S_IFBLK:          } else {
                 vattr.va_type = VBLK;                  VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
                 break;                  if (nd.ni_dvp == vp)
         default:                          vrele(nd.ni_dvp);
                 error = EINVAL;                  else
                 goto bad;                          vput(nd.ni_dvp);
                   if (vp)
                           vrele(vp);
         }          }
         VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);  
         return (VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr));  
 bad:  
         VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);  
         if (nd.ni_dvp == vp)  
                 vrele(nd.ni_dvp);  
         else  
                 vput(nd.ni_dvp);  
         if (vp)  
                 vrele(vp);  
         return (error);          return (error);
 }  }
   
Line 823  link(p, uap, retval)
Line 934  link(p, uap, retval)
         if (error = namei(&nd))          if (error = namei(&nd))
                 return (error);                  return (error);
         vp = nd.ni_vp;          vp = nd.ni_vp;
         if (vp->v_type == VDIR &&          if (vp->v_type != VDIR ||
             (error = suser(p->p_ucred, &p->p_acflag)))              (error = suser(p->p_ucred, &p->p_acflag)) == 0) {
                 goto bad1;                  nd.ni_cnd.cn_nameiop = CREATE;
         nd.ni_cnd.cn_nameiop = CREATE;                  nd.ni_cnd.cn_flags = LOCKPARENT;
         nd.ni_cnd.cn_flags = LOCKPARENT;                  nd.ni_dirp = SCARG(uap, link);
         nd.ni_dirp = SCARG(uap, link);                  if ((error = namei(&nd)) == 0) {
         if (error = namei(&nd))                          if (nd.ni_vp != NULL)
                 goto bad1;                                  error = EEXIST;
         if (nd.ni_vp != NULL) {                          if (!error) {
                 error = EEXIST;                                  VOP_LEASE(nd.ni_dvp, p, p->p_ucred,
                 goto bad2;                                      LEASE_WRITE);
                                   VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
                                   error = VOP_LINK(nd.ni_dvp, vp, &nd.ni_cnd);
                           } else {
                                   VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
                                   if (nd.ni_dvp == nd.ni_vp)
                                           vrele(nd.ni_dvp);
                                   else
                                           vput(nd.ni_dvp);
                                   if (nd.ni_vp)
                                           vrele(nd.ni_vp);
                           }
                   }
         }          }
         VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);  
         VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);  
         error = VOP_LINK(nd.ni_dvp, vp, &nd.ni_cnd);  
         vrele(vp);  
         return (error);  
 bad2:  
         VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);  
         if (nd.ni_dvp == nd.ni_vp)  
                 vrele(nd.ni_dvp);  
         else  
                 vput(nd.ni_dvp);  
         if (nd.ni_vp)  
                 vrele(nd.ni_vp);  
 bad1:  
         vrele(vp);          vrele(vp);
         return (error);          return (error);
 }  }
Line 872  symlink(p, uap, retval)
Line 981  symlink(p, uap, retval)
   
         MALLOC(path, char *, MAXPATHLEN, M_NAMEI, M_WAITOK);          MALLOC(path, char *, MAXPATHLEN, M_NAMEI, M_WAITOK);
         if (error = copyinstr(SCARG(uap, path), path, MAXPATHLEN, (u_int*)0))          if (error = copyinstr(SCARG(uap, path), path, MAXPATHLEN, (u_int*)0))
                 goto bad;                  goto out;
         NDINIT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, SCARG(uap, link), p);          NDINIT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, SCARG(uap, link), p);
         if (error = namei(&nd))          if (error = namei(&nd))
                 goto bad;                  goto out;
         if (nd.ni_vp) {          if (nd.ni_vp) {
                 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);                  VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
                 if (nd.ni_dvp == nd.ni_vp)                  if (nd.ni_dvp == nd.ni_vp)
Line 884  symlink(p, uap, retval)
Line 993  symlink(p, uap, retval)
                         vput(nd.ni_dvp);                          vput(nd.ni_dvp);
                 vrele(nd.ni_vp);                  vrele(nd.ni_vp);
                 error = EEXIST;                  error = EEXIST;
                 goto bad;                  goto out;
         }          }
         VATTR_NULL(&vattr);          VATTR_NULL(&vattr);
         vattr.va_mode = ACCESSPERMS &~ p->p_fd->fd_cmask;          vattr.va_mode = ACCESSPERMS &~ p->p_fd->fd_cmask;
         VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);          VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
         error = VOP_SYMLINK(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr, path);          error = VOP_SYMLINK(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr, path);
 bad:  out:
         FREE(path, M_NAMEI);          FREE(path, M_NAMEI);
         return (error);          return (error);
 }  }
   
 /*  /*
    * Delete a whiteout from the filesystem.
    */
   /* ARGSUSED */
   undelete(p, uap, retval)
           struct proc *p;
           register struct undelete_args /* {
                   syscallarg(char *) path;
           } */ *uap;
           register_t *retval;
   {
           int error;
           struct nameidata nd;
   
           NDINIT(&nd, DELETE, LOCKPARENT|DOWHITEOUT, UIO_USERSPACE,
               SCARG(uap, path), p);
           error = namei(&nd);
           if (error)
                   return (error);
   
           if (nd.ni_vp != NULLVP || !(nd.ni_cnd.cn_flags & ISWHITEOUT)) {
                   VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
                   if (nd.ni_dvp == nd.ni_vp)
                           vrele(nd.ni_dvp);
                   else
                           vput(nd.ni_dvp);
                   if (nd.ni_vp)
                           vrele(nd.ni_vp);
                   return (EEXIST);
           }
   
           VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
           if (error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, DELETE))
                   VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
           vput(nd.ni_dvp);
           return (error);
   }
   
   /*
  * Delete a name from the filesystem.   * Delete a name from the filesystem.
  */   */
 /* ARGSUSED */  /* ARGSUSED */
Line 917  unlink(p, uap, retval)
Line 1064  unlink(p, uap, retval)
         VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);          VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
         VOP_LOCK(vp);          VOP_LOCK(vp);
   
         if (vp->v_type == VDIR &&          if (vp->v_type != VDIR ||
             (error = suser(p->p_ucred, &p->p_acflag)))              (error = suser(p->p_ucred, &p->p_acflag)) == 0) {
                 goto bad;                  /*
         /*                   * The root of a mounted filesystem cannot be deleted.
          * The root of a mounted filesystem cannot be deleted.                   */
          */                  if (vp->v_flag & VROOT)
         if (vp->v_flag & VROOT) {                          error = EBUSY;
                 error = EBUSY;                  else
                 goto bad;                          (void)vnode_pager_uncache(vp);
           }
   
           if (!error) {
                   VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
                   error = VOP_REMOVE(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd);
           } else {
                   VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
                   if (nd.ni_dvp == vp)
                           vrele(nd.ni_dvp);
                   else
                           vput(nd.ni_dvp);
                   if (vp != NULLVP)
                           vput(vp);
         }          }
         (void)vnode_pager_uncache(vp);  
         VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);  
         return (VOP_REMOVE(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd));  
 bad:  
         VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);  
         if (nd.ni_dvp == vp)  
                 vrele(nd.ni_dvp);  
         else  
                 vput(nd.ni_dvp);  
         vput(vp);  
         return (error);          return (error);
 }  }
   
Line 1103  compat_43_lstat(p, uap, retval)
Line 1253  compat_43_lstat(p, uap, retval)
         } */ *uap;          } */ *uap;
         register_t *retval;          register_t *retval;
 {  {
         struct stat sb;          struct vnode *vp, *dvp;
           struct stat sb, sb1;
         struct ostat osb;          struct ostat osb;
         int error;          int error;
         struct nameidata nd;          struct nameidata nd;
   
         NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF, UIO_USERSPACE,          NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | LOCKPARENT, UIO_USERSPACE,
             SCARG(uap, path), p);              SCARG(uap, path), p);
         if (error = namei(&nd))          if (error = namei(&nd))
                 return (error);                  return (error);
         error = vn_stat(nd.ni_vp, &sb, p);          /*
         vput(nd.ni_vp);           * For symbolic links, always return the attributes of its
         if (error)           * containing directory, except for mode, size, and links.
                 return (error);           */
           vp = nd.ni_vp;
           dvp = nd.ni_dvp;
           if (vp->v_type != VLNK) {
                   if (dvp == vp)
                           vrele(dvp);
                   else
                           vput(dvp);
                   error = vn_stat(vp, &sb, p);
                   vput(vp);
                   if (error)
                           return (error);
           } else {
                   error = vn_stat(dvp, &sb, p);
                   vput(dvp);
                   if (error) {
                           vput(vp);
                           return (error);
                   }
                   error = vn_stat(vp, &sb1, p);
                   vput(vp);
                   if (error)
                           return (error);
                   sb.st_mode &= ~S_IFDIR;
                   sb.st_mode |= S_IFLNK;
                   sb.st_nlink = sb1.st_nlink;
                   sb.st_size = sb1.st_size;
                   sb.st_blocks = sb1.st_blocks;
           }
         cvtstat(&sb, &osb);          cvtstat(&sb, &osb);
         error = copyout((caddr_t)&osb, (caddr_t)SCARG(uap, ub), sizeof (osb));          error = copyout((caddr_t)&osb, (caddr_t)SCARG(uap, ub), sizeof (osb));
         return (error);          return (error);
Line 1637  compat_43_truncate(p, uap, retval)
Line 1816  compat_43_truncate(p, uap, retval)
         } */ *uap;          } */ *uap;
         register_t *retval;          register_t *retval;
 {  {
         struct truncate_args nuap;          struct truncate_args /* {
                   syscallarg(char *) path;
                   syscallarg(int) pad;
                   syscallarg(off_t) length;
           } */ nuap;
   
         SCARG(&nuap, path) = SCARG(uap, path);          SCARG(&nuap, path) = SCARG(uap, path);
         SCARG(&nuap, length) = SCARG(uap, length);          SCARG(&nuap, length) = SCARG(uap, length);
Line 1656  compat_43_ftruncate(p, uap, retval)
Line 1839  compat_43_ftruncate(p, uap, retval)
         } */ *uap;          } */ *uap;
         register_t *retval;          register_t *retval;
 {  {
         struct ftruncate_args nuap;          struct ftruncate_args /* {
                   syscallarg(int) fd;
                   syscallarg(int) pad;
                   syscallarg(off_t) length;
           } */ nuap;
   
         SCARG(&nuap, fd) = SCARG(uap, fd);          SCARG(&nuap, fd) = SCARG(uap, fd);
         SCARG(&nuap, length) = SCARG(uap, length);          SCARG(&nuap, length) = SCARG(uap, length);
Line 1964  unionread:
Line 2151  unionread:
 #ifdef UNION  #ifdef UNION
 {  {
         extern int (**union_vnodeop_p)();          extern int (**union_vnodeop_p)();
         extern struct vnode *union_lowervp __P((struct vnode *));          extern struct vnode *union_dircache __P((struct vnode *));
   
         if ((SCARG(uap, count) == auio.uio_resid) &&          if ((SCARG(uap, count) == auio.uio_resid) &&
             (vp->v_op == union_vnodeop_p)) {              (vp->v_op == union_vnodeop_p)) {
                 struct vnode *lvp;                  struct vnode *lvp;
   
                 lvp = union_lowervp(vp);                  lvp = union_dircache(vp);
                   if (lvp != NULLVP) {
                           struct vattr va;
   
                           /*
                            * If the directory is opaque,
                            * then don't show lower entries
                            */
                           error = VOP_GETATTR(vp, &va, fp->f_cred, p);
                           if (va.va_flags & OPAQUE) {
                                   vput(lvp);
                                   lvp = NULL;
                           }
                   }
   
                 if (lvp != NULLVP) {                  if (lvp != NULLVP) {
                         VOP_LOCK(lvp);  
                         error = VOP_OPEN(lvp, FREAD, fp->f_cred, p);                          error = VOP_OPEN(lvp, FREAD, fp->f_cred, p);
                         VOP_UNLOCK(lvp);                          VOP_UNLOCK(lvp);
   
Line 2057  unionread:
Line 2257  unionread:
 #ifdef UNION  #ifdef UNION
 {  {
         extern int (**union_vnodeop_p)();          extern int (**union_vnodeop_p)();
         extern struct vnode *union_lowervp __P((struct vnode *));          extern struct vnode *union_dircache __P((struct vnode *));
   
         if ((SCARG(uap, count) == auio.uio_resid) &&          if ((SCARG(uap, count) == auio.uio_resid) &&
             (vp->v_op == union_vnodeop_p)) {              (vp->v_op == union_vnodeop_p)) {
                 struct vnode *lvp;                  struct vnode *lvp;
   
                 lvp = union_lowervp(vp);                  lvp = union_dircache(vp);
                   if (lvp != NULLVP) {
                           struct vattr va;
   
                           /*
                            * If the directory is opaque,
                            * then don't show lower entries
                            */
                           error = VOP_GETATTR(vp, &va, fp->f_cred, p);
                           if (va.va_flags & OPAQUE) {
                                   vput(lvp);
                                   lvp = NULL;
                           }
                   }
   
                 if (lvp != NULLVP) {                  if (lvp != NULLVP) {
                         VOP_LOCK(lvp);  
                         error = VOP_OPEN(lvp, FREAD, fp->f_cred, p);                          error = VOP_OPEN(lvp, FREAD, fp->f_cred, p);
                         VOP_UNLOCK(lvp);                          VOP_UNLOCK(lvp);
   

Legend:
Removed from v.1.42  
changed lines
  Added in v.1.43

CVSweb <webmaster@jp.NetBSD.org>