2 * $Id: cnid_cdb_lookup.c,v 1.6 2009-11-20 17:22:11 didg Exp $
7 #endif /* HAVE_CONFIG_H */
9 #ifdef CNID_BACKEND_CDB
10 #include "cnid_cdb_private.h"
12 #define LOGFILEMAX 100 /* kbytes */
13 #define CHECKTIMEMAX 30 /* minutes */
15 /* This returns the CNID corresponding to a particular file. It will
16 * also fix up the various databases if there's a problem. */
17 cnid_t cnid_cdb_lookup(struct _cnid_db *cdb, const struct stat *st, const cnid_t did,
18 char *name, const size_t len)
22 DBT key, devdata, diddata;
23 char dev[CNID_DEV_LEN];
24 char ino[CNID_INO_LEN];
25 int devino = 1, didname = 1;
26 u_int32_t type_devino = (unsigned)-1;
27 u_int32_t type_didname = (unsigned)-1;
30 cnid_t id_devino, id_didname,id = 0;
33 if (!cdb || !(db = cdb->_private) || !st || !name) {
37 if ((buf = make_cnid_data(cdb->flags, st, did, name, len)) == NULL) {
38 LOG(log_error, logtype_default, "cnid_lookup: Pathname is too long");
42 memcpy(&type, buf +CNID_TYPE_OFS, sizeof(type));
45 memset(&key, 0, sizeof(key));
46 memset(&diddata, 0, sizeof(diddata));
47 memset(&devdata, 0, sizeof(devdata));
49 /* Look for a CNID for our did/name */
50 key.data = buf +CNID_DEVINO_OFS;
51 key.size = CNID_DEVINO_LEN;
53 memcpy(dev, buf + CNID_DEV_OFS, CNID_DEV_LEN);
54 memcpy(ino, buf + CNID_INO_OFS, CNID_INO_LEN);
56 if (0 != (rc = db->db_didname->get(db->db_devino, NULL, &key, &devdata, 0 )) ) {
57 if (rc != DB_NOTFOUND) {
58 LOG(log_error, logtype_default, "cnid_lookup: Unable to get CNID did 0x%x, name %s: %s",
59 did, name, db_strerror(rc));
65 memcpy(&id_devino, devdata.data, sizeof(cnid_t));
66 memcpy(&type_devino, (char *)devdata.data +CNID_TYPE_OFS, sizeof(type_devino));
67 type_devino = ntohl(type_devino);
70 buf = make_cnid_data(cdb->flags, st, did, name, len);
71 key.data = buf +CNID_DID_OFS;
72 key.size = CNID_DID_LEN + len + 1;
74 if (0 != (rc = db->db_didname->get(db->db_didname, NULL, &key, &diddata, 0 ) ) ) {
75 if (rc != DB_NOTFOUND) {
76 LOG(log_error, logtype_default, "cnid_lookup: Unable to get CNID did 0x%x, name %s: %s",
77 did, name, db_strerror(rc));
83 memcpy(&id_didname, diddata.data, sizeof(cnid_t));
84 memcpy(&type_didname, (char *)diddata.data +CNID_TYPE_OFS, sizeof(type_didname));
85 type_didname = ntohl(type_didname);
88 if (!devino && !didname) {
92 if (devino && didname && id_devino == id_didname && type_devino == type) {
100 * if it's the same dev or not the same type
103 if (!memcmp(dev, (char *)diddata.data + CNID_DEV_OFS, CNID_DEV_LEN) ||
104 type_didname != type) {
105 if (cnid_cdb_delete(cdb, id) < 0) {
116 if (type_devino != type) {
117 /* same dev:inode but not same type one is a folder the other
118 * is a file,it's an inode reused, delete the record
120 if (cnid_cdb_delete(cdb, id) < 0) {
131 /* Fix up the database. assume it was a file move and rename */
132 cnid_cdb_update(cdb, id, st, did, name, len);
135 LOG(log_debug9, logtype_default, "cnid_lookup: Looked up did %u, name %s, as %u (needed update)", ntohl(did), name, ntohl(id));
140 #endif /* CNID_BACKEND_CDB */