Whamcloud - gitweb
- additional debug to catch the case when client gets openhandle w/o capa
[fs/lustre-release.git] / lustre / llite / llite_capa.c
index 3f670d8..e9296b1 100644 (file)
@@ -43,21 +43,28 @@ static struct thread_ctl {
 static inline int have_expired_capa(void)
 {
         struct obd_capa *ocapa;
+        struct lustre_capa *capa;
         int expired = 0;
         unsigned long expiry;
+        struct timeval tv;
+
         ENTRY;
 
+        do_gettimeofday(&tv);
         spin_lock(&capa_lock);
         if (!list_empty(ll_capa_list)) {
                 ocapa = list_entry(ll_capa_list->next, struct obd_capa, c_list);
-
-                expired = __capa_is_to_expire(ocapa);
-                if (!expired && !timer_pending(&ll_capa_timer)) {
-                        /* the expired capa has been put, so set the timer to
-                         * the expired of the next capa */
-                        expiry = expiry_to_jiffies(ocapa->c_capa.lc_expiry);
-                        mod_timer(&ll_capa_timer, expiry);
-                        CDEBUG(D_INFO, "ll_capa_timer new expiry: %lu\n", expiry);
+                expired = __capa_is_to_expire(ocapa, &tv);
+                if (!expired) {
+                        capa = &ocapa->c_capa;
+                        expiry = expiry_to_jiffies(capa->lc_expiry -
+                                                   capa_pre_expiry(capa));
+                        if (time_before(expiry, ll_capa_timer.expires) ||
+                            !timer_pending(&ll_capa_timer)) {
+                                mod_timer(&ll_capa_timer, expiry);
+                                CDEBUG(D_INFO,"ll_capa_timer new expiry: %lu\n",
+                                       expiry);
+                        }
                 }
         }
         spin_unlock(&capa_lock);
@@ -81,14 +88,6 @@ static int ll_renew_capa(struct obd_capa *ocapa)
         int rc;
         ENTRY;
 
-        if (capa_expired(&ocapa->c_capa)) {
-                /* this is the second time try to renew since the last
-                 * renewal failed, it means on one is openning it and
-                 * should be put now. */
-                capa_put(ocapa);
-                RETURN(0);
-        }
-
         rc = md_getattr(md_exp, &lli->lli_id, valid, NULL, NULL, 0,
                         0, ocapa, &req);
         RETURN(rc);
@@ -98,6 +97,7 @@ static int ll_capa_thread(void *arg)
 {
         struct thread_ctl *ctl = arg;
         unsigned long flags;
+        int rc;
         ENTRY;
 
         {
@@ -120,8 +120,10 @@ static int ll_capa_thread(void *arg)
 
         while (1) {
                 struct l_wait_info lwi = { 0 };
-                struct obd_capa *ocapa, *next = NULL, tcapa;
+                struct obd_capa *ocapa, tcapa, *tmp, *next = NULL;
                 unsigned long expiry, sleep = CAPA_PRE_EXPIRY;
+                struct inode *inode;
+                struct timeval tv;
 
                 l_wait_event(capa_thread.t_ctl_waitq,
                              (have_expired_capa() || ll_capa_check_stop()),
@@ -130,17 +132,33 @@ static int ll_capa_thread(void *arg)
                 if (ll_capa_check_stop())
                         break;
 
+                do_gettimeofday(&tv);
                 spin_lock(&capa_lock);
-                list_for_each_entry(ocapa, ll_capa_list, c_list) {
+                list_for_each_entry_safe(ocapa, tmp, ll_capa_list, c_list) {
+                        if (ocapa->c_capa.lc_flags & CAPA_FL_SHORT)
+                                sleep = CAPA_PRE_EXPIRY_SHORT;
+
                         if (ocapa->c_capa.lc_op == CAPA_TRUNC)
                                 continue;
 
-                        if (__capa_is_to_expire(ocapa)) {
-                                /* copy capa in case it's deleted */
+                        if (capa_expired(&ocapa->c_capa)) {
+                                capa_put_nolock(ocapa);
+                                continue;
+                        }
+
+                        if (__capa_is_to_expire(ocapa, &tv)) {
+                                inode = igrab(ocapa->c_inode);
+                                if (inode == NULL) {
+                                        DEBUG_CAPA(D_ERROR, &ocapa->c_capa,
+                                                   "igrab failed for");
+                                        continue;
+                                }
+
                                 tcapa = *ocapa;
                                 spin_unlock(&capa_lock);
 
-                                ll_renew_capa(&tcapa);
+                                rc = ll_renew_capa(&tcapa);
+                                iput(inode);
 
                                 spin_lock(&capa_lock);
                         } else {
@@ -148,12 +166,18 @@ static int ll_capa_thread(void *arg)
                                 break;
                         }
                 }
+
                 if (next) {
-                        expiry = expiry_to_jiffies(next->c_capa.lc_expiry);
-                        mod_timer(&ll_capa_timer, expiry);
-                        CDEBUG(D_INFO, "ll_capa_timer new expiry: %lu\n", expiry);
-                        if (next->c_capa.lc_flags & CAPA_FL_NOROUND)
-                                sleep = CAPA_PRE_EXPIRY_NOROUND;
+                        struct lustre_capa *capa = &next->c_capa;
+
+                        expiry = expiry_to_jiffies(capa->lc_expiry -
+                                                   capa_pre_expiry(capa));
+                        if (time_before(expiry, ll_capa_timer.expires) ||
+                            !timer_pending(&ll_capa_timer)) {
+                                mod_timer(&ll_capa_timer, expiry);
+                                CDEBUG(D_INFO,"ll_capa_timer new expiry: %lu\n",
+                                       expiry);
+                        }
                 }
                 spin_unlock(&capa_lock);
 
@@ -212,7 +236,8 @@ void ll_capa_thread_stop(void)
         EXIT;
 }
 
-int ll_set_capa(struct inode *inode, struct lookup_intent *it)
+int ll_set_capa(struct inode *inode, struct lookup_intent *it,
+                struct obd_client_handle *och)
 {
         struct ptlrpc_request *req = LUSTRE_IT(it)->it_data;
         struct mds_body *body;
@@ -224,12 +249,23 @@ int ll_set_capa(struct inode *inode, struct lookup_intent *it)
         if (!S_ISREG(inode->i_mode))
                 return 0;
 
+        /* GNS code path will have no req */
+        if (!req)
+                return 0;
+
         body = lustre_msg_buf(req->rq_repmsg, 1, sizeof (*body));
         LASSERT(body != NULL);          /* reply already checked out */
         LASSERT_REPSWABBED(req, 1);     /* and swabbed down */
 
-        if (!(body->valid & OBD_MD_CAPA))
+        if (!(body->valid & OBD_MD_CAPA)) {
+                if (atomic_read(&ll_capa_stat))
+                        DEBUG_REQ(D_ERROR, req,
+                                  "no capa for (uid %u, op %d, "DLID4"\n",
+                                   (unsigned)current->uid, it->it_flags,
+                                   OLID4(&lli->lli_id));
+
                 return 0;
+        }
 
         ENTRY;
 
@@ -243,7 +279,7 @@ int ll_set_capa(struct inode *inode, struct lookup_intent *it)
 
         spin_lock(&capa_lock);
         ocapa->c_inode = inode;
-        ocapa->c_handle = body->handle;
+        ocapa->c_handle = och->och_fh;
         spin_unlock(&capa_lock);
 
         spin_lock(&lli->lli_lock);
@@ -312,6 +348,14 @@ struct obd_capa *ll_get_capa(struct inode *inode, uid_t uid, int op)
 
                 RETURN(ocapa);
         }
+
+        if (atomic_read(&ll_capa_stat)) {
+                CDEBUG(D_ERROR, "can't find capa for (uid %u, op %d, mdsid "
+                       LPU64", ino %u igen %u) failed.\n",
+                       (unsigned)uid, op, id_group(&lli->lli_id),
+                       (unsigned)id_ino(&lli->lli_id), id_gen(&lli->lli_id));
+                atomic_set(&ll_capa_stat, 0);
+        }
         
         RETURN(NULL);
 }