Whamcloud - gitweb
Branch: b_new_cmd
authorwangdi <wangdi>
Thu, 10 Aug 2006 03:47:20 +0000 (03:47 +0000)
committerwangdi <wangdi>
Thu, 10 Aug 2006 03:47:20 +0000 (03:47 +0000)
Sometimes, we need revalidate dentries with (IT_CREATE/IT_OPEN), since
we did not unhash the cache totally on client for getpwd(2). so in
ll_revalidate_it we also need allocate the fid. If in mds, it did create
an object. then the dentry should be invalidate(return -ESTALE).
and some related cleanup work should be done in ll_revalidate_finish_it.

lustre/llite/dcache.c

index ad565ae..ff54e9f 100644 (file)
@@ -259,8 +259,30 @@ int ll_revalidate_it_finish(struct ptlrpc_request *request,
         if (!request)
                 RETURN(0);
 
-        if (it_disposition(it, DISP_LOOKUP_NEG))
+        if (it_disposition(it, DISP_LOOKUP_NEG)) {
+                /*Sometimes, revalidate_it might also create node in MDS,
+                 *So we need check whether it is really created, if not,
+                 *just return the -ENOENT, if it is, return -ESTALE anyway.
+                 *which is original done in mdc_intent_lock, 
+                 *but no chance for new fid allocation in client. 
+                 */
+                if (it_disposition(it, DISP_OPEN_CREATE) && 
+                    !it_open_error(DISP_OPEN_CREATE, it)) {
+                         /*These 2 req finished is for balancing 2 add ref
+                          *in mdc_intent_lock, since there are no create_node
+                          *and file_open following revalidate_it*/
+                         it_set_disposition(it, DISP_ENQ_COMPLETE);
+                         if (it_disposition(it, DISP_OPEN_CREATE) &&
+                            !it_open_error(DISP_OPEN_CREATE, it))
+                                ptlrpc_req_finished(request); 
+                         if (it_disposition(it, DISP_OPEN_OPEN) &&
+                            !it_open_error(DISP_OPEN_OPEN, it))
+                                ptlrpc_req_finished(request); 
+                        
+                         RETURN(-ESTALE);
+                }
                 RETURN(-ENOENT);
+        }
 
         rc = ll_prep_inode(&de->d_inode,
                            request, offset, NULL);
@@ -350,9 +372,22 @@ int ll_revalidate_it(struct dentry *de, int lookup_flags,
         OBD_ALLOC_PTR(op_data);
         if (op_data == NULL)
                 RETURN(-ENOMEM);
-
-        ll_prepare_md_op_data(op_data, parent, de->d_inode,
+        
+        ll_prepare_md_op_data(op_data, parent, NULL,
                               de->d_name.name, de->d_name.len, 0);
+        if (it->it_op & IT_CREAT ||
+            (it->it_op & IT_OPEN && it->it_create_mode & O_CREAT)) {
+                struct lu_placement_hint hint = { .ph_pname = NULL,
+                                          .ph_cname = &de->d_name,
+                                          .ph_opc = LUSTRE_OPC_CREATE };
+
+                rc = ll_fid_md_alloc(ll_i2sbi(parent), &op_data->fid2, 
+                                     &hint);
+                if (rc) {
+                        CERROR("can't allocate new fid, rc %d\n", rc);
+                        LBUG();
+                }
+        }
 
         rc = md_intent_lock(exp, op_data, NULL, 0, it, lookup_flags,
                             &req, ll_md_blocking_ast, 0);
@@ -360,8 +395,9 @@ int ll_revalidate_it(struct dentry *de, int lookup_flags,
         OBD_FREE_PTR(op_data);
         /* If req is NULL, then md_intent_lock only tried to do a lock match;
          * if all was well, it will return 1 if it found locks, 0 otherwise. */
-        if (req == NULL && rc >= 0)
+        if (req == NULL && rc >= 0) {
                 GOTO(out, rc);
+        }
 
         if (rc < 0) {
                 if (rc != -ESTALE) {
@@ -373,7 +409,8 @@ int ll_revalidate_it(struct dentry *de, int lookup_flags,
 
         rc = ll_revalidate_it_finish(req, 1, it, de);
         if (rc != 0) {
-                ll_intent_release(it);
+                if (rc != -ESTALE) 
+                        ll_intent_release(it);
                 GOTO(out, rc = 0);
         }
         if ((it->it_op & IT_OPEN) && de->d_inode &&