Whamcloud - gitweb
LU-9484 llite: eat -EEXIST on setting trunsted.lov 26/27126/7
authorBobi Jam <bobijam.xu@intel.com>
Tue, 16 May 2017 12:37:20 +0000 (20:37 +0800)
committerOleg Drokin <oleg.drokin@intel.com>
Sat, 10 Jun 2017 02:48:38 +0000 (02:48 +0000)
Tools like rsync, tar, cp may copy and restore the xattrs on a file.
The client previously ignored the setting of trusted.lov/lustre.lov
if the layout had already been specified, to avoid causing these
tools to fail for no reason.

For PFL files we still need to silently eat -EEXIST on setting these
attributes to avoid problems.

Signed-off-by: Bobi Jam <bobijam.xu@intel.com>
Change-Id: Ic6d359c0f3557d4a21e950a53f57e38ae97a40da
Reviewed-on: https://review.whamcloud.com/27126
Reviewed-by: Dmitry Eremin <dmitry.eremin@intel.com>
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Niu Yawei <yawei.niu@intel.com>
Reviewed-by: James Simmons <uja.ornl@yahoo.com>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
lustre/llite/xattr.c
lustre/tests/sanity.sh

index 527ee40..71fbca5 100644 (file)
@@ -204,63 +204,85 @@ static int get_hsm_state(struct inode *inode, __u32 *hus_states)
        OBD_FREE_PTR(hus);
        return rc;
 }
