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 4f34a80..e9296b1 100644 (file)
@@ -46,12 +46,15 @@ static inline int have_expired_capa(void)
         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);
+                expired = __capa_is_to_expire(ocapa, &tv);
                 if (!expired) {
                         capa = &ocapa->c_capa;
                         expiry = expiry_to_jiffies(capa->lc_expiry -
@@ -85,9 +88,6 @@ static int ll_renew_capa(struct obd_capa *ocapa)
         int rc;
         ENTRY;
 
-        if (capa_expired(&ocapa->c_capa))
-                RETURN(-ESTALE);
-
         rc = md_getattr(md_exp, &lli->lli_id, valid, NULL, NULL, 0,
                         0, ocapa, &req);
         RETURN(rc);
@@ -120,8 +120,10 @@ static int ll_capa_thread(void *arg)
 
         while (1) {
                 struct l_wait_info lwi = { 0 };
-                struct obd_capa *ocapa, *tmp, *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,6 +132,7 @@ static int ll_capa_thread(void *arg)
                 if (ll_capa_check_stop())
                         break;
 
+                do_gettimeofday(&tv);
                 spin_lock(&capa_lock);
                 list_for_each_entry_safe(ocapa, tmp, ll_capa_list, c_list) {
                         if (ocapa->c_capa.lc_flags & CAPA_FL_SHORT)
@@ -138,14 +141,24 @@ static int ll_capa_thread(void *arg)
                         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);
 
                                 rc = ll_renew_capa(&tcapa);
-                                if (rc)
-                                        capa_put(ocapa);
+                                iput(inode);
 
                                 spin_lock(&capa_lock);
                         } else {
@@ -244,8 +257,15 @@ int ll_set_capa(struct inode *inode, struct lookup_intent *it,
         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;
 
@@ -328,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);
 }