Whamcloud - gitweb
LU-3240 mdc: Check for all attributes validity in revalidate
[fs/lustre-release.git] / lustre / mdc / mdc_locks.c
index 12046eb..1a71afb 100644 (file)
@@ -392,13 +392,6 @@ mdc_intent_getxattr_pack(struct obd_export *exp,
 
        mdc_set_capa_size(req, &RMF_CAPA1, op_data->op_capa1);
 
-       if (it->it_op == IT_SETXATTR)
-               /* If we want to upgrade to LCK_PW, let's cancel LCK_PR
-                * locks now. This avoids unnecessary ASTs. */
-               count = mdc_resource_get_unused(exp, &op_data->op_fid1,
-                                               &cancels, LCK_PW,
-                                               MDS_INODELOCK_XATTR);
-
        rc = ldlm_prep_enqueue_req(exp, req, &cancels, count);
        if (rc) {
                ptlrpc_request_free(req);
@@ -862,7 +855,7 @@ resend:
                        RETURN(-EOPNOTSUPP);
                req = mdc_intent_layout_pack(exp, it, op_data);
                lvb_type = LVB_T_LAYOUT;
-       } else if (it->it_op & (IT_GETXATTR | IT_SETXATTR)) {
+       } else if (it->it_op & IT_GETXATTR) {
                req = mdc_intent_getxattr_pack(exp, it, op_data);
        } else {
                 LBUG();
@@ -908,7 +901,9 @@ resend:
                   can not rely on caller and this mainly for F_UNLCKs
                   (explicits or automatically generated by Kernel to clean
                   current FLocks upon exit) that can't be trashed */
-               if ((rc == -EINTR) || (rc == -ETIMEDOUT))
+               if (((rc == -EINTR) || (rc == -ETIMEDOUT)) &&
+                   (einfo->ei_type == LDLM_FLOCK) &&
+                   (einfo->ei_mode == LCK_NL))
                        goto resend;
                 RETURN(rc);
         }
@@ -1089,9 +1084,22 @@ int mdc_revalidate_lock(struct obd_export *exp, struct lookup_intent *it,
         } else {
                 fid_build_reg_res_name(fid, &res_id);
                 switch (it->it_op) {
-                case IT_GETATTR:
-                        policy.l_inodebits.bits = MDS_INODELOCK_UPDATE;
-                        break;
+               case IT_GETATTR:
+                       /* File attributes are held under multiple bits:
+                        * nlink is under lookup lock, size and times are
+                        * under UPDATE lock and recently we've also got
+                        * a separate permissions lock for owner/group/acl that
+                        * were protected by lookup lock before.
+                        * Getattr must provide all of that information,
+                        * so we need to ensure we have all of those locks.
+                        * Unfortunately, if the bits are split across multiple
+                        * locks, there's no easy way to match all of them here,
+                        * so an extra RPC would be performed to fetch all
+                        * of those bits at once for now. */
+                       policy.l_inodebits.bits = MDS_INODELOCK_UPDATE |
+                                                 MDS_INODELOCK_LOOKUP |
+                                                 MDS_INODELOCK_PERM;
+                       break;
                 case IT_LAYOUT:
                         policy.l_inodebits.bits = MDS_INODELOCK_LAYOUT;
                         break;
@@ -1099,6 +1107,7 @@ int mdc_revalidate_lock(struct obd_export *exp, struct lookup_intent *it,
                         policy.l_inodebits.bits = MDS_INODELOCK_LOOKUP;
                         break;
                 }
+
                 mode = ldlm_lock_match(exp->exp_obd->obd_namespace,
                                        LDLM_FL_BLOCK_GRANTED, &res_id,
                                        LDLM_IBITS, &policy,