netlink: make sure nladdr has correct size in netlink_connect()
[pandora-kernel.git] / fs / ext4 / acl.c
index a5c29bb..c36fa74 100644 (file)
@@ -183,8 +183,8 @@ ext4_get_acl(struct inode *inode, int type)
  * inode->i_mutex: down unless called from ext4_new_inode
  */
 static int
-ext4_set_acl(handle_t *handle, struct inode *inode, int type,
-            struct posix_acl *acl)
+__ext4_set_acl(handle_t *handle, struct inode *inode, int type,
+              struct posix_acl *acl)
 {
        int name_index;
        void *value = NULL;
@@ -197,17 +197,6 @@ ext4_set_acl(handle_t *handle, struct inode *inode, int type,
        switch (type) {
        case ACL_TYPE_ACCESS:
                name_index = EXT4_XATTR_INDEX_POSIX_ACL_ACCESS;
-               if (acl) {
-                       error = posix_acl_equiv_mode(acl, &inode->i_mode);
-                       if (error < 0)
-                               return error;
-                       else {
-                               inode->i_ctime = ext4_current_time(inode);
-                               ext4_mark_inode_dirty(handle, inode);
-                               if (error == 0)
-                                       acl = NULL;
-                       }
-               }
                break;
 
        case ACL_TYPE_DEFAULT:
@@ -229,8 +218,34 @@ ext4_set_acl(handle_t *handle, struct inode *inode, int type,
                                      value, size, 0);
 
        kfree(value);
-       if (!error)
+       if (!error) {
                set_cached_acl(inode, type, acl);
+       }
+
+       return error;
+}
+
+static int
+ext4_set_acl(handle_t *handle, struct inode *inode, int type,
+            struct posix_acl *acl)
+{
+       umode_t mode = inode->i_mode;
+       int update_mode = 0;
+       int error;
+
+       if ((type == ACL_TYPE_ACCESS) && acl) {
+               error = posix_acl_update_mode(inode, &mode, &acl);
+               if (error)
+                       return error;
+               update_mode = 1;
+       }
+
+       error = __ext4_set_acl(handle, inode, type, acl);
+       if (!error && update_mode) {
+               inode->i_mode = mode;
+               inode->i_ctime = ext4_current_time(inode);
+               ext4_mark_inode_dirty(handle, inode);
+       }
 
        return error;
 }
@@ -258,8 +273,8 @@ ext4_init_acl(handle_t *handle, struct inode *inode, struct inode *dir)
        }
        if (test_opt(inode->i_sb, POSIX_ACL) && acl) {
                if (S_ISDIR(inode->i_mode)) {
-                       error = ext4_set_acl(handle, inode,
-                                            ACL_TYPE_DEFAULT, acl);
+                       error = __ext4_set_acl(handle, inode,
+                                              ACL_TYPE_DEFAULT, acl);
                        if (error)
                                goto cleanup;
                }
@@ -269,7 +284,7 @@ ext4_init_acl(handle_t *handle, struct inode *inode, struct inode *dir)
 
                if (error > 0) {
                        /* This is an extended ACL */
-                       error = ext4_set_acl(handle, inode, ACL_TYPE_ACCESS, acl);
+                       error = __ext4_set_acl(handle, inode, ACL_TYPE_ACCESS, acl);
                }
        }
 cleanup:
@@ -410,8 +425,10 @@ ext4_xattr_set_acl(struct dentry *dentry, const char *name, const void *value,
 
 retry:
        handle = ext4_journal_start(inode, EXT4_DATA_TRANS_BLOCKS(inode->i_sb));
-       if (IS_ERR(handle))
-               return PTR_ERR(handle);
+       if (IS_ERR(handle)) {
+               error = PTR_ERR(handle);
+               goto release_and_out;
+       }
        error = ext4_set_acl(handle, inode, type, acl);
        ext4_journal_stop(handle);
        if (error == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))