diff --git a/include/Makefile.am b/include/Makefile.am index aabd461..a0aac7d 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -1,6 +1,4 @@ seafiledir = $(includedir)/seafile -noinst_HEADERS = seafile-error.h - -seafile_HEADERS = seafile-rpc.h monitor-rpc.h seafile.h +seafile_HEADERS = seafile-rpc.h seafile-error.h diff --git a/include/monitor-rpc.h b/include/monitor-rpc.h deleted file mode 100644 index 81814cc..0000000 --- a/include/monitor-rpc.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef MONITOR_RPC_H -#define MONITOR_RPC_H - -/** - * monitor_compute_repo_size: - * @repo_id: repo id - * - * Returns 0 if successfully scheduled computation. - */ -int -monitor_compute_repo_size (const char *repo_id, GError **error); - -#endif diff --git a/include/seafile-error.h b/include/seafile-error.h index 058c6e9..8cb09ab 100644 --- a/include/seafile-error.h +++ b/include/seafile-error.h @@ -19,4 +19,8 @@ #define SEAF_ERR_DIR_MISSING 515 #define SEAF_ERR_PATH_NO_EXIST 516 /* the dir or file pointed by this path not exists */ +#define POST_FILE_ERR_FILENAME 517 +#define POST_FILE_ERR_BLOCK_MISSING 518 +#define POST_FILE_ERR_QUOTA_FULL 519 + #endif diff --git a/include/seafile.h b/include/seafile.h deleted file mode 100644 index 7884e7d..0000000 --- a/include/seafile.h +++ /dev/null @@ -1,187 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#ifndef SEAFILE_H -#define SEAFILE_H - -char * -seafile_create_repo (SearpcClient *client, - const gchar *name, - const gchar *description, - const gchar *worktree, - const gchar *passwd, - const gchar *relay_id, - int keep_local_history, GError **error); - -int -seafile_create_repo_async (SearpcClient *client, - const gchar *name, - const gchar *description, - const gchar *worktree, - const gchar *passwd, - const gchar *relay_id, - int keep_local_history, - AsyncCallback callback, void *user_data); - -int seafile_destroy_repo (SearpcClient *client, - const char *repo_id, GError **error); - -int seafile_set_repo_token (SearpcClient *client, - const char *repo_id, - const char *token, - GError **error); - -char * -seafile_get_repo_token (SearpcClient *client, - const char *repo_id, - GError **error); - - -int -seafile_set_repo_property (SearpcClient *client, - const char *repo_id, - const char *key, - const char *value, - GError **error); - -GList * -seafile_get_repo_list (SearpcClient *client, - int offset, - int limit, GError **error); - -GObject * -seafile_get_repo (SearpcClient *client, - const char *repo_id, - GError **error); - - -char *seafile_get_config (SearpcClient *client, const char *key, GError **error); - -int seafile_get_config_async (SearpcClient *client, const char *key, - AsyncCallback callback, void *user_data); - -int seafile_set_config_async (SearpcClient *client, - const char *key, const char *value, - AsyncCallback callback, void *user_data); - -int seafile_calc_dir_size (SearpcClient *client, const char *path, GError **error); - - -/* server */ -int seafile_add_chunk_server (SearpcClient *client, const char *server_id, - GError **error); -int seafile_del_chunk_server (SearpcClient *client, const char *server_id, - GError **error); -char *seafile_list_chunk_servers (SearpcClient *client, GError **error); - -char * -seafile_repo_query_access_property (SearpcClient *client, - const char *repo_id, - GError **error); - -GObject * -seafile_web_query_access_token (SearpcClient *client, - const char *token, - GError **error); - -GObject * -seafile_get_decrypt_key (SearpcClient *client, - const char *repo_id, - const char *user, - GError **error); - -char * -seafile_put_file (SearpcClient *client, - const char *repo_id, - const char *file_path, - const char *parent_dir, - const char *file_name, - const char *user, - const char *head_id, - GError **error); - -char * -seafile_put_file_blocks (SearpcClient *client, - const char *repo_id, - const char *parent_dir, - const char *file_name, - const char *blockids_json, - const char *paths_json, - const char *user, - const char *head_id, - gint64 file_size, - GError **error); - - -int -seafile_post_file (SearpcClient *client, - const char *repo_id, - const char *file_path, - const char *parent_dir, - const char *file_name, - const char *user, - GError **error); - -#define POST_FILE_ERR_FILENAME 401 -#define POST_FILE_ERR_BLOCK_MISSING 402 - -char * -seafile_post_file_blocks (SearpcClient *client, - const char *repo_id, - const char *parent_dir, - const char *file_name, - const char *blockids_json, - const char *paths_json, - const char *user, - gint64 file_size, - int replace_existed, - GError **error); - -char * -seafile_post_multi_files (SearpcClient *client, - const char *repo_id, - const char *parent_dir, - const char *filenames_json, - const char *paths_json, - const char *user, - int replace_existed, - GError **error); - -int -seafile_set_user_quota (SearpcClient *client, - const char *user, - gint64 quota, - GError **error); - -int -seafile_set_org_quota (SearpcClient *client, - int org_id, - gint64 quota, - GError **error); - -int -seafile_set_org_user_quota (SearpcClient *client, - int org_id, - const char *user, - gint64 quota, - GError **error); - -int -seafile_check_quota (SearpcClient *client, - const char *repo_id, - GError **error); - -int -seafile_disable_auto_sync_async (SearpcClient *client, - AsyncCallback callback, - void *user_data); -int -seafile_enable_auto_sync_async (SearpcClient *client, - AsyncCallback callback, - void *user_data); - -int -seafile_is_auto_sync_enabled_async (SearpcClient *client, - AsyncCallback callback, - void *user_data); - -#endif diff --git a/server/pack-dir.c b/server/pack-dir.c index e2a6be3..d3b9d03 100644 --- a/server/pack-dir.c +++ b/server/pack-dir.c @@ -7,7 +7,7 @@ #include "seafile-object.h" #include "seafile-crypt.h" -#include "seafile.h" +#include "seafile-error.h" #include "utils.h" diff --git a/server/repo-mgr.c b/server/repo-mgr.c index b0e8b13..5a9498b 100644 --- a/server/repo-mgr.c +++ b/server/repo-mgr.c @@ -11,7 +11,6 @@ #include #include "utils.h" #include "log.h" -#include "seafile.h" #include "seafile-session.h" #include "commit-mgr.h" diff --git a/server/repo-op.c b/server/repo-op.c index 997b583..61a73a8 100644 --- a/server/repo-op.c +++ b/server/repo-op.c @@ -12,7 +12,6 @@ #include "utils.h" #define DEBUG_FLAG SEAFILE_DEBUG_OTHER #include "log.h" -#include "seafile.h" #include "seafile-object.h" #include "seafile-session.h" @@ -1287,6 +1286,32 @@ out: return ret; } +static int +check_quota_before_commit_blocks (const char *store_id, + int version, + GList *blockids) +{ + GList *ptr; + char *blockid; + gint64 total_size = 0; + BlockMetadata *bmd; + + for (ptr = blockids; ptr; ptr = ptr->next) { + blockid = ptr->data; + bmd = seaf_block_manager_stat_block (seaf->block_mgr, store_id, version, blockid); + if (!bmd) { + seaf_warning ("Failed to stat block %s in store %s.\n", + blockid, store_id); + return -1; + } + + total_size += (gint64)bmd->size; + g_free (bmd); + } + + return seaf_quota_manager_check_quota_with_delta (seaf->quota_mgr, store_id, total_size); +} + int seaf_repo_manager_commit_file_blocks (SeafRepoManager *mgr, const char *repo_id, @@ -1334,6 +1359,14 @@ seaf_repo_manager_commit_file_blocks (SeafRepoManager *mgr, goto out; } + int rc = check_quota_before_commit_blocks (repo->store_id, repo->version, blockids); + if (rc != 0) { + g_set_error (error, SEAFILE_DOMAIN, POST_FILE_ERR_QUOTA_FULL, + "Quota full"); + ret = -1; + goto out; + } + /* Write blocks. */ if (seaf_fs_manager_index_existed_file_blocks ( seaf->fs_mgr, repo->store_id, repo->version, diff --git a/server/repo-perm.c b/server/repo-perm.c index c3d1b06..58d7e4e 100644 --- a/server/repo-perm.c +++ b/server/repo-perm.c @@ -6,7 +6,6 @@ #include #include "utils.h" #include "log.h" -#include "seafile.h" #include "seafile-session.h" #include "repo-mgr.h" diff --git a/server/upload-file.c b/server/upload-file.c index 42d79d7..8736dfd 100644 --- a/server/upload-file.c +++ b/server/upload-file.c @@ -26,6 +26,8 @@ #include "upload-file.h" #include "http-status-codes.h" +#include "seafile-error.h" + enum RecvState { RECV_INIT, RECV_HEADERS, @@ -75,9 +77,6 @@ typedef struct RecvFSM { #define MAX_CONTENT_LINE 10240 -#define POST_FILE_ERR_FILENAME 401 -#define POST_FILE_ERR_BLOCK_MISSING 402 - static GHashTable *upload_progress; static pthread_mutex_t pg_lock; @@ -379,7 +378,10 @@ upload_cb(evhtp_request_t *req, void *arg) if (!check_tmp_file_list (fsm->files, &error_code)) goto error; - if (seaf_quota_manager_check_quota (seaf->quota_mgr, fsm->repo_id) < 0) { + gint64 content_len = evhtp_request_content_len(req); + if (seaf_quota_manager_check_quota_with_delta (seaf->quota_mgr, + fsm->repo_id, + content_len) != 0) { error_code = ERROR_QUOTA; goto error; } @@ -501,7 +503,10 @@ upload_api_cb(evhtp_request_t *req, void *arg) if (!check_tmp_file_list (fsm->files, &error_code)) goto error; - if (seaf_quota_manager_check_quota (seaf->quota_mgr, fsm->repo_id) < 0) { + gint64 content_len = evhtp_request_content_len(req); + if (seaf_quota_manager_check_quota_with_delta (seaf->quota_mgr, + fsm->repo_id, + content_len) != 0) { error_code = ERROR_QUOTA; goto error; } @@ -585,11 +590,6 @@ upload_raw_blks_api_cb(evhtp_request_t *req, void *arg) if (!check_tmp_file_list (fsm->files, &error_code)) goto error; - if (seaf_quota_manager_check_quota (seaf->quota_mgr, fsm->repo_id) < 0) { - error_code = ERROR_QUOTA; - goto error; - } - blockids_json = file_list_to_json (fsm->filenames); tmp_files_json = file_list_to_json (fsm->files); @@ -678,15 +678,18 @@ upload_blks_api_cb(evhtp_request_t *req, void *arg) if (!check_parent_dir (req, fsm->repo_id, parent_dir)) return; - if (seaf_quota_manager_check_quota (seaf->quota_mgr, fsm->repo_id) < 0) { - error_code = ERROR_QUOTA; - goto error; - } - char *new_file_id = NULL; int rc = 0; commitonly_str = evhtp_kv_find (req->uri->query, "commitonly"); if (!commitonly_str) { + gint64 content_len = evhtp_request_content_len (req); + if (seaf_quota_manager_check_quota_with_delta (seaf->quota_mgr, + fsm->repo_id, + content_len) != 0) { + error_code = ERROR_QUOTA; + goto error; + } + if (!check_tmp_file_list (fsm->files, &error_code)) goto error; blockids_json = file_list_to_json (fsm->filenames); @@ -729,6 +732,8 @@ upload_blks_api_cb(evhtp_request_t *req, void *arg) error_code = ERROR_FILENAME; } else if (error->code == POST_FILE_ERR_BLOCK_MISSING) { error_code = ERROR_BLOCK_MISSING; + } else if (error->code == POST_FILE_ERR_QUOTA_FULL) { + error_code = ERROR_QUOTA; } g_clear_error (&error); } @@ -831,7 +836,10 @@ upload_blks_ajax_cb(evhtp_request_t *req, void *arg) if (!check_tmp_file_list (fsm->files, &error_code)) goto error; - if (seaf_quota_manager_check_quota (seaf->quota_mgr, fsm->repo_id) < 0) { + gint64 content_len = evhtp_request_content_len (req); + if (seaf_quota_manager_check_quota_with_delta (seaf->quota_mgr, + fsm->repo_id, + content_len) != 0) { error_code = ERROR_QUOTA; goto error; } @@ -946,7 +954,10 @@ upload_ajax_cb(evhtp_request_t *req, void *arg) if (!check_tmp_file_list (fsm->files, &error_code)) goto error; - if (seaf_quota_manager_check_quota (seaf->quota_mgr, fsm->repo_id) < 0) { + gint64 content_len = evhtp_request_content_len (req); + if (seaf_quota_manager_check_quota_with_delta (seaf->quota_mgr, + fsm->repo_id, + content_len) != 0) { error_code = ERROR_QUOTA; goto error; } @@ -1053,7 +1064,10 @@ update_cb(evhtp_request_t *req, void *arg) head_id = evhtp_kv_find (req->uri->query, "head"); - if (seaf_quota_manager_check_quota (seaf->quota_mgr, fsm->repo_id) < 0) { + gint64 content_len = evhtp_request_content_len(req); + if (seaf_quota_manager_check_quota_with_delta (seaf->quota_mgr, + fsm->repo_id, + content_len) != 0) { error_code = ERROR_QUOTA; goto error; } @@ -1126,7 +1140,10 @@ update_api_cb(evhtp_request_t *req, void *arg) head_id = evhtp_kv_find (req->uri->query, "head"); - if (seaf_quota_manager_check_quota (seaf->quota_mgr, fsm->repo_id) < 0) { + gint64 content_len = evhtp_request_content_len(req); + if (seaf_quota_manager_check_quota_with_delta (seaf->quota_mgr, + fsm->repo_id, + content_len) != 0) { error_code = ERROR_QUOTA; goto error; } @@ -1217,15 +1234,17 @@ update_blks_api_cb(evhtp_request_t *req, void *arg) head_id = evhtp_kv_find (req->uri->query, "head"); - if (seaf_quota_manager_check_quota (seaf->quota_mgr, fsm->repo_id) < 0) { - error_code = ERROR_QUOTA; - goto error; - } - - int rc = 0; commitonly_str = evhtp_kv_find (req->uri->query, "commitonly"); if (!commitonly_str) { + gint64 content_len = evhtp_request_content_len(req); + if (seaf_quota_manager_check_quota_with_delta (seaf->quota_mgr, + fsm->repo_id, + content_len) != 0) { + error_code = ERROR_QUOTA; + goto error; + } + if (!check_tmp_file_list (fsm->files, &error_code)) goto error; @@ -1269,6 +1288,8 @@ update_blks_api_cb(evhtp_request_t *req, void *arg) if (error) { if (g_strcmp0 (error->message, "file does not exist") == 0) { error_code = ERROR_NOT_EXIST; + } else if (error->code == POST_FILE_ERR_QUOTA_FULL) { + error_code = ERROR_QUOTA; } g_clear_error (&error); } @@ -1361,7 +1382,10 @@ update_blks_ajax_cb(evhtp_request_t *req, void *arg) head_id = evhtp_kv_find (req->uri->query, "head"); - if (seaf_quota_manager_check_quota (seaf->quota_mgr, fsm->repo_id) < 0) { + gint64 content_len = evhtp_request_content_len (req); + if (seaf_quota_manager_check_quota_with_delta (seaf->quota_mgr, + fsm->repo_id, + content_len) != 0) { error_code = ERROR_QUOTA; goto error; } @@ -1514,7 +1538,10 @@ update_ajax_cb(evhtp_request_t *req, void *arg) head_id = evhtp_kv_find (req->uri->query, "head"); - if (seaf_quota_manager_check_quota (seaf->quota_mgr, fsm->repo_id) < 0) { + gint64 content_len = evhtp_request_content_len (req); + if (seaf_quota_manager_check_quota_with_delta (seaf->quota_mgr, + fsm->repo_id, + content_len) != 0) { error_code = ERROR_QUOTA; goto error; }