X-Git-Url: http://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Ftdb2%2Fopen.c;h=68f707b920ec8cf72bcf66b9788c1abd25bc26c0;hp=def816775c76efa8cd80db786084926c6e04e5d8;hb=b87e14495d5b07e1b247218a72329f10ecb3da7f;hpb=de868b8eee34e39b4465dd9def9141b97926e847 diff --git a/ccan/tdb2/open.c b/ccan/tdb2/open.c index def81677..68f707b9 100644 --- a/ccan/tdb2/open.c +++ b/ccan/tdb2/open.c @@ -1,3 +1,20 @@ + /* + Trivial Database 2: opening and closing TDBs + Copyright (C) Rusty Russell 2010 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ #include "private.h" #include #include @@ -352,6 +369,7 @@ struct tdb_context *tdb_open(const char *name, int tdb_flags, tdb->log_fn = NULL; tdb->transaction = NULL; tdb->access = NULL; + tdb->open_flags = open_flags; tdb->last_error = TDB_SUCCESS; tdb->file = NULL; tdb->lock_fn = tdb_fcntl_lock; @@ -384,7 +402,8 @@ struct tdb_context *tdb_open(const char *name, int tdb_flags, } if (tdb_flags & ~(TDB_INTERNAL | TDB_NOLOCK | TDB_NOMMAP | TDB_CONVERT - | TDB_NOSYNC | TDB_SEQNUM | TDB_ALLOW_NESTING)) { + | TDB_NOSYNC | TDB_SEQNUM | TDB_ALLOW_NESTING + | TDB_RDONLY)) { ecode = tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR, "tdb_open: unknown flags %u", tdb_flags); goto fail; @@ -398,12 +417,16 @@ struct tdb_context *tdb_open(const char *name, int tdb_flags, } if ((open_flags & O_ACCMODE) == O_RDONLY) { - tdb->read_only = true; - tdb->mmap_flags = PROT_READ; openlock = F_RDLCK; + tdb->flags |= TDB_RDONLY; } else { - tdb->read_only = false; - tdb->mmap_flags = PROT_READ | PROT_WRITE; + if (tdb_flags & TDB_RDONLY) { + ecode = tdb_logerr(tdb, TDB_ERR_EINVAL, + TDB_LOG_USE_ERROR, + "tdb_open: can't use TDB_RDONLY" + " without O_RDONLY"); + goto fail; + } openlock = F_WRLCK; } @@ -515,6 +538,12 @@ struct tdb_context *tdb_open(const char *name, int tdb_flags, name, (long long)hdr.version); goto fail; } + } else if (tdb->flags & TDB_CONVERT) { + ecode = tdb_logerr(tdb, TDB_ERR_IO, TDB_LOG_ERROR, + "tdb_open:" + " %s does not need TDB_CONVERT", + name); + goto fail; } tdb_convert(tdb, &hdr, sizeof(hdr)); @@ -533,17 +562,20 @@ struct tdb_context *tdb_open(const char *name, int tdb_flags, /* Clear any features we don't understand. */ if ((open_flags & O_ACCMODE) != O_RDONLY) { hdr.features_used &= TDB_FEATURE_MASK; - if (tdb_write_convert(tdb, offsetof(struct tdb_header, - features_used), - &hdr.features_used, - sizeof(hdr.features_used)) == -1) + ecode = tdb_write_convert(tdb, offsetof(struct tdb_header, + features_used), + &hdr.features_used, + sizeof(hdr.features_used)); + if (ecode != TDB_SUCCESS) goto fail; } tdb_unlock_open(tdb, openlock); /* This make sure we have current map_size and mmap. */ - tdb->methods->oob(tdb, tdb->file->map_size + 1, true); + ecode = tdb->methods->oob(tdb, tdb->file->map_size + 1, true); + if (unlikely(ecode != TDB_SUCCESS)) + goto fail; /* Now it's fully formed, recover if necessary. */ berr = tdb_needs_recovery(tdb);