Whamcloud - gitweb
LU-13115 mdt: handle mdt_pack_sectx_in_reply() errors 48/37148/4
authorMikhail Pershin <mpershin@whamcloud.com>
Tue, 7 Jan 2020 09:49:20 +0000 (12:49 +0300)
committerOleg Drokin <green@whamcloud.com>
Sat, 18 Jan 2020 04:03:57 +0000 (04:03 +0000)
The mdt_pack_secctx_in_reply() contains mo_xattr_get() call
which -ENOENT error should be checked and exit by error path
if needed.

In DNE environment lu_object may lost its LOHA_EXISTS flag
during osp_xattr_get() and that should be handled to don't
proceed with code paths for existent objects.

Test-Parameters: clientselinux mdtcount=4 envdefinitions=ONLY=185a testlist=sanity,sanity,sanity,sanity
Test-Parameters: clientselinux mdtcount=4 testlist=sanity,recovery-small,sanity-sec
Test-Parameters: clientselinux mdtcount=4 testgroup=review-dne-selinux
Signed-off-by: Mikhail Pershin <mpershin@whamcloud.com>
Change-Id: I55ad666f58dd3fae3ed097018aa23ed94818d246
Reviewed-on: https://review.whamcloud.com/37148
Reviewed-by: Sebastien Buisson <sbuisson@ddn.com>
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Alex Zhuravlev <bzzz@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/mdt/mdt_handler.c
lustre/mdt/mdt_internal.h
lustre/mdt/mdt_lib.c
lustre/mdt/mdt_open.c

index a2ffa2c..e2397cf 100644 (file)
@@ -1735,11 +1735,14 @@ static int mdt_getattr_name_lock(struct mdt_thread_info *info,
                }
 
                rc = mdt_getattr_internal(info, child, 0);
-               if (unlikely(rc != 0))
+               if (unlikely(rc != 0)) {
                        mdt_object_unlock(info, child, lhc, 1);
+                       RETURN(rc);
+               }
 
-               mdt_pack_secctx_in_reply(info, child);
-
+               rc = mdt_pack_secctx_in_reply(info, child);
+               if (unlikely(rc))
+                       mdt_object_unlock(info, child, lhc, 1);
                RETURN(rc);
        }
 
