Module Name:    src
Committed By:   elad
Date:           Fri Jul  3 21:17:42 UTC 2009

Modified Files:
        src/sys/fs/adosfs: advnops.c
        src/sys/fs/cd9660: cd9660_vnops.c
        src/sys/fs/efs: efs_vnops.c
        src/sys/fs/filecorefs: filecore_vnops.c
        src/sys/fs/hfs: hfs_vnops.c
        src/sys/fs/msdosfs: msdosfs_vnops.c
        src/sys/fs/ntfs: ntfs_vnops.c
        src/sys/fs/ptyfs: ptyfs_vnops.c
        src/sys/fs/smbfs: smbfs_vnops.c
        src/sys/fs/sysvbfs: sysvbfs_vnops.c
        src/sys/fs/tmpfs: tmpfs_vnops.c
        src/sys/fs/udf: udf_vnops.c
        src/sys/miscfs/kernfs: kernfs_vnops.c
        src/sys/miscfs/procfs: procfs_vnops.c
        src/sys/ufs/ext2fs: ext2fs_vnops.c
        src/sys/ufs/ufs: ufs_vnops.c

Log Message:
Where possible, extract the file-system's access() routine to two internal
functions: the first checking if the operation is possible (regardless of
permissions), the second checking file-system permissions, ACLs, etc.

Mailing list reference:

        http://mail-index.netbsd.org/tech-kern/2009/06/21/msg005311.html


To generate a diff of this commit:
cvs rdiff -u -r1.34 -r1.35 src/sys/fs/adosfs/advnops.c
cvs rdiff -u -r1.37 -r1.38 src/sys/fs/cd9660/cd9660_vnops.c
cvs rdiff -u -r1.18 -r1.19 src/sys/fs/efs/efs_vnops.c
cvs rdiff -u -r1.31 -r1.32 src/sys/fs/filecorefs/filecore_vnops.c
cvs rdiff -u -r1.14 -r1.15 src/sys/fs/hfs/hfs_vnops.c
cvs rdiff -u -r1.60 -r1.61 src/sys/fs/msdosfs/msdosfs_vnops.c
cvs rdiff -u -r1.44 -r1.45 src/sys/fs/ntfs/ntfs_vnops.c
cvs rdiff -u -r1.31 -r1.32 src/sys/fs/ptyfs/ptyfs_vnops.c
cvs rdiff -u -r1.70 -r1.71 src/sys/fs/smbfs/smbfs_vnops.c
cvs rdiff -u -r1.22 -r1.23 src/sys/fs/sysvbfs/sysvbfs_vnops.c
cvs rdiff -u -r1.60 -r1.61 src/sys/fs/tmpfs/tmpfs_vnops.c
cvs rdiff -u -r1.47 -r1.48 src/sys/fs/udf/udf_vnops.c
cvs rdiff -u -r1.137 -r1.138 src/sys/miscfs/kernfs/kernfs_vnops.c
cvs rdiff -u -r1.175 -r1.176 src/sys/miscfs/procfs/procfs_vnops.c
cvs rdiff -u -r1.87 -r1.88 src/sys/ufs/ext2fs/ext2fs_vnops.c
cvs rdiff -u -r1.178 -r1.179 src/sys/ufs/ufs/ufs_vnops.c

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

Modified files:

Index: src/sys/fs/adosfs/advnops.c
diff -u src/sys/fs/adosfs/advnops.c:1.34 src/sys/fs/adosfs/advnops.c:1.35
--- src/sys/fs/adosfs/advnops.c:1.34	Tue Jun 23 19:36:38 2009
+++ src/sys/fs/adosfs/advnops.c	Fri Jul  3 21:17:40 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: advnops.c,v 1.34 2009/06/23 19:36:38 elad Exp $	*/
+/*	$NetBSD: advnops.c,v 1.35 2009/07/03 21:17:40 elad Exp $	*/
 
 /*
  * Copyright (c) 1994 Christian E. Hopps
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: advnops.c,v 1.34 2009/06/23 19:36:38 elad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: advnops.c,v 1.35 2009/07/03 21:17:40 elad Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -747,6 +747,38 @@
 	return(error);
 }
 
+static int
+adosfs_check_possible(struct vnode *vp, struct anode *ap, mode_t mode)
+{
+
+	/*
+	 * Disallow write attempts 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:
+			return (EROFS);
+		default:
+			break;
+		}
+	}
+
+	return 0;
+}
+
+static int
+adosfs_check_permitted(struct vnode *vp, struct anode *ap, mode_t mode,
+    kauth_cred_t cred)
+{
+
+	return genfs_can_access(vp->v_type,
+	    adunixprot(ap->adprot) & ap->amp->mask, ap->uid, ap->gid, mode,
+	    cred);
+}
 
 int
 adosfs_access(void *v)
@@ -771,24 +803,13 @@
 		panic("adosfs_access: not locked");
 	}
 #endif
-	/*
-	 * Disallow write attempts unless the file is a socket,
-	 * fifo, or a block or character device resident on the
-	 * file system.
-	 */
-	if (sp->a_mode & VWRITE) {
-		switch (vp->v_type) {
-		case VDIR:
-		case VLNK:
-		case VREG:
-			return (EROFS);
-		default:
-			break;
-		}
-	}
-	error = genfs_can_access(sp->a_vp->v_type,
-	    adunixprot(ap->adprot) & ap->amp->mask, ap->uid, ap->gid,
-	    sp->a_mode, sp->a_cred);
+
+	error = adosfs_check_possible(vp, ap, sp->a_mode);
+	if (error)
+		return error;
+
+	error = adosfs_check_permitted(vp, ap, sp->a_mode, sp->a_cred);
+
 #ifdef ADOSFS_DIAGNOSTIC
 	printf(" %d)", error);
 #endif

