From 0ae570b4dccc621c0c5fca9407dd053fc957cc1c Mon Sep 17 00:00:00 2001 From: "John L. Hammond" Date: Mon, 2 Jul 2018 10:07:51 -0500 Subject: [PATCH] LU-11107 mdt: handle nonexistent xattrs correctly In mdt_getxattr_pack_reply() propagate -ENODATA returns from mo_xattr_list() to mdt_getxattr(). Add sanity test_102s() to ensure that getting a nonexistint xattr will fail. Lustre-change: https://review.whamcloud.com/32753 Lustre-commit: 39c7ac4c0dce3c62795814cd12a78bec1877520b Signed-off-by: John L. Hammond Change-Id: Ic7a01feb3fcac66d39f84b4ebdfc86025c3e2779 Reviewed-by: Emoly Liu Reviewed-by: Andreas Dilger Reviewed-by: James Simmons Signed-off-by: Minh Diep Reviewed-on: https://review.whamcloud.com/32910 Tested-by: Jenkins Tested-by: Maloo --- lustre/mdt/mdt_xattr.c | 67 +++++++++++++++++++++++++++++--------------------- lustre/tests/sanity.sh | 26 ++++++++++++++++++++ 2 files changed, 65 insertions(+), 28 deletions(-) diff --git a/lustre/mdt/mdt_xattr.c b/lustre/mdt/mdt_xattr.c index 3cd39f4..36ad43f 100644 --- a/lustre/mdt/mdt_xattr.c +++ b/lustre/mdt/mdt_xattr.c @@ -51,29 +51,41 @@ /* return EADATA length to the caller. negative value means error */ static int mdt_getxattr_pack_reply(struct mdt_thread_info * info) { - struct req_capsule *pill = info->mti_pill ; - struct ptlrpc_request *req = mdt_info_req(info); - char *xattr_name; - __u64 valid; - static const char user_string[] = "user."; - int size, rc; - ENTRY; + struct req_capsule *pill = info->mti_pill; + struct ptlrpc_request *req = mdt_info_req(info); + const char *xattr_name; + u64 valid; + static const char user_string[] = "user."; + int size; + int rc = 0; + int rc2; + ENTRY; valid = info->mti_body->mbo_valid & (OBD_MD_FLXATTR | OBD_MD_FLXATTRLS); - /* Determine how many bytes we need */ + /* Determine how many bytes we need */ if (valid == OBD_MD_FLXATTR) { - xattr_name = req_capsule_client_get(pill, &RMF_NAME); - if (!xattr_name) - RETURN(-EFAULT); + xattr_name = req_capsule_client_get(pill, &RMF_NAME); + if (!xattr_name) + RETURN(-EFAULT); if (!(exp_connect_flags(req->rq_export) & OBD_CONNECT_XATTR) && !strncmp(xattr_name, user_string, sizeof(user_string) - 1)) RETURN(-EOPNOTSUPP); - size = mo_xattr_get(info->mti_env, - mdt_object_child(info->mti_object), - &LU_BUF_NULL, xattr_name); + size = mo_xattr_get(info->mti_env, + mdt_object_child(info->mti_object), + &LU_BUF_NULL, xattr_name); + if (size == -ENODATA) { + /* XXX: Some client code will not handle -ENODATA + * for XATTR_NAME_LOV (trusted.lov) properly. */ + if (strcmp(xattr_name, XATTR_NAME_LOV) == 0) + rc = 0; + else + rc = -ENODATA; + + size = 0; + } } else if (valid == OBD_MD_FLXATTRLS) { size = mo_xattr_list(info->mti_env, mdt_object_child(info->mti_object), @@ -91,9 +103,7 @@ static int mdt_getxattr_pack_reply(struct mdt_thread_info * info) RETURN(-EINVAL); } - if (size == -ENODATA) { - size = 0; - } else if (size < 0) { + if (size < 0) { if (size != -EOPNOTSUPP) CERROR("Error geting EA size: %d\n", size); RETURN(size); @@ -103,18 +113,17 @@ static int mdt_getxattr_pack_reply(struct mdt_thread_info * info) req_capsule_set_size(pill, &RMF_ACL, RCL_SERVER, LUSTRE_POSIX_ACL_MAX_SIZE_OLD); - req_capsule_set_size(pill, &RMF_EADATA, RCL_SERVER, + req_capsule_set_size(pill, &RMF_EADATA, RCL_SERVER, info->mti_body->mbo_eadatasize == 0 ? 0 : size); - rc = req_capsule_server_pack(pill); - if (rc) { - LASSERT(rc < 0); - RETURN(rc); - } - if (OBD_FAIL_CHECK(OBD_FAIL_MDS_GETXATTR_PACK)) - RETURN(-ENOMEM); + rc2 = req_capsule_server_pack(pill); + if (rc2 < 0) + RETURN(rc2); + + if (OBD_FAIL_CHECK(OBD_FAIL_MDS_GETXATTR_PACK)) + RETURN(-ENOMEM); - RETURN(size); + RETURN(rc < 0 ? rc : size); } static int mdt_nodemap_map_acl(struct mdt_thread_info *info, void *buf, @@ -239,8 +248,10 @@ int mdt_getxattr(struct mdt_thread_info *info) next = mdt_object_child(info->mti_object); easize = mdt_getxattr_pack_reply(info); - if (easize < 0) - GOTO(out, rc = err_serious(easize)); + if (easize == -ENODATA) + GOTO(out, rc = easize); + else if (easize < 0) + GOTO(out, rc = err_serious(easize)); repbody = req_capsule_server_get(info->mti_pill, &RMF_MDT_BODY); LASSERT(repbody != NULL); diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index 766ff98..4c3050f 100755 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -7573,6 +7573,32 @@ test_102r() { } run_test 102r "set EAs with empty values" +test_102s() { + [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.52) ] && + skip "MDS needs to be at least 2.11.52" + + local save="$TMP/$TESTSUITE-$TESTNAME.parameters" + + save_lustre_params client "llite.*.xattr_cache" > $save + + for cache in 0 1; do + lctl set_param llite.*.xattr_cache=$cache + + rm -f $DIR/$tfile + touch $DIR/$tfile || error "touch" + for prefix in lustre security system trusted user; do + # Note getxattr() may fail with 'Operation not + # supported' or 'No such attribute' depending + # on prefix and cache. + getfattr -n $prefix.n102s $DIR/$tfile && + error "getxattr '$prefix.n102s' should fail (cache = $cache)" + done + done + + restore_lustre_params < $save +} +run_test 102s "getting nonexistent xattrs should fail" + run_acl_subtest() { $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test -- 1.8.3.1