Whamcloud - gitweb
LU-5523 mdt: add --index option to default dir stripe
[fs/lustre-release.git] / lustre / llite / xattr.c
index 56decef..18429ab 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2013, Intel Corporation.
+ * Copyright (c) 2011, 2014, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -42,7 +42,6 @@
 #define DEBUG_SUBSYSTEM S_LLITE
 
 #include <obd_support.h>
-#include <lustre_lite.h>
 #include <lustre_dlm.h>
 #include <lustre_ver.h>
 #include <lustre_eacl.h>
@@ -123,6 +122,15 @@ int ll_setxattr_common(struct inode *inode, const char *name,
         if (rc)
                 RETURN(rc);
 
+       if ((xattr_type == XATTR_ACL_ACCESS_T ||
+            xattr_type == XATTR_ACL_DEFAULT_T) &&
+#ifdef HAVE_INODE_OWNER_OR_CAPABLE
+           !inode_owner_or_capable(inode))
+#else
+           !is_owner_or_cap(inode))
+#endif
+               return -EPERM;
+
         /* b10667: ignore lustre special xattr for now */
         if ((xattr_type == XATTR_TRUSTED_T && strcmp(name, "trusted.lov") == 0) ||
             (xattr_type == XATTR_LUSTRE_T && strcmp(name, "lustre.lov") == 0))
@@ -215,8 +223,8 @@ int ll_setxattr(struct dentry *dentry, const char *name,
         LASSERT(inode);
         LASSERT(name);
 
-        CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p), xattr %s\n",
-               inode->i_ino, inode->i_generation, inode, name);
+       CDEBUG(D_VFSTRACE, "VFS Op:inode="DFID"(%p), xattr %s\n",
+              PFID(ll_inode2fid(inode)), inode, name);
 
         ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_SETXATTR, 1);
 
@@ -226,8 +234,8 @@ int ll_setxattr(struct dentry *dentry, const char *name,
             (strncmp(name, XATTR_LUSTRE_PREFIX,
                      sizeof(XATTR_LUSTRE_PREFIX) - 1) == 0 &&
              strcmp(name + sizeof(XATTR_LUSTRE_PREFIX) - 1, "lov") == 0)) {
-                struct lov_user_md *lump = (struct lov_user_md *)value;
-                int rc = 0;
+               struct lov_user_md *lump = (struct lov_user_md *)value;
+               int                 rc = 0;
 
                 /* Attributes that are saved via getxattr will always have
                  * the stripe_offset as 0.  Instead, the MDS should be
@@ -238,13 +246,17 @@ int ll_setxattr(struct dentry *dentry, const char *name,
                if (lump != NULL && S_ISREG(inode->i_mode)) {
                        struct file     f;
                        __u64           it_flags = FMODE_WRITE;
-                       int lum_size = (lump->lmm_magic == LOV_USER_MAGIC_V1) ?
-                               sizeof(*lump) : sizeof(struct lov_user_md_v3);
+                       int             lum_size;
+
+                       lum_size = ll_lov_user_md_size(lump);
+                       if (lum_size < 0 || size < lum_size)
+                               return 0; /* b=10667: ignore error */
 
+                       memset(&f, 0, sizeof(f)); /* f.f_flags is used below */
                        f.f_dentry = dentry;
                        rc = ll_lov_setstripe_ea_info(inode, &f, it_flags, lump,
                                                      lum_size);
-                       /* b10667: rc always be 0 here for now */
+                       /* b=10667: rc always be 0 here for now */
                        rc = 0;
                 } else if (S_ISDIR(inode->i_mode)) {
                         rc = ll_dir_setstripe(inode, lump, 0);
@@ -267,15 +279,14 @@ int ll_removexattr(struct dentry *dentry, const char *name)
         LASSERT(inode);
         LASSERT(name);
 
-        CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p), xattr %s\n",
-               inode->i_ino, inode->i_generation, inode, name);
+       CDEBUG(D_VFSTRACE, "VFS Op:inode="DFID"(%p), xattr %s\n",
+              PFID(ll_inode2fid(inode)), inode, name);
 
         ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_REMOVEXATTR, 1);
         return ll_setxattr_common(inode, name, NULL, 0, 0,
                                   OBD_MD_FLXATTRRM);
 }
 
