aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/xattr.c
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /fs/btrfs/xattr.c
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'fs/btrfs/xattr.c')
-rw-r--r--fs/btrfs/xattr.c77
1 files changed, 27 insertions, 50 deletions
diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c
index 446a6848c55..69565e5fc6a 100644
--- a/fs/btrfs/xattr.c
+++ b/fs/btrfs/xattr.c
@@ -122,32 +122,11 @@ static int do_setxattr(struct btrfs_trans_handle *trans,
122 */ 122 */
123 if (!value) 123 if (!value)
124 goto out; 124 goto out;
125 } else {
126 di = btrfs_lookup_xattr(NULL, root, path, btrfs_ino(inode),
127 name, name_len, 0);
128 if (IS_ERR(di)) {
129 ret = PTR_ERR(di);
130 goto out;
131 }
132 if (!di && !value)
133 goto out;
134 btrfs_release_path(path);
135 } 125 }
136 126
137again: 127again:
138 ret = btrfs_insert_xattr_item(trans, root, path, btrfs_ino(inode), 128 ret = btrfs_insert_xattr_item(trans, root, path, btrfs_ino(inode),
139 name, name_len, value, size); 129 name, name_len, value, size);
140 /*
141 * If we're setting an xattr to a new value but the new value is say
142 * exactly BTRFS_MAX_XATTR_SIZE, we could end up with EOVERFLOW getting
143 * back from split_leaf. This is because it thinks we'll be extending
144 * the existing item size, but we're asking for enough space to add the
145 * item itself. So if we get EOVERFLOW just set ret to EEXIST and let
146 * the rest of the function figure it out.
147 */
148 if (ret == -EOVERFLOW)
149 ret = -EEXIST;
150
151 if (ret == -EEXIST) { 130 if (ret == -EEXIST) {
152 if (flags & XATTR_CREATE) 131 if (flags & XATTR_CREATE)
153 goto out; 132 goto out;
@@ -206,13 +185,11 @@ int __btrfs_setxattr(struct btrfs_trans_handle *trans,
206 if (ret) 185 if (ret)
207 goto out; 186 goto out;
208 187
209 inode_inc_iversion(inode);
210 inode->i_ctime = CURRENT_TIME; 188 inode->i_ctime = CURRENT_TIME;
211 set_bit(BTRFS_INODE_COPY_EVERYTHING, &BTRFS_I(inode)->runtime_flags);
212 ret = btrfs_update_inode(trans, root, inode); 189 ret = btrfs_update_inode(trans, root, inode);
213 BUG_ON(ret); 190 BUG_ON(ret);
214out: 191out:
215 btrfs_end_transaction(trans, root); 192 btrfs_end_transaction_throttle(trans, root);
216 return ret; 193 return ret;
217} 194}
218 195
@@ -276,7 +253,7 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
276 253
277 di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item); 254 di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item);
278 if (verify_dir_item(root, leaf, di)) 255 if (verify_dir_item(root, leaf, di))
279 goto next; 256 continue;
280 257
281 name_len = btrfs_dir_name_len(leaf, di); 258 name_len = btrfs_dir_name_len(leaf, di);
282 total_size += name_len + 1; 259 total_size += name_len + 1;
@@ -406,36 +383,36 @@ int btrfs_removexattr(struct dentry *dentry, const char *name)
406 XATTR_REPLACE); 383 XATTR_REPLACE);
407} 384}
408 385
409int btrfs_initxattrs(struct inode *inode, const struct xattr *xattr_array, 386int btrfs_xattr_security_init(struct btrfs_trans_handle *trans,
410 void *fs_info) 387 struct inode *inode, struct inode *dir,
388 const struct qstr *qstr)
411{ 389{
412 const struct xattr *xattr; 390 int err;
413 struct btrfs_trans_handle *trans = fs_info; 391 size_t len;
392 void *value;
393 char *suffix;
414 char *name; 394 char *name;
415 int err = 0;
416 395
417 for (xattr = xattr_array; xattr->name != NULL; xattr++) { 396 err = security_inode_init_security(inode, dir, qstr, &suffix, &value,
418 name = kmalloc(XATTR_SECURITY_PREFIX_LEN + 397 &len);
419 strlen(xattr->name) + 1, GFP_NOFS); 398 if (err) {
420 if (!name) { 399 if (err == -EOPNOTSUPP)
421 err = -ENOMEM; 400 return 0;
422 break; 401 return err;
423 } 402 }
403
404 name = kmalloc(XATTR_SECURITY_PREFIX_LEN + strlen(suffix) + 1,
405 GFP_NOFS);
406 if (!name) {
407 err = -ENOMEM;
408 } else {
424 strcpy(name, XATTR_SECURITY_PREFIX); 409 strcpy(name, XATTR_SECURITY_PREFIX);
425 strcpy(name + XATTR_SECURITY_PREFIX_LEN, xattr->name); 410 strcpy(name + XATTR_SECURITY_PREFIX_LEN, suffix);
426 err = __btrfs_setxattr(trans, inode, name, 411 err = __btrfs_setxattr(trans, inode, name, value, len, 0);
427 xattr->value, xattr->value_len, 0);
428 kfree(name); 412 kfree(name);
429 if (err < 0)
430 break;
431 } 413 }
432 return err;
433}
434 414
435int btrfs_xattr_security_init(struct btrfs_trans_handle *trans, 415 kfree(suffix);
436 struct inode *inode, struct inode *dir, 416 kfree(value);
437 const struct qstr *qstr) 417 return err;
438{
439 return security_inode_init_security(inode, dir, qstr,
440 &btrfs_initxattrs, trans);
441} 418}