update for 4.4BSD-Lite (from mycroft)
[unix-history] / usr / src / sys / isofs / cd9660 / cd9660_vnops.c
index 4a05e80..e2e3eee 100644 (file)
@@ -9,7 +9,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)cd9660_vnops.c      8.3 (Berkeley) %G%
+ *     @(#)cd9660_vnops.c      8.8 (Berkeley) %G%
  */
 
 #include <sys/param.h>
  */
 
 #include <sys/param.h>
@@ -48,7 +48,7 @@ cd9660_mknod(ndp, vap, cred, p)
        free(ndp->ni_pnbuf, M_NAMEI);
        vput(ndp->ni_dvp);
        vput(ndp->ni_vp);
        free(ndp->ni_pnbuf, M_NAMEI);
        vput(ndp->ni_dvp);
        vput(ndp->ni_vp);
-       return EINVAL;
+       return (EINVAL);
 #else
        register struct vnode *vp;
        struct iso_node *ip;
 #else
        register struct vnode *vp;
        struct iso_node *ip;
@@ -64,7 +64,7 @@ cd9660_mknod(ndp, vap, cred, p)
                free(ndp->ni_pnbuf, M_NAMEI);
                vput(ndp->ni_dvp);
                vput(ndp->ni_vp);
                free(ndp->ni_pnbuf, M_NAMEI);
                vput(ndp->ni_dvp);
                vput(ndp->ni_vp);
-               return EINVAL;
+               return (EINVAL);
        }
        
        dp = iso_dmap(ip->i_dev,ip->i_number,1);
        }
        
        dp = iso_dmap(ip->i_dev,ip->i_number,1);
@@ -139,7 +139,50 @@ cd9660_access(ap)
                struct proc *a_p;
        } */ *ap;
 {
                struct proc *a_p;
        } */ *ap;
 {
-       return (0);
+       struct iso_node *ip = VTOI(ap->a_vp);
+       struct ucred *cred = ap->a_cred;
+       mode_t mask, mode = ap->a_mode;
+       gid_t *gp;
+       int i, error;
+
+       /* User id 0 always gets access. */
+       if (cred->cr_uid == 0)
+               return (0);
+
+       mask = 0;
+
+       /* Otherwise, check the owner. */
+       if (cred->cr_uid == ip->inode.iso_uid) {
+               if (mode & VEXEC)
+                       mask |= S_IXUSR;
+               if (mode & VREAD)
+                       mask |= S_IRUSR;
+               if (mode & VWRITE)
+                       mask |= S_IWUSR;
+               return ((ip->inode.iso_mode & mask) == mask ? 0 : EACCES);
+       }
+
+       /* Otherwise, check the groups. */
+       for (i = 0, gp = cred->cr_groups; i < cred->cr_ngroups; i++, gp++)
+               if (ip->inode.iso_gid == *gp) {
+                       if (mode & VEXEC)
+                               mask |= S_IXGRP;
+                       if (mode & VREAD)
+                               mask |= S_IRGRP;
+                       if (mode & VWRITE)
+                               mask |= S_IWGRP;
+                       return ((ip->inode.iso_mode & mask) == mask ?
+                           0 : EACCES);
+               }
+
+       /* Otherwise, check everyone else. */
+       if (mode & VEXEC)
+               mask |= S_IXOTH;
+       if (mode & VREAD)
+               mask |= S_IROTH;
+       if (mode & VWRITE)
+               mask |= S_IWOTH;
+       return ((ip->inode.iso_mode & mask) == mask ? 0 : EACCES);
 }
 
 cd9660_getattr(ap)
 }
 
 cd9660_getattr(ap)
@@ -213,7 +256,7 @@ cd9660_read(ap)
                return (0);
        if (uio->uio_offset < 0)
                return (EINVAL);
                return (0);
        if (uio->uio_offset < 0)
                return (EINVAL);
