summaryrefslogtreecommitdiffstats
path: root/sys/kern/subr_acl_posix1e.c
diff options
context:
space:
mode:
authorcsjp <csjp@FreeBSD.org>2005-09-17 22:01:14 +0000
committercsjp <csjp@FreeBSD.org>2005-09-17 22:01:14 +0000
commit7d71792fdf2076f1666dfa44e20a7c427173b3a2 (patch)
treee2dd9340ed87511977d78d15aa6bf60df9c0bdee /sys/kern/subr_acl_posix1e.c
parentc428222e35b08f0cc96b2691a9defbbb9bcc3dcc (diff)
downloadFreeBSD-src-7d71792fdf2076f1666dfa44e20a7c427173b3a2.zip
FreeBSD-src-7d71792fdf2076f1666dfa44e20a7c427173b3a2.tar.gz
Implement new world order in VFS locking for ACLs. This will remove the
unconditional acquisition of Giant for ACL related operations. If the file system is set as being MP safe and debug.mpsafevfs is 1, do not pickup giant. For any operations which require namei(9) lookups: __acl_get_file __acl_get_link __acl_set_file __acl_set_link __acl_delete_file __acl_delete_link __acl_aclcheck_file __acl_aclcheck_link -Set the MPSAFE flag in NDINIT -Initialize vfslocked variable using the NDHASGIANT macro For functions which operate on fds, make sure the operations are locked: __acl_get_fd __acl_set_fd __acl_delete_fd __acl_aclcheck_fd -Initialize vfslocked using VFS_LOCK_GIANT before we manipulate the vnode Discussed with: jeff
Diffstat (limited to 'sys/kern/subr_acl_posix1e.c')
-rw-r--r--sys/kern/subr_acl_posix1e.c89
1 files changed, 45 insertions, 44 deletions
diff --git a/sys/kern/subr_acl_posix1e.c b/sys/kern/subr_acl_posix1e.c
index f238b98..f346f61 100644
--- a/sys/kern/subr_acl_posix1e.c
+++ b/sys/kern/subr_acl_posix1e.c
@@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
#include <sys/kernel.h>
#include <sys/mac.h>
#include <sys/malloc.h>
+#include <sys/mount.h>
#include <sys/vnode.h>
#include <sys/lock.h>
#include <sys/mutex.h>
@@ -772,16 +773,16 @@ int
__acl_get_file(struct thread *td, struct __acl_get_file_args *uap)
{
struct nameidata nd;
- int error;
+ int vfslocked, error;
- mtx_lock(&Giant);
- NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, td);
+ NDINIT(&nd, LOOKUP, MPSAFE|FOLLOW, UIO_USERSPACE, uap->path, td);
error = namei(&nd);
+ vfslocked = NDHASGIANT(&nd);
if (error == 0) {
error = vacl_get_acl(td, nd.ni_vp, uap->type, uap->aclp);
NDFREE(&nd, 0);
}
- mtx_unlock(&Giant);
+ VFS_UNLOCK_GIANT(vfslocked);
return (error);
}
@@ -794,16 +795,16 @@ int
__acl_get_link(struct thread *td, struct __acl_get_link_args *uap)
{
struct nameidata nd;
- int error;
+ int vfslocked, error;
- mtx_lock(&Giant);
- NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, uap->path, td);
+ NDINIT(&nd, LOOKUP, MPSAFE|NOFOLLOW, UIO_USERSPACE, uap->path, td);
error = namei(&nd);
+ vfslocked = NDHASGIANT(&nd);
if (error == 0) {
error = vacl_get_acl(td, nd.ni_vp, uap->type, uap->aclp);
NDFREE(&nd, 0);
}
- mtx_unlock(&Giant);
+ VFS_UNLOCK_GIANT(vfslocked);
return (error);
}
@@ -816,16 +817,16 @@ int
__acl_set_file(struct thread *td, struct __acl_set_file_args *uap)
{
struct nameidata nd;
- int error;
+ int vfslocked, error;
- mtx_lock(&Giant);
- NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, td);
+ NDINIT(&nd, LOOKUP, MPSAFE|FOLLOW, UIO_USERSPACE, uap->path, td);
error = namei(&nd);
+ vfslocked = NDHASGIANT(&nd);
if (error == 0) {
error = vacl_set_acl(td, nd.ni_vp, uap->type, uap->aclp);
NDFREE(&nd, 0);
}
- mtx_unlock(&Giant);
+ VFS_UNLOCK_GIANT(vfslocked);
return (error);
}
@@ -838,16 +839,16 @@ int
__acl_set_link(struct thread *td, struct __acl_set_link_args *uap)
{
struct nameidata nd;
- int error;
+ int vfslocked, error;
- mtx_lock(&Giant);
- NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, uap->path, td);
+ NDINIT(&nd, LOOKUP, MPSAFE|NOFOLLOW, UIO_USERSPACE, uap->path, td);
error = namei(&nd);
+ vfslocked = NDHASGIANT(&nd);
if (error == 0) {
error = vacl_set_acl(td, nd.ni_vp, uap->type, uap->aclp);
NDFREE(&nd, 0);
}
- mtx_unlock(&Giant);
+ VFS_UNLOCK_GIANT(vfslocked);
return (error);
}
@@ -860,15 +861,15 @@ int
__acl_get_fd(struct thread *td, struct __acl_get_fd_args *uap)
{
struct file *fp;
- int error;
+ int vfslocked, error;
- mtx_lock(&Giant);
error = getvnode(td->td_proc->p_fd, uap->filedes, &fp);
if (error == 0) {
+ vfslocked = VFS_LOCK_GIANT(fp->f_vnode->v_mount);
error = vacl_get_acl(td, fp->f_vnode, uap->type, uap->aclp);
fdrop(fp, td);
+ VFS_UNLOCK_GIANT(vfslocked);
}
- mtx_unlock(&Giant);
return (error);
}
@@ -881,15 +882,15 @@ int
__acl_set_fd(struct thread *td, struct __acl_set_fd_args *uap)
{
struct file *fp;
- int error;
+ int vfslocked, error;
- mtx_lock(&Giant);
error = getvnode(td->td_proc->p_fd, uap->filedes, &fp);
if (error == 0) {
+ vfslocked = VFS_LOCK_GIANT(fp->f_vnode->v_mount);
error = vacl_set_acl(td, fp->f_vnode, uap->type, uap->aclp);
fdrop(fp, td);
+ VFS_UNLOCK_GIANT(vfslocked);
}
- mtx_unlock(&Giant);
return (error);
}
@@ -902,16 +903,16 @@ int
__acl_delete_file(struct thread *td, struct __acl_delete_file_args *uap)
{
struct nameidata nd;
- int error;
+ int vfslocked, error;
- mtx_lock(&Giant);
- NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, td);
+ NDINIT(&nd, LOOKUP, MPSAFE|FOLLOW, UIO_USERSPACE, uap->path, td);
error = namei(&nd);
+ vfslocked = NDHASGIANT(&nd);
if (error == 0) {
error = vacl_delete(td, nd.ni_vp, uap->type);
NDFREE(&nd, 0);
}
- mtx_unlock(&Giant);
+ VFS_UNLOCK_GIANT(vfslocked);
return (error);
}
@@ -924,16 +925,16 @@ int
__acl_delete_link(struct thread *td, struct __acl_delete_link_args *uap)
{
struct nameidata nd;
- int error;
+ int vfslocked, error;
- mtx_lock(&Giant);
- NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, uap->path, td);
+ NDINIT(&nd, LOOKUP, MPSAFE|NOFOLLOW, UIO_USERSPACE, uap->path, td);
error = namei(&nd);
+ vfslocked = NDHASGIANT(&nd);
if (error == 0) {
error = vacl_delete(td, nd.ni_vp, uap->type);
NDFREE(&nd, 0);
}
- mtx_unlock(&Giant);
+ VFS_UNLOCK_GIANT(vfslocked);
return (error);
}
@@ -946,15 +947,15 @@ int
__acl_delete_fd(struct thread *td, struct __acl_delete_fd_args *uap)
{
struct file *fp;
- int error;
+ int vfslocked, error;
- mtx_lock(&Giant);
error = getvnode(td->td_proc->p_fd, uap->filedes, &fp);
if (error == 0) {
+ vfslocked = VFS_LOCK_GIANT(fp->f_vnode->v_mount);
error = vacl_delete(td, fp->f_vnode, uap->type);
fdrop(fp, td);
+ VFS_UNLOCK_GIANT(vfslocked);
}
- mtx_unlock(&Giant);
return (error);
}
@@ -967,16 +968,16 @@ int
__acl_aclcheck_file(struct thread *td, struct __acl_aclcheck_file_args *uap)
{
struct nameidata nd;
- int error;
+ int vfslocked, error;
- mtx_lock(&Giant);
- NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, td);
+ NDINIT(&nd, LOOKUP, MPSAFE|FOLLOW, UIO_USERSPACE, uap->path, td);
error = namei(&nd);
+ vfslocked = NDHASGIANT(&nd);
if (error == 0) {
error = vacl_aclcheck(td, nd.ni_vp, uap->type, uap->aclp);
NDFREE(&nd, 0);
}
- mtx_unlock(&Giant);
+ VFS_UNLOCK_GIANT(vfslocked);
return (error);
}
@@ -989,16 +990,16 @@ int
__acl_aclcheck_link(struct thread *td, struct __acl_aclcheck_link_args *uap)
{
struct nameidata nd;
- int error;
+ int vfslocked, error;
- mtx_lock(&Giant);
- NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, uap->path, td);
+ NDINIT(&nd, LOOKUP, MPSAFE|NOFOLLOW, UIO_USERSPACE, uap->path, td);
error = namei(&nd);
+ vfslocked = NDHASGIANT(&nd);
if (error == 0) {
error = vacl_aclcheck(td, nd.ni_vp, uap->type, uap->aclp);
NDFREE(&nd, 0);
}
- mtx_unlock(&Giant);
+ VFS_UNLOCK_GIANT(vfslocked);
return (error);
}
@@ -1011,15 +1012,15 @@ int
__acl_aclcheck_fd(struct thread *td, struct __acl_aclcheck_fd_args *uap)
{
struct file *fp;
- int error;
+ int vfslocked, error;
- mtx_lock(&Giant);
error = getvnode(td->td_proc->p_fd, uap->filedes, &fp);
if (error == 0) {
+ vfslocked = VFS_LOCK_GIANT(fp->f_vnode->v_mount);
error = vacl_aclcheck(td, fp->f_vnode, uap->type, uap->aclp);
fdrop(fp, td);
+ VFS_UNLOCK_GIANT(vfslocked);
}
- mtx_unlock(&Giant);
return (error);
}
OpenPOWER on IntegriCloud