]> arthur.barton.de Git - netatalk.git/commitdiff
fix errors with Berkeley DB 4.0.x
authordidg <didg>
Mon, 6 Oct 2003 15:17:08 +0000 (15:17 +0000)
committerdidg <didg>
Mon, 6 Oct 2003 15:17:08 +0000 (15:17 +0000)
etc/cnid_dbd/dbd_update.c
etc/cnid_dbd/dbif.c
etc/cnid_dbd/dbif.h
libatalk/cnid/cdb/cnid_cdb_lookup.c
libatalk/cnid/cdb/cnid_cdb_open.c
libatalk/cnid/cdb/cnid_cdb_update.c

index e9628a29eaa5234241b8f66c3a57d82c79d40d4d..46b520a80ea92e8073e676ac33978a000fb43926 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: dbd_update.c,v 1.1.4.1 2003-09-09 16:42:20 didg Exp $
+ * $Id: dbd_update.c,v 1.1.4.2 2003-10-06 15:17:08 didg Exp $
  *
  * Copyright (C) Joerg Lenneis 2003
  * All Rights Reserved.  See COPYRIGHT.
 
 int dbd_update(struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply *rply)
 {
-    DBT key, data;
+    DBT key,pkey, data;
     int rc;
     char *buf;                                                                                               
     int notfound = 0;
-    
+    char getbuf[CNID_HEADER_LEN + MAXPATHLEN +1];    
+
     memset(&key, 0, sizeof(key));
+    memset(&pkey, 0, sizeof(pkey));
+    memset(&data, 0, sizeof(data));
 
     rply->namelen = 0;
 
@@ -40,9 +43,16 @@ int dbd_update(struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply *rply)
     key.data = buf +CNID_DEVINO_OFS;
     key.size = CNID_DEVINO_LEN;
 
-    if ((rc = dbif_del(DBIF_IDX_DEVINO, &key, 0) < 0) ) {
+    data.data = getbuf;
+    data.size = CNID_HEADER_LEN + MAXPATHLEN + 1;
+    if ((rc = dbif_pget(DBIF_IDX_DEVINO, &key, &pkey, &data, 0)) < 0 ) {
         goto err_db;
     }
+    else if  (rc > 0) {
+        if ((rc = dbif_del(DBIF_IDX_DEVINO, &pkey, 0)) < 0 ) {
+            goto err_db;
+        }
+    }
     if (!rc) {
        notfound = 1;
     }
@@ -50,10 +60,16 @@ int dbd_update(struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply *rply)
     buf = pack_cnid_data(rqst);
     key.data = buf + CNID_DID_OFS;
     key.size = CNID_DID_LEN + rqst->namelen +1;
+    memset(&pkey, 0, sizeof(pkey));
 
-    if ((rc = dbif_del(DBIF_IDX_DIDNAME, &key, 0) < 0)) {
+    if ((rc = dbif_pget(DBIF_IDX_DIDNAME, &key, &pkey, &data, 0) < 0)) {
         goto err_db;
     }
+    else if  (rc > 0) {
+        if ((rc = dbif_del(DBIF_IDX_DIDNAME, &pkey, 0)) < 0) {
+            goto err_db;
+        }
+    }
     if (!rc) {
        notfound |= 2;
     }
index 93baf77e15f4ca5a2ac67b1141152ae4bd0ac6ce..8c4f95d0fb40712719ffebc3b03f24e4feca6c7f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: dbif.c,v 1.1.4.2 2003-09-16 12:21:44 rlewczuk Exp $
+ * $Id: dbif.c,v 1.1.4.3 2003-10-06 15:17:08 didg Exp $
  *
  * Copyright (C) Joerg Lenneis 2003
  * All Rights Reserved.  See COPYRIGHT.
@@ -62,12 +62,12 @@ static int env_init(struct db_param *dbp)
 {
     int ret;
 
+#ifdef CNID_BACKEND_DBD_TXN
     if ((ret = db_env_create(&db_env, 0))) {
         LOG(log_error, logtype_cnid, "error creating DB environment: %s", 
             db_strerror(ret));
         return -1;
     }    
-#ifdef CNID_BACKEND_DBD_TXN
     if (db_errlog != NULL)
         db_env->set_errfile(db_env, db_errlog); 
     db_env->set_verbose(db_env, DB_VERB_RECOVERY, 1);
@@ -129,7 +129,7 @@ static int  db_compat_associate (DB *p, DB *s,
 #if DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1)
     return p->associate(p, NULL, s, callback, flags);
 #else
-#if DB_VERSION_MAJOR > 4
+#if (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR == 0)
     return p->associate(p,       s, callback, flags);
 #else
     return 0;
@@ -294,6 +294,29 @@ int dbif_get(const int dbi, DBT *key, DBT *val, u_int32_t flags)
         return 1;
 }
 
+/* search by secondary return primary */
+int dbif_pget(const int dbi, DBT *key, DBT *pkey, DBT *val, u_int32_t flags)
+{
+    int ret;
+    DB *db = db_table[dbi].db;
+
+    ret = db->pget(db, db_txn, key, pkey, val, flags);
+
+#if DB_VERSION_MAJOR >= 4
+    if (ret == DB_NOTFOUND || ret == DB_SECONDARY_BAD) {
+#else
+    if (ret == DB_NOTFOUND) {
+#endif     
+        return 0;
+    }
+    if (ret) {
+        LOG(log_error, logtype_cnid, "error retrieving value from %s: %s", db_table[dbi].name, db_strerror(errno));
+        return -1;
+    } else 
+        return 1;
+}
+
+/* -------------------------- */
 int dbif_put(const int dbi, DBT *key, DBT *val, u_int32_t flags)
 {
     int ret;
index 6e005e51c97e236ff5fe23afd4a1dc5a3e23f30c..e8901016ea3a317cd0b64ef3c03b11ffb63d642e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: dbif.h,v 1.1.4.1 2003-09-09 16:42:20 didg Exp $
+ * $Id: dbif.h,v 1.1.4.2 2003-10-06 15:17:08 didg Exp $
  *
  * Copyright (C) Joerg Lenneis 2003
  * All Rights Reserved.  See COPYRIGHT.
@@ -21,6 +21,7 @@ extern int        dbif_stamp  __P((void *, int));
 extern int        dbif_open  __P((struct db_param *));
 extern int        dbif_close __P((void));
 extern int        dbif_get __P((const int, DBT *, DBT *, u_int32_t));
+extern int        dbif_pget __P((const int, DBT *, DBT *, DBT *, u_int32_t));
 extern int        dbif_put __P((const int, DBT *, DBT *, u_int32_t));
 extern int        dbif_del __P((const int, DBT *, u_int32_t));
 
index 325877e48e9905a9d5e73ace5d420d63d8db8bbc..443c9eb84b7d2e188f7ea590449c0f989d269db5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: cnid_cdb_lookup.c,v 1.1.4.1 2003-09-09 16:42:21 didg Exp $
+ * $Id: cnid_cdb_lookup.c,v 1.1.4.2 2003-10-06 15:17:08 didg Exp $
  */
 
 #ifdef HAVE_CONFIG_H
@@ -32,10 +32,15 @@ cnid_t cnid_cdb_lookup(struct _cnid_db *cdb, const struct stat *st, const cnid_t
 {
     char *buf;
     CNID_private *db;
-    DBT key, diddata;
+    DBT key, devdata, diddata;
     dev_t dev;
     ino_t ino;  
-    cnid_t id = 0;
+    int devino = 1, didname = 1; 
+    u_int32_t type_devino  = (unsigned)-1;
+    u_int32_t type_didname = (unsigned)-1;
+    u_int32_t type;
+    int update = 0;
+    cnid_t id_devino, id_didname,id = 0;
     int rc;
 
     if (!cdb || !(db = cdb->_private) || !st || !name) {
@@ -47,46 +52,96 @@ cnid_t cnid_cdb_lookup(struct _cnid_db *cdb, const struct stat *st, const cnid_t
         return 0;
     }
 
+    memcpy(&type, buf +CNID_TYPE_OFS, sizeof(type));
+    type = ntohl(type);
+
     memset(&key, 0, sizeof(key));
     memset(&diddata, 0, sizeof(diddata));
+    memset(&devdata, 0, sizeof(devdata));
 
     /* Look for a CNID for our did/name */
-    key.data = buf +CNID_DID_OFS;
-    key.size = CNID_DID_LEN + len + 1;
+    key.data = buf +CNID_DEVINO_OFS;
+    key.size = CNID_DEVINO_LEN;
 
     memcpy(&dev, buf + CNID_DEV_OFS, sizeof(dev));
     memcpy(&ino, buf + CNID_INO_OFS, sizeof(ino));
+    
+    if (0 != (rc = db->db_didname->get(db->db_devino, NULL, &key, &devdata, 0 )) ) {
+        if (rc != DB_NOTFOUND) {
+            LOG(log_error, logtype_default, "cnid_lookup: Unable to get CNID did 0x%x, name %s: %s",
+               did, name, db_strerror(rc));
+            return 0;
+        }
+        devino = 0;
+    }
+    else {
+        memcpy(&id_devino, devdata.data, sizeof(cnid_t));
+        memcpy(&type_devino, devdata.data +CNID_TYPE_OFS, sizeof(type_devino));
+        type_devino = ntohl(type_devino);
+    }
 
-    if (0 != (rc = db->db_didname->get(db->db_didname, NULL, &key, &diddata, 0 )) ) {
+    buf = make_cnid_data(st, did, name, len);
+    key.data = buf +CNID_DID_OFS;
+    key.size = CNID_DID_LEN + len + 1;
+    
+    if (0 != (rc = db->db_didname->get(db->db_didname, NULL, &key, &diddata, 0 ) ) ) {
         if (rc != DB_NOTFOUND) {
-           LOG(log_error, logtype_default, "cnid_lookup: Unable to get CNID did 0x%x, name %s: %s",
+            LOG(log_error, logtype_default, "cnid_lookup: Unable to get CNID did 0x%x, name %s: %s",
                did, name, db_strerror(rc));
+            return 0;
         }
+        didname = 0;
+    }
+    else {
+        memcpy(&id_didname, diddata.data, sizeof(cnid_t));
+        memcpy(&type_didname, diddata.data +CNID_TYPE_OFS, sizeof(type_didname));
+        type_didname = ntohl(type_didname);
+    }
+
+    if (!devino && !didname) {  
         return 0;
     }
-    memcpy(&id, diddata.data, sizeof(id));
-    /* if dev:ino the same */
-    if (!memcmp(&dev, (char *)diddata.data + CNID_DEV_OFS, sizeof(dev)) &&
-        !memcmp(&ino, (char *)diddata.data + CNID_INO_OFS, sizeof(ino))
-        /* FIXME and type are the same */
-       )
-    {
-        /* then it's what we are looking for */
-        return id;
+
+    if (devino && didname && id_devino == id_didname && type_devino == type) {
+        /* the same */
+        return id_didname;
     }
  
-    /* with have a did:name but it's not one the same dev:inode
-     * it should be always a different file, but in moveandrename with cross/dev
-     * we don't update the db.
-    */
-    if (!memcmp(&dev, (char *)diddata.data + CNID_DEV_OFS, sizeof(dev)))
-       /* FIXME or diff type */
-    {
-       /* dev are the same so it's a copy */
+    if (didname) {
+        id = id_didname;
+        /* we have a did:name 
+         * if it's the same dev or not the same type
+         * just delete it
+        */
+        if (!memcmp(&dev, (char *)diddata.data + CNID_DEV_OFS, sizeof(dev)) ||
+                   type_didname != type) {
+            if (cnid_cdb_delete(cdb, id) < 0) {
+                return 0;
+            }
+        }
+        else {
+            update = 1;
+        }
+    }
+
+    if (devino) {
+        id = id_devino;
+        if (type_devino != type) {
+            /* same dev:inode but not same type one is a folder the other 
+             * is a file,it's an inode reused, delete the record
+            */
+            if (cnid_cdb_delete(cdb, id) < 0) {
+                return 0;
+            }
+        }
+        else {
+            update = 1;
+        }
+    }
+    if (!update) {
         return 0;
     }
-    /* Fix up the database. */
+    /* Fix up the database. assume it was a file move and rename */
     cnid_cdb_update(cdb, id, st, did, name, len);
 
 #ifdef DEBUG
index c72a9921bb970f6776e0c45c8649362b55b26683..f0863e7b6f85209409b022cd604fb97806dcccd4 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: cnid_cdb_open.c,v 1.1.4.2 2003-09-16 12:20:37 rlewczuk Exp $
+ * $Id: cnid_cdb_open.c,v 1.1.4.3 2003-10-06 15:17:08 didg Exp $
  *
  * Copyright (c) 1999. Adrian Sun (asun@zoology.washington.edu)
  * All Rights Reserved. See COPYRIGHT.
@@ -141,7 +141,7 @@ static int  my_associate (DB *p, DB *s,
 #if DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1)
     return p->associate(p, NULL, s, callback, flags);
 #else
-#if DB_VERSION_MAJOR > 4
+#if (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR == 0)
     return p->associate(p,       s, callback, flags);
 #else
     return 0; /* FIXME */
index ae8303ed3b69bdfe6abeb08a7f9f8c075dd5e508..5d5d646e5b143f8e976036f14584b13735a80a39 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: cnid_cdb_update.c,v 1.1.4.2 2003-09-16 12:20:38 rlewczuk Exp $
+ * $Id: cnid_cdb_update.c,v 1.1.4.3 2003-10-06 15:17:08 didg Exp $
  */
 
 #ifdef HAVE_CONFIG_H
@@ -33,51 +33,68 @@ int cnid_cdb_update(struct _cnid_db *cdb, const cnid_t id, const struct stat *st
 {
     char *buf;
     CNID_private *db;
-    DBT key, data;
+    DBT key, pkey, data;
     int rc;
     int notfound = 0;
+    char getbuf[CNID_HEADER_LEN + MAXPATHLEN +1];
 
     if (!cdb || !(db = cdb->_private) || !id || !st || !name || (db->flags & CNIDFLAG_DB_RO)) {
         return -1;
     }
 
     memset(&key, 0, sizeof(key));
+    memset(&pkey, 0, sizeof(pkey));
+    memset(&data, 0, sizeof(data));
 
     buf = make_cnid_data(st, did, name, len);
 
     key.data = buf +CNID_DEVINO_OFS;
     key.size = CNID_DEVINO_LEN;
+    data.data = getbuf;
+    data.size = CNID_HEADER_LEN + MAXPATHLEN + 1;
 
-    if (0 != (rc = db->db_devino->del(db->db_devino, tid, &key, 0)) ) {
+    if (0 != (rc = db->db_devino->pget(db->db_devino, tid, &key, &pkey, &data, 0)) ) {
 #if DB_VERSION_MAJOR >= 4
         if (rc != DB_NOTFOUND && rc != DB_SECONDARY_BAD) {
 #else
        if (rc != DB_NOTFOUND) {
 #endif
-           LOG(log_error, logtype_default, "cnid_update: Unable to del devino CNID %u, name %s: %s",
+           LOG(log_error, logtype_default, "cnid_update: Unable to get devino CNID %u, name %s: %s",
                ntohl(did), name, db_strerror(rc));
            goto fin;
         }
         notfound = 1;
+    } else {
+        if ((rc = db->db_cnid->del(db->db_cnid, tid, &pkey, 0))) {
+            LOG(log_error, logtype_default, "cnid_update: Unable to delete CNID %u: %s",
+                ntohl(id), db_strerror(rc));
+       }
     }
 
+    memset(&pkey, 0, sizeof(pkey));
     buf = make_cnid_data(st, did, name, len);
     key.data = buf + CNID_DID_OFS;
     key.size = CNID_DID_LEN + len + 1;
 
-    if (0 != (rc = db->db_didname->del(db->db_didname, tid, &key, 0)) ) {
+    if (0 != (rc = db->db_didname->pget(db->db_didname, tid, &key, &pkey, &data, 0)) ) {
 #if DB_VERSION_MAJOR >= 4
         if (rc != DB_NOTFOUND && rc != DB_SECONDARY_BAD) {
 #else
        if (rc != DB_NOTFOUND) {
 #endif
-           LOG(log_error, logtype_default, "cnid_update: Unable to del didname CNID %u, name %s: %s",
+           LOG(log_error, logtype_default, "cnid_update: Unable to get didname CNID %u, name %s: %s",
                ntohl(did), name, db_strerror(rc));
            goto fin;
         }
         notfound |= 2;
+    } else {
+        if ((rc = db->db_cnid->del(db->db_cnid, tid, &pkey, 0))) {
+            LOG(log_error, logtype_default, "cnid_update: Unable to delete CNID %u: %s",
+                ntohl(id), db_strerror(rc));
+       }
     }
 
+
     memset(&key, 0, sizeof(key));
     key.data = (cnid_t *)&id;
     key.size = sizeof(id);