-       ip->i_flag |= IACC;
+       ip->i_flag |= IN_ACCESS;
        imp = ip->i_mnt;
        do {
                lbn = iso_lblkno(imp, uio->uio_offset);
        imp = ip->i_mnt;
        do {
                lbn = iso_lblkno(imp, uio->uio_offset);
@@ -342,9 +385,9 @@ struct isoreaddir {
        off_t curroff;
        struct uio *uio;
        off_t uio_off;
        off_t curroff;
        struct uio *uio;
        off_t uio_off;
-       u_int *cookiep;
+       int eofflag;
+       u_long *cookies;
        int ncookies;
        int ncookies;
-       int eof;
 };
 
 static int
 };
 
 static int
@@ -359,24 +402,24 @@ iso_uiodir(idp,dp,off)
        dp->d_reclen = DIRSIZ(dp);
        
        if (idp->uio->uio_resid < dp->d_reclen) {
        dp->d_reclen = DIRSIZ(dp);
        
        if (idp->uio->uio_resid < dp->d_reclen) {
-               idp->eof = 0;
-               return -1;
+               idp->eofflag = 0;
+               return (-1);
        }
        
        }
        
-       if (idp->cookiep) {
+       if (idp->cookies) {
                if (idp->ncookies <= 0) {
                if (idp->ncookies <= 0) {
-                       idp->eof = 0;
-                       return -1;
+                       idp->eofflag = 0;
+                       return (-1);
                }
                
                }
                
-               *idp->cookiep++ = off;
+               *idp->cookies++ = off;
                --idp->ncookies;
        }
        
        if (error = uiomove(dp,dp->d_reclen,idp->uio))
                --idp->ncookies;
        }
        
        if (error = uiomove(dp,dp->d_reclen,idp->uio))
-               return error;
+               return (error);
        idp->uio_off = off;
        idp->uio_off = off;
-       return 0;
+       return (0);
 }
 
 static int
 }
 
 static int
@@ -407,12 +450,12 @@ iso_shipdir(idp)
                    || bcmp(sname,cname,sl)) {
                        if (idp->assocent.d_namlen) {
                                if (error = iso_uiodir(idp,&idp->assocent,idp->assocoff))
                    || bcmp(sname,cname,sl)) {
                        if (idp->assocent.d_namlen) {
                                if (error = iso_uiodir(idp,&idp->assocent,idp->assocoff))
-                                       return error;
+                                       return (error);
                                idp->assocent.d_namlen = 0;
                        }
                        if (idp->saveent.d_namlen) {
                                if (error = iso_uiodir(idp,&idp->saveent,idp->saveoff))
                                idp->assocent.d_namlen = 0;
                        }
                        if (idp->saveent.d_namlen) {
                                if (error = iso_uiodir(idp,&idp->saveent,idp->saveoff))
-                                       return error;
+                                       return (error);
                                idp->saveent.d_namlen = 0;
                        }
                }
                                idp->saveent.d_namlen = 0;
                        }
                }
@@ -425,13 +468,11 @@ iso_shipdir(idp)
                idp->saveoff = idp->curroff;
                bcopy(&idp->current,&idp->saveent,idp->current.d_reclen);
        }
                idp->saveoff = idp->curroff;
                bcopy(&idp->current,&idp->saveent,idp->current.d_reclen);
        }
-       return 0;
+       return (0);
 }
 
 /*
  * Vnode op for readdir
 }
 
 /*
  * Vnode op for readdir
- * XXX make sure everything still works now that eofflagp and cookiep
- * are no longer args.
  */
 int
 cd9660_readdir(ap)
  */
 int
 cd9660_readdir(ap)
@@ -439,6 +480,9 @@ cd9660_readdir(ap)
                struct vnode *a_vp;
                struct uio *a_uio;
                struct ucred *a_cred;
                struct vnode *a_vp;
                struct uio *a_uio;
                struct ucred *a_cred;
