Whamcloud - gitweb
This patch implements separate function for handling OPEN requests from Lustre client...
authordeen <deen>
Wed, 22 Apr 2009 12:08:34 +0000 (12:08 +0000)
committerdeen <deen>
Wed, 22 Apr 2009 12:08:34 +0000 (12:08 +0000)
NFS servers, named mdt_open_anon_by_fid(). It searches for existing object and, if succeed, takes
an open lock on the object and its attributes. If a client didn't ask for the open lock, it releases
it at the end. We must always take an open lock at the beginning in order to protect object's
attributes.

b=16715
i=oleg.drokin
i=alexey.lyashkov

lustre/mdt/mdt_handler.c
lustre/mdt/mdt_open.c

index 3212962..59c0753 100644 (file)
@@ -3358,7 +3358,6 @@ static int mdt_intent_reint(enum mdt_it_code opcode,
         }
         rep->lock_policy_res2 = clear_serious(rc);
 
-        lhc->mlh_reg_lh.cookie = 0ull;
         if (rc == -ENOTCONN || rc == -ENODEV ||
             rc == -EOVERFLOW) { /**< if VBR failure then return error */
                 /*
@@ -3367,6 +3366,7 @@ static int mdt_intent_reint(enum mdt_it_code opcode,
                  * will detect this, then disconnect, reconnect the import
                  * immediately, instead of impacting the following the rpc.
                  */
+                lhc->mlh_reg_lh.cookie = 0ull;
                 RETURN(rc);
         } else {
                 /*
@@ -3377,7 +3377,14 @@ static int mdt_intent_reint(enum mdt_it_code opcode,
                   * FIXME: when open lock is finished, that should be
                   * checked here.
                   */
-                RETURN(ELDLM_LOCK_ABORTED);
+                if (lustre_handle_is_used(&lhc->mlh_reg_lh)) {
+                        rep->lock_policy_res2 = 0;
+                        rc = mdt_intent_lock_replace(info, lockp, NULL, lhc, flags);
+                        RETURN(rc);
+                } else {
+                        lhc->mlh_reg_lh.cookie = 0ull;
+                        RETURN(ELDLM_LOCK_ABORTED);
+                }
         }
 }
 
index cfa4961..e2bea57 100644 (file)
@@ -809,6 +809,68 @@ static int mdt_open_by_fid(struct mdt_thread_info* info,
         RETURN(rc);
 }
 
+static int mdt_open_anon_by_fid(struct mdt_thread_info* info,
+                                struct ldlm_reply *rep, 
+                                struct mdt_lock_handle *lhc)
+{
+        __u32                    flags = info->mti_spec.sp_cr_flags;
+        struct mdt_reint_record *rr = &info->mti_rr;
+        struct md_attr          *ma = &info->mti_attr;
+        struct mdt_object       *o;
+        int                      rc;
+        ldlm_mode_t              lm;
+        ENTRY;
+
+        o = mdt_object_find(info->mti_env, info->mti_mdt, rr->rr_fid2);
+        if (IS_ERR(o))
+                RETURN(rc = PTR_ERR(o));
+
+        rc = mdt_object_exists(o);
+        if (rc == 0) {
+                mdt_set_disposition(info, rep, (DISP_LOOKUP_EXECD |
+                                    DISP_LOOKUP_NEG));
+                GOTO(out, rc = -ENOENT);
+        } else if (rc < 0) {
+                CERROR("NFS remote open shouldn't happen.\n");
+                GOTO(out, rc);
+        }
+
+        mdt_set_disposition(info, rep, (DISP_IT_EXECD |
+                                        DISP_LOOKUP_EXECD |
+                                        DISP_LOOKUP_POS));
+
+        if (flags & FMODE_WRITE)
+                lm = LCK_CW;
+        else if (flags & MDS_FMODE_EXEC)
+                lm = LCK_PR;
+        else
+                lm = LCK_CR;
+
+        mdt_lock_handle_init(lhc);
+        mdt_lock_reg_init(lhc, lm);
+        rc = mdt_object_lock(info, o, lhc,
+                             MDS_INODELOCK_LOOKUP | MDS_INODELOCK_OPEN,
+                             MDT_CROSS_LOCK);
+        if (rc)
+                GOTO(out, rc);
+
+        rc = mo_attr_get(info->mti_env, mdt_object_child(o), ma);
+        if (rc)
+                GOTO(out, rc);
+
+        if (flags & MDS_OPEN_LOCK)
+                mdt_set_disposition(info, rep, DISP_OPEN_LOCK);
+        rc = mdt_finish_open(info, NULL, o, flags, 0, rep);
+
+        if (!(flags & MDS_OPEN_LOCK))
+                mdt_object_unlock(info, o, lhc, 1);
+
+        GOTO(out, rc);
+out:
+        mdt_object_put(info->mti_env, o);
+        return rc;
+}
+
 int mdt_pin(struct mdt_thread_info* info)
 {
         ENTRY;
@@ -937,6 +999,10 @@ int mdt_reint_open(struct mdt_thread_info *info, struct mdt_lock_handle *lhc)
                 }
                 CDEBUG(D_INFO, "Open replay did find object, continue as "
                        "regular open\n");
+        } else if (rr->rr_namelen == 0 && !info->mti_cross_ref) {
+                result = mdt_open_anon_by_fid(info, ldlm_rep, lhc);
+                if (result != -ENOENT)
+                        GOTO(out, result);
         }
 
         if (OBD_FAIL_CHECK(OBD_FAIL_MDS_OPEN_PACK))