2 * $Id: cnid_cdb_rebuild_add.c,v 1.2 2005-04-28 20:49:59 bfernhomberg Exp $
4 * All Rights Reserved. See COPYRIGHT.
10 #endif /* HAVE_CONFIG_H */
12 #ifdef CNID_BACKEND_CDB
13 #include "cnid_cdb_private.h"
21 /* FIXME: Enhance for 8 byte dev/inode */
22 char *make_cnid_data(const struct stat *st,const cnid_t did,
23 const char *name, const int len)
25 static char start[CNID_HEADER_LEN + MAXPATHLEN + 1];
26 char *buf = start +CNID_LEN;
32 memcpy(buf, &st->st_dev, sizeof(st->st_dev));
33 buf += sizeof(st->st_dev);
35 i = htonl(st->st_ino);
36 memcpy(buf , &st->st_ino, sizeof(st->st_ino));
37 buf += sizeof(st->st_ino);
39 i = S_ISDIR(st->st_mode)?1:0;
41 memcpy(buf, &i, sizeof(i));
44 /* did is already in network byte order */
45 memcpy(buf, &did, sizeof(did));
48 memcpy(buf, name, len);
56 /* ----------------------------- */
57 static cnid_t set_max_cnid(CNID_private *db, cnid_t hint)
59 DBT rootinfo_key, rootinfo_data;
61 char buf[ROOTINFO_DATALEN];
65 memset(&rootinfo_key, 0, sizeof(rootinfo_key));
66 memset(&rootinfo_data, 0, sizeof(rootinfo_data));
68 rootinfo_key.data = ROOTINFO_KEY;
69 rootinfo_key.size = ROOTINFO_KEYLEN;
71 switch ((rc = db->db_cnid->get(db->db_cnid, tid, &rootinfo_key, &rootinfo_data, 0))) {
73 memcpy(buf, (char *)rootinfo_data.data, ROOTINFO_DATALEN);
76 /* FIXME: This duplicates stuff from cnid_cdb_add.c.
77 We also implicitely assume that sizeof(time_t) <= CNID_DEV_LEN */
78 memcpy(buf, ROOTINFO_DATA, ROOTINFO_DATALEN);
80 memset(buf + CNID_DEV_OFS, 0, CNID_DEV_LEN);
81 memcpy(buf + CNID_DEV_OFS, &t, sizeof(time_t));
82 id = htonl(CNID_START);
83 memcpy(buf + CNID_TYPE_OFS, &id, sizeof(id));
86 LOG(log_error, logtype_default, "set_max_cnid: Unable to read rootinfo: %s", db_strerror(rc));
91 memcpy(&id, buf + CNID_TYPE_OFS, sizeof(id));
96 memcpy(buf + CNID_TYPE_OFS, &hint, sizeof(hint));
97 rootinfo_data.data = buf;
98 rootinfo_data.size = ROOTINFO_DATALEN;
99 if ((rc = db->db_cnid->put(db->db_cnid, tid, &rootinfo_key, &rootinfo_data, 0))) {
100 LOG(log_error, logtype_default, "set_max_cnid: Unable to write rootinfo: %s", db_strerror(rc));
112 /* ------------------------ */
113 cnid_t cnid_cdb_rebuild_add(struct _cnid_db *cdb, const struct stat *st,
114 const cnid_t did, const char *name, const int len,
121 if (!cdb || !(db = cdb->_private) || !st || !name || hint == CNID_INVALID || hint < CNID_START) {
122 errno = CNID_ERR_PARAM;
127 /* FIXME: Bjoern does a lookup. Should we not overwrite unconditionally? */
129 id = cnid_cdb_lookup(cdb, st, did, name, len);
130 /* ... Return id if it is valid, or if Rootinfo is read-only. */
131 if (id || (db->flags & CNIDFLAG_DB_RO)) {
133 LOG(log_info, logtype_default, "cnid_add: Looked up did %u, name %s as %u", ntohl(did), name, ntohl(id));
139 /* Initialize our DBT data structures. */
140 memset(&key, 0, sizeof(key));
141 memset(&data, 0, sizeof(data));
143 if ((data.data = make_cnid_data(st, did, name, len)) == NULL) {
144 LOG(log_error, logtype_default, "cnid_add: Path name is too long");
145 errno = CNID_ERR_PATH;
148 data.size = CNID_HEADER_LEN + len + 1;
150 memcpy(data.data, &hint, sizeof(hint));
153 key.size = sizeof(hint);
155 /* Now we need to add the CNID data to the databases. */
156 if ((rc = db->db_cnid->put(db->db_cnid, tid, &key, &data, 0))) {
157 LOG(log_error, logtype_default
158 , "cnid_add: Failed to add CNID for %s to database using hint %u: %s",
159 name, ntohl(hint), db_strerror(rc));
164 if (set_max_cnid(db, hint) == CNID_INVALID) {
170 LOG(log_info, logtype_default, "cnid_add: Returned CNID for did %u, name %s as %u", ntohl(did), name, ntohl(hint));
179 #endif /* CNID_BACKEND_CDB */