+               int *a_eofflag;
+               u_long *a_cookies;
+               int a_ncookies;
        } */ *ap;
 {
        register struct uio *uio = ap->a_uio;
        } */ *ap;
 {
        register struct uio *uio = ap->a_uio;
@@ -456,17 +500,18 @@ cd9660_readdir(ap)
        ip = VTOI(ap->a_vp);
        imp = ip->i_mnt;
        
        ip = VTOI(ap->a_vp);
        imp = ip->i_mnt;
        
-       MALLOC(idp,struct isoreaddir *,sizeof(*idp),M_TEMP,M_WAITOK);
-       idp->saveent.d_namlen = 0;
-       idp->assocent.d_namlen = 0;
+       MALLOC(idp, struct isoreaddir *, sizeof(*idp), M_TEMP, M_WAITOK);
+       idp->saveent.d_namlen = idp->assocent.d_namlen = 0;
+       /*
+        * XXX
+        * Is it worth trying to figure out the type?
+        */
+       idp->saveent.d_type = idp->assocent.d_type = idp->current.d_type =
+           DT_UNKNOWN;
        idp->uio = uio;
        idp->uio = uio;
-#if 0
-       idp->cookiep = cookies;
-       idp->ncookies = ncookies;
-       idp->eof = 1;
-#else
-       idp->cookiep = 0;
-#endif
+       idp->eofflag = 1;
+       idp->cookies = ap->a_cookies;
+       idp->ncookies = ap->a_ncookies;
        idp->curroff = uio->uio_offset;
        
        entryoffsetinblock = iso_blkoff(imp, idp->curroff);
        idp->curroff = uio->uio_offset;
        
        entryoffsetinblock = iso_blkoff(imp, idp->curroff);
@@ -539,9 +584,9 @@ cd9660_readdir(ap)
                 */
                switch (imp->iso_ftype) {
                case ISO_FTYPE_RRIP:
                 */
                switch (imp->iso_ftype) {
                case ISO_FTYPE_RRIP:
-                       cd9660_rrip_getname(ep,idp->current.d_name,
-                                          (u_short *)&idp->current.d_namlen,
+                       cd9660_rrip_getname(ep,idp->current.d_name, &elen,
                                           &idp->current.d_fileno,imp);
                                           &idp->current.d_fileno,imp);
+                       idp->current.d_namlen = (u_char)elen;
                        if (idp->current.d_namlen)
                                error = iso_uiodir(idp,&idp->current,idp->curroff);
                        break;
                        if (idp->current.d_namlen)
                                error = iso_uiodir(idp,&idp->current,idp->curroff);
                        break;
@@ -586,9 +631,7 @@ cd9660_readdir(ap)
                brelse (bp);
 
        uio->uio_offset = idp->uio_off;
                brelse (bp);
 
        uio->uio_offset = idp->uio_off;
-#if 0
-       *eofflagp = idp->eof;
-#endif
+       *ap->a_eofflag = idp->eofflag;
        
        FREE(idp,M_TEMP);
        
        
        FREE(idp,M_TEMP);
        
@@ -625,37 +668,26 @@ cd9660_readlink(ap)
        imp = ip->i_mnt;
        
        if (imp->iso_ftype != ISO_FTYPE_RRIP)
        imp = ip->i_mnt;
        
        if (imp->iso_ftype != ISO_FTYPE_RRIP)
-               return EINVAL;
+               return (EINVAL);
        
        /*
         * Get parents directory record block that this inode included.
         */
        error = bread(imp->im_devvp,
        
        /*
         * Get parents directory record block that this inode included.
         */
        error = bread(imp->im_devvp,
-                     (daddr_t)(ip->i_number / DEV_BSIZE),
+                     (daddr_t)((ip->i_number&~imp->im_bmask) / DEV_BSIZE),
                      imp->logical_block_size,
                      NOCRED,
                      &bp);
        if (error) {
                brelse(bp);
                      imp->logical_block_size,
                      NOCRED,
                      &bp);
        if (error) {
                brelse(bp);
-               return EINVAL;
+               return (EINVAL);
        }
 
        /*
         * Setup the directory pointer for this inode
         */
        dirp = (ISODIR *)(bp->b_un.b_addr + (ip->i_number & imp->im_bmask));
        }
 
        /*
         * Setup the directory pointer for this inode
         */
        dirp = (ISODIR *)(bp->b_un.b_addr + (ip->i_number & imp->im_bmask));
-#ifdef DEBUG
-       printf("lbn=%d,off=%d,bsize=%d,DEV_BSIZE=%d, dirp= %08x, b_addr=%08x, offset=%08x(%08x)\n",
-              (daddr_t)(ip->i_number >> imp->im_bshift),
-              ip->i_number & imp->im_bmask,
-              imp->logical_block_size,
-              DEV_BSIZE,
-              dirp,
-              bp->b_un.b_addr,
-              ip->i_number,
-              ip->i_number & imp->im_bmask );
-#endif
-       
+
        /*
         * Just make sure, we have a right one....
         *   1: Check not cross boundary on block
        /*
         * Just make sure, we have a right one....
         *   1: Check not cross boundary on block
@@ -663,7 +695,7 @@ cd9660_readlink(ap)
        if ((ip->i_number & imp->im_bmask) + isonum_711(dirp->length)
            > imp->logical_block_size) {
                brelse(bp);
        if ((ip->i_number & imp->im_bmask) + isonum_711(dirp->length)
            > imp->logical_block_size) {
                brelse(bp);
-               return EINVAL;
+               return (EINVAL);
        }
        
        /*
        }
        
        /*
@@ -678,7 +710,7 @@ cd9660_readlink(ap)
        if (cd9660_rrip_getsymname(dirp,symname,&symlen,imp) == 0) {
                FREE(symname,M_NAMEI);
                brelse(bp);
        if (cd9660_rrip_getsymname(dirp,symname,&symlen,imp) == 0) {
                FREE(symname,M_NAMEI);
                brelse(bp);
-               return EINVAL;
+               return (EINVAL);
        }
        /*
         * Don't forget before you leave from home ;-)
        }
        /*
         * Don't forget before you leave from home ;-)
@@ -692,7 +724,7 @@ cd9660_readlink(ap)
        
        FREE(symname,M_NAMEI);
        
        
        FREE(symname,M_NAMEI);
        
-       return error;
+       return (error);
 }
 
 /*
 }
 
 /*
@@ -708,7 +740,7 @@ cd9660_abortop(ap)
 {
        if ((ap->a_cnp->cn_flags & (HASBUF | SAVESTART)) == HASBUF)
                FREE(ap->a_cnp->cn_pnbuf, M_NAMEI);
 {
        if ((ap->a_cnp->cn_flags & (HASBUF | SAVESTART)) == HASBUF)
                FREE(ap->a_cnp->cn_pnbuf, M_NAMEI);
-       return 0;
+       return (0);
 }
 
 /*
 }
 
 /*
@@ -720,10 +752,43 @@ cd9660_lock(ap)
                struct vnode *a_vp;
        } */ *ap;
 {
                struct vnode *a_vp;
        } */ *ap;
 {
-       register struct iso_node *ip = VTOI(ap->a_vp);
+       register struct vnode *vp = ap->a_vp;
+       register struct iso_node *ip;
+       struct proc *p = curproc;       /* XXX */
 
 
-       ISO_ILOCK(ip);
-       return 0;
+start:
+       while (vp->v_flag & VXLOCK) {
+               vp->v_flag |= VXWANT;
+               sleep((caddr_t)vp, PINOD);
+       }
+       if (vp->v_tag == VT_NON)
+               return (ENOENT);
+       ip = VTOI(vp);
+       if (ip->i_flag & IN_LOCKED) {
+               ip->i_flag |= IN_WANTED;
+#ifdef DIAGNOSTIC
+               if (p) {
+                       if (p->p_pid == ip->i_lockholder)
+                               panic("locking against myself");
+                       ip->i_lockwaiter = p->p_pid;
+               } else
+                       ip->i_lockwaiter = -1;
+#endif
+               (void) sleep((caddr_t)ip, PINOD);
+       }
+#ifdef DIAGNOSTIC
+       ip->i_lockwaiter = 0;
+       if (ip->i_lockholder != 0)
+               panic("lockholder (%d) != 0", ip->i_lockholder);
+       if (p && p->p_pid == 0)
+               printf("locking by process 0\n");
+       if (p)
+               ip->i_lockholder = p->p_pid;
+       else
+               ip->i_lockholder = -1;
+#endif
+       ip->i_flag |= IN_LOCKED;
+       return (0);
 }
 
 /*
 }
 
 /*
@@ -736,11 +801,25 @@ cd9660_unlock(ap)
        } */ *ap;
 {
        register struct iso_node *ip = VTOI(ap->a_vp);
        } */ *ap;
 {
        register struct iso_node *ip = VTOI(ap->a_vp);
+       struct proc *p = curproc;       /* XXX */
 
 
-       if (!(ip->i_flag & ILOCKED))
-               panic("cd9660_unlock NOT LOCKED");
-       ISO_IUNLOCK(ip);
-       return 0;
+#ifdef DIAGNOSTIC
+       if ((ip->i_flag & IN_LOCKED) == 0) {
+               vprint("ufs_unlock: unlocked inode", ap->a_vp);
+               panic("ufs_unlock NOT LOCKED");
+       }
+       if (p && p->p_pid != ip->i_lockholder && p->p_pid > -1 &&
+           ip->i_lockholder > -1/* && lockcount++ < 100*/)
+               panic("unlocker (%d) != lock holder (%d)",
+                   p->p_pid, ip->i_lockholder);
+       ip->i_lockholder = 0;
+#endif
+       ip->i_flag &= ~IN_LOCKED;
+       if (ip->i_flag & IN_WANTED) {
+               ip->i_flag &= ~IN_WANTED;
+               wakeup((caddr_t)ip);
+       }
+       return (0);
 }
 
 /*
 }
 
 /*
@@ -753,9 +832,9 @@ cd9660_islocked(ap)
        } */ *ap;
 {
 
        } */ *ap;
 {
 
-       if (VTOI(ap->a_vp)->i_flag & ILOCKED)
-               return 1;
-       return 0;
+       if (VTOI(ap->a_vp)->i_flag & IN_LOCKED)
+               return (1);
+       return (0);
 }
 
 /*
 }
 
 /*
@@ -807,7 +886,7 @@ cd9660_print(ap)
        } */ *ap;
 {
        printf("tag VT_ISOFS, isofs vnode\n");
        } */ *ap;
 {
        printf("tag VT_ISOFS, isofs vnode\n");
-       return 0;
+       return (0);
 }
 
 /*
 }
 
 /*