X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=lib%2Ffb-param.c;h=854ba78a78632e950ea6a5efe518a16a2d96ccaf;hb=c4bf633211b0424492b5a3937d6a6d2e0d79a4cf;hp=26225f0ee4d772b7c0dacba8f4b39a57f0b76bc6;hpb=deea16837b54b13974d1dfc24d9b1e6af2d14bb2;p=libucw.git diff --git a/lib/fb-param.c b/lib/fb-param.c index 26225f0e..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,11 +20,22 @@ 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), ((char *[]){"std", "direct", "mmap", NULL})), CF_UNS("BufSize", F(buffer_size)), @@ -49,9 +61,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); @@ -60,12 +72,7 @@ bopen_fd_internal(int fd, struct fb_params *params, uns mode, const byte *name) struct fastbuf *fb; switch (params->type) { - 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; +#ifdef CONFIG_UCW_THREADS case FB_DIRECT: fb = fbdir_open_fd_internal(fd, name, params->asio, params->buffer_size ? : fbpar_def.buffer_size, @@ -74,6 +81,13 @@ bopen_fd_internal(int fd, struct fb_params *params, uns mode, const byte *name) if (!~mode && !fbdir_cheat && ((int)(mode = fcntl(fd, F_GETFL)) < 0 || fcntl(fd, F_SETFL, mode | O_DIRECT)) < 0) 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); @@ -84,12 +98,14 @@ 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; +#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); @@ -123,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; }