Index: src/sys/fs/cd9660/cd9660_vnops.c
diff -u src/sys/fs/cd9660/cd9660_vnops.c:1.37 src/sys/fs/cd9660/cd9660_vnops.c:1.38
--- src/sys/fs/cd9660/cd9660_vnops.c:1.37	Tue Jun 23 19:36:39 2009
+++ src/sys/fs/cd9660/cd9660_vnops.c	Fri Jul  3 21:17:40 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: cd9660_vnops.c,v 1.37 2009/06/23 19:36:39 elad Exp $	*/
+/*	$NetBSD: cd9660_vnops.c,v 1.38 2009/07/03 21:17:40 elad Exp $	*/
 
 /*-
  * Copyright (c) 1994
@@ -37,7 +37,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cd9660_vnops.c,v 1.37 2009/06/23 19:36:39 elad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cd9660_vnops.c,v 1.38 2009/07/03 21:17:40 elad Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -84,28 +84,16 @@
 int	iso_uiodir(struct isoreaddir *, struct dirent *, off_t);
 int	iso_shipdir(struct isoreaddir *);
 
-/*
- * Check mode permission on inode pointer. Mode is READ, WRITE or EXEC.
- * The mode is shifted to select the owner/group/other fields. The
- * super user is granted all permissions.
- */
-int
-cd9660_access(void *v)
+static int
+cd9660_check_possible(struct vnode *vp, struct iso_node *ip, mode_t mode)
 {
-	struct vop_access_args /* {
-		struct vnode *a_vp;
-		int  a_mode;
-		kauth_cred_t a_cred;
-	} */ *ap = v;
-	struct vnode *vp = ap->a_vp;
-	struct iso_node *ip = VTOI(vp);
 
 	/*
 	 * Disallow write attempts unless the file is a socket,
 	 * fifo, or a block or character device resident on the
 	 * file system.
 	 */
-	if (ap->a_mode & VWRITE) {
+	if (mode & VWRITE) {
 		switch (vp->v_type) {
 		case VDIR:
 		case VLNK:
@@ -116,8 +104,42 @@
 		}
 	}
 
-	return (genfs_can_access(vp->v_type, ip->inode.iso_mode & ALLPERMS,
-	    ip->inode.iso_uid, ip->inode.iso_gid, ap->a_mode, ap->a_cred));
+	return 0;
+}
+
+/*
+ * Check mode permission on inode pointer. Mode is READ, WRITE or EXEC.
+ * The mode is shifted to select the owner/group/other fields. The
+ * super user is granted all permissions.
+ */
+static int
+cd9660_check_permitted(struct vnode *vp, struct iso_node *ip, mode_t mode,
+    kauth_cred_t cred)
+{
+
+	return genfs_can_access(vp->v_type, ip->inode.iso_mode & ALLPERMS,
+	    ip->inode.iso_uid, ip->inode.iso_gid, mode, cred);
+}
+
+int
+cd9660_access(void *v)
+{
+	struct vop_access_args /* {
+		struct vnode *a_vp;
+		int  a_mode;
+		kauth_cred_t a_cred;
+	} */ *ap = v;
+	struct vnode *vp = ap->a_vp;
+	struct iso_node *ip = VTOI(vp);
+	int error;
+
+	error = cd9660_check_possible(vp, ip, ap->a_mode);
+	if (error)
+		return error;
+
+	error = cd9660_check_permitted(vp, ip, ap->a_mode, ap->a_cred);
+
+	return error;
 }
 
 int

Index: src/sys/fs/efs/efs_vnops.c
diff -u src/sys/fs/efs/efs_vnops.c:1.18 src/sys/fs/efs/efs_vnops.c:1.19
--- src/sys/fs/efs/efs_vnops.c:1.18	Tue Jun 23 19:36:40 2009
+++ src/sys/fs/efs/efs_vnops.c	Fri Jul  3 21:17:41 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: efs_vnops.c,v 1.18 2009/06/23 19:36:40 elad Exp $	*/
+/*	$NetBSD: efs_vnops.c,v 1.19 2009/07/03 21:17:41 elad Exp $	*/
 
 /*
  * Copyright (c) 2006 Stephen M. Rumble <rum...@ephemeral.org>
@@ -17,7 +17,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: efs_vnops.c,v 1.18 2009/06/23 19:36:40 elad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: efs_vnops.c,v 1.19 2009/07/03 21:17:41 elad Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -128,6 +128,16 @@
 	return (0);
 }
 
+static int
+efs_check_possible(struct vnode *vp, struct efs_inode *eip, mode_t mode)
+{
+
+	if ((ap->a_mode & VWRITE) && (vp->v_mount->mnt_flag & MNT_RDONLY))
+		return (EROFS);
+
+	return 0;
+}
+
 /*
  * Determine the accessiblity of a file based on the permissions allowed by the
  * specified credentials.
@@ -135,6 +145,15 @@
  * Returns 0 on success.
  */
 static int
+efs_check_possible(struct vnode *vp, struct efs_inode *eip, mode_t mode,
+    kauth_cred_t cred)
+{
+
+	return genfs_can_access(vp->v_type, eip->ei_mode, eip->ei_uid,
+	    eip->ei_gid, mode, cred);
+}
+
+static int
 efs_access(void *v)
 {
 	struct vop_access_args /* {
@@ -145,12 +164,15 @@
 	} */ *ap = v;
 	struct vnode *vp = ap->a_vp;
 	struct efs_inode *eip = EFS_VTOI(vp);
+	int error;
 
-	if ((ap->a_mode & VWRITE) && (vp->v_mount->mnt_flag & MNT_RDONLY))
-		return (EROFS);
+	error = efs_check_possible(vp, eip, ap->a_mode);
+	if (error)
+		return error;
+
+	error = efs_check_permitted(vp, eip, ap->a_mode, ap->a_cred);
 
-	return (genfs_can_access(vp->v_type, eip->ei_mode, eip->ei_uid,
-	    eip->ei_gid, ap->a_mode, ap->a_cred));
+	return error;
 }
 
 /*

Index: src/sys/fs/filecorefs/filecore_vnops.c
diff -u src/sys/fs/filecorefs/filecore_vnops.c:1.31 src/sys/fs/filecorefs/filecore_vnops.c:1.32
--- src/sys/fs/filecorefs/filecore_vnops.c:1.31	Tue Jun 23 19:36:39 2009
+++ src/sys/fs/filecorefs/filecore_vnops.c	Fri Jul  3 21:17:40 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: filecore_vnops.c,v 1.31 2009/06/23 19:36:39 elad Exp $	*/
+/*	$NetBSD: filecore_vnops.c,v 1.32 2009/07/03 21:17:40 elad Exp $	*/
 
 /*-
  * Copyright (c) 1994 The Regents of the University of California.
@@ -66,7 +66,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: filecore_vnops.c,v 1.31 2009/06/23 19:36:39 elad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: filecore_vnops.c,v 1.32 2009/07/03 21:17:40 elad Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -91,29 +91,17 @@
 #include <fs/filecorefs/filecore_extern.h>
 #include <fs/filecorefs/filecore_node.h>
 
-/*
- * Check mode permission on inode pointer. Mode is READ, WRITE or EXEC.
- * The mode is shifted to select the owner/group/other fields. The
- * super user is granted all permissions.
- */
-int
-filecore_access(void *v)
+static int
+filecore_check_possible(struct vnode *vp, struct filecore_node *ip,
+    mode_t mode)
 {
-	struct vop_access_args /* {
-		struct vnode *a_vp;
-		int  a_mode;
-		kauth_cred_t a_cred;
-	} */ *ap = v;
-	struct vnode *vp = ap->a_vp;
-	struct filecore_node *ip = VTOI(vp);
-	struct filecore_mnt *fcmp = ip->i_mnt;
 
 	/*
 	 * Disallow write attempts unless the file is a socket,
 	 * fifo, or a block or character device resident on the
 	 * file system.
 	 */
-	if (ap->a_mode & VWRITE) {
+	if (mode & VWRITE) {
 		switch (vp->v_type) {
 		case VDIR:
 		case VLNK:
@@ -124,8 +112,43 @@
 		}
 	}
 
-	return (genfs_can_access(vp->v_type, filecore_mode(ip),
-	    fcmp->fc_uid, fcmp->fc_gid, ap->a_mode, ap->a_cred));
+	return 0;
+}
+
+/*
+ * Check mode permission on inode pointer. Mode is READ, WRITE or EXEC.
+ * The mode is shifted to select the owner/group/other fields. The
+ * super user is granted all permissions.
+ */
+static int
+filecore_check_permitted(struct vnode *vp, struct filecore_node *ip,
+    mode_t mode, kauth_cred_t cred)
+{
+	struct filecore_mnt *fcmp = ip->i_mnt;
+
+	return genfs_can_access(vp->v_type, filecore_mode(ip),
+	    fcmp->fc_uid, fcmp->fc_gid, mode, cred);
+}
+
+int
+filecore_access(void *v)
+{
+	struct vop_access_args /* {
+		struct vnode *a_vp;
+		int  a_mode;
+		kauth_cred_t a_cred;
+	} */ *ap = v;
+	struct vnode *vp = ap->a_vp;
+	struct filecore_node *ip = VTOI(vp);
+	int error;
+
+	error = filecore_check_possible(vp, ip, ap->a_mode);
+	if (error)
+		return error;
+
+	error = filecore_check_permitted(vp, ip, ap->a_mode, ap->a_cred);
+
+	return error;
 }
 
 int

Index: src/sys/fs/hfs/hfs_vnops.c
diff -u src/sys/fs/hfs/hfs_vnops.c:1.14 src/sys/fs/hfs/hfs_vnops.c:1.15
--- src/sys/fs/hfs/hfs_vnops.c:1.14	Tue Jun 23 19:36:39 2009
+++ src/sys/fs/hfs/hfs_vnops.c	Fri Jul  3 21:17:41 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: hfs_vnops.c,v 1.14 2009/06/23 19:36:39 elad Exp $	*/
+/*	$NetBSD: hfs_vnops.c,v 1.15 2009/07/03 21:17:41 elad Exp $	*/
 
 /*-
  * Copyright (c) 2005, 2007 The NetBSD Foundation, Inc.
@@ -101,7 +101,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: hfs_vnops.c,v 1.14 2009/06/23 19:36:39 elad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: hfs_vnops.c,v 1.15 2009/07/03 21:17:41 elad Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_ipsec.h"
@@ -517,28 +517,17 @@
 	return 0;
 }
 
-int
-hfs_vop_access(void *v)
+static int
+hfs_check_possible(struct vnode *vp, mode_t mode)
 {
-	struct vop_access_args /* {
-		struct vnode *a_vp;
-		int a_mode;
-		kauth_cred_t a_cred;
-	} */ *ap = v;
-	struct vattr va;
-	int error;
-
-#ifdef HFS_DEBUG
-	printf("VOP = hfs_vop_access()\n");
-#endif /* HFS_DEBUG */
 
 	/*
 	 * Disallow writes on files, directories, and symlinks
 	 * since we have no write support yet.
 	 */
 
-	if (ap->a_mode & VWRITE) {
-		switch (ap->a_vp->v_type) {
+	if (mode & VWRITE) {
+		switch (vp->v_type) {
 		case VDIR:
 		case VLNK:
 		case VREG:
@@ -548,11 +537,42 @@
 		}
 	}
 
+	return 0;
+}
+
+static int
+hfs_check_permitted(struct vattr *va, mode_t mode, kauth_cred_t cred)
+{
+
+	return genfs_can_access(va->va_type, va->va_mode, va->va_uid,
+	    va->va_gid, mode, cred);
+}
+
+int
+hfs_vop_access(void *v)
+{
+	struct vop_access_args /* {
+		struct vnode *a_vp;
+		int a_mode;
+		kauth_cred_t a_cred;
+	} */ *ap = v;
+	struct vattr va;
+	int error;
+
+#ifdef HFS_DEBUG
+	printf("VOP = hfs_vop_access()\n");
+#endif /* HFS_DEBUG */
+
+	error = hfs_check_possible(ap->a_vp, ap->a_mode);
+	if (error)
+		return error;
+
 	if ((error = VOP_GETATTR(ap->a_vp, &va, ap->a_cred)) != 0)
 		return error;
 
-	return genfs_can_access(va.va_type, va.va_mode, va.va_uid, va.va_gid,
-	    ap->a_mode, ap->a_cred);
+	error = hfs_check_permitted(&va, ap->a_mode, ap->a_cred);
+
+	return error;
 }
 
 int

Index: src/sys/fs/msdosfs/msdosfs_vnops.c
diff -u src/sys/fs/msdosfs/msdosfs_vnops.c:1.60 src/sys/fs/msdosfs/msdosfs_vnops.c:1.61
--- src/sys/fs/msdosfs/msdosfs_vnops.c:1.60	Tue Jun 23 19:36:39 2009
+++ src/sys/fs/msdosfs/msdosfs_vnops.c	Fri Jul  3 21:17:40 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: msdosfs_vnops.c,v 1.60 2009/06/23 19:36:39 elad Exp $	*/
+/*	$NetBSD: msdosfs_vnops.c,v 1.61 2009/07/03 21:17:40 elad Exp $	*/
 
 /*-
  * Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank.
@@ -48,7 +48,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: msdosfs_vnops.c,v 1.60 2009/06/23 19:36:39 elad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: msdosfs_vnops.c,v 1.61 2009/07/03 21:17:40 elad Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -217,18 +217,9 @@
 	return (0);
 }
 
-int
-msdosfs_access(void *v)
+static int
+msdosfs_check_possible(struct vnode *vp, struct denode *dep, mode_t mode)
 {
-	struct vop_access_args /* {
-		struct vnode *a_vp;
-		int a_mode;
-		kauth_cred_t a_cred;
-	} */ *ap = v;
-	struct vnode *vp = ap->a_vp;
-	struct denode *dep = VTODE(vp);
-	struct msdosfsmount *pmp = dep->de_pmp;
-	mode_t mode = ap->a_mode;
 
 	/*
 	 * Disallow write attempts on read-only file systems;
@@ -247,13 +238,45 @@
 		}
 	}
 
+	return 0;
+}
+
+static int
+msdosfs_check_permitted(struct vnode *vp, struct denode *dep, mode_t mode,
+    kauth_cred_t cred)
+{
+	struct msdosfsmount *pmp = dep->de_pmp;
+	mode_t file_mode;
+
 	if ((dep->de_Attributes & ATTR_READONLY) == 0)
-		mode = S_IRWXU|S_IRWXG|S_IRWXO;
+		file_mode = S_IRWXU|S_IRWXG|S_IRWXO;
 	else
-		mode = S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH;
-	return (genfs_can_access(ap->a_vp->v_type,
-	    mode & (vp->v_type == VDIR ? pmp->pm_dirmask : pmp->pm_mask),
-	    pmp->pm_uid, pmp->pm_gid, ap->a_mode, ap->a_cred));
+		file_mode = S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH;
+
+	return genfs_can_access(vp->v_type,
+	    file_mode & (vp->v_type == VDIR ? pmp->pm_dirmask : pmp->pm_mask),
+	    pmp->pm_uid, pmp->pm_gid, mode, cred);
+}
+
+int
+msdosfs_access(void *v)
+{
+	struct vop_access_args /* {
+		struct vnode *a_vp;
+		int a_mode;
+		kauth_cred_t a_cred;
+	} */ *ap = v;
+	struct vnode *vp = ap->a_vp;
+	struct denode *dep = VTODE(vp);
+	int error;
+
+	error = msdosfs_check_possible(vp, dep, ap->a_mode);
+	if (error)
+		return error;
+
+	error = msdosfs_check_permitted(vp, dep, ap->a_mode, ap->a_cred);
+
+	return error;
 }
 
 int

Index: src/sys/fs/ntfs/ntfs_vnops.c
diff -u src/sys/fs/ntfs/ntfs_vnops.c:1.44 src/sys/fs/ntfs/ntfs_vnops.c:1.45
--- src/sys/fs/ntfs/ntfs_vnops.c:1.44	Tue Jun 23 19:36:40 2009
+++ src/sys/fs/ntfs/ntfs_vnops.c	Fri Jul  3 21:17:41 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: ntfs_vnops.c,v 1.44 2009/06/23 19:36:40 elad Exp $	*/
+/*	$NetBSD: ntfs_vnops.c,v 1.45 2009/07/03 21:17:41 elad Exp $	*/
 
 /*
  * Copyright (c) 1992, 1993
@@ -36,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ntfs_vnops.c,v 1.44 2009/06/23 19:36:40 elad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ntfs_vnops.c,v 1.45 2009/07/03 21:17:41 elad Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -395,19 +395,9 @@
 	return (error);
 }
 
-int
-ntfs_access(void *v)
+static int
+ntfs_check_possible(struct vnode *vp, struct ntnode *ip, mode_t mode)
 {
-	struct vop_access_args /* {
-		struct vnode *a_vp;
-		int  a_mode;
-		kauth_cred_t a_cred;
-	} */ *ap = v;
-	struct vnode *vp = ap->a_vp;
-	struct ntnode *ip = VTONT(vp);
-	mode_t file_mode, mode = ap->a_mode;
-
-	dprintf(("ntfs_access: %llu\n", (unsigned long long)ip->i_number));
 
 	/*
 	 * Disallow write attempts on read-only file systems;
@@ -425,10 +415,42 @@
 		}
 	}
 
+	return 0;
+}
+
+static int
+ntfs_check_permitted(struct vnode *vp, struct ntnode *ip, mode_t mode,
+    kauth_cred_t cred)
+{
+	mode_t file_mode;
+
 	file_mode = ip->i_mp->ntm_mode | (S_IXUSR|S_IXGRP|S_IXOTH);
 
-	return (genfs_can_access(vp->v_type, file_mode, ip->i_mp->ntm_uid,
-	    ip->i_mp->ntm_gid, mode, ap->a_cred));
+	return genfs_can_access(vp->v_type, file_mode, ip->i_mp->ntm_uid,
+	    ip->i_mp->ntm_gid, mode, cred);
+}
+
+int
+ntfs_access(void *v)
+{
+	struct vop_access_args /* {
+		struct vnode *a_vp;
+		int  a_mode;
+		kauth_cred_t a_cred;
+	} */ *ap = v;
+	struct vnode *vp = ap->a_vp;
+	struct ntnode *ip = VTONT(vp);
+	int error;
+
+	dprintf(("ntfs_access: %llu\n", (unsigned long long)ip->i_number));
+
+	error = ntfs_check_possible(vp, ip, ap->a_mode);
+	if (error)
+		return error;
+
+	error = ntfs_check_permitted(vp, ip, ap->a_mode, ap->a_cred);
+
+	return error;
 }
 
 /*

Index: src/sys/fs/ptyfs/ptyfs_vnops.c
diff -u src/sys/fs/ptyfs/ptyfs_vnops.c:1.31 src/sys/fs/ptyfs/ptyfs_vnops.c:1.32
--- src/sys/fs/ptyfs/ptyfs_vnops.c:1.31	Tue Jun 23 19:36:39 2009
+++ src/sys/fs/ptyfs/ptyfs_vnops.c	Fri Jul  3 21:17:40 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: ptyfs_vnops.c,v 1.31 2009/06/23 19:36:39 elad Exp $	*/
+/*	$NetBSD: ptyfs_vnops.c,v 1.32 2009/07/03 21:17:40 elad Exp $	*/
 
 /*
  * Copyright (c) 1993, 1995
@@ -76,7 +76,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ptyfs_vnops.c,v 1.31 2009/06/23 19:36:39 elad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ptyfs_vnops.c,v 1.32 2009/07/03 21:17:40 elad Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -498,6 +498,21 @@
 	return 0;
 }
 
+static int
+ptyfs_check_possible(struct vnode *vp, mode_t mode)
+{
+
+	return 0;
+}
+
+static int
+ptyfs_check_permitted(struct vattr *va, mode_t mode, kauth_cred_t cred)
+{
+
+	return genfs_can_access(va->va_type, va->va_mode,
+	    va->va_uid, va->va_gid, mode, cred);
+}
+
 /*
  * implement access checking.
  *
@@ -521,8 +536,13 @@
 	if ((error = VOP_GETATTR(ap->a_vp, &va, ap->a_cred)) != 0)
 		return error;
 
-	return genfs_can_access(va.va_type, va.va_mode,
-	    va.va_uid, va.va_gid, ap->a_mode, ap->a_cred);
+	error = ptyfs_check_possible(ap->a_vp, ap->a_mode);
+	if (error)
+		return error;
+
+	error = ptyfs_check_permitted(&va, ap->a_mode, ap->a_cred);
+
+	return error;
 }
 
 /*

Index: src/sys/fs/smbfs/smbfs_vnops.c
diff -u src/sys/fs/smbfs/smbfs_vnops.c:1.70 src/sys/fs/smbfs/smbfs_vnops.c:1.71
--- src/sys/fs/smbfs/smbfs_vnops.c:1.70	Fri Jul  3 18:35:33 2009
+++ src/sys/fs/smbfs/smbfs_vnops.c	Fri Jul  3 21:17:41 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: smbfs_vnops.c,v 1.70 2009/07/03 18:35:33 njoly Exp $	*/
+/*	$NetBSD: smbfs_vnops.c,v 1.71 2009/07/03 21:17:41 elad Exp $	*/
 
 /*-
  * Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -64,7 +64,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: smbfs_vnops.c,v 1.70 2009/07/03 18:35:33 njoly Exp $");
+__KERNEL_RCSID(0, "$NetBSD: smbfs_vnops.c,v 1.71 2009/07/03 21:17:41 elad Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -160,32 +160,16 @@
 const struct vnodeopv_desc smbfs_vnodeop_opv_desc =
 	{ &smbfs_vnodeop_p, smbfs_vnodeop_entries };
 
-int
-smbfs_access(void *v)
+static int
+smbfs_check_possible(struct vnode *vp, struct smbnode *np, mode_t mode)
 {
-	struct vop_access_args /* {
-		struct vnode *a_vp;
-		int  a_mode;
-		kauth_cred_t a_cred;
-	} */ *ap = v;
-	struct vnode *vp = ap->a_vp;
-#ifdef SMB_VNODE_DEBUG
-	struct smbnode *np = VTOSMB(vp);
-#endif
-	u_int acc_mode = ap->a_mode;
-	struct smbmount *smp = VTOSMBFS(vp);
-
-        SMBVDEBUG("file '%.*s', node mode=%o, acc mode=%x\n",
-	    (int) np->n_nmlen, np->n_name,
-	    (vp->v_type == VDIR) ? smp->sm_args.dir_mode : smp->sm_args.file_mode,
-	    acc_mode);
 
         /*
          * 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 (acc_mode & VWRITE) {
+	if (mode & VWRITE) {
 		switch (vp->v_type) {
 		case VREG:
 		case VDIR:
@@ -197,10 +181,45 @@
 		}
 	}
 
-	return (genfs_can_access(vp->v_type,
+	return 0;
+}
+
+static int
+smbfs_check_permitted(struct vnode *vp, struct smbnode *np, mode_t mode,
+    kauth_cred_t cred)
+{
+	struct smbmount *smp = VTOSMBFS(vp);
+
+	return genfs_can_access(vp->v_type,
 	    (vp->v_type == VDIR) ? smp->sm_args.dir_mode : smp->sm_args.file_mode,
-	    smp->sm_args.uid, smp->sm_args.gid,
-	    acc_mode, ap->a_cred));
+	    smp->sm_args.uid, smp->sm_args.gid, mode, cred);
+}
+
+int
+smbfs_access(void *v)
+{
+	struct vop_access_args /* {
+		struct vnode *a_vp;
+		int  a_mode;
+		kauth_cred_t a_cred;
+	} */ *ap = v;
+	struct vnode *vp = ap->a_vp;
+	struct smbnode *np = VTOSMB(vp);
+	u_int acc_mode = ap->a_mode;
+	int error;
+
+        SMBVDEBUG("file '%.*s', node mode=%o, acc mode=%x\n",
+	    (int) np->n_nmlen, np->n_name,
+	    (vp->v_type == VDIR) ? smp->sm_args.dir_mode : smp->sm_args.file_mode,
+	    acc_mode);
+
+	error = smbfs_check_possible(vp, np, acc_mode);
+	if (error)
+		return error;
+
+	error = smbfs_check_permitted(vp, np, acc_mode, ap->a_cred);
+
+	return error;
 }
 
 /* ARGSUSED */

