u64 start, u64 end, int *page_started,
                                   unsigned long *nr_written, int unlock);
 
+static int btrfs_init_inode_security(struct inode *inode,  struct inode *dir)
+{
+       int err;
+
+       err = btrfs_init_acl(inode, dir);
+       if (!err)
+               err = btrfs_xattr_security_init(inode, dir);
+       return err;
+}
+
 /*
  * a very lame attempt at stopping writes when the FS is 85% full.  There
  * are countless ways this is incorrect, but it is better than nothing.
                inode->i_mapping->backing_dev_info = &root->fs_info->bdi;
                break;
        default:
+               inode->i_op = &btrfs_special_inode_operations;
                init_special_inode(inode, inode->i_mode, rdev);
                break;
        }
        if (IS_ERR(inode))
                goto out_unlock;
 
-       err = btrfs_init_acl(inode, dir);
+       err = btrfs_init_inode_security(inode, dir);
        if (err) {
                drop_inode = 1;
                goto out_unlock;
        if (IS_ERR(inode))
                goto out_unlock;
 
-       err = btrfs_init_acl(inode, dir);
+       err = btrfs_init_inode_security(inode, dir);
        if (err) {
                drop_inode = 1;
                goto out_unlock;
 
        drop_on_err = 1;
 
-       err = btrfs_init_acl(inode, dir);
+       err = btrfs_init_inode_security(inode, dir);
        if (err)
                goto out_fail;
 
        if (IS_ERR(inode))
                goto out_unlock;
 
-       err = btrfs_init_acl(inode, dir);
+       err = btrfs_init_inode_security(inode, dir);
        if (err) {
                drop_inode = 1;
                goto out_unlock;
        .follow_link    = page_follow_link_light,
        .put_link       = page_put_link,
        .permission     = btrfs_permission,
+       .setxattr       = btrfs_setxattr,
+       .getxattr       = btrfs_getxattr,
+       .listxattr      = btrfs_listxattr,
+       .removexattr    = btrfs_removexattr,
 };
 
 #include <linux/slab.h>
 #include <linux/rwsem.h>
 #include <linux/xattr.h>
+#include <linux/security.h>
 #include "ctree.h"
 #include "btrfs_inode.h"
 #include "transaction.h"
                return -EOPNOTSUPP;
        return __btrfs_setxattr(dentry->d_inode, name, NULL, 0, XATTR_REPLACE);
 }
+
+int btrfs_xattr_security_init(struct inode *inode, struct inode *dir)
+{
+       int err;
+       size_t len;
+       void *value;
+       char *suffix;
+       char *name;
+
+       err = security_inode_init_security(inode, dir, &suffix, &value, &len);
+       if (err) {
+               if (err == -EOPNOTSUPP)
+                       return 0;
+               return err;
+       }
+
+       name = kmalloc(XATTR_SECURITY_PREFIX_LEN + strlen(suffix) + 1,
+                      GFP_NOFS);
+       if (!name) {
+               err = -ENOMEM;
+       } else {
+               strcpy(name, XATTR_SECURITY_PREFIX);
+               strcpy(name + XATTR_SECURITY_PREFIX_LEN, suffix);
+               err = __btrfs_setxattr(inode, name, value, len, 0);
+               kfree(name);
+       }
+
+       kfree(suffix);
+       kfree(value);
+       return err;
+}