static void process_commit_list (CcnetProcessor *processor, char *content, int clen) { USE_PRIV; char *object_id; int n_objects; int i; if (clen % 41 != 1 || content[clen-1] != '\0') { g_warning ("[getcommit] Bad commit id list.\n"); ccnet_processor_send_update (processor, SC_BAD_OL, SS_BAD_OL, NULL, 0); transfer_task_set_error (((SeafileGetcommitProc *)processor)->tx_task, TASK_ERR_DOWNLOAD_COMMIT); ccnet_processor_done (processor, FALSE); return; } n_objects = clen/41; request_object_batch_begin(priv); object_id = content; for (i = 0; i < n_objects; ++i) { object_id[40] = '\0'; check_commit (processor, object_id); object_id += 41; } request_object_batch_flush (processor, priv); if (priv->pending_objects == 0) { ccnet_processor_send_update (processor, SC_END, SS_END, NULL, 0); ccnet_processor_done (processor, TRUE); } }
inline static void request_object_batch (CcnetProcessor *processor, SeafileRecvfsProcPriv *priv, const char *id) { memcpy (priv->bufptr, id, 40); priv->bufptr += 40; *priv->bufptr = '\n'; priv->bufptr++; /* Flush when too many objects batched. */ if (++priv->n_batch == MAX_NUM_BATCH) request_object_batch_flush (processor, priv); ++priv->pending_objects; }
static int check_end_condition (CcnetProcessor *processor) { USE_PRIV; char *dir_id; while (priv->checking_dirs < MAX_CHECKING_DIRS) { dir_id = g_queue_pop_head (priv->dir_queue); if (!dir_id) break; #ifdef DEBUG seaf_debug ("[recvfs] Inspect dir %s.\n", dir_id); #endif if (seaf_obj_store_async_read (seaf->fs_mgr->obj_store, priv->reader_id, dir_id) < 0) { seaf_warning ("[recvfs] Failed to start async read of %s.\n", dir_id); ccnet_processor_send_response (processor, SC_BAD_OBJECT, SS_BAD_OBJECT, NULL, 0); ccnet_processor_done (processor, FALSE); return FALSE; } g_free (dir_id); ++(priv->inspect_objects); ++(priv->checking_dirs); } if (priv->checking_dirs > 100) seaf_debug ("Number of checking dirs: %d.\n", priv->checking_dirs); if (priv->inspect_objects > 1000) seaf_debug ("Number of inspect objects: %d.\n", priv->inspect_objects); /* Flush periodically. */ request_object_batch_flush (processor, priv); if (priv->pending_objects == 0 && priv->inspect_objects == 0) { seaf_debug ("Recv fs end.\n"); ccnet_processor_send_response (processor, SC_END, SS_END, NULL, 0); ccnet_processor_done (processor, TRUE); return FALSE; } else return TRUE; }
static int check_object (CcnetProcessor *processor) { USE_PRIV; char *obj_id; SeafDir *dir; static int i = 0; request_object_batch_begin(priv); /* process inspect queue */ /* Note: All files in a directory must be checked in an iteration, * so we may send out more items than REQUEST_THRESHOLD */ while (g_hash_table_size (priv->fs_objects) < MAX_NUM_UNREVD) { obj_id = (char *) g_queue_pop_head (priv->inspect_queue); if (obj_id == NULL) break; if (!seaf_fs_manager_object_exists(seaf->fs_mgr, obj_id)) { request_object_batch (processor, priv, obj_id); } else { dir = seaf_fs_manager_get_seafdir (seaf->fs_mgr, obj_id); if (!dir) { /* corrupt dir object */ request_object_batch (processor, priv, obj_id); } else { check_seafdir(processor, dir); seaf_dir_free (dir); } } g_free (obj_id); /* free the memory */ } request_object_batch_flush (processor, priv); /* check end condition */ if (i%10 == 0) seaf_debug ("[getfs] pending objects num: %d\n", priv->pending_objects); ++i; if (priv->pending_objects == 0 && g_queue_is_empty(priv->inspect_queue)) { ccnet_processor_send_update (processor, SC_END, SS_END, NULL, 0); ccnet_processor_done (processor, TRUE); return FALSE; } else return TRUE; }
inline static void request_object_batch (CcnetProcessor *processor, SeafileGetfsProcPriv *priv, const char *id) { g_assert(priv->bufptr - priv->buf <= (4096-41)); if (g_hash_table_lookup(priv->fs_objects, id)) return; memcpy (priv->bufptr, id, 40); priv->bufptr += 40; *priv->bufptr = '\n'; priv->bufptr++; g_hash_table_insert (priv->fs_objects, g_strdup(id), (gpointer)1); if (++priv->n_batch == MAX_NUM_BATCH) request_object_batch_flush (processor, priv); ++priv->pending_objects; }
static void check_objects_done (void *vdata) { CcnetProcessor *processor = vdata; USE_PRIV; GList *ptr; char *obj_id; priv->worker_running = FALSE; request_object_batch_begin (priv); for (ptr = priv->fetch_objs; ptr; ptr = ptr->next) { obj_id = ptr->data; request_object_batch (processor, priv, obj_id); g_free (obj_id); } request_object_batch_flush (processor, priv); g_list_free (priv->fetch_objs); priv->fetch_objs = NULL; end_or_check_next_dir (processor, priv); }