From 97f53e18953fc2013c0b14f0261ac385e45b0284 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Sun, 21 Oct 2007 15:25:55 +0200 Subject: [PATCH] Move mmap_full_file from osl.c to fd.c. To make it independent from osl.c, we must not pass a pointer to struct osl_data. Replace it by void *, size_t * pointers. Also add new int *fd_ptr parameter. If it's non-NULL the file is not closed after mmap, and the open fd is returned in fd_ptr. --- aft.c | 7 +++++-- error.h | 4 ++-- fd.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ fd.h | 2 ++ fsck.c | 4 ++-- osl.c | 56 +++++--------------------------------------------------- osl.h | 1 - 7 files changed, 69 insertions(+), 58 deletions(-) diff --git a/aft.c b/aft.c index b9db5a81..aae6d66b 100644 --- a/aft.c +++ b/aft.c @@ -6,6 +6,7 @@ /** \file aft.c Audio file table functions. */ +#include /* readdir() */ #include "para.h" #include "error.h" #include "string.h" @@ -15,6 +16,7 @@ #include "afs.h" #include "net.h" #include "vss.h" +#include "fd.h" static struct osl_table *audio_file_table; @@ -638,7 +640,8 @@ int open_and_update_audio_file(struct osl_row *aft_row, struct audio_file_data * ret = get_chunk_table_of_row(aft_row, &afd->afhi); if (ret < 0) return ret; - ret = mmap_full_file(afd->path, O_RDONLY, &afd->map); + ret = mmap_full_file(afd->path, O_RDONLY, &afd->map.data, + &afd->map.size, NULL); if (ret < 0) goto err; hash_function(afd->map.data, afd->map.size, file_hash); @@ -1571,7 +1574,7 @@ static int add_one_audio_file(const char *path, const void *private_data) goto out_free; } /* We still want to add this file. Compute its hash. */ - ret = mmap_full_file(path, O_RDONLY, &map); + ret = mmap_full_file(path, O_RDONLY, &map.data, &map.size, NULL); if (ret < 0) goto out_free; hash_function(map.data, map.size, hash); diff --git a/error.h b/error.h index a3f80bb9..1c3aaa34 100644 --- a/error.h +++ b/error.h @@ -64,8 +64,6 @@ extern const char **para_errlist[]; PARA_ERROR(STAT, "can not stat file"), \ PARA_ERROR(FSTAT, "fstat error"), \ PARA_ERROR(RENAME, "rename failed"), \ - PARA_ERROR(EMPTY, "file empty"), \ - PARA_ERROR(MMAP, "mmap error"), \ PARA_ERROR(MUNMAP, "munmap failed"), \ PARA_ERROR(WRITE, "write error"), \ PARA_ERROR(LSEEK, "lseek error"), \ @@ -409,6 +407,8 @@ extern const char **para_errlist[]; PARA_ERROR(CHDIR, "failed to change directory"), \ PARA_ERROR(OPEN, "failed to open file"), \ PARA_ERROR(CHDIR_PERM, "insufficient permissions to chdir"), \ + PARA_ERROR(EMPTY, "file empty"), \ + PARA_ERROR(MMAP, "mmap error"), \ #define WRITE_ERRORS \ diff --git a/fd.c b/fd.c index 30483006..83c6cd5b 100644 --- a/fd.c +++ b/fd.c @@ -279,3 +279,56 @@ int para_mkdir(const char *path, mode_t mode) return 1; return -ERRNO_TO_PARA_ERROR(errno); } + +/** + * Map a file into memory. + * + * \param path Name of the regular file to map. + * \param open_mode Either \p O_RDONLY or \p O_RDWR. + * \param obj On success, the mapping is returned here. + * + * \return Positive on success, negative on errors. Possible errors include: \p + * E_FSTAT, any errors returned by para_open(), \p E_EMPTY, \p E_MMAP. + * + * \sa para_open(), mmap(2). + */ +int mmap_full_file(const char *path, int open_mode, void **map, + size_t *size, int *fd_ptr) +{ + int fd, ret, mmap_prot, mmap_flags; + struct stat file_status; + + if (open_mode == O_RDONLY) { + mmap_prot = PROT_READ; + mmap_flags = MAP_PRIVATE; + } else { + mmap_prot = PROT_READ | PROT_WRITE; + mmap_flags = MAP_SHARED; + } + ret = para_open(path, open_mode, 0); + if (ret < 0) + return ret; + fd = ret; + if (fstat(fd, &file_status) < 0) { + ret = -ERRNO_TO_PARA_ERROR(errno); + goto out; + } + *size = file_status.st_size; + ret = -E_EMPTY; + PARA_DEBUG_LOG("%s: size %zu\n", path, *size); + if (!*size) + goto out; + *map = mmap(NULL, *size, mmap_prot, mmap_flags, fd, 0); + if (*map == MAP_FAILED) { + *map = NULL; + ret = -E_MMAP; + goto out; + } + ret = 1; +out: + if (ret < 0 || !fd_ptr) + close(fd); + else + *fd_ptr = fd; + return ret; +} diff --git a/fd.h b/fd.h index 82323683..0b25959e 100644 --- a/fd.h +++ b/fd.h @@ -18,3 +18,5 @@ int para_opendir(const char *dirname, DIR **dir, int *cwd); int para_mkdir(const char *path, mode_t mode); int para_fchdir(int fd); int para_chdir(const char *path); +int mmap_full_file(const char *filename, int open_mode, void **map, + size_t *size, int *fd_ptr); diff --git a/fsck.c b/fsck.c index 19f7be67..48fae27d 100644 --- a/fsck.c +++ b/fsck.c @@ -176,7 +176,7 @@ static int map_index(const struct osl_table_description *desc, struct osl_object char *filename = index_filename(desc); int ret; - ret = mmap_full_file(filename, O_RDWR, map); + ret = mmap_full_file(filename, O_RDWR, &map->data, &map->size, NULL); PARA_INFO_LOG("mapping index %s: ret: %d, size: %zu\n", filename, ret, map->size); free(filename); return ret; @@ -758,7 +758,7 @@ static int dump_row(struct osl_table *t, unsigned row_num, const char *row_dir) ds_name = disk_storage_name_of_hash(t, hash); FOR_EACH_DISK_STORAGE_COLUMN(i, t, cd) { filename = disk_storage_path(t, i, ds_name); - ret = mmap_full_file(filename, O_RDONLY, &obj); + ret = mmap_full_file(filename, O_RDONLY, &obj.data, &obj.size, NULL); free(filename); if (ret < 0) goto out; diff --git a/osl.c b/osl.c index 36da808a..6294fbbe 100644 --- a/osl.c +++ b/osl.c @@ -156,54 +156,6 @@ out: return ret; } -/** - * Map a file into memory. - * - * \param path Name of the regular file to map. - * \param open_mode Either \p O_RDONLY or \p O_RDWR. - * \param obj On success, the mapping is returned here. - * - * \return Positive on success, negative on errors. Possible errors include: \p - * E_FSTAT, any errors returned by para_open(), \p E_EMPTY, \p E_MMAP. - * - * \sa para_open(), mmap(2). - */ -int mmap_full_file(const char *path, int open_mode, struct osl_object *obj) -{ - int fd, ret, mmap_prot, mmap_flags; - struct stat file_status; - - if (open_mode == O_RDONLY) { - mmap_prot = PROT_READ; - mmap_flags = MAP_PRIVATE; - } else { - mmap_prot = PROT_READ | PROT_WRITE; - mmap_flags = MAP_SHARED; - } - ret = para_open(path, open_mode, 0); - if (ret < 0) - return ret; - fd = ret; - ret = -E_FSTAT; - if (fstat(fd, &file_status) < 0) - goto out; - obj->size = file_status.st_size; - ret = -E_EMPTY; - PARA_DEBUG_LOG("%s: size %zu\n", path, obj->size); - if (!obj->size) - goto out; - obj->data = mmap(NULL, obj->size, mmap_prot, mmap_flags, fd, 0); - if (obj->data == MAP_FAILED) { - obj->data = NULL; - ret = -E_MMAP; - goto out; - } - ret = 1; -out: - close(fd); - return ret; -} - /** * Traverse the given directory recursively. * @@ -792,7 +744,9 @@ static int map_column(struct osl_table *t, unsigned col_num) return ret; } ret = mmap_full_file(filename, O_RDWR, - &t->columns[col_num].data_map); + &t->columns[col_num].data_map.data, + &t->columns[col_num].data_map.size, + NULL); free(filename); return ret; } @@ -821,7 +775,7 @@ int map_table(struct osl_table *t, enum map_table_flags flags) filename = index_filename(t->desc); PARA_DEBUG_LOG("mapping table '%s' (index: %s)\n", t->desc->name, filename); ret = mmap_full_file(filename, flags & MAP_TBL_FL_MAP_RDONLY? - O_RDONLY : O_RDWR, &t->index_map); + O_RDONLY : O_RDWR, &t->index_map.data, &t->index_map.size, NULL); free(filename); if (ret < 0) return ret; @@ -1952,7 +1906,7 @@ int osl_open_disk_object(const struct osl_table *t, const struct osl_row *r, filename = disk_storage_path(t, col_num, ds_name); free(ds_name); PARA_DEBUG_LOG("filename: %s\n", filename); - ret = mmap_full_file(filename, O_RDONLY, obj); + ret = mmap_full_file(filename, O_RDONLY, &obj->data, &obj->size, NULL); free(filename); return ret; } diff --git a/osl.h b/osl.h index 2fdee777..1fec9865 100644 --- a/osl.h +++ b/osl.h @@ -179,7 +179,6 @@ int osl_get_rank(const struct osl_table *t, struct osl_row *r, int for_each_file_in_dir(const char *dirname, int (*func)(const char *, const void *), const void *private_data); -int mmap_full_file(const char *filename, int open_mode, struct osl_object *obj); ssize_t para_write_all(int fd, const void *buf, size_t size); int para_lseek(int fd, off_t *offset, int whence); int para_write_file(const char *filename, const void *buf, size_t size); -- 2.39.5