From 642c11eb6419e6ce8acabc4d7ebf0124f3bd702c Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Thu, 21 Feb 2008 21:04:11 +0100 Subject: [PATCH] Replace EFF_RDONLY by EFF_PRIVATE Read-only was a bit of a misnomer: you could write to the table by obtaining a pointer into it from ef_ptr(), you just couldn't write to the backing file. Semantic changes: * ef_flush() is now allowed when the table is file-backed or privately mapped. Before, it had to be file-backed. Flushing a privately mapped table does nothing, just like flushing a read-only table did. * ef_write() is now allowed when the table is file-backed or fully cached. Before, it had to be file-backed and not read-only. Writing to a privately mapped file-backed table doesn't write to the file. * ef_extend() is not implemented for privately mapped tables, just like it wasn't implemented for read-only tables. --- include/file.h | 9 +++++---- src/lib/common/file.c | 30 +++++++++++++++++++++--------- src/lib/global/file.c | 4 ++-- 3 files changed, 28 insertions(+), 15 deletions(-) diff --git a/include/file.h b/include/file.h index 6748ba78a..1242a660f 100644 --- a/include/file.h +++ b/include/file.h @@ -57,7 +57,7 @@ struct empfile { int cids; /* # entries in cache */ int fids; /* # entries in table */ int fd; /* file descriptor, -1 if not open */ - /* flags bits EFF_RDONLY, EFF_CUSTOM also vary */ + /* flags bits EFF_PRIVATE, EFF_CUSTOM also vary */ /* User callbacks */ void (*init)(int, void *); /* called after entry creation, unless null */ @@ -86,8 +86,8 @@ struct empfile { /* Flags set when table contents is mapped */ /* Table is entirely in memory */ #define EFF_MEM bit(8) -/* Table is read-only */ -#define EFF_RDONLY bit(9) +/* Table is privately mapped: changes don't affect the underlying file */ +#define EFF_PRIVATE bit(9) /* Table is customized (configuration tables only) */ #define EFF_CUSTOM bit(10) /* Transient flags, only occur in argument of ef_open() */ @@ -97,7 +97,8 @@ struct empfile { /* * Empire `file types' * These are really table IDs. Some tables are backed by files, some - * are compiled into the server. + * are compiled into the server, some initialized from configuration + * files. */ enum { /* Error value */ diff --git a/src/lib/common/file.c b/src/lib/common/file.c index ebf5ab259..a4f728591 100644 --- a/src/lib/common/file.c +++ b/src/lib/common/file.c @@ -73,7 +73,7 @@ ef_open(int type, int how) if (CANT_HAPPEN(ep->fd >= 0)) return 0; oflags = O_RDWR; - if (how & EFF_RDONLY) + if (how & EFF_PRIVATE) oflags = O_RDONLY; if (how & EFF_CREATE) oflags |= O_CREAT | O_TRUNC; @@ -85,7 +85,7 @@ ef_open(int type, int how) return 0; } - lock.l_type = how & EFF_RDONLY ? F_RDLCK : F_WRLCK; + lock.l_type = how & EFF_PRIVATE ? F_RDLCK : F_WRLCK; lock.l_whence = SEEK_SET; lock.l_start = lock.l_len = 0; if (fcntl(fd, F_SETLK, &lock) == -1) { @@ -177,7 +177,8 @@ ef_close(int type) } /* - * Flush file-backed table TYPE (EF_SECTOR, ...) to disk. + * Flush table TYPE (EF_SECTOR, ...) to disk. + * Does nothing if the table is privately mapped. * Return non-zero on success, zero on failure. */ int @@ -188,6 +189,8 @@ ef_flush(int type) if (ef_check(type) < 0) return 0; ep = &empfile[type]; + if (ep->flags & EFF_PRIVATE) + return 1; /* nothing to do */ if (CANT_HAPPEN(ep->fd < 0)) return 0; /* @@ -196,7 +199,7 @@ ef_flush(int type) * allowed only with EFF_MEM. Assume the whole cash is dirty * then. */ - if (!(ep->flags & EFF_RDONLY) && (ep->flags & EFF_MEM)) + if (ep->flags & EFF_MEM) return do_write(ep, ep->cache, ep->baseid, ep->cids) >= 0; return 1; @@ -311,7 +314,8 @@ do_write(struct empfile *ep, void *buf, int id, int count) int n, ret; char *p; - if (CANT_HAPPEN(ep->fd < 0 || id < 0 || count < 0)) + if (CANT_HAPPEN(ep->fd < 0 || (ep->flags & EFF_PRIVATE) + || id < 0 || count < 0)) return -1; if (lseek(ep->fd, id * ep->size, SEEK_SET) == (off_t)-1) { @@ -339,9 +343,10 @@ do_write(struct empfile *ep, void *buf, int id, int count) } /* - * Write element ID into file-backed table TYPE from buffer FROM. + * Write element ID into table TYPE from buffer FROM. * FIXME pass buffer size! - * Write through cache straight to disk. + * If table is file-backed and not privately mapped, write through + * cache straight to disk. * Cannot write beyond the end of fully cached table (flags & EFF_MEM). * Can write at the end of partially cached table. * Return non-zero on success, zero on failure. @@ -355,12 +360,16 @@ ef_write(int type, int id, void *from) if (ef_check(type) < 0) return 0; ep = &empfile[type]; + if (CANT_HAPPEN((ep->flags & (EFF_MEM | EFF_PRIVATE)) == EFF_PRIVATE)) + return 0; if (ep->prewrite) ep->prewrite(id, from); if (CANT_HAPPEN((ep->flags & EFF_MEM) ? id >= ep->fids : id > ep->fids)) return 0; /* not implemented */ - if (do_write(ep, from, id, 1) < 0) - return 0; + if (!(ep->flags & EFF_PRIVATE)) { + if (do_write(ep, from, id, 1) < 0) + return 0; + } if (id >= ep->baseid && id < ep->baseid + ep->cids) { /* update the cache if necessary */ to = ep->cache + (id - ep->baseid) * ep->size; @@ -376,6 +385,7 @@ ef_write(int type, int id, void *from) /* * Extend the file-backed table TYPE by COUNT elements. + * Can't extend privately mapped tables. * Return non-zero on success, zero on failure. */ int @@ -390,6 +400,8 @@ ef_extend(int type, int count) ep = &empfile[type]; if (CANT_HAPPEN(ep->fd < 0 || count < 0)) return 0; + if (CANT_HAPPEN(ep->flags & EFF_PRIVATE)) + return 0; /* not implemented */ tmpobj = calloc(1, ep->size); id = ep->fids; diff --git a/src/lib/global/file.c b/src/lib/global/file.c index 51e28dc11..9db598fc0 100644 --- a/src/lib/global/file.c +++ b/src/lib/global/file.c @@ -85,7 +85,7 @@ SZ((array)), 0, SZ((array)) - 1, SZ((array)) - 1, -1, NULL, NULL, NULL /* Common configuration table flags */ -#define EFF_CFG (EFF_RDONLY | EFF_MEM | EFF_STATIC) +#define EFF_CFG (EFF_PRIVATE | EFF_MEM | EFF_STATIC) struct empfile empfile[] = { /* @@ -95,7 +95,7 @@ struct empfile empfile[] = { * bits of flags get their final value. * If flags & EFF_STATIC, the cache is mapped here, and members * cache, csize get their final value. - * Members baseid, cids, fids and the EFF_MEM|EFF_RDONLY bits of + * Members baseid, cids, fids and the EFF_MEM|EFF_PRIVATE bits of * flags are initialized according the initial cache contents. * Member fd is initialized to -1. * Members init, postread, prewrite get initialized to NULL, but -- 2.43.0