Index: src/sys/fs/sysvbfs/sysvbfs_vnops.c
diff -u src/sys/fs/sysvbfs/sysvbfs_vnops.c:1.22 src/sys/fs/sysvbfs/sysvbfs_vnops.c:1.23
--- src/sys/fs/sysvbfs/sysvbfs_vnops.c:1.22	Tue Jun 23 19:36:39 2009
+++ src/sys/fs/sysvbfs/sysvbfs_vnops.c	Fri Jul  3 21:17:41 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: sysvbfs_vnops.c,v 1.22 2009/06/23 19:36:39 elad Exp $	*/
+/*	$NetBSD: sysvbfs_vnops.c,v 1.23 2009/07/03 21:17:41 elad Exp $	*/
 
 /*-
  * Copyright (c) 2004 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sysvbfs_vnops.c,v 1.22 2009/06/23 19:36:39 elad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sysvbfs_vnops.c,v 1.23 2009/07/03 21:17:41 elad Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -230,6 +230,27 @@
 	return 0;
 }
 
+static int
+sysvbfs_check_possible(struct vnode *vp, struct sysvbfs_node *bnode,
+    mode_t mode)
+{
+
+	if ((mode & VWRITE) && (vp->v_mount->mnt_flag & MNT_RDONLY))
+		return EROFS;
+
+	return 0;
+}
+
+static int
+sysvbfs_check_permitted(struct vnode *vp, struct sysvbfs_node *bnode,
+    mode_t mode, kauth_cred_t cred)
+{
+	struct bfs_fileattr *attr = &bnode->inode->attr;
+
+	return genfs_can_access(vp->v_type, attr->mode, attr->uid, attr->gid,
+	    mode, cred);
+}
+
 int
 sysvbfs_access(void *arg)
 {
@@ -240,14 +261,16 @@
 	} */ *ap = arg;
 	struct vnode *vp = ap->a_vp;
 	struct sysvbfs_node *bnode = vp->v_data;
