5 #ifdef CNID_BACKEND_TDB
8 #include <atalk/logger.h>
10 cnid_t cnid_tdb_lookup(struct _cnid_db *cdb, const struct stat *st, cnid_t did, const char *name, size_t len)
13 struct _cnid_tdb_private *db;
14 TDB_DATA key, devdata, diddata, cniddata;
15 int devino = 1, didname = 1;
16 char dev[CNID_DEV_LEN];
17 char ino[CNID_INO_LEN];
18 u_int32_t type_devino = (unsigned)-1;
19 u_int32_t type_didname = (unsigned)-1;
22 cnid_t id_devino = 0, id_didname = 0,id = 0;
24 if (!cdb || !(db = cdb->_private) || !st || !name) {
28 if ((buf = make_tdb_data(cdb->flags, st, did, name, len)) == NULL) {
29 LOG(log_error, logtype_default, "tdb_lookup: Pathname is too long");
32 memcpy(&type, buf +CNID_TYPE_OFS, sizeof(type));
35 memset(&key, 0, sizeof(key));
36 memset(&devdata, 0, sizeof(devdata));
37 memset(&diddata, 0, sizeof(diddata));
38 memset(&cniddata, 0, sizeof(cniddata));
40 /* Look for a CNID. We have two options: dev/ino or did/name. If we
41 * only get a match in one of them, that means a file has moved. */
42 memcpy(dev, buf + CNID_DEV_OFS, CNID_DEV_LEN);
43 memcpy(ino, buf + CNID_INO_OFS, CNID_INO_LEN);
45 key.dptr = buf +CNID_DEVINO_OFS;
46 key.dsize = CNID_DEVINO_LEN;
47 cniddata = tdb_fetch(db->tdb_devino, key);
53 key.dptr = cniddata.dptr;
54 key.dsize = sizeof(id);
56 devdata = tdb_fetch(db->tdb_cnid, key);
59 memcpy(&id_devino, devdata.dptr, sizeof(cnid_t));
60 memcpy(&type_devino, (char *)devdata.dptr +CNID_TYPE_OFS, sizeof(type_devino));
61 type_devino = ntohl(type_devino);
69 key.dptr = buf + CNID_DID_OFS;
70 key.dsize = CNID_DID_LEN + len + 1;
71 cniddata = tdb_fetch(db->tdb_didname, key);
77 key.dptr = cniddata.dptr;
78 key.dsize = sizeof(id);
80 diddata = tdb_fetch(db->tdb_cnid, key);
83 memcpy(&id_didname, diddata.dptr, sizeof(cnid_t));
84 memcpy(&type_didname, (char *)diddata.dptr +CNID_TYPE_OFS, sizeof(type_didname));
85 type_didname = ntohl(type_didname);
91 /* Set id. Honor did/name over dev/ino as dev/ino isn't necessarily
93 if (!devino && !didname) {
99 if (devino && didname && id_devino == id_didname && type_devino == type) {
108 /* we have a did:name
109 * if it's the same dev or not the same type
112 if (!memcmp(dev, (char *)diddata.dptr + CNID_DEV_OFS, CNID_DEV_LEN) ||
113 type_didname != type) {
114 if (cnid_tdb_delete(cdb, id) < 0) {
127 if (type_devino != type) {
128 /* same dev:inode but not same type one is a folder the other
129 * is a file,it's an inode reused, delete the record
131 if (cnid_tdb_delete(cdb, id) < 0) {
147 /* Fix up the database. */
148 cnid_tdb_update(cdb, id, st, did, name, len);