don't allocate char[PATH_MAX] for each file

This commit makes struct path allocation use strndup().
It reduices the memory footprint for struct path per file (issue #8).
This commit is contained in:
Ryo Nakamura
2024-01-11 21:23:33 +09:00
parent 5cbf3ad648
commit bba53fab03
3 changed files with 34 additions and 27 deletions

View File

@@ -714,7 +714,7 @@ out:
/* cleanup-related functions */ /* cleanup-related functions */
static void free_src(struct list_head *list) static void list_free_src(struct list_head *list)
{ {
struct src *s; struct src *s;
s = list_entry(list, typeof(*s), list); s = list_entry(list, typeof(*s), list);
@@ -722,21 +722,14 @@ static void free_src(struct list_head *list)
free(s); free(s);
} }
static void free_path(struct list_head *list) static void list_free_path(struct list_head *list)
{ {
struct path *p; struct path *p;
p = list_entry(list, typeof(*p), list); p = list_entry(list, typeof(*p), list);
free(p); free_path(p);
} }
static void free_chunk(struct list_head *list) static void list_free_thread(struct list_head *list)
{
struct chunk *c;
c = list_entry(list, typeof(*c), list);
free(c);
}
static void free_thread(struct list_head *list)
{ {
struct mscp_thread *t; struct mscp_thread *t;
t = list_entry(list, typeof(*t), list); t = list_entry(list, typeof(*t), list);
@@ -750,17 +743,17 @@ void mscp_cleanup(struct mscp *m)
m->first = NULL; m->first = NULL;
} }
list_free_f(&m->src_list, free_src); list_free_f(&m->src_list, list_free_src);
INIT_LIST_HEAD(&m->src_list); INIT_LIST_HEAD(&m->src_list);
list_free_f(&m->path_list, free_path); list_free_f(&m->path_list, list_free_path);
INIT_LIST_HEAD(&m->path_list); INIT_LIST_HEAD(&m->path_list);
chunk_pool_release(&m->cp); chunk_pool_release(&m->cp);
chunk_pool_init(&m->cp); chunk_pool_init(&m->cp);
RWLOCK_WRITE_ACQUIRE(&m->thread_rwlock); RWLOCK_WRITE_ACQUIRE(&m->thread_rwlock);
list_free_f(&m->thread_list, free_thread); list_free_f(&m->thread_list, list_free_thread);
RWLOCK_RELEASE(); RWLOCK_RELEASE();
} }

View File

@@ -92,10 +92,9 @@ void chunk_pool_release(struct chunk_pool *cp)
} }
/* paths of copy source resoltion */ /* paths of copy source resoltion */
static int resolve_dst_path(const char *src_file_path, char *dst_file_path, static char *resolve_dst_path(const char *src_file_path, struct path_resolve_args *a)
struct path_resolve_args *a)
{ {
char copy[PATH_MAX + 1]; char copy[PATH_MAX + 1], dst_file_path[PATH_MAX + 1];
char *prefix; char *prefix;
int offset; int offset;
int ret; int ret;
@@ -104,7 +103,7 @@ static int resolve_dst_path(const char *src_file_path, char *dst_file_path,
prefix = dirname(copy); prefix = dirname(copy);
if (!prefix) { if (!prefix) {
mscp_set_error("dirname: %s", strerrno()); mscp_set_error("dirname: %s", strerrno());
return -1; return NULL;
} }
offset = strlen(prefix) + 1; offset = strlen(prefix) + 1;
@@ -147,12 +146,12 @@ static int resolve_dst_path(const char *src_file_path, char *dst_file_path,
if (ret >= PATH_MAX) { if (ret >= PATH_MAX) {
mpr_warn(a->msg_fp, "Too long path: %s\n", dst_file_path); mpr_warn(a->msg_fp, "Too long path: %s\n", dst_file_path);
return -1; return NULL;
} }
mpr_debug(a->msg_fp, "file: %s -> %s\n", src_file_path, dst_file_path); mpr_debug(a->msg_fp, "file: %s -> %s\n", src_file_path, dst_file_path);
return 0; return strndup(dst_file_path, PATH_MAX);
} }
/* chunk preparation */ /* chunk preparation */
@@ -208,6 +207,15 @@ static int resolve_chunk(struct path *p, struct path_resolve_args *a)
return 0; return 0;
} }
void free_path(struct path *p)
{
if (p->path)
free(p->path);
if (p->dst_path)
free(p->dst_path);
free(p);
}
static int append_path(sftp_session sftp, const char *path, struct stat st, static int append_path(sftp_session sftp, const char *path, struct stat st,
struct list_head *path_list, struct path_resolve_args *a) struct list_head *path_list, struct path_resolve_args *a)
{ {
@@ -220,13 +228,16 @@ static int append_path(sftp_session sftp, const char *path, struct stat st,
memset(p, 0, sizeof(*p)); memset(p, 0, sizeof(*p));
INIT_LIST_HEAD(&p->list); INIT_LIST_HEAD(&p->list);
strncpy(p->path, path, PATH_MAX - 1); p->path = strndup(path, PATH_MAX);
if (!p->path)
goto free_out;
p->size = st.st_size; p->size = st.st_size;
p->mode = st.st_mode; p->mode = st.st_mode;
p->state = FILE_STATE_INIT; p->state = FILE_STATE_INIT;
lock_init(&p->lock); lock_init(&p->lock);
if (resolve_dst_path(p->path, p->dst_path, a) < 0) p->dst_path = resolve_dst_path(p->path, a);
if (!p->dst_path)
goto free_out; goto free_out;
if (resolve_chunk(p, a) < 0) if (resolve_chunk(p, a) < 0)
@@ -239,7 +250,7 @@ static int append_path(sftp_session sftp, const char *path, struct stat st,
return 0; return 0;
free_out: free_out:
free(p); free_path(p);
return -1; return -1;
} }

View File

@@ -14,11 +14,11 @@
struct path { struct path {
struct list_head list; /* mscp->path_list */ struct list_head list; /* mscp->path_list */
char path[PATH_MAX]; /* file path */ char *path; /* file path */
size_t size; /* size of file on this path */ size_t size; /* size of file on this path */
mode_t mode; /* permission */ mode_t mode; /* permission */
char dst_path[PATH_MAX]; /* copy dst path */ char *dst_path; /* copy dst path */
int state; int state;
lock lock; lock lock;
@@ -93,6 +93,9 @@ struct path_resolve_args {
int walk_src_path(sftp_session src_sftp, const char *src_path, int walk_src_path(sftp_session src_sftp, const char *src_path,
struct list_head *path_list, struct path_resolve_args *a); struct list_head *path_list, struct path_resolve_args *a);
/* free struct path */
void free_path(struct path *p);
/* copy a chunk. either src_sftp or dst_sftp is not null, and another is null */ /* copy a chunk. either src_sftp or dst_sftp is not null, and another is null */
int copy_chunk(FILE *msg_fp, struct chunk *c, int copy_chunk(FILE *msg_fp, struct chunk *c,
sftp_session src_sftp, sftp_session dst_sftp, sftp_session src_sftp, sftp_session dst_sftp,