tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Splitting <fs>_access to two internal routines



David Laight wrote:

These sort of diffs are difficult to read - since the 'new' code
and 'old' code that diff compares end up being different functions!

That's intended, I don't want to introduce new functionality, but
rather split it to two functions. I'm not sure how to diff without
having that effect on the outcome. :)

I've attached a file with just the new functions added and the
modified ufs_access, though, to make it easier to read.

So I can't see what ufs_check_possible() actually looks like.
However the other parts end up being:

+ufs_check_permitted(struct vnode *vp, struct inode *ip, mode_t mode,
+    kauth_cred_t cred)
+{
+
+       return genfs_can_access(vp->v_type, ip->i_mode & ALLPERMS, ip->i_uid,
+           ip->i_gid, mode, cred);
+}
+
+int
+ufs_access(void *v)
+{
...
+       error = ufs_check_possible(vp, ip, mode, ap->a_cred);
+       if (error)
+               return error;
+
+       return ufs_check_permitted(vp, ip, mode, ap->a_cred);
 }

This looks like a complete waste of cpu cycles stacking arguments
to functions.

The cred to ufs_check_possible() was dropped; other than that, we need
the vnode type, inode flags, and access mode in both, and the
credentials in ufs_check_permitted(). Whether we pass the structures or
just the values is of less concern to me... that's exactly why I posted
it here -- to get feedback on "if we do introduce these functions, what
are the proper prototypes for them?".

Due to lack of consistency across file-systems, we won't be able to make
them all the same, but we can achieve a small about of "versions".
Either way, being private helps a lot to play with the arguments of
choice without affecting anything else.

Thanks,

-e.
static int
ufs_check_possible(struct vnode *vp, struct inode *ip, mode_t mode)
{
#ifdef QUOTA
        int error;
#endif /* QUOTA */

        /*
         * 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);
#ifdef QUOTA
                        fstrans_start(vp->v_mount, FSTRANS_SHARED);
                        error = getinoquota(ip);
                        fstrans_done(vp->v_mount);
                        if (error != 0)
                                return error;
#endif
                        break;
                case VBAD:
                case VBLK:
                case VCHR:
                case VSOCK:
                case VFIFO:
                case VNON:
                default:
                        break;
                }
        }

        /* If it is a snapshot, nobody gets access to it. */
        if ((ip->i_flags & SF_SNAPSHOT))
                return (EPERM);
        /* If immutable bit set, nobody gets to write it. */
        if ((mode & VWRITE) && (ip->i_flags & IMMUTABLE))
                return (EPERM);

        return 0;
}

static int
ufs_check_permitted(struct vnode *vp, struct inode *ip, mode_t mode,
    kauth_cred_t cred)
{

        return genfs_can_access(vp->v_type, ip->i_mode & ALLPERMS, ip->i_uid,
            ip->i_gid, mode, cred);
}

int
ufs_access(void *v)
{
        struct vop_access_args /* {
                struct vnode    *a_vp;
                int             a_mode;
                kauth_cred_t    a_cred;
        } */ *ap = v;
        struct vnode    *vp;
        struct inode    *ip;
        mode_t          mode;
        int             error;

        vp = ap->a_vp;
        ip = VTOI(vp);
        mode = ap->a_mode;

        error = ufs_check_possible(vp, ip, mode);
        if (error)
                return error;

        error = ufs_check_permitted(vp, ip, mode, ap->a_cred);

        return error;
}



Home | Main Index | Thread Index | Old Index