-static
 int ll_getxattr_common(struct inode *inode, const char *name,
                        void *buffer, size_t size, __u64 valid)
 {
@@ -289,8 +300,8 @@ int ll_getxattr_common(struct inode *inode, const char *name,
        struct ll_inode_info *lli = ll_i2info(inode);
         ENTRY;
 
-        CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p)\n",
-               inode->i_ino, inode->i_generation, inode);
+       CDEBUG(D_VFSTRACE, "VFS Op:inode="DFID"(%p)\n",
+              PFID(ll_inode2fid(inode)), inode);
 
         /* listxattr have slightly different behavior from of ext3:
          * without 'user_xattr' ext3 will list all xattr names but
@@ -389,25 +400,25 @@ getxattr_nocache:
 
                /* only detect the xattr size */
                if (size == 0)
-                       GOTO(out, rc = body->eadatasize);
+                       GOTO(out, rc = body->mbo_eadatasize);
 
-               if (size < body->eadatasize) {
+               if (size < body->mbo_eadatasize) {
                        CERROR("server bug: replied size %u > %u\n",
-                               body->eadatasize, (int)size);
+                               body->mbo_eadatasize, (int)size);
                        GOTO(out, rc = -ERANGE);
                }
 
-               if (body->eadatasize == 0)
+               if (body->mbo_eadatasize == 0)
                        GOTO(out, rc = -ENODATA);
 
                /* do not need swab xattr data */
                xdata = req_capsule_server_sized_get(&req->rq_pill, &RMF_EADATA,
-                                                       body->eadatasize);
+                                                       body->mbo_eadatasize);
                if (!xdata)
                        GOTO(out, rc = -EFAULT);
 
-               memcpy(buffer, xdata, body->eadatasize);
-               rc = body->eadatasize;
+               memcpy(buffer, xdata, body->mbo_eadatasize);
+               rc = body->mbo_eadatasize;
        }
 
 #ifdef CONFIG_FS_POSIX_ACL
@@ -448,8 +459,8 @@ ssize_t ll_getxattr(struct dentry *dentry, const char *name,
         LASSERT(inode);
         LASSERT(name);
 
-        CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p), xattr %s\n",
-               inode->i_ino, inode->i_generation, inode, name);
+       CDEBUG(D_VFSTRACE, "VFS Op:inode="DFID"(%p), xattr %s\n",
+              PFID(ll_inode2fid(inode)), inode, name);
 
         ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_GETXATTR, 1);
 
@@ -468,23 +479,17 @@ ssize_t ll_getxattr(struct dentry *dentry, const char *name,
                 if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode))
                         return -ENODATA;
 
-                if (size == 0 && S_ISDIR(inode->i_mode)) {
-                        /* XXX directory EA is fix for now, optimize to save
-                         * RPC transfer */
-                        GOTO(out, rc = sizeof(struct lov_user_md));
-                }
-
                lsm = ccc_inode_lsm_get(inode);
                if (lsm == NULL) {
-                        if (S_ISDIR(inode->i_mode)) {
-                                rc = ll_dir_getstripe(inode, &lmm,
-                                                      &lmmsize, &request);
-                        } else {
-                                rc = -ENODATA;
-                        }
-                } else {
-                        /* LSM is present already after lookup/getattr call.
-                         * we need to grab layout lock once it is implemented */
+                       if (S_ISDIR(inode->i_mode)) {
+                               rc = ll_dir_getstripe(inode, (void **)&lmm,
+                                                     &lmmsize, &request, 0);
+                       } else {
+                               rc = -ENODATA;
+                       }
+               } else {
+                       /* LSM is present already after lookup/getattr call.
+                        * we need to grab layout lock once it is implemented */
                        rc = obd_packmd(ll_i2dtexp(inode), &lmm, lsm);
                        lmmsize = rc;
                }
@@ -537,8 +542,8 @@ ssize_t ll_listxattr(struct dentry *dentry, char *buffer, size_t size)
 
         LASSERT(inode);
 
-        CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p)\n",
-               inode->i_ino, inode->i_generation, inode);
+       CDEBUG(D_VFSTRACE, "VFS Op:inode="DFID"(%p)\n",
+              PFID(ll_inode2fid(inode)), inode);
 
         ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_LISTXATTR, 1);
 
@@ -571,10 +576,11 @@ ssize_t ll_listxattr(struct dentry *dentry, char *buffer, size_t size)
        }
        if (S_ISREG(inode->i_mode)) {
                if (!ll_i2info(inode)->lli_has_smd)
-                        rc2 = -1;
-        } else if (S_ISDIR(inode->i_mode)) {
-                rc2 = ll_dir_getstripe(inode, &lmm, &lmmsize, &request);
-        }
+                       rc2 = -1;
+       } else if (S_ISDIR(inode->i_mode)) {
+               rc2 = ll_dir_getstripe(inode, (void **)&lmm, &lmmsize, &request,
+                                      0);
+       }
 
         if (rc2 < 0) {
                 GOTO(out, rc2 = 0);