Merge branch 'master' into kiconv2
[dragonfly.git] / sys / vfs / msdosfs / msdosfs_vnops.c
index 4df2dfc..f0c6aff 100644 (file)
@@ -242,73 +242,16 @@ msdosfs_close(struct vop_close_args *ap)
 static int
 msdosfs_access(struct vop_access_args *ap)
 {
-       struct vnode *vp = ap->a_vp;
        struct denode *dep = VTODE(ap->a_vp);
        struct msdosfsmount *pmp = dep->de_pmp;
-       struct ucred *cred = ap->a_cred;
-       mode_t mask, file_mode, mode = ap->a_mode;
-       gid_t *gp;
-       int i;
+       mode_t file_mode;
 
        file_mode = (S_IXUSR|S_IXGRP|S_IXOTH) | (S_IRUSR|S_IRGRP|S_IROTH) |
-           ((dep->de_Attributes & ATTR_READONLY) ? 0 : (S_IWUSR|S_IWGRP|S_IWOTH));
+           ((dep->de_Attributes & ATTR_READONLY) ? 
+               0 : (S_IWUSR|S_IWGRP|S_IWOTH));
        file_mode &= pmp->pm_mask;
 
-       /*
-        * Disallow write attempts on read-only file systems;
-        * unless the file is a socket, fifo, or a block or
-        * character device resident on the file system.
-        */
-       if (mode & VWRITE) {
-               switch (vp->v_type) {
-               case VDIR:
-               case VLNK:
-               case VREG:
-                       if (vp->v_mount->mnt_flag & MNT_RDONLY)
-                               return (EROFS);
-                       break;
-               default:
-                       break;
-               }
-       }
-
-       /* User id 0 always gets access. */
-       if (cred->cr_uid == 0)
-               return 0;
-
-       mask = 0;
-
-       /* Otherwise, check the owner. */
-       if (cred->cr_uid == pmp->pm_uid) {
-               if (mode & VEXEC)
-                       mask |= S_IXUSR;
-               if (mode & VREAD)
-                       mask |= S_IRUSR;
-               if (mode & VWRITE)
-                       mask |= S_IWUSR;
-               return (file_mode & mask) == mask ? 0 : EACCES;
-       }
-
-       /* Otherwise, check the groups. */
-       for (i = 0, gp = cred->cr_groups; i < cred->cr_ngroups; i++, gp++)
-               if (pmp->pm_gid == *gp) {
-                       if (mode & VEXEC)
-                               mask |= S_IXGRP;
-                       if (mode & VREAD)
-                               mask |= S_IRGRP;
-                       if (mode & VWRITE)
-                               mask |= S_IWGRP;
-                       return (file_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 (file_mode & mask) == mask ? 0 : EACCES;
+       return (vop_helper_access(ap, pmp->pm_uid, pmp->pm_gid, file_mode, 0));
 }
 
 /*
@@ -491,7 +434,7 @@ msdosfs_setattr(struct vop_setattr_args *ap)
                if (cred->cr_uid != pmp->pm_uid &&
                    (error = priv_check_cred(cred, PRIV_VFS_SETATTR, 0)) &&
                    ((vap->va_vaflags & VA_UTIMES_NULL) == 0 ||
-                   (error = VOP_ACCESS(ap->a_vp, VWRITE, cred))))
+                   (error = VOP_EACCESS(ap->a_vp, VWRITE, cred))))
                        return (error);
                if (vp->v_type != VDIR) {
                        if ((pmp->pm_flags & MSDOSFSMNT_NOWIN95) == 0 &&
@@ -543,7 +486,7 @@ msdosfs_read(struct vop_read_args *ap)
        int error = 0;
        int blsize;
        int isadir;
-       int orig_resid;
+       size_t orig_resid;
        u_int n;
        u_long diff;
        u_long on;
@@ -568,7 +511,7 @@ msdosfs_read(struct vop_read_args *ap)
         * If they didn't ask for any data, then we are done.
         */
        orig_resid = uio->uio_resid;
-       if (orig_resid <= 0)
+       if (orig_resid == 0)
                return (0);
 
        seqcount = ap->a_ioflag >> IO_SEQSHIFT;
@@ -621,14 +564,14 @@ msdosfs_read(struct vop_read_args *ap)
                }
                on = uio->uio_offset & pmp->pm_crbomask;
                diff = pmp->pm_bpcluster - on;
-               n = diff > uio->uio_resid ? uio->uio_resid : diff;
+               n = szmin(uio->uio_resid, diff);
                diff = dep->de_FileSize - uio->uio_offset;
                if (diff < n)
                        n = diff;
                diff = blsize - bp->b_resid;
                if (diff < n)
                        n = diff;
-               error = uiomove(bp->b_data + on, (int) n, uio);
+               error = uiomove(bp->b_data + on, (size_t)n, uio);
                brelse(bp);
        } while (error == 0 && uio->uio_resid > 0 && n != 0);
        if (!isadir && (error == 0 || uio->uio_resid != orig_resid) &&
@@ -648,7 +591,7 @@ msdosfs_write(struct vop_write_args *ap)
 {
        int n;
        int croffset;
-       int resid;
+       size_t resid;
        u_long osize;
        int error = 0;
        u_long count;
@@ -699,6 +642,8 @@ msdosfs_write(struct vop_write_args *ap)
                return (EFBIG);
        }
 
+       if ((uoff_t)uio->uio_offset > DOS_FILESIZE_MAX)
+                return (EFBIG);
        if ((uoff_t)uio->uio_offset + uio->uio_resid > DOS_FILESIZE_MAX)
                 return (EFBIG);
 
@@ -741,7 +686,7 @@ msdosfs_write(struct vop_write_args *ap)
                }
 
                croffset = uio->uio_offset & pmp->pm_crbomask;
-               n = min(uio->uio_resid, pmp->pm_bpcluster - croffset);
+               n = (int)szmin(uio->uio_resid, pmp->pm_bpcluster - croffset);
                if (uio->uio_offset + n > dep->de_FileSize) {
                        dep->de_FileSize = uio->uio_offset + n;
                        /* The object size needs to be set before buffer is allocated */
@@ -809,7 +754,7 @@ msdosfs_write(struct vop_write_args *ap)
                /*
                 * Copy the data from user space into the buf header.
                 */
-               error = uiomove(bp->b_data + croffset, n, uio);
+               error = uiomove(bp->b_data + croffset, (size_t)n, uio);
                if (error) {
                        brelse(bp);
                        break;
@@ -1078,7 +1023,7 @@ abortit:
         * to namei, as the parent directory is unlocked by the
         * call to doscheckpath().
         */
-       error = VOP_ACCESS(fvp, VWRITE, tcnp->cn_cred);
+       error = VOP_EACCESS(fvp, VWRITE, tcnp->cn_cred);
        vn_unlock(fvp);
        if (VTODE(fdvp)->de_StartCluster != VTODE(tdvp)->de_StartCluster)
                newparent = 1;
@@ -1669,7 +1614,7 @@ msdosfs_readdir(struct vop_readdir_args *ap)
        while (uio->uio_resid > 0) {
                lbn = de_off2cn(pmp, offset - bias);
                on = (offset - bias) & pmp->pm_crbomask;
-               n = min(pmp->pm_bpcluster - on, uio->uio_resid);
+               n = szmin(pmp->pm_bpcluster - on, uio->uio_resid);
                diff = dep->de_FileSize - (offset - bias);
                if (diff <= 0)
                        break;