aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/inode.c23
-rw-r--r--fs/btrfs/xattr.c32
-rw-r--r--fs/btrfs/xattr.h2
3 files changed, 53 insertions, 4 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 2bb65e9b1448..4a79e1c5ebd0 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -90,6 +90,16 @@ static noinline int cow_file_range(struct inode *inode,
90 u64 start, u64 end, int *page_started, 90 u64 start, u64 end, int *page_started,
91 unsigned long *nr_written, int unlock); 91 unsigned long *nr_written, int unlock);
92 92
93static int btrfs_init_inode_security(struct inode *inode, struct inode *dir)
94{
95 int err;
96
97 err = btrfs_init_acl(inode, dir);
98 if (!err)
99 err = btrfs_xattr_security_init(inode, dir);
100 return err;
101}
102
93/* 103/*
94 * a very lame attempt at stopping writes when the FS is 85% full. There 104 * a very lame attempt at stopping writes when the FS is 85% full. There
95 * are countless ways this is incorrect, but it is better than nothing. 105 * are countless ways this is incorrect, but it is better than nothing.
@@ -2037,6 +2047,7 @@ void btrfs_read_locked_inode(struct inode *inode)
2037 inode->i_mapping->backing_dev_info = &root->fs_info->bdi; 2047 inode->i_mapping->backing_dev_info = &root->fs_info->bdi;
2038 break; 2048 break;
2039 default: 2049 default:
2050 inode->i_op = &btrfs_special_inode_operations;
2040 init_special_inode(inode, inode->i_mode, rdev); 2051 init_special_inode(inode, inode->i_mode, rdev);
2041 break; 2052 break;
2042 } 2053 }
@@ -3584,7 +3595,7 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry,
3584 if (IS_ERR(inode)) 3595 if (IS_ERR(inode))
3585 goto out_unlock; 3596 goto out_unlock;
3586 3597
3587 err = btrfs_init_acl(inode, dir); 3598 err = btrfs_init_inode_security(inode, dir);
3588 if (err) { 3599 if (err) {
3589 drop_inode = 1; 3600 drop_inode = 1;
3590 goto out_unlock; 3601 goto out_unlock;
@@ -3647,7 +3658,7 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry,
3647 if (IS_ERR(inode)) 3658 if (IS_ERR(inode))
3648 goto out_unlock; 3659 goto out_unlock;
3649 3660
3650 err = btrfs_init_acl(inode, dir); 3661 err = btrfs_init_inode_security(inode, dir);
3651 if (err) { 3662 if (err) {
3652 drop_inode = 1; 3663 drop_inode = 1;
3653 goto out_unlock; 3664 goto out_unlock;
@@ -3770,7 +3781,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
3770 3781
3771 drop_on_err = 1; 3782 drop_on_err = 1;
3772 3783
3773 err = btrfs_init_acl(inode, dir); 3784 err = btrfs_init_inode_security(inode, dir);
3774 if (err) 3785 if (err)
3775 goto out_fail; 3786 goto out_fail;
3776 3787
@@ -4732,7 +4743,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry,
4732 if (IS_ERR(inode)) 4743 if (IS_ERR(inode))
4733 goto out_unlock; 4744 goto out_unlock;
4734 4745
4735 err = btrfs_init_acl(inode, dir); 4746 err = btrfs_init_inode_security(inode, dir);
4736 if (err) { 4747 if (err) {
4737 drop_inode = 1; 4748 drop_inode = 1;
4738 goto out_unlock; 4749 goto out_unlock;
@@ -5043,4 +5054,8 @@ static struct inode_operations btrfs_symlink_inode_operations = {
5043 .follow_link = page_follow_link_light, 5054 .follow_link = page_follow_link_light,
5044 .put_link = page_put_link, 5055 .put_link = page_put_link,
5045 .permission = btrfs_permission, 5056 .permission = btrfs_permission,
5057 .setxattr = btrfs_setxattr,
5058 .getxattr = btrfs_getxattr,
5059 .listxattr = btrfs_listxattr,
5060 .removexattr = btrfs_removexattr,
5046}; 5061};
diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c
index b4fa5f4b6ad1..312b9435e9f8 100644
--- a/fs/btrfs/xattr.c
+++ b/fs/btrfs/xattr.c
@@ -21,6 +21,7 @@
21#include <linux/slab.h> 21#include <linux/slab.h>
22#include <linux/rwsem.h> 22#include <linux/rwsem.h>
23#include <linux/xattr.h> 23#include <linux/xattr.h>
24#include <linux/security.h>
24#include "ctree.h" 25#include "ctree.h"
25#include "btrfs_inode.h" 26#include "btrfs_inode.h"
26#include "transaction.h" 27#include "transaction.h"
@@ -330,3 +331,34 @@ int btrfs_removexattr(struct dentry *dentry, const char *name)
330 return -EOPNOTSUPP; 331 return -EOPNOTSUPP;
331 return __btrfs_setxattr(dentry->d_inode, name, NULL, 0, XATTR_REPLACE); 332 return __btrfs_setxattr(dentry->d_inode, name, NULL, 0, XATTR_REPLACE);
332} 333}
334
335int btrfs_xattr_security_init(struct inode *inode, struct inode *dir)
336{
337 int err;
338 size_t len;
339 void *value;
340 char *suffix;
341 char *name;
342
343 err = security_inode_init_security(inode, dir, &suffix, &value, &len);
344 if (err) {
345 if (err == -EOPNOTSUPP)
346 return 0;
347 return err;
348 }
349
350 name = kmalloc(XATTR_SECURITY_PREFIX_LEN + strlen(suffix) + 1,
351 GFP_NOFS);
352 if (!name) {
353 err = -ENOMEM;
354 } else {
355 strcpy(name, XATTR_SECURITY_PREFIX);
356 strcpy(name + XATTR_SECURITY_PREFIX_LEN, suffix);
357 err = __btrfs_setxattr(inode, name, value, len, 0);
358 kfree(name);
359 }
360
361 kfree(suffix);
362 kfree(value);
363 return err;
364}
diff --git a/fs/btrfs/xattr.h b/fs/btrfs/xattr.h
index 5b1d08f8e68d..c71e9c3cf3f7 100644
--- a/fs/btrfs/xattr.h
+++ b/fs/btrfs/xattr.h
@@ -36,4 +36,6 @@ extern int btrfs_setxattr(struct dentry *dentry, const char *name,
36 const void *value, size_t size, int flags); 36 const void *value, size_t size, int flags);
37extern int btrfs_removexattr(struct dentry *dentry, const char *name); 37extern int btrfs_removexattr(struct dentry *dentry, const char *name);
38 38
39extern int btrfs_xattr_security_init(struct inode *inode, struct inode *dir);
40
39#endif /* __XATTR__ */ 41#endif /* __XATTR__ */