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 */
+
+enum fb_type {
+ FB_STD,
+ FB_DIRECT,
+ FB_MMAP
+};
+
+struct fb_params {
+ enum fb_type type;
+ uns buffer_size;
+ uns read_ahead;
+ uns write_back;
+ struct asio_queue *asio;
+};
+
+struct cf_section;
+extern struct cf_section fbpar_cf;
+extern struct fb_params fbpar_def;
+
+struct fastbuf *bopen_file(byte *name, int mode, struct fb_params *params);
+struct fastbuf *bopen_file_try(byte *name, int mode, struct fb_params *params);
+struct fastbuf *bopen_tmp_file(struct fb_params *params);
+struct fastbuf *bopen_fd(int fd, struct fb_params *params);
+
/* FastIO on standard files (specify buffer size 0 to enable mmaping) */
-struct fastbuf *bfdopen_internal(int fd, uns buflen, byte *name);
+struct fastbuf *bfdopen_internal(int fd, byte *name, uns buflen);
struct fastbuf *bopen(byte *name, uns mode, uns buflen);
struct fastbuf *bopen_try(byte *name, uns mode, uns buflen);
struct fastbuf *bopen_tmp(uns buflen);
/* FastIO on memory mapped files */
+struct fastbuf *bfmmopen_internal(int fd, byte *name, uns mode);
struct fastbuf *bopen_mm(byte *name, uns mode);
/* FastIO on files opened with O_DIRECT (see fb-direct.c for description) */
extern uns fbdir_cheat;
struct asio_queue;
-struct fastbuf *fbdir_open_fd_internal(int fd, struct asio_queue *io_queue, byte *name);
+struct fastbuf *fbdir_open_fd_internal(int fd, byte *name, struct asio_queue *io_queue, uns buffer_size, uns read_ahead, uns write_back);
struct fastbuf *fbdir_open(byte *name, uns mode, struct asio_queue *io_queue);
struct fastbuf *fbdir_open_try(byte *name, uns mode, struct asio_queue *io_queue);
struct fastbuf *fbdir_open_fd(int fd, struct asio_queue *io_queue);
struct fastbuf *fbdir_open_tmp(struct asio_queue *io_queue);
-/* FastIO on files with run-time parametrization */
-
-enum fb_type {
- FB_STD,
- FB_DIRECT,
- FB_MMAP
-};
-
-struct fb_params {
- enum fb_type type;
- uns buffer_size;
- struct asio_queue *asio;
-};
-
-struct cf_section;
-extern struct cf_section fbpar_cf;
-extern struct fb_params fbpar_def;
-
-struct fastbuf *bopen_file(byte *name, int mode, struct fb_params *params);
-struct fastbuf *bopen_file_try(byte *name, int mode, struct fb_params *params);
-struct fastbuf *bopen_tmp_file(struct fb_params *params);
-struct fastbuf *bopen_fd(int fd, struct fb_params *params);
-
/* FastI on file descriptors with limit */
struct fastbuf *bopen_limited_fd(int fd, uns bufsize, uns limit);
#include <stdio.h>
uns fbdir_cheat;
-static uns fbdir_buffer_size = 65536;
-static uns fbdir_read_ahead = 1;
-static uns fbdir_write_back = 1;
static struct cf_section fbdir_cf = {
CF_ITEMS {
CF_UNS("Cheat", &fbdir_cheat),
- CF_UNS("BufferSize", &fbdir_buffer_size),
- CF_UNS("ReadAhead", &fbdir_read_ahead),
- CF_UNS("WriteBack", &fbdir_write_back),
CF_END
}
};
}
static struct asio_queue *
-fbdir_get_io_queue(void)
+fbdir_get_io_queue(uns buffer_size, uns write_back)
{
struct ucwlib_context *ctx = ucwlib_thread_context();
struct asio_queue *q = ctx->io_queue;
if (!q)
{
q = xmalloc_zero(sizeof(struct asio_queue));
- q->buffer_size = fbdir_buffer_size;
- q->max_writebacks = fbdir_write_back;
+ q->buffer_size = buffer_size;
+ q->max_writebacks = write_back;
asio_init_queue(q);
ctx->io_queue = q;
}
}
struct fastbuf *
-fbdir_open_fd_internal(int fd, struct asio_queue *q, byte *name)
+fbdir_open_fd_internal(int fd, byte *name, struct asio_queue *q, uns buffer_size, uns read_ahead UNUSED, uns write_back)
{
int namelen = strlen(name) + 1;
struct fb_direct *F = xmalloc(sizeof(struct fb_direct) + namelen);
if (q)
F->io_queue = F->user_queue = q;
else
- F->io_queue = fbdir_get_io_queue();
+ F->io_queue = fbdir_get_io_queue(buffer_size, write_back);
f->refill = fbdir_refill;
f->spout = fbdir_spout;
f->seek = fbdir_seek;
}
struct fastbuf *
-bfdopen_internal(int fd, uns buflen, byte *name)
+bfdopen_internal(int fd, byte *name, uns buflen)
{
+ ASSERT(buflen);
int namelen = strlen(name) + 1;
struct fb_file *F = xmalloc(sizeof(struct fb_file) + buflen + namelen);
struct fastbuf *f = &F->fb;
- ASSERT(buflen);
bzero(F, sizeof(*F));
f->buffer = (byte *)(F+1);
f->bptr = f->bstop = f->buffer;
}
}
-static struct fastbuf *
+struct fastbuf *
bfmmopen_internal(int fd, byte *name, uns mode)
{
int namelen = strlen(name) + 1;
struct fastbuf *
bopen_mm(byte *name, uns mode)
{
- int fd;
-
if ((mode & O_ACCMODE) == O_WRONLY)
mode = (mode & ~O_ACCMODE) | O_RDWR;
- fd = sh_open(name, mode, 0666);
- if (fd < 0)
- die("Unable to %s file %s: %m",
- (mode & O_CREAT) ? "create" : "open", name);
- return bfmmopen_internal(fd, name, mode);
+ return bopen_file(name, mode, &(struct fb_params){ .type = FB_MMAP });
}
#ifdef TEST
struct fb_params fbpar_def = {
.buffer_size = 65536,
+ .read_ahead = 1,
+ .write_back = 1,
};
struct cf_section fbpar_cf = {
# define F(x) PTR_TO(struct fb_params, x)
CF_TYPE(struct fb_params),
CF_ITEMS {
- // FIXME
CF_LOOKUP("Type", (int *)F(type), ((byte *[]){"std", "direct", "mmap", NULL})),
CF_UNS("BufSize", F(buffer_size)),
+ CF_UNS("ReadAhead", F(read_ahead)),
+ CF_UNS("WriteBack", F(write_back)),
CF_END
}
# undef F
}
static struct fastbuf *
-bopen_fd_internal(int fd, struct fb_params *params, byte *name)
+bopen_fd_internal(int fd, struct fb_params *params, uns mode, byte *name)
{
+ byte buf[32];
+ if (!name)
+ sprintf(name = buf, "fd%d", fd);
struct fastbuf *fb;
switch (params->type)
{
case FB_STD:
- return bfdopen_internal(fd, params->buffer_size, name);
+ return bfdopen_internal(fd, name,
+ params->buffer_size ? : fbpar_def.buffer_size);
case FB_DIRECT:
- fb = fbdir_open_fd_internal(fd, params->asio, name);
- if (!fbdir_cheat && fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_DIRECT) < 0)
+ 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);
return fb;
case FB_MMAP:
- // FIXME
- ASSERT(0);
+ if (!~mode && (int)(mode = fcntl(fd, F_GETFL)) < 0)
+ die("Cannot get flags of fd %d: %m", fd);
+ return bfmmopen_internal(fd, name, mode);
}
ASSERT(0);
}
return NULL;
else
die("Unable to %s file %s: %m", (mode & O_CREAT) ? "create" : "open", name);
- struct fastbuf *fb = bopen_fd_internal(fd, params, name);
+ struct fastbuf *fb = bopen_fd_internal(fd, params, mode, name);
ASSERT(fb);
if (mode & O_APPEND)
bseek(fb, 0, SEEK_END);
struct fastbuf *
bopen_fd(int fd, struct fb_params *params)
{
- byte x[32];
- sprintf(x, "fd%d", fd);
- return bopen_fd_internal(fd, params ? : &fbpar_def, x);
+ return bopen_fd_internal(fd, params ? : &fbpar_def, ~0U, NULL);
}
struct fastbuf *