2 * UCW Library -- FastIO on files with run-time parametrization
4 * (c) 2007 Pavel Charvat <pchar@ucw.cz>
6 * This software may be freely distributed and used according to the terms
7 * of the GNU Lesser General Public License.
13 #include "lib/fastbuf.h"
18 struct fb_params fbpar_def = {
24 struct cf_section fbpar_cf = {
25 # define F(x) PTR_TO(struct fb_params, x)
26 CF_TYPE(struct fb_params),
28 CF_LOOKUP("Type", (int *)F(type), ((char *[]){"std", "direct", "mmap", NULL})),
29 CF_UNS("BufSize", F(buffer_size)),
30 CF_UNS("KeepBackBuf", F(keep_back_buf)),
31 CF_UNS("ReadAhead", F(read_ahead)),
32 CF_UNS("WriteBack", F(write_back)),
38 static struct cf_section fbpar_global_cf = {
40 CF_SECTION("Defaults", &fbpar_def, &fbpar_cf),
45 static void CONSTRUCTOR
46 fbpar_global_init(void)
48 cf_declare_section("FBParam", &fbpar_global_cf, 0);
51 static struct fastbuf *
52 bopen_fd_internal(int fd, struct fb_params *params, uns mode, const byte *name)
57 sprintf(buf, "fd%d", fd);
64 fb = bfdopen_internal(fd, name,
65 params->buffer_size ? : fbpar_def.buffer_size);
66 if (params->keep_back_buf)
67 bconfig(fb, BCONFIG_KEEP_BACK_BUF, 1);
70 fb = fbdir_open_fd_internal(fd, name, params->asio,
71 params->buffer_size ? : fbpar_def.buffer_size,
72 params->read_ahead ? : fbpar_def.read_ahead,
73 params->write_back ? : fbpar_def.write_back);
74 if (!~mode && !fbdir_cheat && ((int)(mode = fcntl(fd, F_GETFL)) < 0 || fcntl(fd, F_SETFL, mode | O_DIRECT)) < 0)
75 msg(L_WARN, "Cannot set O_DIRECT on fd %d: %m", fd);
78 if (!~mode && (int)(mode = fcntl(fd, F_GETFL)) < 0)
79 die("Cannot get flags of fd %d: %m", fd);
80 return bfmmopen_internal(fd, name, mode);
86 static struct fastbuf *
87 bopen_file_internal(const byte *name, int mode, struct fb_params *params, int try)
89 if (params->type == FB_DIRECT && !fbdir_cheat)
91 if (params->type == FB_MMAP && (mode & O_ACCMODE) == O_WRONLY)
92 mode = (mode & ~O_ACCMODE) | O_RDWR;
93 int fd = sh_open(name, mode, 0666);
98 die("Unable to %s file %s: %m", (mode & O_CREAT) ? "create" : "open", name);
99 struct fastbuf *fb = bopen_fd_internal(fd, params, mode, name);
102 bseek(fb, 0, SEEK_END);
107 bopen_file(const char *name, int mode, struct fb_params *params)
109 return bopen_file_internal(name, mode, params ? : &fbpar_def, 0);
113 bopen_file_try(const char *name, int mode, struct fb_params *params)
115 return bopen_file_internal(name, mode, params ? : &fbpar_def, 1);
119 bopen_fd(int fd, struct fb_params *params)
121 return bopen_fd_internal(fd, params ? : &fbpar_def, ~0U, NULL);
125 bopen_tmp_file(struct fb_params *params)
127 byte buf[TEMP_FILE_NAME_LEN];
129 struct fastbuf *fb = bopen_file_internal(buf, O_RDWR | O_CREAT | O_TRUNC, params, 0);
130 bconfig(fb, BCONFIG_IS_TEMP_FILE, 1);