Update to 3.4-rc5.
[linux-flexiantxendom0-3.2.10.git] / fs / ext4 / super.c
index e1fb1d5..3266db3 100644 (file)
@@ -50,6 +50,7 @@
 #include "xattr.h"
 #include "acl.h"
 #include "mballoc.h"
+#include "richacl.h"
 
 #define CREATE_TRACE_POINTS
 #include <trace/events/ext4.h>
@@ -921,7 +922,9 @@ static struct inode *ext4_alloc_inode(struct super_block *sb)
        ei = kmem_cache_alloc(ext4_inode_cachep, GFP_NOFS);
        if (!ei)
                return NULL;
-
+#ifdef CONFIG_EXT4_FS_RICHACL
+       ei->i_richacl = EXT4_RICHACL_NOT_CACHED;
+#endif
        ei->vfs_inode.i_version = 1;
        ei->vfs_inode.i_data.writeback_index = 0;
        memset(&ei->i_cached_extent, 0, sizeof(struct ext4_ext_cache));
@@ -1009,6 +1012,13 @@ void ext4_clear_inode(struct inode *inode)
        invalidate_inode_buffers(inode);
        end_writeback(inode);
        dquot_drop(inode);
+#ifdef CONFIG_EXT4_FS_RICHACL
+       if (EXT4_I(inode)->i_richacl &&
+               EXT4_I(inode)->i_richacl != EXT4_RICHACL_NOT_CACHED) {
+               richacl_put(EXT4_I(inode)->i_richacl);
+               EXT4_I(inode)->i_richacl = EXT4_RICHACL_NOT_CACHED;
+       }
+#endif
        ext4_discard_preallocations(inode);
        if (EXT4_I(inode)->jinode) {
                jbd2_journal_release_jbd_inode(EXT4_JOURNAL(inode),
@@ -1171,7 +1181,7 @@ enum {
        Opt_bsd_df, Opt_minix_df, Opt_grpid, Opt_nogrpid,
        Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic, Opt_err_ro,
        Opt_nouid32, Opt_debug, Opt_removed,
-       Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl,
+       Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_richacl, Opt_noacl,
        Opt_auto_da_alloc, Opt_noauto_da_alloc, Opt_noload,
        Opt_commit, Opt_min_batch_time, Opt_max_batch_time,
        Opt_journal_dev, Opt_journal_checksum, Opt_journal_async_commit,
@@ -1208,6 +1218,7 @@ static const match_table_t tokens = {
        {Opt_user_xattr, "user_xattr"},
        {Opt_nouser_xattr, "nouser_xattr"},
        {Opt_acl, "acl"},
+       {Opt_richacl, "richacl"},
        {Opt_noacl, "noacl"},
        {Opt_noload, "norecovery"},
        {Opt_noload, "noload"},
@@ -1467,6 +1478,9 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token,
        case Opt_nouser_xattr:
                ext4_msg(sb, KERN_WARNING, deprecated_msg, opt, "3.5");
                break;
+       case Opt_richacl:
+               sb->s_flags |= MS_RICHACL;
+               return 1;
        case Opt_sb:
                return 1;       /* handled by get_sb_block() */
        case Opt_removed:
@@ -1648,6 +1662,10 @@ static int parse_options(char *options, struct super_block *sb,
                }
        }
 #endif
+#if defined(CONFIG_EXT4_FS_RICHACL) && defined(CONFIG_EXT4_FS_POSIX_ACL)
+       if (test_opt(sb, POSIX_ACL) && (sb->s_flags & MS_RICHACL))
+               clear_opt(sb, POSIX_ACL);
+#endif
        return 1;
 }
 
@@ -1772,6 +1790,9 @@ static int _ext4_show_options(struct seq_file *seq, struct super_block *sb,
                       (sbi->s_li_wait_mult != EXT4_DEF_LI_WAIT_MULT)))
                SEQ_OPTS_PRINT("init_itable=%u", sbi->s_li_wait_mult);
 
+       if (sb->s_flags & MS_RICHACL)
+               SEQ_OPTS_PUTS("richacl");
+
        ext4_show_quota_options(seq, sb);
        return 0;
 }
@@ -2967,6 +2988,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
        int err;
        unsigned int journal_ioprio = DEFAULT_JOURNAL_IOPRIO;
        ext4_group_t first_not_zeroed;
+       unsigned long acl_flags = 0;
 
        sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
        if (!sbi)
@@ -3038,7 +3060,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
 #ifdef CONFIG_EXT4_FS_XATTR
        set_opt(sb, XATTR_USER);
 #endif
-#ifdef CONFIG_EXT4_FS_POSIX_ACL
+#if defined(CONFIG_EXT4_FS_POSIX_ACL)
        set_opt(sb, POSIX_ACL);
 #endif
        set_opt(sb, MBLK_IO_SUBMIT);
@@ -3121,8 +3143,12 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
                }
        }
 
-       sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
-               (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0);
+       if (sb->s_flags & MS_RICHACL)
+               acl_flags = MS_RICHACL;
+       else if (test_opt(sb, POSIX_ACL))
+               acl_flags = MS_POSIXACL;
+
+       sb->s_flags = (sb->s_flags & ~(MS_POSIXACL | MS_RICHACL)) | acl_flags;
 
        if (le32_to_cpu(es->s_rev_level) == EXT4_GOOD_OLD_REV &&
            (EXT4_HAS_COMPAT_FEATURE(sb, ~0U) ||
@@ -4233,6 +4259,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
        ext4_group_t g;
        unsigned int journal_ioprio = DEFAULT_JOURNAL_IOPRIO;
        int err = 0;
+       unsigned long acl_flags = 0;
 #ifdef CONFIG_QUOTA
        int i;
 #endif
@@ -4267,8 +4294,12 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
        if (sbi->s_mount_flags & EXT4_MF_FS_ABORTED)
                ext4_abort(sb, "Abort forced by user");
 
-       sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
-               (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0);
+       if (sb->s_flags & MS_RICHACL)
+               acl_flags = MS_RICHACL;
+       else if (test_opt(sb, POSIX_ACL))
+               acl_flags = MS_POSIXACL;
+
+       sb->s_flags = (sb->s_flags & ~(MS_POSIXACL | MS_RICHACL)) | acl_flags;
 
        es = sbi->s_es;