diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /fs/btrfs/xattr.c | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'fs/btrfs/xattr.c')
-rw-r--r-- | fs/btrfs/xattr.c | 77 |
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 | ||
137 | again: | 127 | again: |
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); |
214 | out: | 191 | out: |
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 | ||
409 | int btrfs_initxattrs(struct inode *inode, const struct xattr *xattr_array, | 386 | int 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 | ||
435 | int 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 | } |