svn commit: r193092 - in head: share/man/man9 sys/fs/nullfs
sys/kern sys/sys
Edward Tomasz Napierala
trasz at FreeBSD.org
Sat May 30 13:59:07 UTC 2009
Author: trasz
Date: Sat May 30 13:59:05 2009
New Revision: 193092
URL: http://svn.freebsd.org/changeset/base/193092
Log:
Add VOP_ACCESSX, which can be used to query for newly added V*
permissions, such as VWRITE_ACL. For a filsystems that don't
implement it, there is a default implementation, which works
as a wrapper around VOP_ACCESS.
Reviewed by: rwatson@
Modified:
head/share/man/man9/Makefile
head/share/man/man9/VOP_ACCESS.9
head/sys/fs/nullfs/null_vnops.c
head/sys/kern/vfs_default.c
head/sys/kern/vfs_subr.c
head/sys/kern/vnode_if.src
head/sys/sys/vnode.h
Modified: head/share/man/man9/Makefile
==============================================================================
--- head/share/man/man9/Makefile Sat May 30 12:26:11 2009 (r193091)
+++ head/share/man/man9/Makefile Sat May 30 13:59:05 2009 (r193092)
@@ -1288,6 +1288,7 @@ MLINKS+=vm_page_io.9 vm_page_io_finish.9
MLINKS+=vm_page_wakeup.9 vm_page_busy.9 \
vm_page_wakeup.9 vm_page_flash.9
MLINKS+=vm_page_wire.9 vm_page_unwire.9
+MLINKS+=VOP_ACCESS.9 VOP_ACCESSX.9
MLINKS+=VOP_ATTRIB.9 VOP_GETATTR.9 \
VOP_ATTRIB.9 VOP_SETATTR.9
MLINKS+=VOP_CREATE.9 VOP_MKDIR.9 \
Modified: head/share/man/man9/VOP_ACCESS.9
==============================================================================
--- head/share/man/man9/VOP_ACCESS.9 Sat May 30 12:26:11 2009 (r193091)
+++ head/share/man/man9/VOP_ACCESS.9 Sat May 30 13:59:05 2009 (r193092)
@@ -29,17 +29,20 @@
.\"
.\" $FreeBSD$
.\"
-.Dd July 24, 1996
+.Dd May 30, 2009
.Os
.Dt VOP_ACCESS 9
.Sh NAME
-.Nm VOP_ACCESS
+.Nm VOP_ACCESS ,
+.Nm VOP_ACCESSX
.Nd "check access permissions of a file or Unix domain socket"
.Sh SYNOPSIS
.In sys/param.h
.In sys/vnode.h
.Ft int
.Fn VOP_ACCESS "struct vnode *vp" "accmode_t accmode" "struct ucred *cred" "struct thread *td"
+.Ft int
+.Fn VOP_ACCESSX "struct vnode *vp" "accmode_t accmode" "struct ucred *cred" "struct thread *td"
.Sh DESCRIPTION
This entry point checks the access permissions of the file against the
given credentials.
@@ -63,6 +66,20 @@ is a mask which can contain flags descri
.Dv VWRITE
or
.Dv VEXEC .
+For
+.Fn VOP_ACCESS ,
+the only flags that may be set in
+.Fa accmode
+are
+.Dv VEXEC ,
+.Dv VWRITE ,
+.Dv VREAD ,
+.Dv VADMIN
+and
+.Dv VAPPEND .
+To check for other bits, one has to use
+.Fn VOP_ACCESSX
+instead.
.Sh LOCKS
The vnode will be locked on entry and should remain locked on return.
.Sh RETURN VALUES
Modified: head/sys/fs/nullfs/null_vnops.c
==============================================================================
--- head/sys/fs/nullfs/null_vnops.c Sat May 30 12:26:11 2009 (r193091)
+++ head/sys/fs/nullfs/null_vnops.c Sat May 30 13:59:05 2009 (r193092)
@@ -472,6 +472,32 @@ null_access(struct vop_access_args *ap)
return (null_bypass((struct vop_generic_args *)ap));
}
+static int
+null_accessx(struct vop_accessx_args *ap)
+{
+ struct vnode *vp = ap->a_vp;
+ accmode_t accmode = ap->a_accmode;
+
+ /*
+ * Disallow write attempts on read-only layers;
+ * unless the file is a socket, fifo, or a block or
+ * character device resident on the filesystem.
+ */
+ if (accmode & VWRITE) {
+ switch (vp->v_type) {
+ case VDIR:
+ case VLNK:
+ case VREG:
+ if (vp->v_mount->mnt_flag & MNT_RDONLY)
+ return (EROFS);
+ break;
+ default:
+ break;
+ }
+ }
+ return (null_bypass((struct vop_generic_args *)ap));
+}
+
/*
* We handle this to eliminate null FS to lower FS
* file moving. Don't know why we don't allow this,
@@ -720,6 +746,7 @@ null_vptofh(struct vop_vptofh_args *ap)
struct vop_vector null_vnodeops = {
.vop_bypass = null_bypass,
.vop_access = null_access,
+ .vop_accessx = null_accessx,
.vop_bmap = VOP_EOPNOTSUPP,
.vop_getattr = null_getattr,
.vop_getwritemount = null_getwritemount,
Modified: head/sys/kern/vfs_default.c
==============================================================================
--- head/sys/kern/vfs_default.c Sat May 30 12:26:11 2009 (r193091)
+++ head/sys/kern/vfs_default.c Sat May 30 13:59:05 2009 (r193092)
@@ -87,6 +87,7 @@ struct vop_vector default_vnodeops = {
.vop_default = NULL,
.vop_bypass = VOP_EOPNOTSUPP,
+ .vop_accessx = vop_stdaccessx,
.vop_advlock = vop_stdadvlock,
.vop_advlockasync = vop_stdadvlockasync,
.vop_bmap = vop_stdbmap,
@@ -322,6 +323,22 @@ out:
return (found);
}
+int
+vop_stdaccessx(struct vop_accessx_args *ap)
+{
+ int error;
+ accmode_t accmode = ap->a_accmode;
+
+ error = vfs_unixify_accmode(&accmode);
+ if (error != 0)
+ return (error);
+
+ if (accmode == 0)
+ return (0);
+
+ return (VOP_ACCESS(ap->a_vp, accmode, ap->a_cred, ap->a_td));
+}
+
/*
* Advisory record locking support
*/
Modified: head/sys/kern/vfs_subr.c
==============================================================================
--- head/sys/kern/vfs_subr.c Sat May 30 12:26:11 2009 (r193091)
+++ head/sys/kern/vfs_subr.c Sat May 30 13:59:05 2009 (r193092)
@@ -4253,3 +4253,50 @@ vfs_mark_atime(struct vnode *vp, struct
if ((vp->v_mount->mnt_flag & (MNT_NOATIME | MNT_RDONLY)) == 0)
(void)VOP_MARKATIME(vp);
}
+
+/*
+ * The purpose of this routine is to remove granularity from accmode_t,
+ * reducing it into standard unix access bits - VEXEC, VREAD, VWRITE,
+ * VADMIN and VAPPEND.
+ *
+ * If it returns 0, the caller is supposed to continue with the usual
+ * access checks using 'accmode' as modified by this routine. If it
+ * returns nonzero value, the caller is supposed to return that value
+ * as errno.
+ *
+ * Note that after this routine runs, accmode may be zero.
+ */
+int
+vfs_unixify_accmode(accmode_t *accmode)
+{
+ /*
+ * There is no way to specify explicit "deny" rule using
+ * file mode or POSIX.1e ACLs.
+ */
+ if (*accmode & VEXPLICIT_DENY) {
+ *accmode = 0;
+ return (0);
+ }
+
+ /*
+ * None of these can be translated into usual access bits.
+ * Also, the common case for NFSv4 ACLs is to not contain
+ * either of these bits. Caller should check for VWRITE
+ * on the containing directory instead.
+ */
+ if (*accmode & (VDELETE_CHILD | VDELETE))
+ return (EPERM);
+
+ if (*accmode & VADMIN_PERMS) {
+ *accmode &= ~VADMIN_PERMS;
+ *accmode |= VADMIN;
+ }
+
+ /*
+ * There is no way to deny VREAD_ATTRIBUTES, VREAD_ACL
+ * or VSYNCHRONIZE using file mode or POSIX.1e ACL.
+ */
+ *accmode &= ~(VSTAT_PERMS | VSYNCHRONIZE);
+
+ return (0);
+}
Modified: head/sys/kern/vnode_if.src
==============================================================================
--- head/sys/kern/vnode_if.src Sat May 30 12:26:11 2009 (r193091)
+++ head/sys/kern/vnode_if.src Sat May 30 13:59:05 2009 (r193092)
@@ -153,6 +153,16 @@ vop_access {
};
+%% accessx vp L L L
+
+vop_accessx {
+ IN struct vnode *vp;
+ IN accmode_t accmode;
+ IN struct ucred *cred;
+ IN struct thread *td;
+};
+
+
%% getattr vp L L L
vop_getattr {
Modified: head/sys/sys/vnode.h
==============================================================================
--- head/sys/sys/vnode.h Sat May 30 12:26:11 2009 (r193091)
+++ head/sys/sys/vnode.h Sat May 30 13:59:05 2009 (r193092)
@@ -676,6 +676,7 @@ int vop_stdlock(struct vop_lock1_args *)
int vop_stdputpages(struct vop_putpages_args *);
int vop_stdunlock(struct vop_unlock_args *);
int vop_nopoll(struct vop_poll_args *);
+int vop_stdaccessx(struct vop_accessx_args *ap);
int vop_stdadvlock(struct vop_advlock_args *ap);
int vop_stdadvlockasync(struct vop_advlockasync_args *ap);
int vop_stdpathconf(struct vop_pathconf_args *);
@@ -766,6 +767,8 @@ void vfs_mark_atime(struct vnode *vp, st
struct dirent;
int vfs_read_dirent(struct vop_readdir_args *ap, struct dirent *dp, off_t off);
+int vfs_unixify_accmode(accmode_t *accmode);
+
#endif /* _KERNEL */
#endif /* !_SYS_VNODE_H_ */
More information about the svn-src-head
mailing list