Пример #1
0
static int
check_blocks (const char *file_id, FsckData *fsck_data, gboolean *io_error)
{
    Seafile *seafile;
    int i;
    char *block_id;
    int ret = 0;
    int dummy;

    gboolean ok = TRUE;
    SeafRepo *repo = fsck_data->repo;
    const char *store_id = repo->store_id;
    int version = repo->version;

    seafile = seaf_fs_manager_get_seafile (seaf->fs_mgr, store_id,
                                           version, file_id);

    for (i = 0; i < seafile->n_blocks; ++i) {
        block_id = seafile->blk_sha1s[i];

        if (g_hash_table_lookup (fsck_data->existing_blocks, block_id))
            continue;

        if (!seaf_block_manager_block_exists (seaf->block_mgr,
                                              store_id, version,
                                              block_id)) {
            seaf_warning ("Block %s:%s is missing.\n", store_id, block_id);
            ret = -1;
            break;
        }

        // check block integrity, if not remove it
        ok = seaf_block_manager_verify_block (seaf->block_mgr,
                                              store_id, version,
                                              block_id, io_error);
        if (!ok) {
            if (*io_error) {
                ret = -1;
                break;
            } else {
                if (fsck_data->repair) {
                    seaf_message ("Block %s is corrupted, remove it.\n", block_id);
                    seaf_block_manager_remove_block (seaf->block_mgr,
                                                     store_id, version,
                                                     block_id);
                } else {
                    seaf_message ("Block %s is corrupted.\n", block_id);
                }
                ret = -1;
                break;
            }
        }

        g_hash_table_insert (fsck_data->existing_blocks, g_strdup(block_id), &dummy);
    }

    seafile_unref (seafile);

    return ret;
}
Пример #2
0
static int
check_blocks (VerifyData *data, const char *file_id)
{
    SeafRepo *repo = data->repo;
    Seafile *seafile;
    int i;

    seafile = seaf_fs_manager_get_seafile (seaf->fs_mgr,
                                           repo->store_id,
                                           repo->version,
                                           file_id);
    if (!seafile) {
        seaf_warning ("Failed to find file %s.\n", file_id);
        return -1;
    }

    for (i = 0; i < seafile->n_blocks; ++i) {
        if (!seaf_block_manager_block_exists (seaf->block_mgr,
                                              repo->store_id,
                                              repo->version,
                                              seafile->blk_sha1s[i]))
            g_message ("Block %s is missing.\n", seafile->blk_sha1s[i]);
    }

    seafile_unref (seafile);

    return 0;
}
Пример #3
0
static int
migrate_file_blocks (SeafFSManager *mgr, MigrationData *data, const char *file_id)
{
    SeafRepo *repo = data->repo;
    Seafile *seafile;
    int i;
    char *block_id;

    seafile = seaf_fs_manager_get_seafile (mgr, repo->store_id, repo->version, file_id);
    if (!seafile) {
        seaf_warning ("Failed to find file %s.\n", file_id);
        return -1;
    }

    for (i = 0; i < seafile->n_blocks; ++i) {
        block_id = seafile->blk_sha1s[i];
        if (seaf_block_manager_copy_block (seaf->block_mgr,
                                           repo->store_id, repo->version,
                                           repo->store_id, 1,
                                           block_id) < 0) {
            seaf_warning ("Failed to copy block %s.\n", block_id);
            seafile_unref (seafile);
            return -1;
        }
    }

    seafile_unref (seafile);

    return 0;
}
Пример #4
0
static int
check_blocks (SeafFSManager *mgr, FsckRes *res, const char *file_id)
{
    SeafRepo *repo = res->repo;
    Seafile *seafile;
    int i;
    char *block_id;
    int ret = 0;
    int dummy;
    gboolean io_error = FALSE;
    gboolean ok = TRUE;


    seafile = seaf_fs_manager_get_seafile (mgr, repo->store_id, repo->version, file_id);
    if (!seafile) {
        seaf_warning ("Failed to find file %s.\n", file_id);
        return -1;
    }

    for (i = 0; i < seafile->n_blocks; ++i) {
        block_id = seafile->blk_sha1s[i];

        if (g_hash_table_lookup (res->existing_blocks, block_id))
            continue;

        if (!seaf_block_manager_block_exists (seaf->block_mgr,
                                              repo->store_id, repo->version,
                                              block_id)) {
            seaf_message ("Block %s is missing.\n", block_id);
            ret = -1;
            break;
        }

        // check block integrity, if not remove it
        ok = seaf_block_manager_verify_block (seaf->block_mgr,
                                              repo->store_id, repo->version,
                                              block_id, &io_error);
        if (!ok && !io_error) {
            seaf_message ("Block %s is corrupted, remove it.\n", block_id);
            seaf_block_manager_remove_block (seaf->block_mgr,
                                             repo->store_id, repo->version,
                                             block_id);
            ret = -1;
            break;
        }

        g_hash_table_insert (res->existing_blocks, g_strdup(block_id), &dummy);
    }

    seafile_unref (seafile);

    return ret;
}
Пример #5
0
static int check_seafile (const char *id)
{
    Seafile *seafile;

    seafile = seaf_fs_manager_get_seafile (seaf->fs_mgr, id);
    if (!seafile) {
        fprintf (stderr, "Failed to read seafile %s\n", id);
        return -1;
    }

    seafile_unref (seafile);
    return 0;
}
Пример #6
0
static void
create_file (const char *repo_id,
             const char *file_id,
             const char *path)
{
    int i;
    char *block_id;
    int fd;
    Seafile *seafile;
    gboolean ret = TRUE;
    int version = 1;

    fd = g_open (path, O_CREAT | O_WRONLY | O_BINARY, 0666);
    if (fd < 0) {
        seaf_warning ("Open file %s failed: %s.\n", path, strerror (errno));
        return;
    }

    seafile = seaf_fs_manager_get_seafile (seaf->fs_mgr, repo_id,
                                           version, file_id);
    if (!seafile) {
        ret = FALSE;
        goto out;
    }

    for (i = 0; i < seafile->n_blocks; ++i) {
        block_id = seafile->blk_sha1s[i];

        ret = write_nonenc_block_to_file (repo_id, version, block_id,
                                          fd, path);
        if (!ret) {
            break;
        }
    }

out:
    close (fd);
    if (!ret) {
        if (g_unlink (path) < 0) {
            seaf_warning ("Failed to delete file %s: %s.\n", path, strerror (errno));
        }
        seaf_message ("Failed to export file %s.\n", path);
    } else {
        seaf_message ("Export file %s.\n", path);
    }
    seafile_unref (seafile);
}
Пример #7
0
void
fill_seafile_blocks (const unsigned char *sha1, BlockList *bl)
{
    char file_id[41];
    Seafile *seafile;
    int i;

    rawdata_to_hex (sha1, file_id, 20);
    seafile = seaf_fs_manager_get_seafile (seaf->fs_mgr, file_id);
    if (!seafile) {
        g_warning ("Failed to find file %s.\n", file_id);
        return;
    }

    for (i = 0; i < seafile->n_blocks; ++i)
        block_list_insert (bl, seafile->blk_sha1s[i]);

    seafile_unref (seafile);
}
Пример #8
0
static int
check_blocks (SeafFSManager *mgr, const char *file_id)
{
    Seafile *seafile;
    int i;

    seafile = seaf_fs_manager_get_seafile (mgr, file_id);
    if (!seafile) {
        seaf_warning ("Failed to find file %s.\n", file_id);
        return -1;
    }

    for (i = 0; i < seafile->n_blocks; ++i) {
        if (!seaf_block_manager_block_exists (seaf->block_mgr,
                                              seafile->blk_sha1s[i]))
            g_message ("Block %s is missing.\n", seafile->blk_sha1s[i]);
    }

    seafile_unref (seafile);

    return 0;
}
Пример #9
0
static int seaf_fuse_read(const char *path, char *buf, size_t size,
                          off_t offset, struct fuse_file_info *info)
{
    int n_parts;
    char *user, *repo_id, *repo_path;
    SeafRepo *repo = NULL;
    SeafBranch *branch = NULL;
    SeafCommit *commit = NULL;
    Seafile *file = NULL;
    char *file_id = NULL;
    int ret = 0;

    /* Now we only support read-only mode */
    if ((info->flags & 3) != O_RDONLY)
        return -EACCES;

    if (parse_fuse_path (path, &n_parts, &user, &repo_id, &repo_path) < 0) {
        seaf_warning ("Invalid input path %s.\n", path);
        return -ENOENT;
    }

    if (n_parts != 2 && n_parts != 3) {
        seaf_warning ("Invalid input path for open: %s.\n", path);
        ret = -EACCES;
        goto out;
    }

    repo = seaf_repo_manager_get_repo(seaf->repo_mgr, repo_id);
    if (!repo) {
        seaf_warning ("Failed to get repo %s.\n", repo_id);
        ret = -ENOENT;
        goto out;
    }

    branch = repo->head;
    commit = seaf_commit_manager_get_commit(seaf->commit_mgr,
                                            repo->id,
                                            repo->version,
                                            branch->commit_id);
    if (!commit) {
        seaf_warning ("Failed to get commit %s:%.8s.\n", repo->id, branch->commit_id);
        ret = -ENOENT;
        goto out;
    }

    file_id = seaf_fs_manager_get_seafile_id_by_path(seaf->fs_mgr,
                                                     repo->store_id, repo->version,
                                                     commit->root_id,
                                                     repo_path, NULL);
    if (!file_id) {
        seaf_warning ("Path %s doesn't exist in repo %s.\n", repo_path, repo_id);
        ret = -ENOENT;
        goto out;
    }

    file = seaf_fs_manager_get_seafile(seaf->fs_mgr,
                                       repo->store_id, repo->version, file_id);
    if (!file) {
        ret = -ENOENT;
        goto out;
    }

    ret = read_file(seaf, repo->store_id, repo->version,
                    file, buf, size, offset, info);
    seafile_unref (file);

out:
    g_free (user);
    g_free (repo_id);
    g_free (repo_path);
    g_free (file_id);
    seaf_repo_unref (repo);
    seaf_commit_unref (commit);
    return ret;
}
Пример #10
0
static int getattr_repo(SeafileSession *seaf,
                        const char *user, const char *repo_id, const char *repo_path,
                        struct stat *stbuf)
{
    SeafRepo *repo = NULL;
    SeafBranch *branch;
    SeafCommit *commit = NULL;
    guint32 mode = 0;
    char *id = NULL;
    int ret = 0;

