linux/drivers/staging/lustre/lustre/llite/xattr.c
<<
>>
Prefs
   1/*
   2 * GPL HEADER START
   3 *
   4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2 only,
   8 * as published by the Free Software Foundation.
   9 *
  10 * This program is distributed in the hope that it will be useful, but
  11 * WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13 * General Public License version 2 for more details (a copy is included
  14 * in the LICENSE file that accompanied this code).
  15 *
  16 * You should have received a copy of the GNU General Public License
  17 * version 2 along with this program; If not, see
  18 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
  19 *
  20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  21 * CA 95054 USA or visit www.sun.com if you need additional information or
  22 * have any questions.
  23 *
  24 * GPL HEADER END
  25 */
  26/*
  27 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  28 * Use is subject to license terms.
  29 *
  30 * Copyright (c) 2011, 2012, Intel Corporation.
  31 */
  32/*
  33 * This file is part of Lustre, http://www.lustre.org/
  34 * Lustre is a trademark of Sun Microsystems, Inc.
  35 */
  36
  37#include <linux/fs.h>
  38#include <linux/sched.h>
  39#include <linux/mm.h>
  40#include <linux/selinux.h>
  41
  42#define DEBUG_SUBSYSTEM S_LLITE
  43
  44#include "../include/obd_support.h"
  45#include "../include/lustre_lite.h"
  46#include "../include/lustre_dlm.h"
  47#include "../include/lustre_ver.h"
  48#include "../include/lustre_eacl.h"
  49
  50#include "llite_internal.h"
  51
  52#define XATTR_USER_T        (1)
  53#define XATTR_TRUSTED_T  (2)
  54#define XATTR_SECURITY_T        (3)
  55#define XATTR_ACL_ACCESS_T      (4)
  56#define XATTR_ACL_DEFAULT_T     (5)
  57#define XATTR_LUSTRE_T    (6)
  58#define XATTR_OTHER_T      (7)
  59
  60static
  61int get_xattr_type(const char *name)
  62{
  63        if (!strcmp(name, POSIX_ACL_XATTR_ACCESS))
  64                return XATTR_ACL_ACCESS_T;
  65
  66        if (!strcmp(name, POSIX_ACL_XATTR_DEFAULT))
  67                return XATTR_ACL_DEFAULT_T;
  68
  69        if (!strncmp(name, XATTR_USER_PREFIX,
  70                     sizeof(XATTR_USER_PREFIX) - 1))
  71                return XATTR_USER_T;
  72
  73        if (!strncmp(name, XATTR_TRUSTED_PREFIX,
  74                     sizeof(XATTR_TRUSTED_PREFIX) - 1))
  75                return XATTR_TRUSTED_T;
  76
  77        if (!strncmp(name, XATTR_SECURITY_PREFIX,
  78                     sizeof(XATTR_SECURITY_PREFIX) - 1))
  79                return XATTR_SECURITY_T;
  80
  81        if (!strncmp(name, XATTR_LUSTRE_PREFIX,
  82                     sizeof(XATTR_LUSTRE_PREFIX) - 1))
  83                return XATTR_LUSTRE_T;
  84
  85        return XATTR_OTHER_T;
  86}
  87
  88static
  89int xattr_type_filter(struct ll_sb_info *sbi, int xattr_type)
  90{
  91        if ((xattr_type == XATTR_ACL_ACCESS_T ||
  92             xattr_type == XATTR_ACL_DEFAULT_T) &&
  93           !(sbi->ll_flags & LL_SBI_ACL))
  94                return -EOPNOTSUPP;
  95
  96        if (xattr_type == XATTR_USER_T && !(sbi->ll_flags & LL_SBI_USER_XATTR))
  97                return -EOPNOTSUPP;
  98        if (xattr_type == XATTR_TRUSTED_T && !capable(CFS_CAP_SYS_ADMIN))
  99                return -EPERM;
 100        if (xattr_type == XATTR_OTHER_T)
 101                return -EOPNOTSUPP;
 102
 103        return 0;
 104}
 105
 106static
 107int ll_setxattr_common(struct inode *inode, const char *name,
 108                       const void *value, size_t size,
 109                       int flags, __u64 valid)
 110{
 111        struct ll_sb_info *sbi = ll_i2sbi(inode);
 112        struct ptlrpc_request *req = NULL;
 113        int xattr_type, rc;
 114        struct obd_capa *oc;
 115#ifdef CONFIG_FS_POSIX_ACL
 116        struct rmtacl_ctl_entry *rce = NULL;
 117        posix_acl_xattr_header *new_value = NULL;
 118        ext_acl_xattr_header *acl = NULL;
 119#endif
 120        const char *pv = value;
 121
 122        xattr_type = get_xattr_type(name);
 123        rc = xattr_type_filter(sbi, xattr_type);
 124        if (rc)
 125                return rc;
 126
 127        if ((xattr_type == XATTR_ACL_ACCESS_T ||
 128             xattr_type == XATTR_ACL_DEFAULT_T) &&
 129            !inode_owner_or_capable(inode))
 130                return -EPERM;
 131
 132        /* b10667: ignore lustre special xattr for now */
 133        if ((xattr_type == XATTR_TRUSTED_T && strcmp(name, "trusted.lov") == 0) ||
 134            (xattr_type == XATTR_LUSTRE_T && strcmp(name, "lustre.lov") == 0))
 135                return 0;
 136
 137        /* b15587: ignore security.capability xattr for now */
 138        if ((xattr_type == XATTR_SECURITY_T &&
 139            strcmp(name, "security.capability") == 0))
 140                return 0;
 141
 142        /* LU-549:  Disable security.selinux when selinux is disabled */
 143        if (xattr_type == XATTR_SECURITY_T && !selinux_is_enabled() &&
 144            strcmp(name, "security.selinux") == 0)
 145                return -EOPNOTSUPP;
 146
 147#ifdef CONFIG_FS_POSIX_ACL
 148        if (sbi->ll_flags & LL_SBI_RMT_CLIENT &&
 149            (xattr_type == XATTR_ACL_ACCESS_T ||
 150            xattr_type == XATTR_ACL_DEFAULT_T)) {
 151                rce = rct_search(&sbi->ll_rct, current_pid());
 152                if (rce == NULL ||
 153                    (rce->rce_ops != RMT_LSETFACL &&
 154                    rce->rce_ops != RMT_RSETFACL))
 155                        return -EOPNOTSUPP;
 156
 157                if (rce->rce_ops == RMT_LSETFACL) {
 158                        struct eacl_entry *ee;
 159
 160                        ee = et_search_del(&sbi->ll_et, current_pid(),
 161                                           ll_inode2fid(inode), xattr_type);
 162                        LASSERT(ee != NULL);
 163                        if (valid & OBD_MD_FLXATTR) {
 164                                acl = lustre_acl_xattr_merge2ext(
 165                                                (posix_acl_xattr_header *)value,
 166                                                size, ee->ee_acl);
 167                                if (IS_ERR(acl)) {
 168                                        ee_free(ee);
 169                                        return PTR_ERR(acl);
 170                                }
 171                                size =  CFS_ACL_XATTR_SIZE(\
 172                                                le32_to_cpu(acl->a_count), \
 173                                                ext_acl_xattr);
 174                                pv = (const char *)acl;
 175                        }
 176                        ee_free(ee);
 177                } else if (rce->rce_ops == RMT_RSETFACL) {
 178                        size = lustre_posix_acl_xattr_filter(
 179                                                (posix_acl_xattr_header *)value,
 180                                                size, &new_value);
 181                        if (unlikely(size < 0))
 182                                return size;
 183
 184                        pv = (const char *)new_value;
 185                } else
 186                        return -EOPNOTSUPP;
 187
 188                valid |= rce_ops2valid(rce->rce_ops);
 189        }
 190#endif
 191                oc = ll_mdscapa_get(inode);
 192                rc = md_setxattr(sbi->ll_md_exp, ll_inode2fid(inode), oc,
 193                                valid, name, pv, size, 0, flags,
 194                                ll_i2suppgid(inode), &req);
 195                capa_put(oc);
 196#ifdef CONFIG_FS_POSIX_ACL
 197        if (new_value != NULL)
 198                lustre_posix_acl_xattr_free(new_value, size);
 199        if (acl != NULL)
 200                lustre_ext_acl_xattr_free(acl);
 201#endif
 202        if (rc) {
 203                if (rc == -EOPNOTSUPP && xattr_type == XATTR_USER_T) {
 204                        LCONSOLE_INFO("Disabling user_xattr feature because it is not supported on the server\n");
 205                        sbi->ll_flags &= ~LL_SBI_USER_XATTR;
 206                }
 207                return rc;
 208        }
 209
 210        ptlrpc_req_finished(req);
 211        return 0;
 212}
 213
 214int ll_setxattr(struct dentry *dentry, const char *name,
 215                const void *value, size_t size, int flags)
 216{
 217        struct inode *inode = d_inode(dentry);
 218
 219        LASSERT(inode);
 220        LASSERT(name);
 221
 222        CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p), xattr %s\n",
 223               inode->i_ino, inode->i_generation, inode, name);
 224
 225        ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_SETXATTR, 1);
 226
 227        if ((strncmp(name, XATTR_TRUSTED_PREFIX,
 228                     sizeof(XATTR_TRUSTED_PREFIX) - 1) == 0 &&
 229             strcmp(name + sizeof(XATTR_TRUSTED_PREFIX) - 1, "lov") == 0) ||
 230            (strncmp(name, XATTR_LUSTRE_PREFIX,
 231                     sizeof(XATTR_LUSTRE_PREFIX) - 1) == 0 &&
 232             strcmp(name + sizeof(XATTR_LUSTRE_PREFIX) - 1, "lov") == 0)) {
 233                struct lov_user_md *lump = (struct lov_user_md *)value;
 234                int rc = 0;
 235
 236                if (size != 0 && size < sizeof(struct lov_user_md))
 237                        return -EINVAL;
 238
 239                /* Attributes that are saved via getxattr will always have
 240                 * the stripe_offset as 0.  Instead, the MDS should be
 241                 * allowed to pick the starting OST index.   b=17846 */
 242                if (lump != NULL && lump->lmm_stripe_offset == 0)
 243                        lump->lmm_stripe_offset = -1;
 244
 245                if (lump != NULL && S_ISREG(inode->i_mode)) {
 246                        int flags = FMODE_WRITE;
 247                        int lum_size = (lump->lmm_magic == LOV_USER_MAGIC_V1) ?
 248                                sizeof(*lump) : sizeof(struct lov_user_md_v3);
 249
 250                        rc = ll_lov_setstripe_ea_info(inode, dentry, flags, lump,
 251                                                      lum_size);
 252                        /* b10667: rc always be 0 here for now */
 253                        rc = 0;
 254                } else if (S_ISDIR(inode->i_mode)) {
 255                        rc = ll_dir_setstripe(inode, lump, 0);
 256                }
 257
 258                return rc;
 259
 260        } else if (strcmp(name, XATTR_NAME_LMA) == 0 ||
 261                   strcmp(name, XATTR_NAME_LINK) == 0)
 262                return 0;
 263
 264        return ll_setxattr_common(inode, name, value, size, flags,
 265                                  OBD_MD_FLXATTR);
 266}
 267
 268int ll_removexattr(struct dentry *dentry, const char *name)
 269{
 270        struct inode *inode = d_inode(dentry);
 271
 272        LASSERT(inode);
 273        LASSERT(name);
 274
 275        CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p), xattr %s\n",
 276               inode->i_ino, inode->i_generation, inode, name);
 277
 278        ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_REMOVEXATTR, 1);
 279        return ll_setxattr_common(inode, name, NULL, 0, 0,
 280                                  OBD_MD_FLXATTRRM);
 281}
 282
 283static
 284int ll_getxattr_common(struct inode *inode, const char *name,
 285                       void *buffer, size_t size, __u64 valid)
 286{
 287        struct ll_sb_info *sbi = ll_i2sbi(inode);
 288        struct ptlrpc_request *req = NULL;
 289        struct mdt_body *body;
 290        int xattr_type, rc;
 291        void *xdata;
 292        struct obd_capa *oc;
 293        struct rmtacl_ctl_entry *rce = NULL;
 294        struct ll_inode_info *lli = ll_i2info(inode);
 295
 296        CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p)\n",
 297               inode->i_ino, inode->i_generation, inode);
 298
 299        /* listxattr have slightly different behavior from of ext3:
 300         * without 'user_xattr' ext3 will list all xattr names but
 301         * filtered out "^user..*"; we list them all for simplicity.
 302         */
 303        if (!name) {
 304                xattr_type = XATTR_OTHER_T;
 305                goto do_getxattr;
 306        }
 307
 308        xattr_type = get_xattr_type(name);
 309        rc = xattr_type_filter(sbi, xattr_type);
 310        if (rc)
 311                return rc;
 312
 313        /* b15587: ignore security.capability xattr for now */
 314        if ((xattr_type == XATTR_SECURITY_T &&
 315            strcmp(name, "security.capability") == 0))
 316                return -ENODATA;
 317
 318        /* LU-549:  Disable security.selinux when selinux is disabled */
 319        if (xattr_type == XATTR_SECURITY_T && !selinux_is_enabled() &&
 320            strcmp(name, "security.selinux") == 0)
 321                return -EOPNOTSUPP;
 322
 323#ifdef CONFIG_FS_POSIX_ACL
 324        if (sbi->ll_flags & LL_SBI_RMT_CLIENT &&
 325            (xattr_type == XATTR_ACL_ACCESS_T ||
 326            xattr_type == XATTR_ACL_DEFAULT_T)) {
 327                rce = rct_search(&sbi->ll_rct, current_pid());
 328                if (rce == NULL ||
 329                    (rce->rce_ops != RMT_LSETFACL &&
 330                    rce->rce_ops != RMT_LGETFACL &&
 331                    rce->rce_ops != RMT_RSETFACL &&
 332                    rce->rce_ops != RMT_RGETFACL))
 333                        return -EOPNOTSUPP;
 334        }
 335
 336        /* posix acl is under protection of LOOKUP lock. when calling to this,
 337         * we just have path resolution to the target inode, so we have great
 338         * chance that cached ACL is uptodate.
 339         */
 340        if (xattr_type == XATTR_ACL_ACCESS_T &&
 341            !(sbi->ll_flags & LL_SBI_RMT_CLIENT)) {
 342
 343                struct posix_acl *acl;
 344
 345                spin_lock(&lli->lli_lock);
 346                acl = posix_acl_dup(lli->lli_posix_acl);
 347                spin_unlock(&lli->lli_lock);
 348
 349                if (!acl)
 350                        return -ENODATA;
 351
 352                rc = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
 353                posix_acl_release(acl);
 354                return rc;
 355        }
 356        if (xattr_type == XATTR_ACL_DEFAULT_T && !S_ISDIR(inode->i_mode))
 357                return -ENODATA;
 358#endif
 359
 360do_getxattr:
 361        if (sbi->ll_xattr_cache_enabled && xattr_type != XATTR_ACL_ACCESS_T) {
 362                rc = ll_xattr_cache_get(inode, name, buffer, size, valid);
 363                if (rc == -EAGAIN)
 364                        goto getxattr_nocache;
 365                if (rc < 0)
 366                        goto out_xattr;
 367
 368                /* Add "system.posix_acl_access" to the list */
 369                if (lli->lli_posix_acl != NULL && valid & OBD_MD_FLXATTRLS) {
 370                        if (size == 0) {
 371                                rc += sizeof(XATTR_NAME_ACL_ACCESS);
 372                        } else if (size - rc >= sizeof(XATTR_NAME_ACL_ACCESS)) {
 373                                memcpy(buffer + rc, XATTR_NAME_ACL_ACCESS,
 374                                       sizeof(XATTR_NAME_ACL_ACCESS));
 375                                rc += sizeof(XATTR_NAME_ACL_ACCESS);
 376                        } else {
 377                                rc = -ERANGE;
 378                                goto out_xattr;
 379                        }
 380                }
 381        } else {
 382getxattr_nocache:
 383                oc = ll_mdscapa_get(inode);
 384                rc = md_getxattr(sbi->ll_md_exp, ll_inode2fid(inode), oc,
 385                                valid | (rce ? rce_ops2valid(rce->rce_ops) : 0),
 386                                name, NULL, 0, size, 0, &req);
 387                capa_put(oc);
 388
 389                if (rc < 0)
 390                        goto out_xattr;
 391
 392                body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY);
 393                LASSERT(body);
 394
 395                /* only detect the xattr size */
 396                if (size == 0) {
 397                        rc = body->eadatasize;
 398                        goto out;
 399                }
 400
 401                if (size < body->eadatasize) {
 402                        CERROR("server bug: replied size %u > %u\n",
 403                                body->eadatasize, (int)size);
 404                        rc = -ERANGE;
 405                        goto out;
 406                }
 407
 408                if (body->eadatasize == 0) {
 409                        rc = -ENODATA;
 410                        goto out;
 411                }
 412
 413                /* do not need swab xattr data */
 414                xdata = req_capsule_server_sized_get(&req->rq_pill, &RMF_EADATA,
 415                                                        body->eadatasize);
 416                if (!xdata) {
 417                        rc = -EFAULT;
 418                        goto out;
 419                }
 420
 421                memcpy(buffer, xdata, body->eadatasize);
 422                rc = body->eadatasize;
 423        }
 424
 425#ifdef CONFIG_FS_POSIX_ACL
 426        if (rce && rce->rce_ops == RMT_LSETFACL) {
 427                ext_acl_xattr_header *acl;
 428
 429                acl = lustre_posix_acl_xattr_2ext(
 430                                        (posix_acl_xattr_header *)buffer, rc);
 431                if (IS_ERR(acl)) {
 432                        rc = PTR_ERR(acl);
 433                        goto out;
 434                }
 435
 436                rc = ee_add(&sbi->ll_et, current_pid(), ll_inode2fid(inode),
 437                            xattr_type, acl);
 438                if (unlikely(rc < 0)) {
 439                        lustre_ext_acl_xattr_free(acl);
 440                        goto out;
 441                }
 442        }
 443#endif
 444
 445out_xattr:
 446        if (rc == -EOPNOTSUPP && xattr_type == XATTR_USER_T) {
 447                LCONSOLE_INFO(
 448                        "%s: disabling user_xattr feature because it is not supported on the server: rc = %d\n",
 449                        ll_get_fsname(inode->i_sb, NULL, 0), rc);
 450                sbi->ll_flags &= ~LL_SBI_USER_XATTR;
 451        }
 452out:
 453        ptlrpc_req_finished(req);
 454        return rc;
 455}
 456
 457ssize_t ll_getxattr(struct dentry *dentry, const char *name,
 458                    void *buffer, size_t size)
 459{
 460        struct inode *inode = d_inode(dentry);
 461
 462        LASSERT(inode);
 463        LASSERT(name);
 464
 465        CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p), xattr %s\n",
 466               inode->i_ino, inode->i_generation, inode, name);
 467
 468        ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_GETXATTR, 1);
 469
 470        if ((strncmp(name, XATTR_TRUSTED_PREFIX,
 471                     sizeof(XATTR_TRUSTED_PREFIX) - 1) == 0 &&
 472             strcmp(name + sizeof(XATTR_TRUSTED_PREFIX) - 1, "lov") == 0) ||
 473            (strncmp(name, XATTR_LUSTRE_PREFIX,
 474                     sizeof(XATTR_LUSTRE_PREFIX) - 1) == 0 &&
 475             strcmp(name + sizeof(XATTR_LUSTRE_PREFIX) - 1, "lov") == 0)) {
 476                struct lov_stripe_md *lsm;
 477                struct lov_user_md *lump;
 478                struct lov_mds_md *lmm = NULL;
 479                struct ptlrpc_request *request = NULL;
 480                int rc = 0, lmmsize = 0;
 481
 482                if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode))
 483                        return -ENODATA;
 484
 485                if (size == 0 && S_ISDIR(inode->i_mode)) {
 486                        /* XXX directory EA is fix for now, optimize to save
 487                         * RPC transfer */
 488                        rc = sizeof(struct lov_user_md);
 489                        goto out;
 490                }
 491
 492                lsm = ccc_inode_lsm_get(inode);
 493                if (lsm == NULL) {
 494                        if (S_ISDIR(inode->i_mode)) {
 495                                rc = ll_dir_getstripe(inode, &lmm,
 496                                                      &lmmsize, &request);
 497                        } else {
 498                                rc = -ENODATA;
 499                        }
 500                } else {
 501                        /* LSM is present already after lookup/getattr call.
 502                         * we need to grab layout lock once it is implemented */
 503                        rc = obd_packmd(ll_i2dtexp(inode), &lmm, lsm);
 504                        lmmsize = rc;
 505                }
 506                ccc_inode_lsm_put(inode, lsm);
 507
 508                if (rc < 0)
 509                        goto out;
 510
 511                if (size == 0) {
 512                        /* used to call ll_get_max_mdsize() forward to get
 513                         * the maximum buffer size, while some apps (such as
 514                         * rsync 3.0.x) care much about the exact xattr value
 515                         * size */
 516                        rc = lmmsize;
 517                        goto out;
 518                }
 519
 520                if (size < lmmsize) {
 521                        CERROR("server bug: replied size %d > %d for %pd (%s)\n",
 522                               lmmsize, (int)size, dentry, name);
 523                        rc = -ERANGE;
 524                        goto out;
 525                }
 526
 527                lump = (struct lov_user_md *)buffer;
 528                memcpy(lump, lmm, lmmsize);
 529                /* do not return layout gen for getxattr otherwise it would
 530                 * confuse tar --xattr by recognizing layout gen as stripe
 531                 * offset when the file is restored. See LU-2809. */
 532                lump->lmm_layout_gen = 0;
 533
 534                rc = lmmsize;
 535out:
 536                if (request)
 537                        ptlrpc_req_finished(request);
 538                else if (lmm)
 539                        obd_free_diskmd(ll_i2dtexp(inode), &lmm);
 540                return rc;
 541        }
 542
 543        return ll_getxattr_common(inode, name, buffer, size, OBD_MD_FLXATTR);
 544}
 545
 546ssize_t ll_listxattr(struct dentry *dentry, char *buffer, size_t size)
 547{
 548        struct inode *inode = d_inode(dentry);
 549        int rc = 0, rc2 = 0;
 550        struct lov_mds_md *lmm = NULL;
 551        struct ptlrpc_request *request = NULL;
 552        int lmmsize;
 553
 554        LASSERT(inode);
 555
 556        CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p)\n",
 557               inode->i_ino, inode->i_generation, inode);
 558
 559        ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_LISTXATTR, 1);
 560
 561        rc = ll_getxattr_common(inode, NULL, buffer, size, OBD_MD_FLXATTRLS);
 562        if (rc < 0)
 563                goto out;
 564
 565        if (buffer != NULL) {
 566                struct ll_sb_info *sbi = ll_i2sbi(inode);
 567                char *xattr_name = buffer;
 568                int xlen, rem = rc;
 569
 570                while (rem > 0) {
 571                        xlen = strnlen(xattr_name, rem - 1) + 1;
 572                        rem -= xlen;
 573                        if (xattr_type_filter(sbi,
 574                                        get_xattr_type(xattr_name)) == 0) {
 575                                /* skip OK xattr type
 576                                 * leave it in buffer
 577                                 */
 578                                xattr_name += xlen;
 579                                continue;
 580                        }
 581                        /* move up remaining xattrs in buffer
 582                         * removing the xattr that is not OK
 583                         */
 584                        memmove(xattr_name, xattr_name + xlen, rem);
 585                        rc -= xlen;
 586                }
 587        }
 588        if (S_ISREG(inode->i_mode)) {
 589                if (!ll_i2info(inode)->lli_has_smd)
 590                        rc2 = -1;
 591        } else if (S_ISDIR(inode->i_mode)) {
 592                rc2 = ll_dir_getstripe(inode, &lmm, &lmmsize, &request);
 593        }
 594
 595        if (rc2 < 0) {
 596                rc2 = 0;
 597                goto out;
 598        } else if (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)) {
 599                const int prefix_len = sizeof(XATTR_LUSTRE_PREFIX) - 1;
 600                const size_t name_len   = sizeof("lov") - 1;
 601                const size_t total_len  = prefix_len + name_len + 1;
 602
 603                if (((rc + total_len) > size) && (buffer != NULL)) {
 604                        ptlrpc_req_finished(request);
 605                        return -ERANGE;
 606                }
 607
 608                if (buffer != NULL) {
 609                        buffer += rc;
 610                        memcpy(buffer, XATTR_LUSTRE_PREFIX, prefix_len);
 611                        memcpy(buffer + prefix_len, "lov", name_len);
 612                        buffer[prefix_len + name_len] = '\0';
 613                }
 614                rc2 = total_len;
 615        }
 616out:
 617        ptlrpc_req_finished(request);
 618        rc = rc + rc2;
 619
 620        return rc;
 621}
 622