(clean): clean universal binary intermediate steps, too
[arla.git] / arlad / d-trans.c
blob62f78c052887f36a8c909286e3957ae245f99a7e
1 /*
2 * Copyright (c) 2002, Stockholms universitet
3 * (Stockholm University, Stockholm Sweden)
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the university nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
34 #include "arla_local.h"
35 #ifdef RCSID
36 RCSID("$Id$") ;
37 #endif
40 struct transform_fid {
41 VenusFid dfid; /* disconnected fid */
42 VenusFid cfid; /* connecteted fid */
49 static Hashtab *transform_htab;
52 * Transaction fid related functions
56 * Find disconnected fid `dfid' in the transaction database.
59 static struct transform_fid *
60 find_fid_transform(VenusFid *dfid)
62 struct transform_fid key;
63 key.dfid = *dfid;
64 return hashtabsearch(transform_htab, &key);
68 * Transform the `fid` to a connected fid, return the pointer to `fid'
69 * so it can be used in a paramater to a function call.
72 static VenusFid *
73 transform_fid(VenusFid *fid)
75 struct transform_fid *t = find_fid_transform(fid);
76 if (t)
77 *fid = t->cfid;
78 return fid;
82 * Add a mapping between the disconnected fid `dfid' and the connected
83 * fid `cfid' in the transaction database.
86 static void
87 add_fid_transform(VenusFid *dfid, VenusFid *cfid)
89 struct transform_fid *f = find_fid_transform(dfid);
90 if (f)
91 abort();
93 f = malloc(sizeof(*f));
94 if (f == NULL)
95 abort();
97 f->cfid = *cfid;
98 f->dfid = *dfid;
100 hashtabadd(transform_htab, f);
104 * Help function for hashtable, compare `p1' and `p2'.
107 static int
108 tfid_cmp(void *p1, void *p2)
110 struct transform_fid *t1 = (struct transform_fid *)p1;
111 struct transform_fid *t2 = (struct transform_fid *)p2;
112 return VenusFid_cmp(&t1->dfid, &t2->dfid);
116 * Help function for hashtable, calculate hash for `p'.
119 static unsigned
120 tfid_hash(void *p)
122 struct transform_fid *t = (struct transform_fid *)p;
123 return t->dfid.Cell + t->dfid.fid.Volume + t->dfid.fid.Vnode
124 + t->dfid.fid.Unique;
127 static Bool
128 tfid_free(void *p, void *arg)
130 struct transform_fid *t = (struct transform_fid *)p;
131 memset(t, 0, sizeof(*t));
132 free(t);
133 return TRUE;
138 * Reintegrate the log
142 disco_reintegrate(nnpfs_pag_t pag)
144 struct disco_play_context *c;
145 char buf[DISCO_MAX_BUF_SZ];
146 CredCacheEntry *ce;
147 FCacheEntry *dir_entry, *child_entry;
148 #if 0
149 VenusFid dir_fid;
150 #endif
151 VenusFid child_fid;
152 AFSStoreStatus store_status;
153 AFSFetchStatus fetch_status;
154 int ret, store_data;
155 int old_conn_mode = connected_mode;
157 transform_htab = hashtabnewf(0, tfid_cmp, tfid_hash, HASHTAB_GROW);
158 if (transform_htab == NULL)
159 return ENOMEM;
161 #if 0
162 modified_log = 0; /* XXX */
163 #endif
165 disco_openlog();
167 connected_mode = CONNECTED;
169 disco_init_context(&c);
171 while(disco_next_entry(c, buf, sizeof(buf)) == 0) {
172 struct disco_header *h = (struct disco_header *)buf;
174 if (h->opcode >= DISCO_OP_MAX_OPCODE)
175 abort();
177 dir_entry = NULL;
178 child_entry = NULL;
179 ce = NULL;
181 if (h->flags & DISCO_HEADER_NOP)
182 goto next_entry;
184 switch(h->opcode) {
185 case DISCO_OP_UNLINK:
186 break;
187 case DISCO_OP_REMOVE_DIR:
188 break;
189 case DISCO_OP_CREATE_FILE: {
190 struct disco_create_file *f = (struct disco_create_file *)buf;
192 store_data = 0;
194 transform_fid(&f->parentfid);
196 ce = cred_get(f->parentfid.Cell, pag, CRED_ANY);
197 assert(ce);
199 ret = fcache_find(&dir_entry, f->parentfid);
200 if (ret != 0) {
201 arla_warnx(ADEBERROR, "create failed: (parent)"
202 "parent fid %d.%d.%d.%d name %s",
203 f->parentfid.Cell, f->parentfid.fid.Volume,
204 f->parentfid.fid.Vnode, f->parentfid.fid.Unique,
205 f->name);
206 goto next_entry;
209 transform_fid(&f->fid);
211 ret = fcache_find(&child_entry, f->fid);
212 if (ret != 0) {
213 arla_warnx(ADEBERROR, "create failed (child): "
214 "parent fid %d.%d.%d.%d name %s",
215 f->parentfid.Cell, f->parentfid.fid.Volume,
216 f->parentfid.fid.Vnode, f->parentfid.fid.Unique,
217 f->name);
218 goto next_entry;
222 /* XXX make summery of chain */
223 store_status = f->storestatus; /* XXX */
225 ret = create_file(dir_entry, f->name, &store_status, &child_fid,
226 &fetch_status, ce);
228 if (ret == 0) {
229 if (VenusFid_cmp(&f->fid, &child_fid) != 0) {
230 add_fid_transform(&f->fid, &child_fid);
232 recon_hashtabdel(child_entry);
233 child_entry->fid = child_fid;
234 update_fid (f->fid, NULL, child_fid, child_entry);
235 recon_hashtabadd(child_entry);
237 adir_changefid(&dir_entry, f->name, &child_fid, &ce);
240 if (store_data)
241 store_data = 1;
243 } else {
244 /* XXX invalidate name cache */
245 arla_warn(ADEBWARN, ret, "create failed (create_file): "
246 "parent fid %d.%d.%d.%d name %s",
247 f->parentfid.Cell, f->parentfid.fid.Volume,
248 f->parentfid.fid.Vnode, f->parentfid.fid.Unique,
249 f->name);
252 /* XXX invalidate the parent's name cache */
253 break_callback(dir_entry);
255 break;
257 case DISCO_OP_CREATE_SYMLINK:
258 case DISCO_OP_CREATE_LINK:
259 break;
260 case DISCO_OP_STOREDATA:
261 break;
264 next_entry:
266 if (dir_entry)
267 fcache_release(dir_entry);
268 if (child_entry)
269 fcache_release(child_entry);
270 if (ce)
271 cred_free(ce);
273 arla_warnx(ADEBWARN, "next reintegrate entry");
276 disco_close_context(c);
278 disco_closelog();
281 hashtabcleantab(transform_htab, tfid_free, NULL);
282 hashtabrelease(transform_htab);
283 transform_htab = NULL;
285 connected_mode = old_conn_mode;
287 return 0;