Whamcloud - gitweb
LU-6714 llog: fix wrong offset in llog_process_thread()
[fs/lustre-release.git] / lustre / obdclass / llog_cat.c
index c8c2da3..e1ad2cd 100644 (file)
@@ -72,6 +72,14 @@ static int llog_cat_new_log(const struct lu_env *env,
        if (OBD_FAIL_CHECK(OBD_FAIL_MDS_LLOG_CREATE_FAILED))
                RETURN(-ENOSPC);
 
+       if (loghandle->lgh_hdr != NULL) {
+               /* If llog object is remote and creation is failed, lgh_hdr
+                * might be left over here, free it first */
+               LASSERT(!llog_exist(loghandle));
+               OBD_FREE_PTR(loghandle->lgh_hdr);
+               loghandle->lgh_hdr = NULL;
+       }
+
        rc = llog_create(env, loghandle, th);
        /* if llog is already created, no need to initialize it */
        if (rc == -EEXIST) {
@@ -256,7 +264,7 @@ static struct llog_handle *llog_cat_current_log(struct llog_handle *cathandle,
                down_write_nested(&loghandle->lgh_lock, LLOGH_LOG);
                llh = loghandle->lgh_hdr;
                if (llh == NULL ||
-                   loghandle->lgh_last_idx < LLOG_BITMAP_SIZE(llh) - 1) {
+                   loghandle->lgh_last_idx < LLOG_HDR_BITMAP_SIZE(llh) - 1) {
                        up_read(&cathandle->lgh_lock);
                         RETURN(loghandle);
                 } else {
@@ -276,12 +284,12 @@ static struct llog_handle *llog_cat_current_log(struct llog_handle *cathandle,
                down_write_nested(&loghandle->lgh_lock, LLOGH_LOG);
                llh = loghandle->lgh_hdr;
                LASSERT(llh);
-                if (loghandle->lgh_last_idx < LLOG_BITMAP_SIZE(llh) - 1) {
+               if (loghandle->lgh_last_idx < LLOG_HDR_BITMAP_SIZE(llh) - 1) {
                        up_write(&cathandle->lgh_lock);
-                        RETURN(loghandle);
-                } else {
+                       RETURN(loghandle);
+               } else {
                        up_write(&loghandle->lgh_lock);
-                }
+               }
         }
 
        CDEBUG(D_INODE, "use next log\n");
@@ -308,7 +316,7 @@ int llog_cat_add_rec(const struct lu_env *env, struct llog_handle *cathandle,
         int rc;
         ENTRY;
 
-        LASSERT(rec->lrh_len <= LLOG_CHUNK_SIZE);
+       LASSERT(rec->lrh_len <= cathandle->lgh_ctxt->loc_chunk_size);
        loghandle = llog_cat_current_log(cathandle, th);
        LASSERT(!IS_ERR(loghandle));
 
@@ -740,33 +748,40 @@ int llog_cat_reverse_process(const struct lu_env *env,
 }
 EXPORT_SYMBOL(llog_cat_reverse_process);
 
-static int llog_cat_set_first_idx(struct llog_handle *cathandle, int index)
+static int llog_cat_set_first_idx(struct llog_handle *cathandle, int idx)
 {
-        struct llog_log_hdr *llh = cathandle->lgh_hdr;
-        int i, bitmap_size, idx;
-        ENTRY;
+       struct llog_log_hdr *llh = cathandle->lgh_hdr;
+       int bitmap_size;
 
-        bitmap_size = LLOG_BITMAP_SIZE(llh);
-        if (llh->llh_cat_idx == (index - 1)) {
-                idx = llh->llh_cat_idx + 1;
-                llh->llh_cat_idx = idx;
-                if (idx == cathandle->lgh_last_idx)
-                        goto out;
-                for (i = (index + 1) % bitmap_size;
-                     i != cathandle->lgh_last_idx;
-                     i = (i + 1) % bitmap_size) {
-                        if (!ext2_test_bit(i, llh->llh_bitmap)) {
-                                idx = llh->llh_cat_idx + 1;
-                                llh->llh_cat_idx = idx;
-                        } else if (i == 0) {
-                                llh->llh_cat_idx = 0;
-                        } else {
-                                break;
-                        }
-                }
-out:
-               CDEBUG(D_RPCTRACE, "set catlog "DOSTID" first idx %u\n",
-                      POSTID(&cathandle->lgh_id.lgl_oi), llh->llh_cat_idx);
+       ENTRY;
+
+       bitmap_size = LLOG_HDR_BITMAP_SIZE(llh);
+       /*
+        * The llh_cat_idx equals to the first used index minus 1
+        * so if we canceled the first index then llh_cat_idx
+        * must be renewed.
+        */
+       if (llh->llh_cat_idx == (idx - 1)) {
+               llh->llh_cat_idx = idx;
+
+               do {
+                       idx = (idx + 1) % bitmap_size;
+                       if (!ext2_test_bit(idx, LLOG_HDR_BITMAP(llh))) {
+                               /* update llh_cat_idx for each unset bit,
+                                * expecting the*/
+                               llh->llh_cat_idx = idx;
+                       } else if (idx == 0) {
+                               /* skip header bit */
+                               continue;
+                       } else {
+                               /* the first index is found */
+                               break;
+                       }
+               } while (idx != cathandle->lgh_last_idx);
+
+               CDEBUG(D_RPCTRACE, "Set catlog "DOSTID" first idx %u,"
+                      " (last_idx %u)\n", POSTID(&cathandle->lgh_id.lgl_oi),
+                      llh->llh_cat_idx, cathandle->lgh_last_idx);
        }
 
        RETURN(0);