2 * UCW Library -- FastIO on files with run-time parametrization
4 * (c) 2007 Pavel Charvat <pchar@ucw.cz>
5 * (c) 2007 Martin Mares <mj@ucw.cz>
7 * This software may be freely distributed and used according to the terms
8 * of the GNU Lesser General Public License.
14 #include "ucw/fastbuf.h"
19 struct fb_params fbpar_def = {
26 fbpar_cf_commit(struct fb_params *p UNUSED)
28 if (p->type == FB_DIRECT)
30 #ifndef CONFIG_UCW_THREADS
31 return "Direct I/O is supported only with CONFIG_UCW_THREADS";
34 return "Direct I/O is not supported on darwin";
36 #ifndef CONFIG_DIRECT_IO
37 return "Direct I/O disabled by configure switch -CONFIG_DIRECT_IO";
39 #ifndef CONFIG_UCW_FB_DIRECT
40 return "Direct I/O disabled by configure switch -CONFIG_UCW_FB_DIRECT";
46 struct cf_section fbpar_cf = {
47 # define F(x) PTR_TO(struct fb_params, x)
48 CF_TYPE(struct fb_params),
49 CF_COMMIT(fbpar_cf_commit),
51 CF_LOOKUP("Type", (int *)F(type), ((const char * const []){"std", "direct", "mmap", NULL})),
52 CF_UNS("BufSize", F(buffer_size)),
53 CF_UNS("KeepBackBuf", F(keep_back_buf)),
54 CF_UNS("ReadAhead", F(read_ahead)),
55 CF_UNS("WriteBack", F(write_back)),
61 static struct cf_section fbpar_global_cf = {
63 CF_SECTION("Defaults", &fbpar_def, &fbpar_cf),
68 static void CONSTRUCTOR
69 fbpar_global_init(void)
71 cf_declare_section("FBParam", &fbpar_global_cf, 0);
74 static struct fastbuf *
75 bopen_fd_internal(int fd, struct fb_params *params, uns mode, const char *name)
80 sprintf(buf, "fd%d", fd);
86 #ifdef CONFIG_UCW_FB_DIRECT
88 fb = fbdir_open_fd_internal(fd, name, params->asio,
89 params->buffer_size ? : fbpar_def.buffer_size,
90 params->read_ahead ? : fbpar_def.read_ahead,
91 params->write_back ? : fbpar_def.write_back);
92 if (!~mode && !fbdir_cheat && ((int)(mode = fcntl(fd, F_GETFL)) < 0 || fcntl(fd, F_SETFL, mode | O_DIRECT)) < 0)
93 msg(L_WARN, "Cannot set O_DIRECT on fd %d: %m", fd);
97 fb = bfdopen_internal(fd, name,
98 params->buffer_size ? : fbpar_def.buffer_size);
99 if (params->keep_back_buf)
100 bconfig(fb, BCONFIG_KEEP_BACK_BUF, 1);
103 if (!~mode && (int)(mode = fcntl(fd, F_GETFL)) < 0)
104 die("Cannot get flags of fd %d: %m", fd);
105 return bfmmopen_internal(fd, name, mode);
111 static struct fastbuf *
112 bopen_file_internal(const char *name, int mode, struct fb_params *params, int try)
116 #ifdef CONFIG_UCW_FB_DIRECT
117 if (params->type == FB_DIRECT && !fbdir_cheat)
120 if (params->type == FB_MMAP && (mode & O_ACCMODE) == O_WRONLY)
121 mode = (mode & ~O_ACCMODE) | O_RDWR;
122 int fd = ucw_open(name, mode, 0666);
127 die("Unable to %s file %s: %m", (mode & O_CREAT) ? "create" : "open", name);
128 struct fastbuf *fb = bopen_fd_internal(fd, params, mode, name);
131 bseek(fb, 0, SEEK_END);
136 bopen_file(const char *name, int mode, struct fb_params *params)
138 return bopen_file_internal(name, mode, params, 0);
142 bopen_file_try(const char *name, int mode, struct fb_params *params)
144 return bopen_file_internal(name, mode, params, 1);
148 bopen_fd_name(int fd, struct fb_params *params, const char *name)
150 return bopen_fd_internal(fd, params ? : &fbpar_def, ~0U, name);
153 /* Function for use by individual file back-ends */
156 bclose_file_helper(struct fastbuf *f, int fd, int is_temp_file)
158 switch (is_temp_file)
161 if (unlink(f->name) < 0)
162 msg(L_ERROR, "unlink(%s): %m", f->name);
165 die("close(%s): %m", f->name);
169 /* Compatibility wrappers */
172 bopen_try(const char *name, uns mode, uns buflen)
174 return bopen_file_try(name, mode, &(struct fb_params){ .type = FB_STD, .buffer_size = buflen });
178 bopen(const char *name, uns mode, uns buflen)
180 return bopen_file(name, mode, &(struct fb_params){ .type = FB_STD, .buffer_size = buflen });
184 bfdopen(int fd, uns buflen)
186 return bopen_fd(fd, &(struct fb_params){ .type = FB_STD, .buffer_size = buflen });
190 bfdopen_shared(int fd, uns buflen)
192 struct fastbuf *f = bfdopen(fd, buflen);
193 bconfig(f, BCONFIG_IS_TEMP_FILE, 2);