-	struct bfs_fileattr *attr = &bnode->inode->attr;
 
 	DPRINTF("%s:\n", __func__);
-	if ((ap->a_mode & VWRITE) && (vp->v_mount->mnt_flag & MNT_RDONLY))
-		return EROFS;
 
-	return genfs_can_access(vp->v_type, attr->mode, attr->uid, attr->gid,
-	    ap->a_mode, ap->a_cred);
+	error = sysvbfs_check_possible(vp, bnode, ap->a_mode);
+	if (error)
+		return error;
+
+	error = sysvbfs_check_permitted(vp, bnode, ap->a_mode, ap->a_cred);
+
+	return error;
 }
 
 int

Index: src/sys/fs/tmpfs/tmpfs_vnops.c
diff -u src/sys/fs/tmpfs/tmpfs_vnops.c:1.60 src/sys/fs/tmpfs/tmpfs_vnops.c:1.61
--- src/sys/fs/tmpfs/tmpfs_vnops.c:1.60	Tue Jun 23 19:36:39 2009
+++ src/sys/fs/tmpfs/tmpfs_vnops.c	Fri Jul  3 21:17:41 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: tmpfs_vnops.c,v 1.60 2009/06/23 19:36:39 elad Exp $	*/
+/*	$NetBSD: tmpfs_vnops.c,v 1.61 2009/07/03 21:17:41 elad Exp $	*/
 
 /*
  * Copyright (c) 2005, 2006, 2007 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tmpfs_vnops.c,v 1.60 2009/06/23 19:36:39 elad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tmpfs_vnops.c,v 1.61 2009/07/03 21:17:41 elad Exp $");
 
 #include <sys/param.h>
 #include <sys/dirent.h>
@@ -337,19 +337,10 @@
 
 /* --------------------------------------------------------------------- */
 
