/* * Recursively check fs tree rooted at @dir_id. This function returns when * all non-existent or invalid objects have been put into data->fetch_objs. */ static void check_seafdir (CcnetProcessor *processor, const char *dir_id) { SeafileGetfsProc *proc = (SeafileGetfsProc *)processor; USE_PRIV; SeafDir *dir = NULL; GList *ptr; SeafDirent *dent; if (!seaf_fs_manager_object_exists(seaf->fs_mgr, dir_id)) { priv->fetch_objs = g_list_prepend (priv->fetch_objs, g_strdup(dir_id)); return; } dir = seaf_fs_manager_get_seafdir (seaf->fs_mgr, dir_id); if (!dir) { /* corrupt dir object */ priv->fetch_objs = g_list_prepend (priv->fetch_objs, g_strdup(dir_id)); return; } for (ptr = dir->entries; ptr; ptr = ptr->next) { dent = ptr->data; /* Don't check objects that have been checked before. */ if (g_hash_table_lookup (priv->fs_objects, dent->id)) continue; g_hash_table_insert (priv->fs_objects, g_strdup(dent->id), (gpointer)1); if (!seaf_fs_manager_object_exists(seaf->fs_mgr, dent->id)) { priv->fetch_objs = g_list_prepend (priv->fetch_objs, g_strdup(dent->id)); continue; } if (S_ISDIR(dent->mode)) { check_seafdir (processor, dent->id); } else if (S_ISREG (dent->mode) && proc->tx_task->is_clone) { /* Only check seafile object integrity when clone. * This is for the purpose of recovery. * In ordinary sync, checking every file object's integrity would * take too much CPU time. */ gboolean ok; gboolean err = FALSE; ok = seaf_fs_manager_verify_seafile (seaf->fs_mgr, dent->id, TRUE, &err); if (!ok && !err) { seaf_warning ("File object %.8s is corrupt, recover from server.\n", dent->id); priv->fetch_objs = g_list_prepend (priv->fetch_objs, g_strdup(dent->id)); } } } seaf_dir_free (dir); }
static gboolean fsck_verify_seafobj (const char *store_id, int version, const char *obj_id, gboolean *io_error, VerifyType type, gboolean repair) { gboolean valid = TRUE; valid = seaf_fs_manager_object_exists (seaf->fs_mgr, store_id, version, obj_id); if (!valid) { if (type == VERIFY_FILE) { seaf_message ("File %s is missing.\n", obj_id); } else if (type == VERIFY_DIR) { seaf_message ("Dir %s is missing.\n", obj_id); } return valid; } if (type == VERIFY_FILE) { valid = seaf_fs_manager_verify_seafile (seaf->fs_mgr, store_id, version, obj_id, TRUE, io_error); if (!valid && !*io_error && repair) { seaf_message ("File %s is corrupted, remove it.\n", obj_id); seaf_fs_manager_delete_object (seaf->fs_mgr, store_id, version, obj_id); } } else if (type == VERIFY_DIR) { valid = seaf_fs_manager_verify_seafdir (seaf->fs_mgr, store_id, version, obj_id, TRUE, io_error); if (!valid && !*io_error && repair) { seaf_message ("Dir %s is corrupted, remove it.\n", obj_id); seaf_fs_manager_delete_object (seaf->fs_mgr, store_id, version, obj_id); } } return valid; }