switch posix_acl_from_mode() to umode_t
[linux-2.6.git] / fs / posix_acl.c
index 296480e..4e16e80 100644 (file)
@@ -14,7 +14,7 @@
 
 #include <linux/kernel.h>
 #include <linux/slab.h>
-#include <asm/atomic.h>
+#include <linux/atomic.h>
 #include <linux/fs.h>
 #include <linux/sched.h>
 #include <linux/posix_acl.h>
 
 #include <linux/errno.h>
 
+EXPORT_SYMBOL(posix_acl_init);
 EXPORT_SYMBOL(posix_acl_alloc);
-EXPORT_SYMBOL(posix_acl_clone);
 EXPORT_SYMBOL(posix_acl_valid);
 EXPORT_SYMBOL(posix_acl_equiv_mode);
 EXPORT_SYMBOL(posix_acl_from_mode);
-EXPORT_SYMBOL(posix_acl_create_masq);
-EXPORT_SYMBOL(posix_acl_chmod_masq);
-EXPORT_SYMBOL(posix_acl_permission);
+
+/*
+ * Init a fresh posix_acl
+ */
+void
+posix_acl_init(struct posix_acl *acl, int count)
+{
+       atomic_set(&acl->a_refcount, 1);
+       acl->a_count = count;
+}
 
 /*
  * Allocate a new ACL with the specified number of entries.
  */
 struct posix_acl *
-posix_acl_alloc(int count, unsigned int __nocast flags)
+posix_acl_alloc(int count, gfp_t flags)
 {
        const size_t size = sizeof(struct posix_acl) +
                            count * sizeof(struct posix_acl_entry);
        struct posix_acl *acl = kmalloc(size, flags);
-       if (acl) {
-               atomic_set(&acl->a_refcount, 1);
-               acl->a_count = count;
-       }
+       if (acl)
+               posix_acl_init(acl, count);
        return acl;
 }
 
 /*
  * Clone an ACL.
  */
-struct posix_acl *
-posix_acl_clone(const struct posix_acl *acl, unsigned int __nocast flags)
+static struct posix_acl *
+posix_acl_clone(const struct posix_acl *acl, gfp_t flags)
 {
        struct posix_acl *clone = NULL;
 
        if (acl) {
                int size = sizeof(struct posix_acl) + acl->a_count *
                           sizeof(struct posix_acl_entry);
-               clone = kmalloc(size, flags);
-               if (clone) {
-                       memcpy(clone, acl, size);
+               clone = kmemdup(acl, size, flags);
+               if (clone)
                        atomic_set(&clone->a_refcount, 1);
-               }
        }
        return clone;
 }
@@ -146,10 +149,10 @@ posix_acl_valid(const struct posix_acl *acl)
  * file mode permission bits, or else 1. Returns -E... on error.
  */
 int
-posix_acl_equiv_mode(const struct posix_acl *acl, mode_t *mode_p)
+posix_acl_equiv_mode(const struct posix_acl *acl, umode_t *mode_p)
 {
        const struct posix_acl_entry *pa, *pe;
-       mode_t mode = 0;
+       umode_t mode = 0;
        int not_equiv = 0;
 
        FOREACH_ACL_ENTRY(pa, acl, pe) {
@@ -185,7 +188,7 @@ posix_acl_equiv_mode(const struct posix_acl *acl, mode_t *mode_p)
  * Create an ACL representing the file mode permission bits of an inode.
  */
 struct posix_acl *
-posix_acl_from_mode(mode_t mode, unsigned int __nocast flags)
+posix_acl_from_mode(umode_t mode, gfp_t flags)
 {
        struct posix_acl *acl = posix_acl_alloc(3, flags);
        if (!acl)
@@ -219,11 +222,11 @@ posix_acl_permission(struct inode *inode, const struct posix_acl *acl, int want)
                 switch(pa->e_tag) {
                         case ACL_USER_OBJ:
                                /* (May have been checked already) */
-                                if (inode->i_uid == current->fsuid)
+                               if (inode->i_uid == current_fsuid())
                                         goto check_perm;
                                 break;
                         case ACL_USER:
-                                if (pa->e_id == current->fsuid)
+                               if (pa->e_id == current_fsuid())
                                         goto mask;
                                break;
                         case ACL_GROUP_OBJ:
@@ -276,12 +279,11 @@ check_perm:
  * system calls. All permissions that are not granted by the acl are removed.
  * The permissions in the acl are changed to reflect the mode_p parameter.
  */
-int
-posix_acl_create_masq(struct posix_acl *acl, mode_t *mode_p)
+static int posix_acl_create_masq(struct posix_acl *acl, umode_t *mode_p)
 {
        struct posix_acl_entry *pa, *pe;
        struct posix_acl_entry *group_obj = NULL, *mask_obj = NULL;
-       mode_t mode = *mode_p;
+       umode_t mode = *mode_p;
        int not_equiv = 0;
 
        /* assert(atomic_read(acl->a_refcount) == 1); */
@@ -334,8 +336,7 @@ posix_acl_create_masq(struct posix_acl *acl, mode_t *mode_p)
 /*
  * Modify the ACL for the chmod syscall.
  */
-int
-posix_acl_chmod_masq(struct posix_acl *acl, mode_t mode)
+static int posix_acl_chmod_masq(struct posix_acl *acl, mode_t mode)
 {
        struct posix_acl_entry *group_obj = NULL, *mask_obj = NULL;
        struct posix_acl_entry *pa, *pe;
@@ -379,3 +380,39 @@ posix_acl_chmod_masq(struct posix_acl *acl, mode_t mode)
 
        return 0;
 }
+
+int
+posix_acl_create(struct posix_acl **acl, gfp_t gfp, umode_t *mode_p)
+{
+       struct posix_acl *clone = posix_acl_clone(*acl, gfp);
+       int err = -ENOMEM;
+       if (clone) {
+               err = posix_acl_create_masq(clone, mode_p);
+               if (err < 0) {
+                       posix_acl_release(clone);
+                       clone = NULL;
+               }
+       }
+       posix_acl_release(*acl);
+       *acl = clone;
+       return err;
+}
+EXPORT_SYMBOL(posix_acl_create);
+
+int
+posix_acl_chmod(struct posix_acl **acl, gfp_t gfp, mode_t mode)
+{
+       struct posix_acl *clone = posix_acl_clone(*acl, gfp);
+       int err = -ENOMEM;
+       if (clone) {
+               err = posix_acl_chmod_masq(clone, mode);
+               if (err) {
+                       posix_acl_release(clone);
+                       clone = NULL;
+               }
+       }
+       posix_acl_release(*acl);
+       *acl = clone;
+       return err;
+}
+EXPORT_SYMBOL(posix_acl_chmod);