reorganization to move ufsmount ops to be vnode ops;
[unix-history] / usr / src / sys / kern / vfs_syscalls.c
index 014a1f0..61920f5 100644 (file)
@@ -4,7 +4,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)vfs_syscalls.c      7.69 (Berkeley) %G%
+ *     @(#)vfs_syscalls.c      7.74 (Berkeley) %G%
  */
 
 #include "param.h"
  */
 
 #include "param.h"
@@ -552,9 +552,11 @@ open(p, uap, retval)
        struct nameidata *ndp;
        register struct filedesc *fdp = p->p_fd;
        register struct file *fp;
        struct nameidata *ndp;
        register struct filedesc *fdp = p->p_fd;
        register struct file *fp;
+       register struct vnode *vp;
        int fmode, cmode;
        struct file *nfp;
        int fmode, cmode;
        struct file *nfp;
-       int indx, error;
+       int type, indx, error;
+       struct flock lf;
        struct nameidata nd;
        extern struct fileops vnops;
 
        struct nameidata nd;
        extern struct fileops vnops;
 
@@ -568,8 +570,7 @@ open(p, uap, retval)
        ndp->ni_dirp = uap->fname;
        p->p_dupfd = -indx - 1;                 /* XXX check for fdopen */
        if (error = vn_open(ndp, p, fmode, cmode)) {
        ndp->ni_dirp = uap->fname;
        p->p_dupfd = -indx - 1;                 /* XXX check for fdopen */
        if (error = vn_open(ndp, p, fmode, cmode)) {
-               crfree(fp->f_cred);
-               fp->f_count--;
+               ffree(fp);
                if (error == ENODEV &&          /* XXX from fdopen */
                    p->p_dupfd >= 0 &&
                    (error = dupfdopen(fdp, indx, p->p_dupfd, fmode)) == 0) {
                if (error == ENODEV &&          /* XXX from fdopen */
                    p->p_dupfd >= 0 &&
                    (error = dupfdopen(fdp, indx, p->p_dupfd, fmode)) == 0) {
@@ -581,10 +582,32 @@ open(p, uap, retval)
                fdp->fd_ofiles[indx] = NULL;
                return (error);
        }
                fdp->fd_ofiles[indx] = NULL;
                return (error);
        }
+       vp = ndp->ni_vp;
        fp->f_flag = fmode & FMASK;
        fp->f_flag = fmode & FMASK;
+       if (fmode & (O_EXLOCK | O_SHLOCK)) {
+               lf.l_whence = SEEK_SET;
+               lf.l_start = 0;
+               lf.l_len = 0;
+               if (fmode & O_EXLOCK)
+                       lf.l_type = F_WRLCK;
+               else
+                       lf.l_type = F_RDLCK;
+               type = F_FLOCK;
+               if ((fmode & FNONBLOCK) == 0)
+                       type |= F_WAIT;
+               if (error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, type)) {
+                       VOP_UNLOCK(vp);
+                       (void) vn_close(vp, fp->f_flag, fp->f_cred, p);
+                       ffree(fp);
+                       fdp->fd_ofiles[indx] = NULL;
+                       return (error);
+               }
+               fp->f_flag |= FHASLOCK;
+       }
+       VOP_UNLOCK(vp);
        fp->f_type = DTYPE_VNODE;
        fp->f_ops = &vnops;
        fp->f_type = DTYPE_VNODE;
        fp->f_ops = &vnops;
-       fp->f_data = (caddr_t)ndp->ni_vp;
+       fp->f_data = (caddr_t)vp;
        *retval = indx;
        return (0);
 }
        *retval = indx;
        return (0);
 }
@@ -1450,24 +1473,21 @@ rename(p, uap, retval)
        int *retval;
 {
        register struct vnode *tvp, *fvp, *tdvp;
        int *retval;
 {
        register struct vnode *tvp, *fvp, *tdvp;
-       register struct nameidata *ndp;
+       struct nameidata fromnd, tond;
        int error;
        int error;
-       struct nameidata nd, tond;
 
 
-       ndp = &nd;
-       ndp->ni_nameiop = DELETE | WANTPARENT;
-       ndp->ni_segflg = UIO_USERSPACE;
-       ndp->ni_dirp = uap->from;
-       if (error = namei(ndp, p))
+       fromnd.ni_nameiop = DELETE | WANTPARENT | SAVESTART;
+       fromnd.ni_segflg = UIO_USERSPACE;
+       fromnd.ni_dirp = uap->from;
+       if (error = namei(&fromnd, p))
                return (error);
                return (error);
-       fvp = ndp->ni_vp;
-       nddup(ndp, &tond);
-       tond.ni_nameiop = RENAME | LOCKPARENT | LOCKLEAF | NOCACHE;
+       fvp = fromnd.ni_vp;
+       tond.ni_nameiop = RENAME | LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART;
        tond.ni_segflg = UIO_USERSPACE;
        tond.ni_dirp = uap->to;
        if (error = namei(&tond, p)) {
        tond.ni_segflg = UIO_USERSPACE;
        tond.ni_dirp = uap->to;
        if (error = namei(&tond, p)) {
-               VOP_ABORTOP(ndp);
-               vrele(ndp->ni_dvp);
+               VOP_ABORTOP(&fromnd);
+               vrele(fromnd.ni_dvp);
                vrele(fvp);
                goto out1;
        }
                vrele(fvp);
                goto out1;
        }
@@ -1493,14 +1513,17 @@ rename(p, uap, retval)
        if (fvp == tdvp)
                error = EINVAL;
        /*
        if (fvp == tdvp)
                error = EINVAL;
        /*
-        * If source is the same as the destination,
+        * If source is the same as the destination (that is the
+        * same inode number with the same name in the same directory),
         * then there is nothing to do.
         */
         * then there is nothing to do.
         */
-       if (fvp == tvp)
+       if (fvp == tvp && fromnd.ni_dvp == tdvp &&
+           fromnd.ni_namelen == tond.ni_namelen &&
+           !bcmp(fromnd.ni_ptr, tond.ni_ptr, fromnd.ni_namelen))
                error = -1;
 out:
        if (!error) {
                error = -1;
 out:
        if (!error) {
-               error = VOP_RENAME(ndp, &tond, p);
+               error = VOP_RENAME(&fromnd, &tond, p);
        } else {
                VOP_ABORTOP(&tond);
                if (tdvp == tvp)
        } else {
                VOP_ABORTOP(&tond);
                if (tdvp == tvp)
@@ -1509,12 +1532,17 @@ out:
                        vput(tdvp);
                if (tvp)
                        vput(tvp);
                        vput(tdvp);
                if (tvp)
                        vput(tvp);
-               VOP_ABORTOP(ndp);
-               vrele(ndp->ni_dvp);
+               VOP_ABORTOP(&fromnd);
+               vrele(fromnd.ni_dvp);
                vrele(fvp);
        }
                vrele(fvp);
        }
+       p->p_spare[1]--;
+       vrele(tond.ni_startdir);
+       FREE(tond.ni_pnbuf, M_NAMEI);
 out1:
 out1:
-       ndrele(&tond);
+       p->p_spare[1]--;
+       vrele(fromnd.ni_startdir);
+       FREE(fromnd.ni_pnbuf, M_NAMEI);
        if (error == -1)
                return (0);
        return (error);
        if (error == -1)
                return (0);
        return (error);