~ubuntu-branches/debian/lenny/netatalk/lenny

« back to all changes in this revision

Viewing changes to libatalk/cnid/db3/cnid_db3_update.c

  • Committer: Bazaar Package Importer
  • Author(s): Ante Karamatic
  • Date: 2005-10-07 13:46:11 UTC
  • mfrom: (1.1.2 upstream) (2.1.1 sarge)
  • Revision ID: james.westby@ubuntu.com-20051007134611-r07qa2g67xwkp2if
Tags: 2.0.3-1ubuntu1
* debian/netatalk.init
  - run cnid_metad if CNID_METAD_RUN=yes

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * $Id: cnid_db3_update.c,v 1.1.4.2.2.1 2005/01/30 20:56:22 didg Exp $
 
3
 */
 
4
 
 
5
#ifdef HAVE_CONFIG_H
 
6
#include "config.h"
 
7
#endif /* HAVE_CONFIG_H */
 
8
 
 
9
#ifdef CNID_BACKEND_DB3
 
10
 
 
11
#include <stdio.h>
 
12
#include <string.h>
 
13
#include <sys/param.h>
 
14
#include <sys/stat.h>
 
15
#include <errno.h>
 
16
#include <atalk/logger.h>
 
17
 
 
18
#ifdef HAVE_DB4_DB_H
 
19
#include <db4/db.h>
 
20
#else
 
21
#include <db.h>
 
22
#endif
 
23
#include <netatalk/endian.h>
 
24
#include <atalk/adouble.h>
 
25
#include "cnid_db3.h"
 
26
 
 
27
#include "cnid_db3_private.h"
 
28
 
 
29
/* cnid_update: takes the given cnid and updates the metadata.  To
 
30
 * handle the did/name data, there are a bunch of functions to get
 
31
 * and set the various fields. */
 
32
int cnid_db3_update(struct _cnid_db *cdb, const cnid_t id, const struct stat *st,
 
33
                const cnid_t did, char *name, const int len
 
34
                /*, const char *info, const int infolen*/)
 
35
{
 
36
    CNID_private *db;
 
37
    DBT key, data, altdata;
 
38
    DB_TXN *tid;
 
39
    int rc;
 
40
 
 
41
    if (!cdb || !(db = cdb->_private) || !id || !st || !name || (db->flags & CNIDFLAG_DB_RO)) {
 
42
        return -1;
 
43
    }
 
44
 
 
45
    memset(&key, 0, sizeof(key));
 
46
    memset(&altdata, 0, sizeof(altdata));
 
47
 
 
48
retry:
 
49
    if ((rc = db3_txn_begin(db->dbenv, NULL, &tid, 0))) {
 
50
        LOG(log_error, logtype_default, "cnid_update: Failed to begin transaction: %s", db_strerror(rc));
 
51
        return rc;
 
52
    }
 
53
 
 
54
    /* Get the old info. */
 
55
    key.data = (cnid_t *)&id;
 
56
    key.size = sizeof(id);
 
57
    memset(&data, 0, sizeof(data));
 
58
    if ((rc = db->db_cnid->get(db->db_cnid, tid, &key, &data, DB_RMW))) {
 
59
        db3_txn_abort(tid);
 
60
        switch (rc) {
 
61
        case DB_LOCK_DEADLOCK:
 
62
            goto retry;
 
63
        case DB_NOTFOUND:
 
64
            /* Silently fail here.  We're allowed to do this since this CNID
 
65
             * might have been deleted out from under us, or someone has
 
66
             * called cnid_lookup then cnid_update (which is redundant). */
 
67
            return 0;
 
68
        default:
 
69
            goto update_err;
 
70
        }
 
71
    }
 
72
 
 
73
    /* Delete the old dev/ino mapping. */
 
74
    key.data = data.data;
 
75
    key.size = CNID_DEVINO_LEN;
 
76
    if ((rc = db->db_devino->del(db->db_devino, tid, &key, 0))) {
 
77
        switch (rc) {
 
78
        case DB_LOCK_DEADLOCK:
 
79
            db3_txn_abort(tid);
 
80
            goto retry;
 
81
        case DB_NOTFOUND:
 
82
            break;
 
83
        default:
 
84
            db3_txn_abort(tid);
 
85
            goto update_err;
 
86
        }
 
87
    }
 
88
 
 
89
    /* Delete the old did/name mapping. */
 
90
    key.data = (char *) data.data + CNID_DEVINO_LEN;
 
91
    key.size = data.size - CNID_DEVINO_LEN;
 
92
    if ((rc = db->db_didname->del(db->db_didname, tid, &key, 0))) {
 
93
        switch (rc) {
 
94
        case DB_LOCK_DEADLOCK:
 
95
            db3_txn_abort(tid);
 
96
            goto retry;
 
97
        case DB_NOTFOUND:
 
98
            break;
 
99
        default:
 
100
            db3_txn_abort(tid);
 
101
            goto update_err;
 
102
        }
 
103
    }
 
104
 
 
105
    /* Make a new entry. */
 
106
    data.data = make_cnid_data(st, did, name, len);
 
107
    data.size = CNID_HEADER_LEN + len + 1;
 
108
 
 
109
    /* Update the old CNID with the new info. */
 
110
    key.data = (cnid_t *) &id;
 
111
    key.size = sizeof(id);
 
112
    if ((rc = db->db_cnid->put(db->db_cnid, tid, &key, &data, 0))) {
 
113
        db3_txn_abort(tid);
 
114
        switch (rc) {
 
115
        case DB_LOCK_DEADLOCK:
 
116
            goto retry;
 
117
        default:
 
118
            goto update_err;
 
119
        }
 
120
    }
 
121
 
 
122
    /* Put in a new dev/ino mapping. */
 
123
    key.data = data.data;
 
124
    key.size = CNID_DEVINO_LEN;
 
125
    altdata.data = (cnid_t *) &id;
 
126
    altdata.size = sizeof(id);
 
127
    if ((rc = db->db_devino->put(db->db_devino, tid, &key, &altdata, 0))) {
 
128
        db3_txn_abort(tid);
 
129
        switch (rc) {
 
130
        case DB_LOCK_DEADLOCK:
 
131
            goto retry;
 
132
        default:
 
133
            goto update_err;
 
134
        }
 
135
    }
 
136
 
 
137
    /* put in a new did/name mapping. */
 
138
    key.data = (char *) data.data + CNID_DEVINO_LEN;
 
139
    key.size = data.size - CNID_DEVINO_LEN;
 
140
    if ((rc = db->db_didname->put(db->db_didname, tid, &key, &altdata, 0))) {
 
141
        db3_txn_abort(tid);
 
142
        switch (rc) {
 
143
        case DB_LOCK_DEADLOCK:
 
144
            goto retry;
 
145
        default:
 
146
            goto update_err;
 
147
        }
 
148
    }
 
149
 
 
150
 
 
151
    return db3_txn_commit(tid, 0);
 
152
 
 
153
update_err:
 
154
    LOG(log_error, logtype_default, "cnid_update: Unable to update CNID %u: %s",
 
155
        ntohl(id), db_strerror(rc));
 
156
    return -1;
 
157
}
 
158
 
 
159
#endif /* CNID_BACKEND_DB3 */