2
* $Id: cnid_tdb_add.c,v 1.1.2.1.2.2 2005/01/31 17:01:16 didg Exp $
4
* Copyright (c) 1999. Adrian Sun (asun@zoology.washington.edu)
5
* All Rights Reserved. See COPYRIGHT.
13
#ifdef CNID_BACKEND_TDB
15
#include <atalk/util.h>
16
#include <sys/param.h>
17
#include <sys/types.h>
20
#include <atalk/logger.h>
22
/* add an entry to the CNID databases. we do this as a transaction
23
* to prevent messiness. */
25
static int add_cnid (struct _cnid_tdb_private *db, TDB_DATA *key, TDB_DATA *data) {
26
TDB_DATA altkey, altdata;
28
memset(&altkey, 0, sizeof(altkey));
29
memset(&altdata, 0, sizeof(altdata));
33
if (tdb_store(db->tdb_cnid, *key, *data, TDB_REPLACE)) {
37
/* dev/ino database */
38
altkey.dptr = data->dptr;
39
altkey.dsize = TDB_DEVINO_LEN;
40
altdata.dptr = key->dptr;
41
altdata.dsize = key->dsize;
42
if (tdb_store(db->tdb_devino, altkey, altdata, TDB_REPLACE)) {
46
/* did/name database */
47
altkey.dptr = (char *) data->dptr + TDB_DEVINO_LEN;
48
altkey.dsize = data->dsize - TDB_DEVINO_LEN;
49
if (tdb_store(db->tdb_didname, altkey, altdata, TDB_REPLACE)) {
58
/* ----------------------- */
59
static cnid_t get_cnid(struct _cnid_tdb_private *db)
61
TDB_DATA rootinfo_key, data;
64
memset(&rootinfo_key, 0, sizeof(rootinfo_key));
65
memset(&data, 0, sizeof(data));
66
rootinfo_key.dptr = ROOTINFO_KEY;
67
rootinfo_key.dsize = ROOTINFO_KEYLEN;
69
tdb_chainlock(db->tdb_didname, rootinfo_key);
70
data = tdb_fetch(db->tdb_didname, rootinfo_key);
73
memcpy(&hint, data.dptr, sizeof(cnid_t));
76
/* If we've hit the max CNID allowed, we return a fatal error. CNID
77
* needs to be recycled before proceding. */
78
if (++id == CNID_INVALID) {
79
LOG(log_error, logtype_default, "cnid_add: FATAL: CNID database has reached its limit.");
86
hint = htonl(TDB_START);
89
memset(&data, 0, sizeof(data));
90
data.dptr = (char *)&hint;
91
data.dsize = sizeof(hint);
92
if (tdb_store(db->tdb_didname, rootinfo_key, data, TDB_REPLACE)) {
96
tdb_chainunlock(db->tdb_didname, rootinfo_key );
99
tdb_chainunlock(db->tdb_didname, rootinfo_key);
104
/* ------------------------ */
105
cnid_t cnid_tdb_add(struct _cnid_db *cdb, const struct stat *st,
106
const cnid_t did, char *name, const int len, cnid_t hint)
108
const struct stat *lstp;
110
struct _cnid_tdb_private *priv;
114
if (!cdb || !(priv = cdb->_private) || !st || !name) {
115
errno = CNID_ERR_PARAM;
119
id = cnid_tdb_lookup(cdb, st, did, name, len);
120
/* ... Return id if it is valid, or if Rootinfo is read-only. */
121
if (id || (priv->flags & TDBFLAG_DB_RO)) {
127
lstp = lstat(name, &lst) < 0 ? st : &lst;
131
/* Initialize our DBT data structures. */
132
memset(&key, 0, sizeof(key));
133
memset(&data, 0, sizeof(data));
135
key.dptr = (char *)&hint;
136
key.dsize = sizeof(cnid_t);
137
if ((data.dptr = make_tdb_data(lstp, did, name, len)) == NULL) {
138
LOG(log_error, logtype_default, "tdb_add: Path name is too long");
139
errno = CNID_ERR_PATH;
142
data.dsize = TDB_HEADER_LEN + len + 1;
143
hint = get_cnid(priv);
149
/* Now we need to add the CNID data to the databases. */
150
rc = add_cnid(priv, &key, &data);
152
LOG(log_error, logtype_default, "tdb_add: Failed to add CNID for %s to database using hint %u", name, ntohl(hint));