-int ll_setstripe_ea(struct dentry *dentry, struct lov_user_md *lump,
-                   size_t size)
+
+static int ll_adjust_lum(struct inode *inode, struct lov_user_md *lump)
 {
-       struct inode *inode = dentry->d_inode;
+       struct lov_comp_md_v1 *comp_v1 = (struct lov_comp_md_v1 *)lump;
+       struct lov_user_md *v1 = lump;
+       bool release_checked = false;
+       bool need_clear_release = false;
+       __u16 entry_count = 1;
+       bool is_composite = false;
        int rc = 0;
-       bool return_err = false;
+       int i;
+
+       if (lump == NULL)
+               return 0;
 
-       if (lump != NULL && lump->lmm_magic == LOV_USER_MAGIC_COMP_V1) {
-               return_err = true;
-               goto setstripe;
+       if (lump->lmm_magic == LOV_USER_MAGIC_COMP_V1) {
+               entry_count = comp_v1->lcm_entry_count;
+               is_composite = true;
        }
 
-       /* Attributes that are saved via getxattr will always have
-        * the stripe_offset as 0.  Instead, the MDS should be
-        * allowed to pick the starting OST index.   b=17846 */
-       if (lump != NULL && lump->lmm_stripe_offset == 0)
-               lump->lmm_stripe_offset = -1;
-       /* Avoid anyone directly setting the RELEASED flag. */
-       if (lump != NULL &&
-               (lump->lmm_pattern & LOV_PATTERN_F_RELEASED)) {
-               /* Only if we have a released flag check if the file
-               * was indeed archived. */
-               __u32 state = HS_NONE;
-               rc = get_hsm_state(inode, &state);
-               if (rc != 0)
-                       RETURN(rc);
-               if (!(state & HS_ARCHIVED)) {
-                       CDEBUG(D_VFSTRACE,
-                               "hus_states state = %x, pattern = %x\n",
-                               state, lump->lmm_pattern);
-                       /* Here the state is: real file is not
-                        * archived but user is requesting to set
-                        * the RELEASED flag so we mask off the
-                        * released flag from the request */
-                       lump->lmm_pattern ^= LOV_PATTERN_F_RELEASED;
+       for (i = 0; i < entry_count; i++) {
+               if (lump->lmm_magic == LOV_USER_MAGIC_COMP_V1)
+                       v1 = (struct lov_user_md *)((char *)comp_v1 +
+                                       comp_v1->lcm_entries[i].lcme_offset);
+
+               /* Attributes that are saved via getxattr will always
+                * have the stripe_offset as 0.  Instead, the MDS
+                * should be allowed to pick the starting OST index.
+                * b=17846 */
+               if (!is_composite && v1->lmm_stripe_offset == 0)
+                       v1->lmm_stripe_offset = -1;
+
+               /* Avoid anyone directly setting the RELEASED flag. */
+               if (v1->lmm_pattern & LOV_PATTERN_F_RELEASED) {
+                       if (!release_checked) {
+                               __u32 state = HS_NONE;
+                               rc = get_hsm_state(inode, &state);
+                               if (rc)
+                                       return rc;
+                               if (!(state & HS_ARCHIVED))
+                                       need_clear_release = true;
+                               release_checked = true;
+                       }
+                       if (need_clear_release)
+                               v1->lmm_pattern ^= LOV_PATTERN_F_RELEASED;
                }
        }
 
-setstripe:
+       return rc;
+}
+
+int ll_setstripe_ea(struct dentry *dentry, struct lov_user_md *lump,
+                   size_t size)
+{
+       struct inode *inode = dentry->d_inode;
+       int rc = 0;
+
+       rc = ll_adjust_lum(inode, lump);
+       if (rc)
+               return rc;
+
        if (lump != NULL && S_ISREG(inode->i_mode)) {
                __u64 it_flags = FMODE_WRITE;
                int lum_size;
 
                lum_size = ll_lov_user_md_size(lump);
-               /**
-                * b=10667: ignore error.
-                * Silently eat error on setting strusted.lov attribute for
-                * SuSE 9, it added default option to copy all attributes in
-                * 'cp' command.
-                */
                if (lum_size < 0 || size < lum_size)
-                       return return_err ? -ERANGE : 0;
+                       return -ERANGE;
 
                rc = ll_lov_setstripe_ea_info(inode, dentry, it_flags, lump,
                                              lum_size);
-               /* b=10667 */
-               if (!return_err)
+               /**
+                * b=10667: ignore -EEXIST.
+                * Silently eat error on setting trusted.lov/lustre.lov
+                * attribute for SuSE 9, it added default option to copy
+                * all attributes in 'cp' command. rsync, tar --xattrs
+                * also will try to set LOVEA for existing files.
+                */
+               if (rc == -EEXIST)
                        rc = 0;
        } else if (S_ISDIR(inode->i_mode)) {
                rc = ll_dir_setstripe(inode, lump, 0);
index 6d66dbe..c69aa4a 100755 (executable)
@@ -7041,13 +7041,15 @@ test_102a() {
 
        setfattr -x user.author1 $testfile ||
                error "$testfile error deleting user.author1"
-       getfattr -d -m user $testfile 2> /dev/null | grep "user.author1" &&
-               error "$testfile did not delete trusted.name1 xattr"
-
-       # b10667: setting lustre special xattr be silently discarded
        echo "set lustre special xattr ..."
-       setfattr -n "trusted.lov" -v "invalid value" $testfile ||
-               error "$testfile allowed setting trusted.lov"
+       $LFS setstripe -c1 $testfile
+       local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
+               awk -F "=" '/trusted.lov/ { print $2 }' )
+       setfattr -n "trusted.lov" -v $lovea $testfile ||
+               error "$testfile doesn't ignore setting trusted.lov again"
+       setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
+               error "$testfile allow setting invalid trusted.lov"
+       rm -f $testfile
 }
 run_test 102a "user xattr test =================================="
 
@@ -7362,8 +7364,13 @@ test_102n() { # LU-4101 mdt: protect internal xattrs
                # Try to set a garbage xattr.
                value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
 
-               setfattr --name=trusted.$name --value="$value" $file1 ||
-                       error "setxattr 'trusted.$name' failed"
+               if [[ x$name == "xlov" ]]; then
+                       setfattr --name=trusted.lov --value="$value" $file1 &&
+                       error "setxattr invalid 'trusted.lov' success"
+               else
+                       setfattr --name=trusted.$name --value="$value" $file1 ||
+                               error "setxattr invalid 'trusted.$name' failed"
+               fi
 
                # Try to remove the xattr from $file1. We don't care if this
                # appears to succeed or fail, we just don't want there to be