From: Bobi Jam Date: Tue, 16 May 2017 12:37:20 +0000 (+0800) Subject: LU-9484 llite: eat -EEXIST on setting trunsted.lov X-Git-Tag: 2.9.59~11 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=0e90e02ceddd60f24fac9709f3ab9e9421c80315 LU-9484 llite: eat -EEXIST on setting trunsted.lov 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 Change-Id: Ic6d359c0f3557d4a21e950a53f57e38ae97a40da Reviewed-on: https://review.whamcloud.com/27126 Reviewed-by: Dmitry Eremin Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Niu Yawei Reviewed-by: James Simmons Reviewed-by: Andreas Dilger --- diff --git a/lustre/llite/xattr.c b/lustre/llite/xattr.c index 527ee40..71fbca5 100644 --- a/lustre/llite/xattr.c +++ b/lustre/llite/xattr.c @@ -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); diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index 6d66dbe..c69aa4a 100755 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -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