]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - fs/ocfs2/super.c
ocfs2: Add extended attribute support
[karo-tx-linux.git] / fs / ocfs2 / super.c
index 88255d3f52b40ba39a847a0bd1976f98e94ab5e7..3b04f5d2e896c9add19e1e67882bd8ce6a4e25fb 100644 (file)
@@ -64,6 +64,7 @@
 #include "sysfile.h"
 #include "uptodate.h"
 #include "ver.h"
+#include "xattr.h"
 
 #include "buffer_head_io.h"
 
@@ -154,10 +155,12 @@ enum {
        Opt_localalloc,
        Opt_localflocks,
        Opt_stack,
+       Opt_user_xattr,
+       Opt_nouser_xattr,
        Opt_err,
 };
 
-static match_table_t tokens = {
+static const match_table_t tokens = {
        {Opt_barrier, "barrier=%u"},
        {Opt_err_panic, "errors=panic"},
        {Opt_err_ro, "errors=remount-ro"},
@@ -173,6 +176,8 @@ static match_table_t tokens = {
        {Opt_localalloc, "localalloc=%d"},
        {Opt_localflocks, "localflocks"},
        {Opt_stack, "cluster_stack=%s"},
+       {Opt_user_xattr, "user_xattr"},
+       {Opt_nouser_xattr, "nouser_xattr"},
        {Opt_err, NULL}
 };
 
@@ -637,7 +642,8 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
        osb->s_atime_quantum = parsed_options.atime_quantum;
        osb->preferred_slot = parsed_options.slot;
        osb->osb_commit_interval = parsed_options.commit_interval;
-       osb->local_alloc_size = parsed_options.localalloc_opt;
+       osb->local_alloc_default_bits = ocfs2_megabytes_to_clusters(sb, parsed_options.localalloc_opt);
+       osb->local_alloc_bits = osb->local_alloc_default_bits;
 
        status = ocfs2_verify_userspace_stack(osb, &parsed_options);
        if (status)
@@ -847,6 +853,12 @@ static int ocfs2_parse_options(struct super_block *sb,
                case Opt_data_writeback:
                        mopt->mount_opt |= OCFS2_MOUNT_DATA_WRITEBACK;
                        break;
+               case Opt_user_xattr:
+                       mopt->mount_opt &= ~OCFS2_MOUNT_NOUSERXATTR;
+                       break;
+               case Opt_nouser_xattr:
+                       mopt->mount_opt |= OCFS2_MOUNT_NOUSERXATTR;
+                       break;
                case Opt_atime_quantum:
                        if (match_int(&args[0], &option)) {
                                status = 0;
@@ -938,6 +950,7 @@ static int ocfs2_show_options(struct seq_file *s, struct vfsmount *mnt)
 {
        struct ocfs2_super *osb = OCFS2_SB(mnt->mnt_sb);
        unsigned long opts = osb->s_mount_opt;
+       unsigned int local_alloc_megs;
 
        if (opts & OCFS2_MOUNT_HB_LOCAL)
                seq_printf(s, ",_netdev,heartbeat=local");
@@ -970,8 +983,9 @@ static int ocfs2_show_options(struct seq_file *s, struct vfsmount *mnt)
                seq_printf(s, ",commit=%u",
                           (unsigned) (osb->osb_commit_interval / HZ));
 
-       if (osb->local_alloc_size != OCFS2_DEFAULT_LOCAL_ALLOC_SIZE)
-               seq_printf(s, ",localalloc=%d", osb->local_alloc_size);
+       local_alloc_megs = osb->local_alloc_bits >> (20 - osb->s_clustersize_bits);
+       if (local_alloc_megs != OCFS2_DEFAULT_LOCAL_ALLOC_SIZE)
+               seq_printf(s, ",localalloc=%d", local_alloc_megs);
 
        if (opts & OCFS2_MOUNT_LOCALFLOCKS)
                seq_printf(s, ",localflocks,");
@@ -1132,6 +1146,7 @@ static void ocfs2_inode_init_once(void *data)
        oi->ip_dir_start_lookup = 0;
 
        init_rwsem(&oi->ip_alloc_sem);
+       init_rwsem(&oi->ip_xattr_sem);
        mutex_init(&oi->ip_io_mutex);
 
        oi->ip_blkno = 0ULL;
@@ -1375,6 +1390,7 @@ static int ocfs2_initialize_super(struct super_block *sb,
        sb->s_fs_info = osb;
        sb->s_op = &ocfs2_sops;
        sb->s_export_op = &ocfs2_export_ops;
+       sb->s_xattr = ocfs2_xattr_handlers;
        sb->s_time_gran = 1;
        sb->s_flags |= MS_NOATIME;
        /* this is needed to support O_LARGEFILE */
@@ -1421,8 +1437,11 @@ static int ocfs2_initialize_super(struct super_block *sb,
 
        osb->slot_num = OCFS2_INVALID_SLOT;
 
+       osb->s_xattr_inline_size = OCFS2_MIN_XATTR_INLINE_SIZE;
+
        osb->local_alloc_state = OCFS2_LA_UNUSED;
        osb->local_alloc_bh = NULL;
+       INIT_DELAYED_WORK(&osb->la_enable_wq, ocfs2_la_enable_worker);
 
        init_waitqueue_head(&osb->osb_mount_event);
 
@@ -1568,6 +1587,7 @@ static int ocfs2_initialize_super(struct super_block *sb,
        osb->first_cluster_group_blkno =
                le64_to_cpu(di->id2.i_super.s_first_cluster_group);
        osb->fs_generation = le32_to_cpu(di->i_fs_generation);
+       osb->uuid_hash = le32_to_cpu(di->id2.i_super.s_uuid_hash);
        mlog(0, "vol_label: %s\n", osb->vol_label);
        mlog(0, "uuid: %s\n", osb->uuid_str);
        mlog(0, "root_blkno=%llu, system_dir_blkno=%llu\n",