From: Martin Mares Date: Sat, 25 Aug 2007 14:15:08 +0000 (+0200) Subject: Cleanup of file fastbufs. X-Git-Tag: holmes-import~506^2~13^2~83 X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=b131627991008b2968b5a4ed36153f71a1abe37c;p=libucw.git Cleanup of file fastbufs. o Common parts of close code moved to bclose_file_helper(). o Compatibility wrappers moved to fb-param.c. o Everything related to temp files moved to fb-temp.c. o Several byte -> char conversions. o Better comments. o Testing code compiles again. --- diff --git a/lib/fastbuf.h b/lib/fastbuf.h index 9878beeb..c763f243 100644 --- a/lib/fastbuf.h +++ b/lib/fastbuf.h @@ -73,21 +73,19 @@ struct fastbuf { int can_overwrite_buffer; /* Can the buffer be altered? (see discussion above) 0=never, 1=temporarily, 2=permanently */ }; -/* FastIO on files with run-time parametrization */ +/* FastIO on files with several configurable back-ends */ enum fb_type { /* Which back-end you want to use */ FB_STD, /* Standard buffered I/O */ - FB_DIRECT, /* Direct I/O bypassing system caches (see fb-direct.c for description) */ + FB_DIRECT, /* Direct I/O bypassing system caches (see fb-direct.c for a description) */ FB_MMAP /* Memory mapped files */ }; struct fb_params { enum fb_type type; - uns buffer_size; - /* FB_STD only */ - uns keep_back_buf; - /* FB_DIRECT only */ - uns read_ahead; + uns buffer_size; /* 0 for default size */ + uns keep_back_buf; /* FB_STD: optimize for bi-directional access */ + uns read_ahead; /* FB_DIRECT options */ uns write_back; struct asio_queue *asio; }; @@ -101,9 +99,8 @@ struct fastbuf *bopen_file_try(const char *name, int mode, struct fb_params *par struct fastbuf *bopen_tmp_file(struct fb_params *params); struct fastbuf *bopen_fd(int fd, struct fb_params *params); -/* FastIO on standard files */ +/* FastIO on standard files (shortcuts for FB_STD) */ -struct fastbuf *bfdopen_internal(int fd, const char *name, uns buflen); struct fastbuf *bopen(const char *name, uns mode, uns buflen); struct fastbuf *bopen_try(const char *name, uns mode, uns buflen); struct fastbuf *bopen_tmp(uns buflen); @@ -111,18 +108,23 @@ struct fastbuf *bfdopen(int fd, uns buflen); struct fastbuf *bfdopen_shared(int fd, uns buflen); void bfilesync(struct fastbuf *b); +/* Temporary files */ + #define TEMP_FILE_NAME_LEN 256 void temp_file_name(char *name); void bfix_tmp_file(struct fastbuf *fb, const char *name); /* Internal functions of some file back-ends */ +struct fastbuf *bfdopen_internal(int fd, const char *name, uns buflen); struct fastbuf *bfmmopen_internal(int fd, const char *name, uns mode); extern uns fbdir_cheat; struct asio_queue; struct fastbuf *fbdir_open_fd_internal(int fd, const char *name, struct asio_queue *io_queue, uns buffer_size, uns read_ahead, uns write_back); +void bclose_file_helper(struct fastbuf *f, int fd, int is_temp_file); + /* FastIO on in-memory streams */ struct fastbuf *fbmem_create(uns blocksize); /* Create stream and return its writing fastbuf */ @@ -185,8 +187,8 @@ fbatomic_commit(struct fastbuf *b) /* Configuring stream parameters */ enum bconfig_type { - BCONFIG_IS_TEMP_FILE, - BCONFIG_KEEP_BACK_BUF, + BCONFIG_IS_TEMP_FILE, /* 0=normal file, 1=temporary file, -1=shared fd */ + BCONFIG_KEEP_BACK_BUF, /* Optimize for bi-directional access */ }; int bconfig(struct fastbuf *f, uns type, int data); @@ -198,7 +200,7 @@ void bflush(struct fastbuf *f); void bseek(struct fastbuf *f, sh_off_t pos, int whence); void bsetpos(struct fastbuf *f, sh_off_t pos); void brewind(struct fastbuf *f); -sh_off_t bfilesize(struct fastbuf *f); // -1 if not seekable +sh_off_t bfilesize(struct fastbuf *f); /* -1 if not seekable */ static inline sh_off_t btell(struct fastbuf *f) { diff --git a/lib/fb-direct.c b/lib/fb-direct.c index 2fa6ec7f..1765eae8 100644 --- a/lib/fb-direct.c +++ b/lib/fb-direct.c @@ -1,7 +1,7 @@ /* * UCW Library -- Fast Buffered I/O on O_DIRECT Files * - * (c) 2006 Martin Mares + * (c) 2006--2007 Martin Mares * * This software may be freely distributed and used according to the terms * of the GNU Lesser General Public License. @@ -20,7 +20,6 @@ * * FIXME: what if the OS doesn't support O_DIRECT? * FIXME: unaligned seeks and partial writes? - * FIXME: merge with other file-oriented fastbufs */ #undef LOCAL_DEBUG @@ -57,7 +56,7 @@ enum fbdir_mode { // Current operating mode struct fb_direct { struct fastbuf fb; int fd; // File descriptor - int is_temp_file; // 0=normal file, 1=temporary file, delete on close, -1=shared FD + int is_temp_file; struct asio_queue *io_queue; // I/O queue to use struct asio_queue *user_queue; // If io_queue was supplied by the user struct asio_request *pending_read; @@ -264,15 +263,7 @@ fbdir_close(struct fastbuf *f) if (!F->user_queue) fbdir_put_io_queue(); - switch (F->is_temp_file) - { - case 1: - if (unlink(f->name) < 0) - msg(L_ERROR, "unlink(%s): %m", f->name); - case 0: - close(F->fd); - } - + bclose_file_helper(f, F->fd, F->is_temp_file); xfree(f); } @@ -323,13 +314,14 @@ fbdir_open_fd_internal(int fd, const char *name, struct asio_queue *q, uns buffe int main(int argc, char **argv) { + struct fb_params par = { .type = FB_DIRECT }; struct fastbuf *f, *t; log_init(NULL); if (cf_getopt(argc, argv, CF_SHORT_OPTS, CF_NO_LONG_OPTS, NULL) >= 0) die("Hey, whaddya want?"); - f = (optind < argc) ? fbdir_open(argv[optind++], O_RDONLY, NULL) : fbdir_open_fd(0, NULL); - t = (optind < argc) ? fbdir_open(argv[optind++], O_RDWR | O_CREAT | O_TRUNC, NULL) : fbdir_open_fd(1, NULL); + f = (optind < argc) ? bopen_file(argv[optind++], O_RDONLY, &par) : bopen_fd(0, &par); + t = (optind < argc) ? bopen_file(argv[optind++], O_RDWR | O_CREAT | O_TRUNC, &par) : bopen_fd(1, &par); bbcopy(f, t, ~0U); ASSERT(btell(f) == btell(t)); diff --git a/lib/fb-file.c b/lib/fb-file.c index 34a534cb..30f8eac5 100644 --- a/lib/fb-file.c +++ b/lib/fb-file.c @@ -1,7 +1,7 @@ /* * UCW Library -- Fast Buffered I/O on Files * - * (c) 1997--2004 Martin Mares + * (c) 1997--2007 Martin Mares * (c) 2007 Pavel Charvat * * This software may be freely distributed and used according to the terms @@ -20,7 +20,7 @@ struct fb_file { struct fastbuf fb; int fd; /* File descriptor */ - int is_temp_file; /* 0=normal file, 1=temporary file, delete on close, -1=shared FD */ + int is_temp_file; int keep_back_buf; /* Optimize for backwards reading */ sh_off_t wpos; /* Real file position */ uns wlen; /* Window size */ @@ -199,15 +199,7 @@ bfd_seek(struct fastbuf *f, sh_off_t pos, int whence) static void bfd_close(struct fastbuf *f) { - switch (FB_FILE(f)->is_temp_file) - { - case 1: - if (unlink(f->name) < 0) - msg(L_ERROR, "unlink(%s): %m", f->name); - case 0: - if (close(FB_FILE(f)->fd)) - die("close(%s): %m", f->name); - } + bclose_file_helper(f, FB_FILE(f)->fd, FB_FILE(f)->is_temp_file); xfree(f); } @@ -255,32 +247,6 @@ bfdopen_internal(int fd, const char *name, uns buflen) return f; } -struct fastbuf * -bopen_try(const char *name, uns mode, uns buflen) -{ - return bopen_file_try(name, mode, &(struct fb_params){ .type = FB_STD, .buffer_size = buflen }); -} - -struct fastbuf * -bopen(const char *name, uns mode, uns buflen) -{ - return bopen_file(name, mode, &(struct fb_params){ .type = FB_STD, .buffer_size = buflen }); -} - -struct fastbuf * -bfdopen(int fd, uns buflen) -{ - return bopen_fd(fd, &(struct fb_params){ .type = FB_STD, .buffer_size = buflen }); -} - -struct fastbuf * -bfdopen_shared(int fd, uns buflen) -{ - struct fastbuf *f = bfdopen(fd, buflen); - FB_FILE(f)->is_temp_file = -1; - return f; -} - void bfilesync(struct fastbuf *b) { @@ -295,7 +261,7 @@ int main(void) { struct fastbuf *f, *t; f = bopen_tmp(16); - t = bfdopen(1, 13); + t = bfdopen_shared(1, 13); for (uns i = 0; i < 16; i++) bwrite(f, "", 7); bprintf(t, "%d\n", (int)btell(f)); diff --git a/lib/fb-mmap.c b/lib/fb-mmap.c index 56c2ef66..a57d1034 100644 --- a/lib/fb-mmap.c +++ b/lib/fb-mmap.c @@ -7,6 +7,8 @@ * of the GNU Lesser General Public License. */ +#undef LOCAL_DEBUG + #include "lib/lib.h" #include "lib/fastbuf.h" #include "lib/lfs.h" @@ -142,15 +144,7 @@ bfmm_close(struct fastbuf *f) if (F->file_extend > F->file_size && sh_ftruncate(F->fd, F->file_size)) die("ftruncate(%s): %m", f->name); - switch (F->is_temp_file) - { - case 1: - if (unlink(f->name) < 0) - msg(L_ERROR, "unlink(%s): %m", f->name); - case 0: - if (close(F->fd)) - die("close(%s): %m", f->name); - } + bclose_file_helper(f, F->fd, F->is_temp_file); xfree(f); } @@ -200,8 +194,9 @@ bfmmopen_internal(int fd, const char *name, uns mode) int main(int argc, char **argv) { - struct fastbuf *f = bopen_mm(argv[1], O_RDONLY); - struct fastbuf *g = bopen_mm(argv[2], O_RDWR | O_CREAT | O_TRUNC); + struct fb_params par = { .type = FB_MMAP }; + struct fastbuf *f = bopen_file(argv[1], O_RDONLY, &par); + struct fastbuf *g = bopen_file(argv[2], O_RDWR | O_CREAT | O_TRUNC, &par); int c; DBG("Copying"); diff --git a/lib/fb-param.c b/lib/fb-param.c index 26225f0e..bbe9e340 100644 --- a/lib/fb-param.c +++ b/lib/fb-param.c @@ -2,6 +2,7 @@ * UCW Library -- FastIO on files with run-time parametrization * * (c) 2007 Pavel Charvat + * (c) 2007 Martin Mares * * This software may be freely distributed and used according to the terms * of the GNU Lesser General Public License. @@ -49,9 +50,9 @@ fbpar_global_init(void) } static struct fastbuf * -bopen_fd_internal(int fd, struct fb_params *params, uns mode, const byte *name) +bopen_fd_internal(int fd, struct fb_params *params, uns mode, const char *name) { - byte buf[32]; + char buf[32]; if (!name) { sprintf(buf, "fd%d", fd); @@ -84,7 +85,7 @@ bopen_fd_internal(int fd, struct fb_params *params, uns mode, const byte *name) } static struct fastbuf * -bopen_file_internal(const byte *name, int mode, struct fb_params *params, int try) +bopen_file_internal(const char *name, int mode, struct fb_params *params, int try) { if (!params) params = &fbpar_def; @@ -123,12 +124,47 @@ bopen_fd(int fd, struct fb_params *params) return bopen_fd_internal(fd, params ? : &fbpar_def, ~0U, NULL); } +/* Function for use by individual file back-ends */ + +void +bclose_file_helper(struct fastbuf *f, int fd, int is_temp_file) +{ + switch (is_temp_file) + { + case 1: + if (unlink(f->name) < 0) + msg(L_ERROR, "unlink(%s): %m", f->name); + case 0: + if (close(fd)) + die("close(%s): %m", f->name); + } +} + +/* Compatibility wrappers */ + struct fastbuf * -bopen_tmp_file(struct fb_params *params) +bopen_try(const char *name, uns mode, uns buflen) { - byte buf[TEMP_FILE_NAME_LEN]; - temp_file_name(buf); - struct fastbuf *fb = bopen_file_internal(buf, O_RDWR | O_CREAT | O_TRUNC, params, 0); - bconfig(fb, BCONFIG_IS_TEMP_FILE, 1); - return fb; + return bopen_file_try(name, mode, &(struct fb_params){ .type = FB_STD, .buffer_size = buflen }); } + +struct fastbuf * +bopen(const char *name, uns mode, uns buflen) +{ + return bopen_file(name, mode, &(struct fb_params){ .type = FB_STD, .buffer_size = buflen }); +} + +struct fastbuf * +bfdopen(int fd, uns buflen) +{ + return bopen_fd(fd, &(struct fb_params){ .type = FB_STD, .buffer_size = buflen }); +} + +struct fastbuf * +bfdopen_shared(int fd, uns buflen) +{ + struct fastbuf *f = bfdopen(fd, buflen); + bconfig(f, BCONFIG_IS_TEMP_FILE, -1); + return f; +} + diff --git a/lib/fb-temp.c b/lib/fb-temp.c index 54daad1b..1975c8cc 100644 --- a/lib/fb-temp.c +++ b/lib/fb-temp.c @@ -1,7 +1,7 @@ /* * UCW Library -- Temporary Fastbufs * - * (c) 2002--2006 Martin Mares + * (c) 2002--2007 Martin Mares * * This software may be freely distributed and used according to the terms * of the GNU Lesser General Public License. @@ -43,16 +43,19 @@ temp_file_name(char *buf) } struct fastbuf * -bopen_tmp(uns buflen) +bopen_tmp_file(struct fb_params *params) { - char buf[TEMP_FILE_NAME_LEN]; - struct fastbuf *f; + char name[TEMP_FILE_NAME_LEN]; + temp_file_name(name); + struct fastbuf *fb = bopen_file(name, O_RDWR | O_CREAT | O_TRUNC, params); + bconfig(fb, BCONFIG_IS_TEMP_FILE, 1); + return fb; +} - // FIXME: This needs cleanup and merging with other bopen functions. - temp_file_name(buf); - f = bopen(buf, O_RDWR | O_CREAT | O_TRUNC, buflen); - bconfig(f, BCONFIG_IS_TEMP_FILE, 1); - return f; +struct fastbuf * +bopen_tmp(uns buflen) +{ + return bopen_tmp_file(&(struct fb_params){ .type = FB_STD, .buffer_size = buflen }); } void bfix_tmp_file(struct fastbuf *fb, const char *name)