summaryrefslogtreecommitdiffstats
path: root/fs/btrfs/xattr.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-02-06 18:37:22 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2009-02-06 18:37:22 -0800
commitae1a25da8448271a99745da03100d5299575a269 (patch)
tree841c931e9eed1003d7d1c8157e9c6214939384c4 /fs/btrfs/xattr.c
parentfd9fc842bbab0cb5560b0d52ce4598c898707863 (diff)
parent42f15d77df8a7e8a2feb15041d5d30710ee7f951 (diff)
downloadblackbird-obmc-linux-ae1a25da8448271a99745da03100d5299575a269.tar.gz
blackbird-obmc-linux-ae1a25da8448271a99745da03100d5299575a269.zip
Merge git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable
* git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable: (37 commits) Btrfs: Make sure dir is non-null before doing S_ISGID checks Btrfs: Fix memory leak in cache_drop_leaf_ref Btrfs: don't return congestion in write_cache_pages as often Btrfs: Only prep for btree deletion balances when nodes are mostly empty Btrfs: fix btrfs_unlock_up_safe to walk the entire path Btrfs: change btrfs_del_leaf to drop locks earlier Btrfs: Change btrfs_truncate_inode_items to stop when it hits the inode Btrfs: Don't try to compress pages past i_size Btrfs: join the transaction in __btrfs_setxattr Btrfs: Handle SGID bit when creating inodes Btrfs: Make btrfs_drop_snapshot work in larger and more efficient chunks Btrfs: Change btree locking to use explicit blocking points Btrfs: hash_lock is no longer needed Btrfs: disable leak debugging checks in extent_io.c Btrfs: sort references by byte number during btrfs_inc_ref Btrfs: async threads should try harder to find work Btrfs: selinux support Btrfs: make btrfs acls selectable Btrfs: Catch missed bios in the async bio submission thread Btrfs: fix readdir on 32 bit machines ...
Diffstat (limited to 'fs/btrfs/xattr.c')
-rw-r--r--fs/btrfs/xattr.c48
1 files changed, 45 insertions, 3 deletions
diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c
index 7f332e270894..a9d3bf4d2689 100644
--- a/fs/btrfs/xattr.c
+++ b/fs/btrfs/xattr.c
@@ -21,6 +21,7 @@
#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"
@@ -45,9 +46,12 @@ ssize_t __btrfs_getxattr(struct inode *inode, const char *name,
/* lookup the xattr by name */
di = btrfs_lookup_xattr(NULL, root, path, inode->i_ino, name,
strlen(name), 0);
- if (!di || IS_ERR(di)) {
+ if (!di) {
ret = -ENODATA;
goto out;
+ } else if (IS_ERR(di)) {
+ ret = PTR_ERR(di);
+ goto out;
}
leaf = path->nodes[0];
@@ -62,6 +66,14 @@ ssize_t __btrfs_getxattr(struct inode *inode, const char *name,
ret = -ERANGE;
goto out;
}
+
+ /*
+ * The way things are packed into the leaf is like this
+ * |struct btrfs_dir_item|name|data|
+ * where name is the xattr name, so security.foo, and data is the
+ * content of the xattr. data_ptr points to the location in memory
+ * where the data starts in the in memory leaf
+ */
data_ptr = (unsigned long)((char *)(di + 1) +
btrfs_dir_name_len(leaf, di));
read_extent_buffer(leaf, buffer, data_ptr,
@@ -86,7 +98,7 @@ int __btrfs_setxattr(struct inode *inode, const char *name,
if (!path)
return -ENOMEM;
- trans = btrfs_start_transaction(root, 1);
+ trans = btrfs_join_transaction(root, 1);
btrfs_set_trans_block_group(trans, inode);
/* first lets see if we already have this xattr */
@@ -176,7 +188,6 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
if (ret < 0)
goto err;
- ret = 0;
advance = 0;
while (1) {
leaf = path->nodes[0];
@@ -320,3 +331,34 @@ int btrfs_removexattr(struct dentry *dentry, const char *name)
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;
+}
OpenPOWER on IntegriCloud