staging: lustre: add SPDX identifiers to all lustre files
[linux-2.6-block.git] / drivers / staging / lustre / lustre / llite / xattr.c
CommitLineData
c14dd9d5 1// SPDX-License-Identifier: GPL-2.0
d7e09d03
PT
2/*
3 * GPL HEADER START
4 *
5 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 only,
9 * as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License version 2 for more details (a copy is included
15 * in the LICENSE file that accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License
18 * version 2 along with this program; If not, see
6a5b99a4 19 * http://www.gnu.org/licenses/gpl-2.0.html
d7e09d03 20 *
d7e09d03
PT
21 * GPL HEADER END
22 */
23/*
24 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
25 * Use is subject to license terms.
26 *
1dc563a6 27 * Copyright (c) 2011, 2015, Intel Corporation.
d7e09d03
PT
28 */
29/*
30 * This file is part of Lustre, http://www.lustre.org/
31 * Lustre is a trademark of Sun Microsystems, Inc.
32 */
33
34#include <linux/fs.h>
35#include <linux/sched.h>
36#include <linux/mm.h>
a49c8634 37#include <linux/xattr.h>
d7e09d03
PT
38#include <linux/selinux.h>
39
40#define DEBUG_SUBSYSTEM S_LLITE
41
b2e475b1
JS
42#include <obd_support.h>
43#include <lustre_dlm.h>
d7e09d03
PT
44
45#include "llite_internal.h"
46
51cfb8c4 47const struct xattr_handler *get_xattr_type(const char *name)
d7e09d03 48{
51cfb8c4 49 int i = 0;
d7e09d03 50
51cfb8c4
SB
51 while (ll_xattr_handlers[i]) {
52 size_t len = strlen(ll_xattr_handlers[i]->prefix);
d7e09d03 53
51cfb8c4
SB
54 if (!strncmp(ll_xattr_handlers[i]->prefix, name, len))
55 return ll_xattr_handlers[i];
56 i++;
57 }
58 return NULL;
d7e09d03
PT
59}
60
51cfb8c4
SB
61static int xattr_type_filter(struct ll_sb_info *sbi,
62 const struct xattr_handler *handler)
d7e09d03 63{
51cfb8c4
SB
64 /* No handler means XATTR_OTHER_T */
65 if (!handler)
66 return -EOPNOTSUPP;
67
68 if ((handler->flags == XATTR_ACL_ACCESS_T ||
69 handler->flags == XATTR_ACL_DEFAULT_T) &&
d7e09d03
PT
70 !(sbi->ll_flags & LL_SBI_ACL))
71 return -EOPNOTSUPP;
72
51cfb8c4
SB
73 if (handler->flags == XATTR_USER_T &&
74 !(sbi->ll_flags & LL_SBI_USER_XATTR))
d7e09d03 75 return -EOPNOTSUPP;
51cfb8c4
SB
76
77 if (handler->flags == XATTR_TRUSTED_T &&
78 !capable(CFS_CAP_SYS_ADMIN))
d7e09d03 79 return -EPERM;
d7e09d03
PT
80
81 return 0;
82}
83
2c563880
JS
84static int
85ll_xattr_set_common(const struct xattr_handler *handler,
86 struct dentry *dentry, struct inode *inode,
87 const char *name, const void *value, size_t size,
88 int flags)
d7e09d03 89{
2c563880 90 char fullname[strlen(handler->prefix) + strlen(name) + 1];
d7e09d03 91 struct ll_sb_info *sbi = ll_i2sbi(inode);
7fc1f831 92 struct ptlrpc_request *req = NULL;
d7e09d03 93 const char *pv = value;
2c563880
JS
94 __u64 valid;
95 int rc;
d7e09d03 96
2c563880
JS
97 if (flags == XATTR_REPLACE) {
98 ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_REMOVEXATTR, 1);
99 valid = OBD_MD_FLXATTRRM;
100 } else {
101 ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_SETXATTR, 1);
102 valid = OBD_MD_FLXATTR;
103 }
104
51cfb8c4 105 rc = xattr_type_filter(sbi, handler);
d7e09d03 106 if (rc)
0a3bdb00 107 return rc;
d7e09d03 108
2c563880
JS
109 if ((handler->flags == XATTR_ACL_ACCESS_T ||
110 handler->flags == XATTR_ACL_DEFAULT_T) &&
0667dfff
LX
111 !inode_owner_or_capable(inode))
112 return -EPERM;
113
d7e09d03 114 /* b10667: ignore lustre special xattr for now */
bb371b95
AP
115 if (!strcmp(name, "hsm") ||
116 ((handler->flags == XATTR_TRUSTED_T && !strcmp(name, "lov")) ||
117 (handler->flags == XATTR_LUSTRE_T && !strcmp(name, "lov"))))
0a3bdb00 118 return 0;
d7e09d03
PT
119
120 /* b15587: ignore security.capability xattr for now */
2c563880
JS
121 if ((handler->flags == XATTR_SECURITY_T &&
122 !strcmp(name, "capability")))
0a3bdb00 123 return 0;
d7e09d03
PT
124
125 /* LU-549: Disable security.selinux when selinux is disabled */
2c563880
JS
126 if (handler->flags == XATTR_SECURITY_T && !selinux_is_enabled() &&
127 strcmp(name, "selinux") == 0)
0a3bdb00 128 return -EOPNOTSUPP;
d7e09d03 129
115ee9d0
HZ
130 /*FIXME: enable IMA when the conditions are ready */
131 if (handler->flags == XATTR_SECURITY_T &&
132 (!strcmp(name, "ima") || !strcmp(name, "evm")))
133 return -EOPNOTSUPP;
134
07b71df1
DE
135 /*
136 * In user.* namespace, only regular files and directories can have
137 * extended attributes.
138 */
139 if (handler->flags == XATTR_USER_T) {
140 if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode))
141 return -EPERM;
142 }
143
2c563880 144 sprintf(fullname, "%s%s\n", handler->prefix, name);
ef2e0f55 145 rc = md_setxattr(sbi->ll_md_exp, ll_inode2fid(inode),
2c563880 146 valid, fullname, pv, size, 0, flags,
a612b007 147 ll_i2suppgid(inode), &req);
d7e09d03 148 if (rc) {
2c563880 149 if (rc == -EOPNOTSUPP && handler->flags == XATTR_USER_T) {
2d00bd17 150 LCONSOLE_INFO("Disabling user_xattr feature because it is not supported on the server\n");
d7e09d03
PT
151 sbi->ll_flags &= ~LL_SBI_USER_XATTR;
152 }
0a3bdb00 153 return rc;
d7e09d03
PT
154 }
155
156 ptlrpc_req_finished(req);
0a3bdb00 157 return 0;
d7e09d03
PT
158}
159
bb371b95
AP
160static int get_hsm_state(struct inode *inode, u32 *hus_states)
161{
162 struct md_op_data *op_data;
163 struct hsm_user_state *hus;
164 int rc;
165
166 hus = kzalloc(sizeof(*hus), GFP_NOFS);
167 if (!hus)
168 return -ENOMEM;
169
170 op_data = ll_prep_md_op_data(NULL, inode, NULL, NULL, 0, 0,
171 LUSTRE_OPC_ANY, hus);
172 if (!IS_ERR(op_data)) {
173 rc = obd_iocontrol(LL_IOC_HSM_STATE_GET, ll_i2mdexp(inode),
174 sizeof(*op_data), op_data, NULL);
175 if (!rc)
176 *hus_states = hus->hus_states;
177 else
178 CDEBUG(D_VFSTRACE, "obd_iocontrol failed. rc = %d\n",
179 rc);
180
181 ll_finish_md_op_data(op_data);
182 } else {
183 rc = PTR_ERR(op_data);
184 CDEBUG(D_VFSTRACE, "Could not prepare the opdata. rc = %d\n",
185 rc);
186 }
187 kfree(hus);
188 return rc;
189}
190
2c563880
JS
191static int ll_xattr_set(const struct xattr_handler *handler,
192 struct dentry *dentry, struct inode *inode,
193 const char *name, const void *value, size_t size,
194 int flags)
d7e09d03 195{
d7e09d03
PT
196 LASSERT(inode);
197 LASSERT(name);
198
1ada25dc 199 CDEBUG(D_VFSTRACE, "VFS Op:inode=" DFID "(%p), xattr %s\n",
97a075cd 200 PFID(ll_inode2fid(inode)), inode, name);
d7e09d03 201
2c563880 202 if (!strcmp(name, "lov")) {
d7e09d03 203 struct lov_user_md *lump = (struct lov_user_md *)value;
2c563880
JS
204 int op_type = flags == XATTR_REPLACE ? LPROC_LL_REMOVEXATTR :
205 LPROC_LL_SETXATTR;
d7e09d03
PT
206 int rc = 0;
207
2c563880
JS
208 ll_stats_ops_tally(ll_i2sbi(inode), op_type, 1);
209
87ebccf9
DC
210 if (size != 0 && size < sizeof(struct lov_user_md))
211 return -EINVAL;
212
2c563880
JS
213 /*
214 * It is possible to set an xattr to a "" value of zero size.
215 * For this case we are going to treat it as a removal.
216 */
217 if (!size && lump)
218 lump = NULL;
219
d7e09d03
PT
220 /* Attributes that are saved via getxattr will always have
221 * the stripe_offset as 0. Instead, the MDS should be
c0894c6c
OD
222 * allowed to pick the starting OST index. b=17846
223 */
6e16818b 224 if (lump && lump->lmm_stripe_offset == 0)
d7e09d03
PT
225 lump->lmm_stripe_offset = -1;
226
bb371b95
AP
227 /* Avoid anyone directly setting the RELEASED flag. */
228 if (lump && (lump->lmm_pattern & LOV_PATTERN_F_RELEASED)) {
229 /* Only if we have a released flag check if the file
230 * was indeed archived.
231 */
232 u32 state = HS_NONE;
233
234 rc = get_hsm_state(inode, &state);
235 if (rc)
236 return rc;
237
238 if (!(state & HS_ARCHIVED)) {
239 CDEBUG(D_VFSTRACE,
240 "hus_states state = %x, pattern = %x\n",
241 state, lump->lmm_pattern);
242 /*
243 * Here the state is: real file is not
244 * archived but user is requesting to set
245 * the RELEASED flag so we mask off the
246 * released flag from the request
247 */
248 lump->lmm_pattern ^= LOV_PATTERN_F_RELEASED;
249 }
250 }
251
6e16818b 252 if (lump && S_ISREG(inode->i_mode)) {
d467220e 253 __u64 it_flags = FMODE_WRITE;
dbf789ce
JX
254 int lum_size;
255
256 lum_size = ll_lov_user_md_size(lump);
257 if (lum_size < 0 || size < lum_size)
258 return 0; /* b=10667: ignore error */
d7e09d03 259
d467220e
NY
260 rc = ll_lov_setstripe_ea_info(inode, dentry, it_flags,
261 lump, lum_size);
dbf789ce 262 /* b=10667: rc always be 0 here for now */
d7e09d03
PT
263 rc = 0;
264 } else if (S_ISDIR(inode->i_mode)) {
265 rc = ll_dir_setstripe(inode, lump, 0);
266 }
267
268 return rc;
269
2c563880
JS
270 } else if (!strcmp(name, "lma") || !strcmp(name, "link")) {
271 ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_SETXATTR, 1);
d7e09d03 272 return 0;
2c563880 273 }
d7e09d03 274
2c563880
JS
275 return ll_xattr_set_common(handler, dentry, inode, name, value, size,
276 flags);
d7e09d03
PT
277}
278
a6d879fd 279int
1e1f9ff4
JS
280ll_xattr_list(struct inode *inode, const char *name, int type, void *buffer,
281 size_t size, __u64 valid)
d7e09d03 282{
1e1f9ff4 283 struct ll_inode_info *lli = ll_i2info(inode);
d7e09d03
PT
284 struct ll_sb_info *sbi = ll_i2sbi(inode);
285 struct ptlrpc_request *req = NULL;
286 struct mdt_body *body;
d7e09d03 287 void *xdata;
1e1f9ff4 288 int rc;
d7e09d03 289
51cfb8c4
SB
290 if (sbi->ll_xattr_cache_enabled && type != XATTR_ACL_ACCESS_T &&
291 (type != XATTR_SECURITY_T || strcmp(name, "security.selinux"))) {
7fc1f831 292 rc = ll_xattr_cache_get(inode, name, buffer, size, valid);
e93a3082
AP
293 if (rc == -EAGAIN)
294 goto getxattr_nocache;
7fc1f831 295 if (rc < 0)
34e1f2bb 296 goto out_xattr;
e93a3082
AP
297
298 /* Add "system.posix_acl_access" to the list */
6e16818b 299 if (lli->lli_posix_acl && valid & OBD_MD_FLXATTRLS) {
e93a3082
AP
300 if (size == 0) {
301 rc += sizeof(XATTR_NAME_ACL_ACCESS);
302 } else if (size - rc >= sizeof(XATTR_NAME_ACL_ACCESS)) {
303 memcpy(buffer + rc, XATTR_NAME_ACL_ACCESS,
304 sizeof(XATTR_NAME_ACL_ACCESS));
305 rc += sizeof(XATTR_NAME_ACL_ACCESS);
306 } else {
34e1f2bb
JL
307 rc = -ERANGE;
308 goto out_xattr;
e93a3082
AP
309 }
310 }
7fc1f831 311 } else {
e93a3082 312getxattr_nocache:
ef2e0f55 313 rc = md_getxattr(sbi->ll_md_exp, ll_inode2fid(inode),
341f1f0a 314 valid, name, NULL, 0, size, 0, &req);
7fc1f831 315 if (rc < 0)
34e1f2bb 316 goto out_xattr;
7fc1f831
AP
317
318 body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY);
319 LASSERT(body);
320
321 /* only detect the xattr size */
34e1f2bb 322 if (size == 0) {
2e1b5b8b 323 rc = body->mbo_eadatasize;
34e1f2bb
JL
324 goto out;
325 }
7fc1f831 326
2e1b5b8b 327 if (size < body->mbo_eadatasize) {
7fc1f831 328 CERROR("server bug: replied size %u > %u\n",
2e1b5b8b 329 body->mbo_eadatasize, (int)size);
34e1f2bb
JL
330 rc = -ERANGE;
331 goto out;
d7e09d03 332 }
d7e09d03 333
2e1b5b8b 334 if (body->mbo_eadatasize == 0) {
34e1f2bb
JL
335 rc = -ENODATA;
336 goto out;
337 }
d7e09d03 338
7fc1f831
AP
339 /* do not need swab xattr data */
340 xdata = req_capsule_server_sized_get(&req->rq_pill, &RMF_EADATA,
2e1b5b8b 341 body->mbo_eadatasize);
34e1f2bb
JL
342 if (!xdata) {
343 rc = -EFAULT;
344 goto out;
345 }
d7e09d03 346
2e1b5b8b
JH
347 memcpy(buffer, xdata, body->mbo_eadatasize);
348 rc = body->mbo_eadatasize;
d7e09d03
PT
349 }
350
7fc1f831 351out_xattr:
1e1f9ff4 352 if (rc == -EOPNOTSUPP && type == XATTR_USER_T) {
7fc1f831
AP
353 LCONSOLE_INFO(
354 "%s: disabling user_xattr feature because it is not supported on the server: rc = %d\n",
355 ll_get_fsname(inode->i_sb, NULL, 0), rc);
356 sbi->ll_flags &= ~LL_SBI_USER_XATTR;
d7e09d03 357 }
d7e09d03
PT
358out:
359 ptlrpc_req_finished(req);
360 return rc;
361}
362
2c563880
JS
363static int ll_xattr_get_common(const struct xattr_handler *handler,
364 struct dentry *dentry, struct inode *inode,
365 const char *name, void *buffer, size_t size)
1e1f9ff4 366{
2c563880 367 char fullname[strlen(handler->prefix) + strlen(name) + 1];
1e1f9ff4 368 struct ll_sb_info *sbi = ll_i2sbi(inode);
d6a80699 369#ifdef CONFIG_FS_POSIX_ACL
1e1f9ff4 370 struct ll_inode_info *lli = ll_i2info(inode);
d6a80699 371#endif
2c563880 372 int rc;
1e1f9ff4 373
1ada25dc 374 CDEBUG(D_VFSTRACE, "VFS Op:inode=" DFID "(%p)\n",
1e1f9ff4
JS
375 PFID(ll_inode2fid(inode)), inode);
376
2c563880
JS
377 ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_GETXATTR, 1);
378
51cfb8c4 379 rc = xattr_type_filter(sbi, handler);
1e1f9ff4
JS
380 if (rc)
381 return rc;
382
383 /* b15587: ignore security.capability xattr for now */
2c563880 384 if ((handler->flags == XATTR_SECURITY_T && !strcmp(name, "capability")))
1e1f9ff4
JS
385 return -ENODATA;
386
387 /* LU-549: Disable security.selinux when selinux is disabled */
2c563880
JS
388 if (handler->flags == XATTR_SECURITY_T && !selinux_is_enabled() &&
389 !strcmp(name, "selinux"))
1e1f9ff4
JS
390 return -EOPNOTSUPP;
391
392#ifdef CONFIG_FS_POSIX_ACL
393 /* posix acl is under protection of LOOKUP lock. when calling to this,
394 * we just have path resolution to the target inode, so we have great
395 * chance that cached ACL is uptodate.
396 */
2c563880 397 if (handler->flags == XATTR_ACL_ACCESS_T) {
1e1f9ff4
JS
398 struct posix_acl *acl;
399
400 spin_lock(&lli->lli_lock);
401 acl = posix_acl_dup(lli->lli_posix_acl);
402 spin_unlock(&lli->lli_lock);
403
404 if (!acl)
405 return -ENODATA;
406
407 rc = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
408 posix_acl_release(acl);
409 return rc;
410 }
2c563880 411 if (handler->flags == XATTR_ACL_DEFAULT_T && !S_ISDIR(inode->i_mode))
1e1f9ff4
JS
412 return -ENODATA;
413#endif
2c563880
JS
414 sprintf(fullname, "%s%s\n", handler->prefix, name);
415 return ll_xattr_list(inode, fullname, handler->flags, buffer, size,
1e1f9ff4
JS
416 OBD_MD_FLXATTR);
417}
418
55554f31 419static ssize_t ll_getxattr_lov(struct inode *inode, void *buf, size_t buf_size)
d7e09d03 420{
55554f31 421 ssize_t rc;
d7e09d03 422
55554f31
JH
423 if (S_ISREG(inode->i_mode)) {
424 struct cl_object *obj = ll_i2info(inode)->lli_clob;
425 struct cl_layout cl = {
426 .cl_buf.lb_buf = buf,
427 .cl_buf.lb_len = buf_size,
428 };
429 struct lu_env *env;
3ee45c7e 430 u16 refcheck;
55554f31
JH
431
432 if (!obj)
433 return -ENODATA;
d7e09d03 434
55554f31
JH
435 env = cl_env_get(&refcheck);
436 if (IS_ERR(env))
437 return PTR_ERR(env);
2c563880 438
55554f31
JH
439 rc = cl_object_layout_get(env, obj, &cl);
440 if (rc < 0)
441 goto out_env;
d7e09d03 442
55554f31
JH
443 if (!cl.cl_size) {
444 rc = -ENODATA;
445 goto out_env;
d7e09d03 446 }
d7e09d03 447
55554f31
JH
448 rc = cl.cl_size;
449
450 if (!buf_size)
451 goto out_env;
452
453 LASSERT(buf && rc <= buf_size);
454
455 /*
456 * Do not return layout gen for getxattr() since
457 * otherwise it would confuse tar --xattr by
458 * recognizing layout gen as stripe offset when the
459 * file is restored. See LU-2809.
460 */
461 ((struct lov_mds_md *)buf)->lmm_layout_gen = 0;
462out_env:
463 cl_env_put(env, &refcheck);
464
465 return rc;
466 } else if (S_ISDIR(inode->i_mode)) {
467 struct ptlrpc_request *req = NULL;
468 struct lov_mds_md *lmm = NULL;
469 int lmm_size = 0;
470
471 rc = ll_dir_getstripe(inode, (void **)&lmm, &lmm_size,
472 &req, 0);
d7e09d03 473 if (rc < 0)
55554f31 474 goto out_req;
d7e09d03 475
55554f31
JH
476 if (!buf_size) {
477 rc = lmm_size;
478 goto out_req;
d7e09d03
PT
479 }
480
55554f31 481 if (buf_size < lmm_size) {
34e1f2bb 482 rc = -ERANGE;
55554f31 483 goto out_req;
d7e09d03
PT
484 }
485
55554f31
JH
486 memcpy(buf, lmm, lmm_size);
487 rc = lmm_size;
488out_req:
489 if (req)
490 ptlrpc_req_finished(req);
d7e09d03 491
fbe7c6c7 492 return rc;
55554f31
JH
493 } else {
494 return -ENODATA;
495 }
496}
497
498static int ll_xattr_get(const struct xattr_handler *handler,
499 struct dentry *dentry, struct inode *inode,
500 const char *name, void *buffer, size_t size)
501{
502 LASSERT(inode);
503 LASSERT(name);
504
505 CDEBUG(D_VFSTRACE, "VFS Op:inode=" DFID "(%p), xattr %s\n",
506 PFID(ll_inode2fid(inode)), inode, name);
507
508 if (!strcmp(name, "lov")) {
509 ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_GETXATTR, 1);
510
511 return ll_getxattr_lov(inode, buffer, size);
d7e09d03
PT
512 }
513
2c563880 514 return ll_xattr_get_common(handler, dentry, inode, name, buffer, size);
d7e09d03
PT
515}
516
517ssize_t ll_listxattr(struct dentry *dentry, char *buffer, size_t size)
518{
2b0143b5 519 struct inode *inode = d_inode(dentry);
55554f31
JH
520 struct ll_sb_info *sbi = ll_i2sbi(inode);
521 char *xattr_name;
522 ssize_t rc, rc2;
523 size_t len, rem;
d7e09d03
PT
524
525 LASSERT(inode);
526
1ada25dc 527 CDEBUG(D_VFSTRACE, "VFS Op:inode=" DFID "(%p)\n",
97a075cd 528 PFID(ll_inode2fid(inode)), inode);
d7e09d03
PT
529
530 ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_LISTXATTR, 1);
531
1e1f9ff4
JS
532 rc = ll_xattr_list(inode, NULL, XATTR_OTHER_T, buffer, size,
533 OBD_MD_FLXATTRLS);
d7e09d03 534 if (rc < 0)
55554f31
JH
535 return rc;
536 /*
537 * If we're being called to get the size of the xattr list
538 * (buf_size == 0) then just assume that a lustre.lov xattr
539 * exists.
540 */
541 if (!size)
542 return rc + sizeof(XATTR_LUSTRE_LOV);
543
544 xattr_name = buffer;
545 rem = rc;
546
547 while (rem > 0) {
548 len = strnlen(xattr_name, rem - 1) + 1;
549 rem -= len;
550 if (!xattr_type_filter(sbi, get_xattr_type(xattr_name))) {
551 /* Skip OK xattr type leave it in buffer */
552 xattr_name += len;
553 continue;
d7e09d03 554 }
55554f31
JH
555
556 /*
557 * Move up remaining xattrs in buffer
558 * removing the xattr that is not OK
559 */
560 memmove(xattr_name, xattr_name + len, rem);
561 rc -= len;
d7e09d03
PT
562 }
563
55554f31
JH
564 rc2 = ll_getxattr_lov(inode, NULL, 0);
565 if (rc2 == -ENODATA)
566 return rc;
cb6a2db6 567
55554f31
JH
568 if (rc2 < 0)
569 return rc2;
d7e09d03 570
55554f31
JH
571 if (size < rc + sizeof(XATTR_LUSTRE_LOV))
572 return -ERANGE;
573
574 memcpy(buffer + rc, XATTR_LUSTRE_LOV, sizeof(XATTR_LUSTRE_LOV));
575
576 return rc + sizeof(XATTR_LUSTRE_LOV);
d7e09d03 577}
2c563880
JS
578
579static const struct xattr_handler ll_user_xattr_handler = {
580 .prefix = XATTR_USER_PREFIX,
581 .flags = XATTR_USER_T,
582 .get = ll_xattr_get_common,
583 .set = ll_xattr_set_common,
584};
585
586static const struct xattr_handler ll_trusted_xattr_handler = {
587 .prefix = XATTR_TRUSTED_PREFIX,
588 .flags = XATTR_TRUSTED_T,
589 .get = ll_xattr_get,
590 .set = ll_xattr_set,
591};
592
593static const struct xattr_handler ll_security_xattr_handler = {
594 .prefix = XATTR_SECURITY_PREFIX,
595 .flags = XATTR_SECURITY_T,
596 .get = ll_xattr_get_common,
597 .set = ll_xattr_set_common,
598};
599
600static const struct xattr_handler ll_acl_access_xattr_handler = {
601 .prefix = XATTR_NAME_POSIX_ACL_ACCESS,
602 .flags = XATTR_ACL_ACCESS_T,
603 .get = ll_xattr_get_common,
604 .set = ll_xattr_set_common,
605};
606
607static const struct xattr_handler ll_acl_default_xattr_handler = {
608 .prefix = XATTR_NAME_POSIX_ACL_DEFAULT,
609 .flags = XATTR_ACL_DEFAULT_T,
610 .get = ll_xattr_get_common,
611 .set = ll_xattr_set_common,
612};
613
614static const struct xattr_handler ll_lustre_xattr_handler = {
615 .prefix = XATTR_LUSTRE_PREFIX,
616 .flags = XATTR_LUSTRE_T,
617 .get = ll_xattr_get,
618 .set = ll_xattr_set,
619};
620
621const struct xattr_handler *ll_xattr_handlers[] = {
622 &ll_user_xattr_handler,
623 &ll_trusted_xattr_handler,
624 &ll_security_xattr_handler,
625#ifdef CONFIG_FS_POSIX_ACL
626 &ll_acl_access_xattr_handler,
627 &ll_acl_default_xattr_handler,
628#endif
629 &ll_lustre_xattr_handler,
630 NULL,
631};