-int
-tmpfs_access(void *v)
+static int
+tmpfs_check_possible(struct vnode *vp, struct tmpfs_node *node, mode_t mode)
 {
-	struct vnode *vp = ((struct vop_access_args *)v)->a_vp;
-	int mode = ((struct vop_access_args *)v)->a_mode;
-	kauth_cred_t cred = ((struct vop_access_args *)v)->a_cred;
-
-	int error;
-	struct tmpfs_node *node;
-
-	KASSERT(VOP_ISLOCKED(vp));
-
-	node = VP_TO_TMPFS_NODE(vp);
+	int error = 0;
 
 	switch (vp->v_type) {
 	case VDIR:
@@ -382,8 +373,38 @@
 		goto out;
 	}
 
-	error = genfs_can_access(vp->v_type, node->tn_mode, node->tn_uid,
+ out:
+	return error;
+}
+
+static int
+tmpfs_check_permitted(struct vnode *vp, struct tmpfs_node *node, mode_t mode,
+    kauth_cred_t cred)
+{
+
+	return genfs_can_access(vp->v_type, node->tn_mode, node->tn_uid,
 	    node->tn_gid, mode, cred);
+}
+
+int
+tmpfs_access(void *v)
+{
+	struct vnode *vp = ((struct vop_access_args *)v)->a_vp;
+	int mode = ((struct vop_access_args *)v)->a_mode;
+	kauth_cred_t cred = ((struct vop_access_args *)v)->a_cred;
+
+	int error;
+	struct tmpfs_node *node;
+
+	KASSERT(VOP_ISLOCKED(vp));
+
+	node = VP_TO_TMPFS_NODE(vp);
+
+	error = tmpfs_check_possible(vp, node, mode);
+	if (error)
+		goto out;
+
+	error = tmpfs_check_permitted(vp, node, mode, cred);
 
 out:
 	KASSERT(VOP_ISLOCKED(vp));

Index: src/sys/fs/udf/udf_vnops.c
diff -u src/sys/fs/udf/udf_vnops.c:1.47 src/sys/fs/udf/udf_vnops.c:1.48
--- src/sys/fs/udf/udf_vnops.c:1.47	Thu Jun 25 17:16:33 2009
+++ src/sys/fs/udf/udf_vnops.c	Fri Jul  3 21:17:41 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: udf_vnops.c,v 1.47 2009/06/25 17:16:33 reinoud Exp $ */
+/* $NetBSD: udf_vnops.c,v 1.48 2009/07/03 21:17:41 elad Exp $ */
 
 /*
  * Copyright (c) 2006, 2008 Reinoud Zandijk
@@ -32,7 +32,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__KERNEL_RCSID(0, "$NetBSD: udf_vnops.c,v 1.47 2009/06/25 17:16:33 reinoud Exp $");
+__KERNEL_RCSID(0, "$NetBSD: udf_vnops.c,v 1.48 2009/07/03 21:17:41 elad Exp $");
 #endif /* not lint */
 
 
@@ -1310,31 +1310,13 @@
 
 /* --------------------------------------------------------------------- */
 
-int
-udf_access(void *v)
+static int
+udf_check_possible(struct vattr *vap, mode_t mode)
 {
-	struct vop_access_args /* {
-		struct vnode *a_vp;
-		int a_mode;
-		kauth_cred_t a_cred;
-		struct proc *a_p;
-	} */ *ap = v;
-	struct vnode    *vp   = ap->a_vp;
-	mode_t	         mode = ap->a_mode;
-	kauth_cred_t     cred = ap->a_cred;
-	/* struct udf_node *udf_node = VTOI(vp); */
-	struct vattr vap;
 	int flags;
-	int error;
-
-	DPRINTF(CALL, ("udf_access called\n"));
-
-	error = VOP_GETATTR(vp, &vap, NULL);
-	if (error)
-		return error;
 
 	/* check if we are allowed to write */
-	switch (vap.va_type) {
+	switch (vap->va_type) {
 	case VDIR:
 	case VLNK:
 	case VREG:
@@ -1365,12 +1347,51 @@
 	if ((mode & VWRITE) && (flags & IMMUTABLE))
 		return EPERM;
 
+	return 0;
+}
+
+static int
+udf_check_permitted(struct vnode *vp, struct vattr *vap, mode_t mode,
+    kauth_cred_t cred)
+{
+
 	/* ask the generic genfs_can_access to advice on security */
 	return genfs_can_access(vp->v_type,
-			vap.va_mode, vap.va_uid, vap.va_gid,
+			vap->va_mode, vap->va_uid, vap->va_gid,
 			mode, cred);
 }
 
+int
+udf_access(void *v)
+{
+	struct vop_access_args /* {
+		struct vnode *a_vp;
+		int a_mode;
+		kauth_cred_t a_cred;
+		struct proc *a_p;
+	} */ *ap = v;
+	struct vnode    *vp   = ap->a_vp;
+	mode_t	         mode = ap->a_mode;
+	kauth_cred_t     cred = ap->a_cred;
+	/* struct udf_node *udf_node = VTOI(vp); */
+	struct vattr vap;
+	int error;
+
+	DPRINTF(CALL, ("udf_access called\n"));
+
+	error = VOP_GETATTR(vp, &vap, NULL);
+	if (error)
+		return error;
+
+	error = udf_check_possible(&vap, mode);
+	if (error)
+		return error;
+
+	error = udf_check_permitted(vp, &vap, mode, cred);
+
+	return error;
+}
+
 /* --------------------------------------------------------------------- */
 
 int

Index: src/sys/miscfs/kernfs/kernfs_vnops.c
diff -u src/sys/miscfs/kernfs/kernfs_vnops.c:1.137 src/sys/miscfs/kernfs/kernfs_vnops.c:1.138
--- src/sys/miscfs/kernfs/kernfs_vnops.c:1.137	Tue Jun 23 19:36:40 2009
+++ src/sys/miscfs/kernfs/kernfs_vnops.c	Fri Jul  3 21:17:41 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: kernfs_vnops.c,v 1.137 2009/06/23 19:36:40 elad Exp $	*/
+/*	$NetBSD: kernfs_vnops.c,v 1.138 2009/07/03 21:17:41 elad Exp $	*/
 
 /*
  * Copyright (c) 1992, 1993
@@ -39,7 +39,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kernfs_vnops.c,v 1.137 2009/06/23 19:36:40 elad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kernfs_vnops.c,v 1.138 2009/07/03 21:17:41 elad Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_ipsec.h"
@@ -763,6 +763,21 @@
 	return (0);
 }
 
+static int
+kernfs_check_possible(struct vnode *vp, mode_t mode)
+{
+
+	return 0;
+}
+
+static int
+kernfs_check_permitted(struct vattr *va, mode_t mode, kauth_cred_t cred)
+{
+
+	return genfs_can_access(va->va_type, va->va_mode, va->va_uid, va->va_gid,
+	    mode, cred);
+}
+
 int
 kernfs_access(void *v)
 {
@@ -777,8 +792,13 @@
 	if ((error = VOP_GETATTR(ap->a_vp, &va, ap->a_cred)) != 0)
 		return (error);
 
-	return (genfs_can_access(va.va_type, va.va_mode, va.va_uid, va.va_gid,
-	    ap->a_mode, ap->a_cred));
+	error = kernfs_check_possible(ap->a_vp, ap->a_mode);
+	if (error)
+		return error;
+
+	error = kernfs_check_permitted(&va, ap->a_mode, ap->a_cred);
+
+	return error;
 }
 
 static int

Index: src/sys/miscfs/procfs/procfs_vnops.c
diff -u src/sys/miscfs/procfs/procfs_vnops.c:1.175 src/sys/miscfs/procfs/procfs_vnops.c:1.176
--- src/sys/miscfs/procfs/procfs_vnops.c:1.175	Tue Jun 23 19:36:40 2009
+++ src/sys/miscfs/procfs/procfs_vnops.c	Fri Jul  3 21:17:42 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: procfs_vnops.c,v 1.175 2009/06/23 19:36:40 elad Exp $	*/
+/*	$NetBSD: procfs_vnops.c,v 1.176 2009/07/03 21:17:42 elad Exp $	*/
 
 /*-
  * Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -105,7 +105,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: procfs_vnops.c,v 1.175 2009/06/23 19:36:40 elad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: procfs_vnops.c,v 1.176 2009/07/03 21:17:42 elad Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -909,6 +909,21 @@
 	return (0);
 }
 
+static int
+procfs_check_possible(struct vnode *vp, mode_t mode)
+{
+
+	return 0;
+}
+
+static int
+procfs_check_permitted(struct vattr *va, mode_t mode, kauth_cred_t cred)
+{
+
+	return genfs_can_access(va->va_type, va->va_mode,
+	    va->va_uid, va->va_gid, mode, cred);
+}
+
 /*
  * implement access checking.
  *
@@ -932,8 +947,13 @@
 	if ((error = VOP_GETATTR(ap->a_vp, &va, ap->a_cred)) != 0)
 		return (error);
 
-	return (genfs_can_access(va.va_type, va.va_mode,
-	    va.va_uid, va.va_gid, ap->a_mode, ap->a_cred));
+	error = procfs_check_possible(ap->a_vp, ap->a_mode);
+	if (error)
+		return error;
+
+	error = procfs_check_permitted(&va, ap->a_mode, ap->a_cred);
+
+	return error;
 }
 
 /*

Index: src/sys/ufs/ext2fs/ext2fs_vnops.c
diff -u src/sys/ufs/ext2fs/ext2fs_vnops.c:1.87 src/sys/ufs/ext2fs/ext2fs_vnops.c:1.88
--- src/sys/ufs/ext2fs/ext2fs_vnops.c:1.87	Tue Jun 23 19:36:40 2009
+++ src/sys/ufs/ext2fs/ext2fs_vnops.c	Fri Jul  3 21:17:42 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: ext2fs_vnops.c,v 1.87 2009/06/23 19:36:40 elad Exp $	*/
+/*	$NetBSD: ext2fs_vnops.c,v 1.88 2009/07/03 21:17:42 elad Exp $	*/
 
 /*
  * Copyright (c) 1982, 1986, 1989, 1993
@@ -70,7 +70,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ext2fs_vnops.c,v 1.87 2009/06/23 19:36:40 elad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ext2fs_vnops.c,v 1.88 2009/07/03 21:17:42 elad Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -224,17 +224,9 @@
 	return (0);
 }
 
-int
-ext2fs_access(void *v)
+static int
+ext2fs_check_possible(struct vnode *vp, struct inode *ip, mode_t mode)
 {
-	struct vop_access_args /* {
-		struct vnode *a_vp;
-		int  a_mode;
-		kauth_cred_t a_cred;
-	} */ *ap = v;
-	struct vnode *vp = ap->a_vp;
-	struct inode *ip = VTOI(vp);
-	mode_t mode = ap->a_mode;
 
 	/*
 	 * Disallow write attempts on read-only file systems;
@@ -258,8 +250,38 @@
 	if ((mode & VWRITE) && (ip->i_e2fs_flags & EXT2_IMMUTABLE))
 		return (EPERM);
 
-	return (genfs_can_access(vp->v_type, ip->i_e2fs_mode & ALLPERMS,
-			ip->i_uid, ip->i_gid, mode, ap->a_cred));
+	return 0;
+}
+
+static int
+ext2fs_check_permitted(struct vnode *vp, struct inode *ip, mode_t mode,
+    kauth_cred_t cred)
+{
+
+	return genfs_can_access(vp->v_type, ip->i_e2fs_mode & ALLPERMS,
+	    ip->i_uid, ip->i_gid, mode, cred);
+}
+
+int
+ext2fs_access(void *v)
+{
+	struct vop_access_args /* {
+		struct vnode *a_vp;
+		int  a_mode;
+		kauth_cred_t a_cred;
+	} */ *ap = v;
+	struct vnode *vp = ap->a_vp;
+	struct inode *ip = VTOI(vp);
+	mode_t mode = ap->a_mode;
+	int error;
+
+	error = ext2fs_check_possible(vp, ip, mode);
+	if (error)
+		return error;
+
+	error = ext2fs_check_permitted(vp, ip, mode, ap->a_cred);
+
+	return error;
 }
 
 /* ARGSUSED */

Index: src/sys/ufs/ufs/ufs_vnops.c
diff -u src/sys/ufs/ufs/ufs_vnops.c:1.178 src/sys/ufs/ufs/ufs_vnops.c:1.179
--- src/sys/ufs/ufs/ufs_vnops.c:1.178	Tue Jun 23 19:36:40 2009
+++ src/sys/ufs/ufs/ufs_vnops.c	Fri Jul  3 21:17:42 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: ufs_vnops.c,v 1.178 2009/06/23 19:36:40 elad Exp $	*/
+/*	$NetBSD: ufs_vnops.c,v 1.179 2009/07/03 21:17:42 elad Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -66,7 +66,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ufs_vnops.c,v 1.178 2009/06/23 19:36:40 elad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ufs_vnops.c,v 1.179 2009/07/03 21:17:42 elad Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_ffs.h"
@@ -272,24 +272,13 @@
 	return (0);
 }
 
-int
-ufs_access(void *v)
+static int
+ufs_check_possible(struct vnode *vp, struct inode *ip, mode_t mode)
 {
-	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;
 #ifdef QUOTA
-	int		error;
-#endif
+	int error;
+#endif /* QUOTA */
 
-	vp = ap->a_vp;
-	ip = VTOI(vp);
-	mode = ap->a_mode;
 	/*
 	 * Disallow write attempts on read-only file systems;
 	 * unless the file is a socket, fifo, or a block or
@@ -328,8 +317,42 @@
 	if ((mode & VWRITE) && (ip->i_flags & IMMUTABLE))
 		return (EPERM);
 
-	return (genfs_can_access(vp->v_type, ip->i_mode & ALLPERMS,
-		ip->i_uid, ip->i_gid, mode, ap->a_cred));
+	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;
 }
 
 /* ARGSUSED */

Reply via email to