Fix a few bugs and memory leak.

This commit is contained in:
Jiaqiang Xu 2014-03-26 13:54:50 +08:00
parent b17f378fb8
commit abad5959ed
9 changed files with 117 additions and 93 deletions

View File

@ -554,11 +554,11 @@ seaf_fs_manager_index_blocks (SeafFSManager *mgr,
g_warning ("Failed to chunk file with CDC.\n");
return -1;
}
}
if (write_data && write_seafile (mgr, repo_id, version, &cdc, sha1) < 0) {
g_warning ("Failed to write seafile for %s.\n", file_path);
return -1;
if (write_data && write_seafile (mgr, repo_id, version, &cdc, sha1) < 0) {
g_warning ("Failed to write seafile for %s.\n", file_path);
return -1;
}
}
*size = (gint64)sb.st_size;
@ -690,12 +690,12 @@ seaf_fs_manager_index_file_blocks (SeafFSManager *mgr,
ret = -1;
goto out;
}
}
if (write_seafile (mgr, repo_id, version, &cdc, sha1) < 0) {
seaf_warning ("Failed to write seafile.\n");
ret = -1;
goto out;
if (write_seafile (mgr, repo_id, version, &cdc, sha1) < 0) {
seaf_warning ("Failed to write seafile.\n");
ret = -1;
goto out;
}
}
out:
@ -1019,6 +1019,8 @@ seaf_dirent_new (int version, const char *sha1, int mode, const char *name,
void
seaf_dirent_free (SeafDirent *dent)
{
if (!dent)
return;
g_free (dent->name);
g_free (dent->modifier);
g_free (dent);
@ -1333,9 +1335,24 @@ seaf_dir_to_json (SeafDir *dir, int *len)
void *
seaf_dir_to_data (SeafDir *dir, int *len)
{
if (dir->version > 0)
return seaf_dir_to_json (dir, len);
else
if (dir->version > 0) {
guint8 *data;
int orig_len;
guint8 *compressed;
data = seaf_dir_to_json (dir, &orig_len);
if (!data)
return NULL;
if (seaf_compress (data, orig_len, &compressed, len) < 0) {
seaf_warning ("Failed to compress dir object %s.\n", dir->dir_id);
g_free (data);
return NULL;
}
g_free (data);
return compressed;
} else
return seaf_dir_to_v0_data (dir, len);
}
@ -1346,23 +1363,15 @@ seaf_dir_save (SeafFSManager *fs_mgr,
SeafDir *dir)
{
int ret = 0;
guint8 *compressed;
int outlen;
/* Don't need to save empty dir on disk. */
if (memcmp (dir->dir_id, EMPTY_SHA1, 40) == 0)
return 0;
if (seaf_compress (dir->ondisk, dir->ondisk_size, &compressed, &outlen) < 0) {
seaf_warning ("Failed to compress dir object %s.\n", dir->dir_id);
return -1;
}
if (seaf_obj_store_write_obj (fs_mgr->obj_store, repo_id, version, dir->dir_id,
compressed, outlen, FALSE) < 0)
dir->ondisk, dir->ondisk_size, FALSE) < 0)
ret = -1;
g_free (compressed);
return ret;
}

View File

