X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=lib%2Ffb-param.c;h=854ba78a78632e950ea6a5efe518a16a2d96ccaf;hb=4cd590195cb23a667ff5f329a721b6f4ce2e6dc3;hp=38cd5801118293e1bdf71c5268c612cb869e7394;hpb=434c630cf7aa4b4facc1d2fcfb6e9bc4cf21dff1;p=libucw.git diff --git a/lib/fb-param.c b/lib/fb-param.c index 38cd5801..854ba78a 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. @@ -19,14 +20,26 @@ struct fb_params fbpar_def = { .buffer_size = 65536, .read_ahead = 1, .write_back = 1, -}; +}; + +static char * +fbpar_cf_commit(struct fb_params *p UNUSED) +{ +#ifndef CONFIG_UCW_THREADS + if (p->type == FB_DIRECT) + return "Direct I/O is supported only with CONFIG_UCW_THREADS"; +#endif + return NULL; +} struct cf_section fbpar_cf = { # define F(x) PTR_TO(struct fb_params, x) CF_TYPE(struct fb_params), + CF_COMMIT(fbpar_cf_commit), CF_ITEMS { - CF_LOOKUP("Type", (int *)F(type), ((byte *[]){"std", "direct", "mmap", NULL})), + CF_LOOKUP("Type", (int *)F(type), ((char *[]){"std", "direct", "mmap", NULL})), CF_UNS("BufSize", F(buffer_size)), + CF_UNS("KeepBackBuf", F(keep_back_buf)), CF_UNS("ReadAhead", F(read_ahead)), CF_UNS("WriteBack", F(write_back)), CF_END @@ -48,38 +61,51 @@ fbpar_global_init(void) } static struct fastbuf * -bopen_fd_internal(int fd, struct fb_params *params, uns mode, 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(name = buf, "fd%d", fd); + { + sprintf(buf, "fd%d", fd); + name = buf; + } struct fastbuf *fb; switch (params->type) { - case FB_STD: - return bfdopen_internal(fd, name, - params->buffer_size ? : fbpar_def.buffer_size); +#ifdef CONFIG_UCW_THREADS case FB_DIRECT: fb = fbdir_open_fd_internal(fd, name, params->asio, params->buffer_size ? : fbpar_def.buffer_size, params->read_ahead ? : fbpar_def.read_ahead, params->write_back ? : fbpar_def.write_back); if (!~mode && !fbdir_cheat && ((int)(mode = fcntl(fd, F_GETFL)) < 0 || fcntl(fd, F_SETFL, mode | O_DIRECT)) < 0) - log(L_WARN, "Cannot set O_DIRECT on fd %d: %m", fd); + msg(L_WARN, "Cannot set O_DIRECT on fd %d: %m", fd); + return fb; +#endif + case FB_STD: + fb = bfdopen_internal(fd, name, + params->buffer_size ? : fbpar_def.buffer_size); + if (params->keep_back_buf) + bconfig(fb, BCONFIG_KEEP_BACK_BUF, 1); return fb; case FB_MMAP: if (!~mode && (int)(mode = fcntl(fd, F_GETFL)) < 0) die("Cannot get flags of fd %d: %m", fd); return bfmmopen_internal(fd, name, mode); + default: + ASSERT(0); } - ASSERT(0); } static struct fastbuf * -bopen_file_internal(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; +#ifdef CONFIG_UCW_THREADS if (params->type == FB_DIRECT && !fbdir_cheat) mode |= O_DIRECT; +#endif if (params->type == FB_MMAP && (mode & O_ACCMODE) == O_WRONLY) mode = (mode & ~O_ACCMODE) | O_RDWR; int fd = sh_open(name, mode, 0666); @@ -96,15 +122,15 @@ bopen_file_internal(byte *name, int mode, struct fb_params *params, int try) } struct fastbuf * -bopen_file(byte *name, int mode, struct fb_params *params) +bopen_file(const char *name, int mode, struct fb_params *params) { - return bopen_file_internal(name, mode, params ? : &fbpar_def, 0); + return bopen_file_internal(name, mode, params, 0); } struct fastbuf * -bopen_file_try(byte *name, int mode, struct fb_params *params) +bopen_file_try(const char *name, int mode, struct fb_params *params) { - return bopen_file_internal(name, mode, params ? : &fbpar_def, 1); + return bopen_file_internal(name, mode, params, 1); } struct fastbuf * @@ -113,12 +139,46 @@ 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, 2); + return f; }