@@ -1854,7 +1857,7 @@ static int mdt_getattr_name_lock(struct mdt_thread_info *info,
                mdt_lock_reg_init(lhc, LCK_PR);
 
                if (!(child_bits & MDS_INODELOCK_UPDATE) &&
-                     mdt_object_exists(child) && !mdt_object_remote(child)) {
+                   !mdt_object_remote(child)) {
                        struct md_attr *ma = &info->mti_attr;
 
                        ma->ma_valid = 0;
@@ -1868,12 +1871,12 @@ static int mdt_getattr_name_lock(struct mdt_thread_info *info,
                         * lock and this might save us RPC on later STAT. For
                         * directories, it also let negative dentry cache start
                         * working for this dir. */
-                        if (ma->ma_valid & MA_INODE &&
-                            ma->ma_attr.la_valid & LA_CTIME &&
-                            info->mti_mdt->mdt_namespace->ns_ctime_age_limit +
-                               ma->ma_attr.la_ctime < ktime_get_real_seconds())
-                                child_bits |= MDS_INODELOCK_UPDATE;
-                }
+                       if (ma->ma_valid & MA_INODE &&
+                           ma->ma_attr.la_valid & LA_CTIME &&
+                           info->mti_mdt->mdt_namespace->ns_ctime_age_limit +
+                           ma->ma_attr.la_ctime < ktime_get_real_seconds())
+                               child_bits |= MDS_INODELOCK_UPDATE;
+               }
 
                /* layout lock must be granted in a best-effort way
                 * for IT operations */
@@ -1915,7 +1918,11 @@ static int mdt_getattr_name_lock(struct mdt_thread_info *info,
                GOTO(out_child, rc);
        }
 
-       mdt_pack_secctx_in_reply(info, child);
+       rc = mdt_pack_secctx_in_reply(info, child);
+       if (unlikely(rc)) {
+               mdt_object_unlock(info, child, lhc, 1);
+               GOTO(out_child, rc);
+       }
 
        lock = ldlm_handle2lock(&lhc->mlh_reg_lh);
        if (lock) {
@@ -1927,8 +1934,7 @@ static int mdt_getattr_name_lock(struct mdt_thread_info *info,
                         PLDLMRES(lock->l_resource),
                         PFID(mdt_object_fid(child)));
 
-               if (mdt_object_exists(child) &&
-                   S_ISREG(lu_object_attr(&child->mot_obj)) &&
+               if (S_ISREG(lu_object_attr(&child->mot_obj)) &&
                    !mdt_object_remote(child) && child != parent) {
                        mdt_object_put(info->mti_env, child);
                        rc = mdt_pack_size2body(info, child_fid,
index 6083c9b..723cd55 100644 (file)
@@ -942,8 +942,8 @@ int mdt_links_read(struct mdt_thread_info *info,
                   struct linkea_data *ldata);
 int mdt_close_internal(struct mdt_thread_info *info, struct ptlrpc_request *req,
                       struct mdt_body *repbody);
-void mdt_pack_secctx_in_reply(struct mdt_thread_info *info,
-                             struct mdt_object *child);
+int mdt_pack_secctx_in_reply(struct mdt_thread_info *info,
+                            struct mdt_object *child);
 
 static inline struct mdt_device *mdt_dev(struct lu_device *d)
 {
index 69c916b..71290c2 100644 (file)
@@ -1779,14 +1779,14 @@ int mdt_reint_unpack(struct mdt_thread_info *info, __u32 op)
         RETURN(rc);
 }
 
-void mdt_pack_secctx_in_reply(struct mdt_thread_info *info,
-                             struct mdt_object *child)
+int mdt_pack_secctx_in_reply(struct mdt_thread_info *info,
+                            struct mdt_object *child)
 {
        char *secctx_name;
        struct lu_buf *buffer;
        struct mdt_body *repbody;
        struct req_capsule *pill = info->mti_pill;
-       int rc;
+       int rc = 0;
 
        if (req_capsule_has_field(pill, &RMF_FILE_SECCTX, RCL_SERVER) &&
            req_capsule_get_size(pill, &RMF_FILE_SECCTX, RCL_SERVER) != 0) {
@@ -1811,12 +1811,21 @@ void mdt_pack_secctx_in_reply(struct mdt_thread_info *info,
                        if (rc < buffer->lb_len)
                                req_capsule_shrink(pill, &RMF_FILE_SECCTX, rc,
                                                   RCL_SERVER);
+                       rc = 0;
                } else {
                        CDEBUG(D_SEC,
                             "security context not found for "DFID": rc = %d\n",
                             PFID(mdt_object_fid(child)), rc);
                        req_capsule_shrink(pill, &RMF_FILE_SECCTX, 0,
                                           RCL_SERVER);
+                       /* handling -ENOENT is important because it may change
+                        * object state in DNE env dropping LOHA_EXISTS flag,
+                        * it is important to return that to the caller.
+                        * Check LU-13115 for details.
+                        */
+                       if (rc != -ENOENT)
+                               rc = 0;
                }
        }
+       return rc;
 }
index 8baaa48..7b1b1f3 100644 (file)
@@ -1218,7 +1218,9 @@ static int mdt_cross_open(struct mdt_thread_info *info,
                        if (rc != 0)
                                GOTO(out, rc);
 
-                       mdt_pack_secctx_in_reply(info, o);
+                       rc = mdt_pack_secctx_in_reply(info, o);
+                       if (unlikely(rc))
+                               GOTO(out, rc);
 
                        rc = mdt_finish_open(info, NULL, o, open_flags, 0, rep);
                } else {
@@ -1573,7 +1575,9 @@ again:
                }
        }
 
-       mdt_pack_secctx_in_reply(info, child);
+       rc = mdt_pack_secctx_in_reply(info, child);
+       if (unlikely(rc))
+               GOTO(out_child, result = rc);
 
        rc = mdt_check_resent_lock(info, child, lhc);
        if (rc < 0) {