@ -6,14 +6,14 @@
#include "log.h"
static int
merge_trees_recursive (const char *repo_id, int version,
merge_trees_recursive (const char *store_id, int version,
int n, SeafDir *trees[],
const char *basedir,
MergeOptions *opt);
static char *
merge_conflict_filename (const char *repo_id, int version,
const char *remote_head,
merge_conflict_filename (const char *store_id, int version,
MergeOptions *opt,
const char *basedir,
const char *filename)
{
@ -23,14 +23,19 @@ merge_conflict_filename (const char *repo_id, int version,
path = g_strconcat (basedir, filename, NULL);
int rc = get_file_modifier_mtime (repo_id, version, remote_head, path,
int rc = get_file_modifier_mtime (opt->remote_repo_id,
store_id,
version,
opt->remote_head,
path,
&modifier, &mtime);
if (rc < 0) {
commit = seaf_commit_manager_get_commit (seaf->commit_mgr,
repo_id, version,
remote_head);
opt->remote_repo_id,
version,
opt->remote_head);
if (!commit) {
seaf_warning ("Failed to find remote head %s.\n", remote_head);
seaf_warning ("Failed to find remote head %s.\n", opt->remote_head);
goto out;
}
modifier = g_strdup(commit->creator_name);
@ -47,8 +52,8 @@ out:
}
static char *
merge_conflict_dirname (const char *repo_id, int version,
const char *remote_head,
merge_conflict_dirname (const char *store_id, int version,
MergeOptions *opt,
const char *basedir,
const char *dirname)
{
@ -56,10 +61,10 @@ merge_conflict_dirname (const char *repo_id, int version,
SeafCommit *commit;
commit = seaf_commit_manager_get_commit (seaf->commit_mgr,
repo_id, version,
remote_head);
opt->remote_repo_id, version,
opt->remote_head);
if (!commit) {
seaf_warning ("Failed to find remote head %s.\n", remote_head);
seaf_warning ("Failed to find remote head %s.\n", opt->remote_head);
goto out;
}
modifier = g_strdup(commit->creator_name);
@ -73,7 +78,7 @@ out:
}
static int
merge_entries (const char *repo_id, int version,
merge_entries (const char *store_id, int version,
int n, SeafDirent *dents[],
const char *basedir,
GList **dents_out,
@ -125,8 +130,8 @@ merge_entries (const char *repo_id, int version,
seaf_debug ("%s%s: files conflict\n", basedir, head->name);
conflict_name = merge_conflict_filename(repo_id, version,
opt->remote_head,
conflict_name = merge_conflict_filename(store_id, version,
opt,
basedir,
head->name);
if (!conflict_name)
@ -135,9 +140,9 @@ merge_entries (const char *repo_id, int version,
/* Change remote entry name in place. So opt->callback
* will see the conflict name, not the original name.
*/
g_strlcpy (remote->name, conflict_name, sizeof(remote->name));
g_free (remote->name);
remote->name = conflict_name;
remote->name_len = strlen (remote->name);
g_free (conflict_name);
*dents_out = g_list_prepend (*dents_out, seaf_dirent_dup(head));
*dents_out = g_list_prepend (*dents_out, seaf_dirent_dup(remote));
@ -153,8 +158,8 @@ merge_entries (const char *repo_id, int version,
seaf_debug ("%s%s: DFC, file -> dir, file\n",
basedir, remote->name);
conflict_name = merge_conflict_filename(repo_id, version,
opt->remote_head,
conflict_name = merge_conflict_filename(store_id, version,
opt,
basedir,
remote->name);
if (!conflict_name)
@ -162,9 +167,9 @@ merge_entries (const char *repo_id, int version,
/* Change the name of remote, keep dir name in head unchanged.
*/
g_strlcpy (remote->name, conflict_name, sizeof(remote->name));
g_free (remote->name);
remote->name = conflict_name;
remote->name_len = strlen (remote->name);
g_free (conflict_name);
*dents_out = g_list_prepend (*dents_out, seaf_dirent_dup(remote));
@ -197,16 +202,16 @@ merge_entries (const char *repo_id, int version,
/* We use remote head commit author name as conflict
* suffix of a dir.
*/
conflict_name = merge_conflict_dirname (repo_id, version,
opt->remote_head,
conflict_name = merge_conflict_dirname (store_id, version,
opt,
basedir, dents[2]->name);
if (!conflict_name)
return -1;
/* Change remote dir name to conflict name in place. */
g_strlcpy (dents[2]->name, conflict_name, sizeof(dents[2]->name));
g_free (dents[2]->name);
dents[2]->name = conflict_name;
dents[2]->name_len = strlen (dents[2]->name);
g_free (conflict_name);
*dents_out = g_list_prepend (*dents_out, seaf_dirent_dup(head));
@ -252,16 +257,16 @@ merge_entries (const char *repo_id, int version,
seaf_debug ("%s%s: DFC, dir -> dir, file\n", basedir, remote->name);
conflict_name = merge_conflict_filename(repo_id, version,
opt->remote_head,
conflict_name = merge_conflict_filename(store_id, version,
opt,
basedir,
remote->name);
if (!conflict_name)
return -1;
g_strlcpy (remote->name, conflict_name, sizeof(remote->name));
g_free (remote->name);
remote->name = conflict_name;
remote->name_len = strlen (remote->name);
g_free (conflict_name);
*dents_out = g_list_prepend (*dents_out, seaf_dirent_dup(remote));
@ -292,15 +297,15 @@ merge_entries (const char *repo_id, int version,
seaf_debug ("%s%s: DFC, dir -> file, dir\n", basedir, head->name);
conflict_name = merge_conflict_dirname (repo_id, version,
opt->remote_head,
conflict_name = merge_conflict_dirname (store_id, version,
opt,
basedir, dents[2]->name);
if (!conflict_name)
return -1;
g_strlcpy (dents[2]->name, conflict_name, sizeof(dents[2]->name));
g_free (dents[2]->name);
dents[2]->name = conflict_name;
dents[2]->name_len = strlen (dents[2]->name);
g_free (conflict_name);
*dents_out = g_list_prepend (*dents_out, seaf_dirent_dup(head));
@ -315,7 +320,7 @@ merge_entries (const char *repo_id, int version,
}
static int
merge_directories (const char *repo_id, int version,
merge_directories (const char *store_id, int version,
int n, SeafDirent *dents[],
const char *basedir,
GList **dents_out,
@ -404,7 +409,7 @@ merge_directories (const char *repo_id, int version,
for (i = 0; i < n; ++i) {
if (dents[i] != NULL && S_ISDIR(dents[i]->mode)) {
dir = seaf_fs_manager_get_seafdir (seaf->fs_mgr,
repo_id, version,
store_id, version,
dents[i]->id);
if (!dir) {
seaf_warning ("Failed to find dir %s.\n", dents[i]->id);
@ -420,7 +425,7 @@ merge_directories (const char *repo_id, int version,
new_basedir = g_strconcat (basedir, dirname, "/", NULL);
ret = merge_trees_recursive (repo_id, version, n, sub_dirs, new_basedir, opt);
ret = merge_trees_recursive (store_id, version, n, sub_dirs, new_basedir, opt);
g_free (new_basedir);
@ -452,7 +457,7 @@ compare_dirents (gconstpointer a, gconstpointer b)
}
static int
merge_trees_recursive (const char *repo_id, int version,
merge_trees_recursive (const char *store_id, int version,
int n, SeafDir *trees[],
const char *basedir,
MergeOptions *opt)
@ -515,7 +520,7 @@ merge_trees_recursive (const char *repo_id, int version,
/* Merge entries of this level. */
if (n_files > 0) {
ret = merge_entries (repo_id, version,
ret = merge_entries (store_id, version,
n, dents, basedir, &merged_dents, opt);
if (ret < 0)
return ret;
@ -523,7 +528,7 @@ merge_trees_recursive (const char *repo_id, int version,
/* Recurse into sub level. */
if (n_dirs > 0) {
ret = merge_directories (repo_id, version,
ret = merge_directories (store_id, version,
n, dents, basedir, &merged_dents, opt);
if (ret < 0)
return ret;
@ -541,7 +546,7 @@ merge_trees_recursive (const char *repo_id, int version,
(trees[2] && strcmp (trees[2]->dir_id, merged_tree->dir_id) == 0)) {
seaf_dir_free (merged_tree);
} else {
ret = seaf_dir_save (seaf->fs_mgr, repo_id, version, merged_tree);
ret = seaf_dir_save (seaf->fs_mgr, store_id, version, merged_tree);
seaf_dir_free (merged_tree);
if (ret < 0) {
seaf_warning ("Failed to save merged tree %s.\n", basedir);
@ -553,7 +558,7 @@ merge_trees_recursive (const char *repo_id, int version,
}
int
seaf_merge_trees (const char *repo_id, int version,
seaf_merge_trees (const char *store_id, int version,
int n, const char *roots[], MergeOptions *opt)
{
SeafDir **trees, *root;
@ -563,7 +568,7 @@ seaf_merge_trees (const char *repo_id, int version,
trees = g_new0 (SeafDir *, n);
for (i = 0; i < n; ++i) {
root = seaf_fs_manager_get_seafdir (seaf->fs_mgr, repo_id, version, roots[i]);
root = seaf_fs_manager_get_seafdir (seaf->fs_mgr, store_id, version, roots[i]);
if (!root) {
seaf_warning ("Failed to find dir %s.\n", roots[i]);
g_free (trees);
@ -572,7 +577,7 @@ seaf_merge_trees (const char *repo_id, int version,
trees[i] = root;
}
ret = merge_trees_recursive (repo_id, version, n, trees, "", opt);
ret = merge_trees_recursive (store_id, version, n, trees, "", opt);
for (i = 0; i < n; ++i)
seaf_dir_free (trees[i]);

View File

@ -18,6 +18,7 @@ typedef struct MergeOptions {
void * data;
/* options only used in 3-way merge. */
char remote_repo_id[37];
char remote_head[41];
gboolean do_merge; /* really merge the contents
* and handle conflicts */
@ -27,7 +28,7 @@ typedef struct MergeOptions {
} MergeOptions;
int
seaf_merge_trees (const char *repo_id, int version,
seaf_merge_trees (const char *store_id, int version,
int n, const char *roots[], MergeOptions *opt);
#endif

View File

@ -496,7 +496,7 @@ get_file_modifier_mtime_v0 (const char *repo_id, int version,
}
static int
get_file_modifier_mtime_v1 (const char *repo_id, int version,
get_file_modifier_mtime_v1 (const char *repo_id, const char *store_id, int version,
const char *head, const char *path,
char **modifier, gint64 *mtime)
{
@ -521,7 +521,7 @@ get_file_modifier_mtime_v1 (const char *repo_id, int version,
char *filename = g_path_get_basename (path);
dir = seaf_fs_manager_get_seafdir_by_path (seaf->fs_mgr,
repo_id, version,
store_id, version,
commit->root_id,
parent, NULL);
if (!dir) {
@ -562,15 +562,20 @@ out:
* @path: path of the file.
*/
int
get_file_modifier_mtime (const char *repo_id, int version,
const char *head, const char *path,
char **modifier, gint64 *mtime)
get_file_modifier_mtime (const char *repo_id,
const char *store_id,
int version,
const char *head,
const char *path,
char **modifier,
gint64 *mtime)
{
if (version > 0)
return get_file_modifier_mtime_v1 (repo_id, version,
return get_file_modifier_mtime_v1 (repo_id, store_id, version,
head, path,
modifier, mtime);
else
/* for version 0, repo_id and store_id are always the same. */
return get_file_modifier_mtime_v0 (repo_id, version,
head, path,
modifier, mtime);
@ -613,7 +618,11 @@ gen_conflict_path_wrapper (const char *repo_id, int version,
char *modifier;
gint64 mtime;
if (get_file_modifier_mtime (repo_id, version, head, in_repo_path,
/* XXX: this function is only used in client, so store_id is always
* the same as repo_id. This can be changed if it's also called in
* server.
*/
if (get_file_modifier_mtime (repo_id, repo_id, version, head, in_repo_path,
&modifier, &mtime) < 0)
return NULL;

View File

@ -38,7 +38,7 @@ gen_conflict_path (const char *original_path,
gint64 mtime);
int
get_file_modifier_mtime (const char *repo_id, int version,
get_file_modifier_mtime (const char *repo_id, const char *store_id, int version,
const char *head, const char *path,
char **modifier, gint64 *mtime);

View File

@ -189,6 +189,7 @@ static int get_files_dirs_recursive(struct merge_options *o, SeafDir *tree,
}
ret = get_files_dirs_recursive(o, subdir, base, new_baselen);
base[baselen] = 0;
seaf_dir_free (subdir);
break;
case S_IFLNK:
break;

View File

@ -1085,6 +1085,7 @@ out:
if (master)
seaf_branch_unref (master);
g_free (last_uploaded);
g_free (last_checkout);
}
static void

View File

@ -460,6 +460,7 @@ retry:
memset (&opt, 0, sizeof(opt));
opt.n_ways = 3;
memcpy (opt.remote_repo_id, repo_id, 36);
memcpy (opt.remote_head, new_commit->commit_id, 40);
opt.do_merge = TRUE;
@ -670,8 +671,7 @@ out:
seaf_repo_unref (repo);
if (head_commit)
seaf_commit_unref(head_commit);
if (new_dent)
g_free (new_dent);
seaf_dirent_free (new_dent);
g_free (root_id);
g_free (canon_path);
g_free (crypt);
@ -1147,8 +1147,7 @@ out:
seaf_commit_unref(head_commit);
string_list_free (blockids);
string_list_free (paths);
if (new_dent)
g_free (new_dent);
seaf_dirent_free (new_dent);
g_free (root_id);
g_free (canon_path);
@ -1533,9 +1532,9 @@ out:
if (dst_canon_path)
g_free (dst_canon_path);
if (src_dent)
g_free(src_dent);
seaf_dirent_free(src_dent);
if (dst_dent)
g_free(dst_dent);
seaf_dirent_free(dst_dent);
if (ret == 0) {
update_repo_size (dst_repo_id);
@ -1701,8 +1700,8 @@ out:
if (src_canon_path) g_free (src_canon_path);
if (dst_canon_path) g_free (dst_canon_path);
if (src_dent) g_free(src_dent);
if (dst_dent) g_free(dst_dent);
seaf_dirent_free(src_dent);
seaf_dirent_free(dst_dent);
if (ret == 0) {
update_repo_size (dst_repo_id);
@ -1774,8 +1773,7 @@ out:
seaf_repo_unref (repo);
if (head_commit)
seaf_commit_unref(head_commit);
if (new_dent)
g_free (new_dent);
seaf_dirent_free (new_dent);
g_free (root_id);
g_free (canon_path);
@ -1847,8 +1845,7 @@ out:
seaf_repo_unref (repo);
if (head_commit)
seaf_commit_unref(head_commit);
if (new_dent)
g_free (new_dent);
seaf_dirent_free (new_dent);
g_free (root_id);
g_free (canon_path);
@ -2282,8 +2279,7 @@ out:
seaf_repo_unref (repo);
if (head_commit)
seaf_commit_unref(head_commit);
if (new_dent)
g_free (new_dent);
seaf_dirent_free (new_dent);
g_free (root_id);
g_free (canon_path);
g_free (crypt);
@ -2393,7 +2389,7 @@ seaf_repo_manager_update_dir (SeafRepoManager *mgr,
out:
seaf_repo_unref (repo);
seaf_commit_unref (head_commit);
g_free (new_dent);
seaf_dirent_free (new_dent);
g_free (canon_path);
g_free (dirname);
g_free (root_id);
@ -2532,8 +2528,7 @@ out:
seaf_commit_unref(head_commit);
string_list_free (blockids);
string_list_free (paths);
if (new_dent)
g_free (new_dent);
seaf_dirent_free (new_dent);
g_free (root_id);
g_free (canon_path);
g_free (old_file_id);
@ -2634,7 +2629,7 @@ out:
g_free (basename);
g_free (ext);
g_free (newdent);
seaf_dirent_free (newdent);
return new_root_id;
}
@ -2715,7 +2710,7 @@ out:
g_free (basename);
g_free (ext);
g_free (newdent);
seaf_dirent_free (newdent);
return new_root_id;
}
@ -2956,7 +2951,7 @@ out:
if (dir)
seaf_dir_free (dir);
g_free (newdent);
seaf_dirent_free (newdent);
return new_root_id;
}
@ -3903,6 +3898,7 @@ add_deleted_entry (SeafRepo *repo,
return;
}
g_object_set (entry, "file_size", file->file_size, NULL);
seafile_unref (file);
}
g_hash_table_insert (entries, path, entry);
@ -4178,6 +4174,7 @@ seaf_repo_manager_get_deleted_entries (SeafRepoManager *mgr,
g_hash_table_foreach_steal (entries, hash_to_list, &ret);
g_hash_table_destroy (entries);
seaf_repo_unref (repo);
return ret;
}

View File

@ -719,6 +719,7 @@ static void *merge_virtual_repo (void *vtask)
memset (&opt, 0, sizeof(opt));
opt.n_ways = 3;
memcpy (opt.remote_repo_id, repo_id, 36);
memcpy (opt.remote_head, head->commit_id, 40);
opt.do_merge = TRUE;