    repo = seaf_repo_manager_get_repo(seaf->repo_mgr, repo_id);
    if (!repo) {
        seaf_warning ("Failed to get repo %s.\n", repo_id);
        ret = -ENOENT;
        goto out;
    }

    branch = repo->head;
    commit = seaf_commit_manager_get_commit(seaf->commit_mgr, branch->commit_id);
    if (!commit) {
        seaf_warning ("Failed to get commit %.8s.\n", branch->commit_id);
        ret = -ENOENT;
        goto out;
    }

    id = seaf_fs_manager_path_to_obj_id(seaf->fs_mgr, commit->root_id,
                                        repo_path, &mode, NULL);
    if (!id) {
        seaf_warning ("Path %s doesn't exist in repo %s.\n", repo_path, repo_id);
        ret = -ENOENT;
        goto out;
    }

    if (S_ISDIR(mode)) {
        SeafDir *dir;
        GList *l;
        int cnt = 2; /* '.' and '..' */

        dir = seaf_fs_manager_get_seafdir(seaf->fs_mgr, id);
        if (dir) {
            for (l = dir->entries; l; l = l->next)
                cnt++;
        }

        stbuf->st_size += cnt * sizeof(SeafDirent);
        stbuf->st_mode = mode | 0755;
        stbuf->st_nlink = 2;

        seaf_dir_free (dir);
    } else if (S_ISREG(mode)) {
        Seafile *file;

        file = seaf_fs_manager_get_seafile(seaf->fs_mgr, id);
        if (file)
            stbuf->st_size = file->file_size;

        stbuf->st_mode = mode | 0644;
        stbuf->st_nlink = 1;

        seafile_unref (file);
    } else {
        return -ENOENT;
    }

out:
    g_free (id);
    seaf_repo_unref (repo);
    seaf_commit_unref (commit);
    return ret;
}