Blame view
fs/btrfs/xattr.c
12.3 KB
c1d7c514f btrfs: replace GP... |
1 |
// SPDX-License-Identifier: GPL-2.0 |
5103e947b xattr support for... |
2 3 |
/* * Copyright (C) 2007 Red Hat. All rights reserved. |
5103e947b xattr support for... |
4 5 6 7 8 9 10 |
*/ #include <linux/init.h> #include <linux/fs.h> #include <linux/slab.h> #include <linux/rwsem.h> #include <linux/xattr.h> |
0279b4cd8 Btrfs: selinux su... |
11 |
#include <linux/security.h> |
996a710d4 btrfs: use generi... |
12 |
#include <linux/posix_acl_xattr.h> |
ae5e165d8 fs: new API for h... |
13 |
#include <linux/iversion.h> |
827aa18e7 Btrfs: use nofs c... |
14 |
#include <linux/sched/mm.h> |
5103e947b xattr support for... |
15 16 17 18 19 |
#include "ctree.h" #include "btrfs_inode.h" #include "transaction.h" #include "xattr.h" #include "disk-io.h" |
63541927c Btrfs: add suppor... |
20 |
#include "props.h" |
5f5bc6b1e Btrfs: make xattr... |
21 |
#include "locking.h" |
33268eaf0 Btrfs: Add ACL su... |
22 |
|
bcadd7050 btrfs: adjust ret... |
23 |
int btrfs_getxattr(struct inode *inode, const char *name, |
95819c057 Btrfs: optimize b... |
24 |
void *buffer, size_t size) |
5103e947b xattr support for... |
25 26 27 28 29 |
{ struct btrfs_dir_item *di; struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_path *path; struct extent_buffer *leaf; |
5103e947b xattr support for... |
30 31 |
int ret = 0; unsigned long data_ptr; |
5103e947b xattr support for... |
32 33 |
path = btrfs_alloc_path(); |
95819c057 Btrfs: optimize b... |
34 |
if (!path) |
5103e947b xattr support for... |
35 |
return -ENOMEM; |
5103e947b xattr support for... |
36 |
|
5103e947b xattr support for... |
37 |
/* lookup the xattr by name */ |
f85b7379c btrfs: fix over-8... |
38 39 |
di = btrfs_lookup_xattr(NULL, root, path, btrfs_ino(BTRFS_I(inode)), name, strlen(name), 0); |
070604040 Btrfs: cleanup xa... |
40 |
if (!di) { |
5103e947b xattr support for... |
41 42 |
ret = -ENODATA; goto out; |
070604040 Btrfs: cleanup xa... |
43 44 45 |
} else if (IS_ERR(di)) { ret = PTR_ERR(di); goto out; |
5103e947b xattr support for... |
46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
} leaf = path->nodes[0]; /* if size is 0, that means we want the size of the attr */ if (!size) { ret = btrfs_dir_data_len(leaf, di); goto out; } /* now get the data out of our dir_item */ if (btrfs_dir_data_len(leaf, di) > size) { ret = -ERANGE; goto out; } |
070604040 Btrfs: cleanup xa... |
60 61 62 63 64 65 66 67 |
/* * 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 */ |
5103e947b xattr support for... |
68 69 70 |
data_ptr = (unsigned long)((char *)(di + 1) + btrfs_dir_name_len(leaf, di)); read_extent_buffer(leaf, buffer, data_ptr, |
3acd7ee87 Btrfs: xattr fixes |
71 |
btrfs_dir_data_len(leaf, di)); |
5103e947b xattr support for... |
72 73 74 |
ret = btrfs_dir_data_len(leaf, di); out: |
5103e947b xattr support for... |
75 76 77 |
btrfs_free_path(path); return ret; } |
3e125a74f btrfs: export btr... |
78 79 |
int btrfs_setxattr(struct btrfs_trans_handle *trans, struct inode *inode, const char *name, const void *value, size_t size, int flags) |
5103e947b xattr support for... |
80 |
{ |
5f5bc6b1e Btrfs: make xattr... |
81 |
struct btrfs_dir_item *di = NULL; |
5103e947b xattr support for... |
82 |
struct btrfs_root *root = BTRFS_I(inode)->root; |
2ff7e61e0 btrfs: take an fs... |
83 |
struct btrfs_fs_info *fs_info = root->fs_info; |
5103e947b xattr support for... |
84 |
struct btrfs_path *path; |
f34f57a3a Btrfs: Pass trans... |
85 86 |
size_t name_len = strlen(name); int ret = 0; |
04e6863b1 btrfs: split btrf... |
87 |
ASSERT(trans); |
da17066c4 btrfs: pull node/... |
88 |
if (name_len + size > BTRFS_MAX_XATTR_SIZE(root->fs_info)) |
f34f57a3a Btrfs: Pass trans... |
89 |
return -ENOSPC; |
5103e947b xattr support for... |
90 91 |
path = btrfs_alloc_path(); |
95819c057 Btrfs: optimize b... |
92 |
if (!path) |
5103e947b xattr support for... |
93 |
return -ENOMEM; |
5f5bc6b1e Btrfs: make xattr... |
94 95 96 |
path->skip_release_on_error = 1; if (!value) { |
f85b7379c btrfs: fix over-8... |
97 98 |
di = btrfs_lookup_xattr(trans, root, path, btrfs_ino(BTRFS_I(inode)), name, name_len, -1); |
5f5bc6b1e Btrfs: make xattr... |
99 100 |
if (!di && (flags & XATTR_REPLACE)) ret = -ENODATA; |
5cdf83edb Btrfs: do not ign... |
101 102 |
else if (IS_ERR(di)) ret = PTR_ERR(di); |
5f5bc6b1e Btrfs: make xattr... |
103 104 105 106 |
else if (di) ret = btrfs_delete_one_dir_name(trans, root, path, di); goto out; } |
5103e947b xattr support for... |
107 |
|
5f5bc6b1e Btrfs: make xattr... |
108 109 110 111 112 113 114 |
/* * For a replace we can't just do the insert blindly. * Do a lookup first (read-only btrfs_search_slot), and return if xattr * doesn't exist. If it exists, fall down below to the insert/replace * path - we can't race with a concurrent xattr delete, because the VFS * locks the inode's i_mutex before calling setxattr or removexattr. */ |
fa09200b8 Btrfs: try to onl... |
115 |
if (flags & XATTR_REPLACE) { |
5955102c9 wrappers for ->i_... |
116 |
ASSERT(inode_is_locked(inode)); |
f85b7379c btrfs: fix over-8... |
117 118 |
di = btrfs_lookup_xattr(NULL, root, path, btrfs_ino(BTRFS_I(inode)), name, name_len, 0); |
5cdf83edb Btrfs: do not ign... |
119 |
if (!di) |
fa09200b8 Btrfs: try to onl... |
120 |
ret = -ENODATA; |
5cdf83edb Btrfs: do not ign... |
121 122 123 |
else if (IS_ERR(di)) ret = PTR_ERR(di); if (ret) |
5103e947b xattr support for... |
124 |
goto out; |
b3b4aa74b btrfs: drop unuse... |
125 |
btrfs_release_path(path); |
5f5bc6b1e Btrfs: make xattr... |
126 127 |
di = NULL; } |
4815053ab btrfs: xattr: fix... |
128 |
|
4a0cc7ca6 btrfs: Make btrfs... |
129 |
ret = btrfs_insert_xattr_item(trans, root, path, btrfs_ino(BTRFS_I(inode)), |
5f5bc6b1e Btrfs: make xattr... |
130 131 |
name, name_len, value, size); if (ret == -EOVERFLOW) { |
4815053ab btrfs: xattr: fix... |
132 |
/* |
5f5bc6b1e Btrfs: make xattr... |
133 134 135 |
* We have an existing item in a leaf, split_leaf couldn't * expand it. That item might have or not a dir_item that * matches our target xattr, so lets check. |
4815053ab btrfs: xattr: fix... |
136 |
*/ |
5f5bc6b1e Btrfs: make xattr... |
137 138 |
ret = 0; btrfs_assert_tree_locked(path->nodes[0]); |
2ff7e61e0 btrfs: take an fs... |
139 |
di = btrfs_match_dir_item_name(fs_info, path, name, name_len); |
5f5bc6b1e Btrfs: make xattr... |
140 141 |
if (!di && !(flags & XATTR_REPLACE)) { ret = -ENOSPC; |
01e6deb25 Btrfs: don't add ... |
142 143 |
goto out; } |
5f5bc6b1e Btrfs: make xattr... |
144 145 |
} else if (ret == -EEXIST) { ret = 0; |
2ff7e61e0 btrfs: take an fs... |
146 |
di = btrfs_match_dir_item_name(fs_info, path, name, name_len); |
5f5bc6b1e Btrfs: make xattr... |
147 148 149 |
ASSERT(di); /* logic error */ } else if (ret) { goto out; |
fa09200b8 Btrfs: try to onl... |
150 |
} |
5103e947b xattr support for... |
151 |
|
5f5bc6b1e Btrfs: make xattr... |
152 |
if (di && (flags & XATTR_CREATE)) { |
ed3ee9f44 Btrfs: fix regres... |
153 |
ret = -EEXIST; |
5f5bc6b1e Btrfs: make xattr... |
154 155 |
goto out; } |
ed3ee9f44 Btrfs: fix regres... |
156 |
|
5f5bc6b1e Btrfs: make xattr... |
157 |
if (di) { |
fa09200b8 Btrfs: try to onl... |
158 |
/* |
5f5bc6b1e Btrfs: make xattr... |
159 160 161 162 163 |
* We're doing a replace, and it must be atomic, that is, at * any point in time we have either the old or the new xattr * value in the tree. We don't want readers (getxattr and * listxattrs) to miss a value, this is specially important * for ACLs. |
fa09200b8 Btrfs: try to onl... |
164 |
*/ |
5f5bc6b1e Btrfs: make xattr... |
165 166 167 168 169 170 171 172 173 174 |
const int slot = path->slots[0]; struct extent_buffer *leaf = path->nodes[0]; const u16 old_data_len = btrfs_dir_data_len(leaf, di); const u32 item_size = btrfs_item_size_nr(leaf, slot); const u32 data_size = sizeof(*di) + name_len + size; struct btrfs_item *item; unsigned long data_ptr; char *ptr; if (size > old_data_len) { |
e902baac6 btrfs: get fs_inf... |
175 |
if (btrfs_leaf_free_space(leaf) < |
5f5bc6b1e Btrfs: make xattr... |
176 177 178 179 |
(size - old_data_len)) { ret = -ENOSPC; goto out; } |
fa09200b8 Btrfs: try to onl... |
180 |
} |
33268eaf0 Btrfs: Add ACL su... |
181 |
|
5f5bc6b1e Btrfs: make xattr... |
182 183 184 |
if (old_data_len + name_len + sizeof(*di) == item_size) { /* No other xattrs packed in the same leaf item. */ if (size > old_data_len) |
c71dd8800 btrfs: remove unu... |
185 |
btrfs_extend_item(path, size - old_data_len); |
5f5bc6b1e Btrfs: make xattr... |
186 |
else if (size < old_data_len) |
78ac4f9e5 btrfs: remove unu... |
187 |
btrfs_truncate_item(path, data_size, 1); |
5f5bc6b1e Btrfs: make xattr... |
188 189 190 191 192 |
} else { /* There are other xattrs packed in the same item. */ ret = btrfs_delete_one_dir_name(trans, root, path, di); if (ret) goto out; |
c71dd8800 btrfs: remove unu... |
193 |
btrfs_extend_item(path, data_size); |
5f5bc6b1e Btrfs: make xattr... |
194 |
} |
fa09200b8 Btrfs: try to onl... |
195 |
|
5f5bc6b1e Btrfs: make xattr... |
196 197 198 199 200 201 202 203 204 |
item = btrfs_item_nr(slot); ptr = btrfs_item_ptr(leaf, slot, char); ptr += btrfs_item_size(leaf, item) - data_size; di = (struct btrfs_dir_item *)ptr; btrfs_set_dir_data_len(leaf, di, size); data_ptr = ((unsigned long)(di + 1)) + name_len; write_extent_buffer(leaf, value, data_ptr, size); btrfs_mark_buffer_dirty(leaf); } else { |
fa09200b8 Btrfs: try to onl... |
205 |
/* |
5f5bc6b1e Btrfs: make xattr... |
206 207 208 |
* Insert, and we had space for the xattr, so path->slots[0] is * where our xattr dir_item is and btrfs_insert_xattr_item() * filled it. |
fa09200b8 Btrfs: try to onl... |
209 |
*/ |
5103e947b xattr support for... |
210 |
} |
f34f57a3a Btrfs: Pass trans... |
211 212 |
out: btrfs_free_path(path); |
877381645 btrfs: skip unnec... |
213 |
if (!ret) { |
3763771cf Btrfs: fix failur... |
214 215 |
set_bit(BTRFS_INODE_COPY_EVERYTHING, &BTRFS_I(inode)->runtime_flags); |
877381645 btrfs: skip unnec... |
216 217 |
clear_bit(BTRFS_INODE_NO_XATTRS, &BTRFS_I(inode)->runtime_flags); } |
f34f57a3a Btrfs: Pass trans... |
218 219 |
return ret; } |
4815053ab btrfs: xattr: fix... |
220 221 222 |
/* * @value: "" makes the attribute to empty, NULL removes it */ |
e3de9b159 btrfs: cleanup bt... |
223 |
int btrfs_setxattr_trans(struct inode *inode, const char *name, |
cac237ae0 btrfs: rename btr... |
224 |
const void *value, size_t size, int flags) |
f34f57a3a Btrfs: Pass trans... |
225 226 |
{ struct btrfs_root *root = BTRFS_I(inode)->root; |
e3de9b159 btrfs: cleanup bt... |
227 |
struct btrfs_trans_handle *trans; |
f34f57a3a Btrfs: Pass trans... |
228 |
int ret; |
a22285a6a Btrfs: Integrate ... |
229 230 231 |
trans = btrfs_start_transaction(root, 2); if (IS_ERR(trans)) return PTR_ERR(trans); |
5103e947b xattr support for... |
232 |
|
2d74fa3ef btrfs: rename do_... |
233 |
ret = btrfs_setxattr(trans, inode, name, value, size, flags); |
f34f57a3a Btrfs: Pass trans... |
234 235 |
if (ret) goto out; |
0c4d2d95d Btrfs: use i_vers... |
236 |
inode_inc_iversion(inode); |
c2050a454 fs: Replace curre... |
237 |
inode->i_ctime = current_time(inode); |
f34f57a3a Btrfs: Pass trans... |
238 239 240 |
ret = btrfs_update_inode(trans, root, inode); BUG_ON(ret); out: |
3a45bb207 btrfs: remove roo... |
241 |
btrfs_end_transaction(trans); |
5103e947b xattr support for... |
242 243 244 245 246 |
return ret; } ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size) { |
daac7ba61 Btrfs: fix listxa... |
247 |
struct btrfs_key key; |
2b0143b5c VFS: normal files... |
248 |
struct inode *inode = d_inode(dentry); |
5103e947b xattr support for... |
249 250 |
struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_path *path; |
daac7ba61 Btrfs: fix listxa... |
251 |
int ret = 0; |
eaa47d861 btrfs: optmize li... |
252 |
size_t total_size = 0, size_left = size; |
5103e947b xattr support for... |
253 254 255 256 257 258 |
/* * ok we want all objects associated with this id. * NOTE: we set key.offset = 0; because we want to start with the * first xattr that we find and walk forward */ |
4a0cc7ca6 btrfs: Make btrfs... |
259 |
key.objectid = btrfs_ino(BTRFS_I(inode)); |
962a298f3 btrfs: kill the k... |
260 |
key.type = BTRFS_XATTR_ITEM_KEY; |
5103e947b xattr support for... |
261 262 263 |
key.offset = 0; path = btrfs_alloc_path(); |
5103e947b xattr support for... |
264 265 |
if (!path) return -ENOMEM; |
e4058b54d btrfs: cleanup, u... |
266 |
path->reada = READA_FORWARD; |
5103e947b xattr support for... |
267 |
|
5103e947b xattr support for... |
268 269 270 271 |
/* search for our xattrs */ ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); if (ret < 0) goto err; |
2e6a00356 Btrfs: Check if b... |
272 |
|
5103e947b xattr support for... |
273 |
while (1) { |
daac7ba61 Btrfs: fix listxa... |
274 275 276 277 278 279 |
struct extent_buffer *leaf; int slot; struct btrfs_dir_item *di; struct btrfs_key found_key; u32 item_size; u32 cur; |
5103e947b xattr support for... |
280 |
leaf = path->nodes[0]; |
5103e947b xattr support for... |
281 282 283 |
slot = path->slots[0]; /* this is where we start walking through the path */ |
2e6a00356 Btrfs: Check if b... |
284 |
if (slot >= btrfs_header_nritems(leaf)) { |
5103e947b xattr support for... |
285 286 287 288 |
/* * if we've reached the last slot in this leaf we need * to go to the next leaf and reset everything */ |
2e6a00356 Btrfs: Check if b... |
289 290 291 292 293 294 |
ret = btrfs_next_leaf(root, path); if (ret < 0) goto err; else if (ret > 0) break; continue; |
5103e947b xattr support for... |
295 |
} |
5103e947b xattr support for... |
296 |
|
5103e947b xattr support for... |
297 298 299 300 301 |
btrfs_item_key_to_cpu(leaf, &found_key, slot); /* check to make sure this item is what we want */ if (found_key.objectid != key.objectid) break; |
f1cd1f0b7 Btrfs: fix race w... |
302 |
if (found_key.type > BTRFS_XATTR_ITEM_KEY) |
5103e947b xattr support for... |
303 |
break; |
f1cd1f0b7 Btrfs: fix race w... |
304 |
if (found_key.type < BTRFS_XATTR_ITEM_KEY) |
daac7ba61 Btrfs: fix listxa... |
305 |
goto next_item; |
5103e947b xattr support for... |
306 307 |
di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item); |
daac7ba61 Btrfs: fix listxa... |
308 309 310 311 312 313 314 |
item_size = btrfs_item_size_nr(leaf, slot); cur = 0; while (cur < item_size) { u16 name_len = btrfs_dir_name_len(leaf, di); u16 data_len = btrfs_dir_data_len(leaf, di); u32 this_len = sizeof(*di) + name_len + data_len; unsigned long name_ptr = (unsigned long)(di + 1); |
daac7ba61 Btrfs: fix listxa... |
315 316 317 318 319 320 321 |
total_size += name_len + 1; /* * We are just looking for how big our buffer needs to * be. */ if (!size) goto next; |
5103e947b xattr support for... |
322 |
|
daac7ba61 Btrfs: fix listxa... |
323 324 325 326 |
if (!buffer || (name_len + 1) > size_left) { ret = -ERANGE; goto err; } |
5103e947b xattr support for... |
327 |
|
daac7ba61 Btrfs: fix listxa... |
328 329 |
read_extent_buffer(leaf, buffer, name_ptr, name_len); buffer[name_len] = '\0'; |
eaa47d861 btrfs: optmize li... |
330 |
|
daac7ba61 Btrfs: fix listxa... |
331 332 |
size_left -= name_len + 1; buffer += name_len + 1; |
2e6a00356 Btrfs: Check if b... |
333 |
next: |
daac7ba61 Btrfs: fix listxa... |
334 335 336 337 |
cur += this_len; di = (struct btrfs_dir_item *)((char *)di + this_len); } next_item: |
2e6a00356 Btrfs: Check if b... |
338 |
path->slots[0]++; |
5103e947b xattr support for... |
339 340 341 342 |
} ret = total_size; err: |
5103e947b xattr support for... |
343 344 345 346 |
btrfs_free_path(path); return ret; } |
9172abbcd btrfs: Use xattr ... |
347 |
static int btrfs_xattr_handler_get(const struct xattr_handler *handler, |
b296821a7 xattr_handler: pa... |
348 |
struct dentry *unused, struct inode *inode, |
3484eba91 FROMLIST: Add fla... |
349 350 |
const char *name, void *buffer, size_t size, int flags) |
95819c057 Btrfs: optimize b... |
351 |
{ |
9172abbcd btrfs: Use xattr ... |
352 |
name = xattr_full_name(handler, name); |
7852781d9 btrfs: drop under... |
353 |
return btrfs_getxattr(inode, name, buffer, size); |
69a32ac51 Btrfs: Change mag... |
354 |
} |
9172abbcd btrfs: Use xattr ... |
355 |
static int btrfs_xattr_handler_set(const struct xattr_handler *handler, |
593012268 switch xattr_hand... |
356 357 358 |
struct dentry *unused, struct inode *inode, const char *name, const void *buffer, size_t size, int flags) |
95819c057 Btrfs: optimize b... |
359 |
{ |
9172abbcd btrfs: Use xattr ... |
360 |
name = xattr_full_name(handler, name); |
e3de9b159 btrfs: cleanup bt... |
361 |
return btrfs_setxattr_trans(inode, name, buffer, size, flags); |
9172abbcd btrfs: Use xattr ... |
362 |
} |
5103e947b xattr support for... |
363 |
|
9172abbcd btrfs: Use xattr ... |
364 |
static int btrfs_xattr_handler_set_prop(const struct xattr_handler *handler, |
593012268 switch xattr_hand... |
365 |
struct dentry *unused, struct inode *inode, |
9172abbcd btrfs: Use xattr ... |
366 367 368 |
const char *name, const void *value, size_t size, int flags) { |
f22125e5d btrfs: refactor b... |
369 |
int ret; |
b3f6a4be1 btrfs: start tran... |
370 371 |
struct btrfs_trans_handle *trans; struct btrfs_root *root = BTRFS_I(inode)->root; |
f22125e5d btrfs: refactor b... |
372 |
|
9172abbcd btrfs: Use xattr ... |
373 |
name = xattr_full_name(handler, name); |
f22125e5d btrfs: refactor b... |
374 375 376 |
ret = btrfs_validate_prop(name, value, size); if (ret) return ret; |
b3f6a4be1 btrfs: start tran... |
377 378 379 380 381 382 383 384 385 |
trans = btrfs_start_transaction(root, 2); if (IS_ERR(trans)) return PTR_ERR(trans); ret = btrfs_set_prop(trans, inode, name, value, size, flags); if (!ret) { inode_inc_iversion(inode); inode->i_ctime = current_time(inode); |
b3f6a4be1 btrfs: start tran... |
386 387 388 389 390 391 392 |
ret = btrfs_update_inode(trans, root, inode); BUG_ON(ret); } btrfs_end_transaction(trans); return ret; |
95819c057 Btrfs: optimize b... |
393 |
} |
5103e947b xattr support for... |
394 |
|
9172abbcd btrfs: Use xattr ... |
395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 |
static const struct xattr_handler btrfs_security_xattr_handler = { .prefix = XATTR_SECURITY_PREFIX, .get = btrfs_xattr_handler_get, .set = btrfs_xattr_handler_set, }; static const struct xattr_handler btrfs_trusted_xattr_handler = { .prefix = XATTR_TRUSTED_PREFIX, .get = btrfs_xattr_handler_get, .set = btrfs_xattr_handler_set, }; static const struct xattr_handler btrfs_user_xattr_handler = { .prefix = XATTR_USER_PREFIX, .get = btrfs_xattr_handler_get, .set = btrfs_xattr_handler_set, }; static const struct xattr_handler btrfs_btrfs_xattr_handler = { .prefix = XATTR_BTRFS_PREFIX, .get = btrfs_xattr_handler_get, .set = btrfs_xattr_handler_set_prop, }; const struct xattr_handler *btrfs_xattr_handlers[] = { &btrfs_security_xattr_handler, #ifdef CONFIG_BTRFS_FS_POSIX_ACL &posix_acl_access_xattr_handler, &posix_acl_default_xattr_handler, #endif &btrfs_trusted_xattr_handler, &btrfs_user_xattr_handler, &btrfs_btrfs_xattr_handler, NULL, }; |
48a3b6366 btrfs: make stati... |
430 |
static int btrfs_initxattrs(struct inode *inode, |
419a6f30f btrfs: rename fs_... |
431 |
const struct xattr *xattr_array, void *fs_private) |
0279b4cd8 Btrfs: selinux su... |
432 |
{ |
419a6f30f btrfs: rename fs_... |
433 |
struct btrfs_trans_handle *trans = fs_private; |
9d8f13ba3 security: new sec... |
434 |
const struct xattr *xattr; |
827aa18e7 Btrfs: use nofs c... |
435 |
unsigned int nofs_flag; |
0279b4cd8 Btrfs: selinux su... |
436 |
char *name; |
9d8f13ba3 security: new sec... |
437 |
int err = 0; |
0279b4cd8 Btrfs: selinux su... |
438 |
|
827aa18e7 Btrfs: use nofs c... |
439 440 441 442 443 |
/* * We're holding a transaction handle, so use a NOFS memory allocation * context to avoid deadlock if reclaim happens. */ nofs_flag = memalloc_nofs_save(); |
9d8f13ba3 security: new sec... |
444 445 |
for (xattr = xattr_array; xattr->name != NULL; xattr++) { name = kmalloc(XATTR_SECURITY_PREFIX_LEN + |
39a27ec10 btrfs: use GFP_KE... |
446 |
strlen(xattr->name) + 1, GFP_KERNEL); |
9d8f13ba3 security: new sec... |
447 448 449 450 |
if (!name) { err = -ENOMEM; break; } |
0279b4cd8 Btrfs: selinux su... |
451 |
strcpy(name, XATTR_SECURITY_PREFIX); |
9d8f13ba3 security: new sec... |
452 |
strcpy(name + XATTR_SECURITY_PREFIX_LEN, xattr->name); |
04e6863b1 btrfs: split btrf... |
453 454 |
err = btrfs_setxattr(trans, inode, name, xattr->value, xattr->value_len, 0); |
0279b4cd8 Btrfs: selinux su... |
455 |
kfree(name); |
9d8f13ba3 security: new sec... |
456 457 |
if (err < 0) break; |
0279b4cd8 Btrfs: selinux su... |
458 |
} |
827aa18e7 Btrfs: use nofs c... |
459 |
memalloc_nofs_restore(nofs_flag); |
0279b4cd8 Btrfs: selinux su... |
460 461 |
return err; } |
9d8f13ba3 security: new sec... |
462 463 464 465 466 467 468 469 |
int btrfs_xattr_security_init(struct btrfs_trans_handle *trans, struct inode *inode, struct inode *dir, const struct qstr *qstr) { return security_inode_init_security(inode, dir, qstr, &btrfs_initxattrs, trans); } |