diff options
Diffstat (limited to 'fs/afs/vnode.c')
-rw-r--r-- | fs/afs/vnode.c | 388 |
1 files changed, 193 insertions, 195 deletions
diff --git a/fs/afs/vnode.c b/fs/afs/vnode.c index 4ab1ed710286..d2ca1398474f 100644 --- a/fs/afs/vnode.c +++ b/fs/afs/vnode.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* AFS vnode management | 1 | /* AFS vnode management |
2 | * | 2 | * |
3 | * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved. | 3 | * Copyright (C) 2002, 2007 Red Hat, Inc. All Rights Reserved. |
4 | * Written by David Howells (dhowells@redhat.com) | 4 | * Written by David Howells (dhowells@redhat.com) |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or | 6 | * This program is free software; you can redistribute it and/or |
@@ -14,72 +14,183 @@ | |||
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
16 | #include <linux/fs.h> | 16 | #include <linux/fs.h> |
17 | #include <linux/pagemap.h> | ||
18 | #include "volume.h" | ||
19 | #include "cell.h" | ||
20 | #include "cmservice.h" | ||
21 | #include "fsclient.h" | ||
22 | #include "vlclient.h" | ||
23 | #include "vnode.h" | ||
24 | #include "internal.h" | 17 | #include "internal.h" |
25 | 18 | ||
26 | static void afs_vnode_cb_timed_out(struct afs_timer *timer); | 19 | #if 0 |
20 | static noinline bool dump_tree_aux(struct rb_node *node, struct rb_node *parent, | ||
21 | int depth, char lr) | ||
22 | { | ||
23 | struct afs_vnode *vnode; | ||
24 | bool bad = false; | ||
25 | |||
26 | if (!node) | ||
27 | return false; | ||
28 | |||
29 | if (node->rb_left) | ||
30 | bad = dump_tree_aux(node->rb_left, node, depth + 2, '/'); | ||
31 | |||
32 | vnode = rb_entry(node, struct afs_vnode, cb_promise); | ||
33 | kdebug("%c %*.*s%c%p {%d}", | ||
34 | rb_is_red(node) ? 'R' : 'B', | ||
35 | depth, depth, "", lr, | ||
36 | vnode, vnode->cb_expires_at); | ||
37 | if (rb_parent(node) != parent) { | ||
38 | printk("BAD: %p != %p\n", rb_parent(node), parent); | ||
39 | bad = true; | ||
40 | } | ||
27 | 41 | ||
28 | struct afs_timer_ops afs_vnode_cb_timed_out_ops = { | 42 | if (node->rb_right) |
29 | .timed_out = afs_vnode_cb_timed_out, | 43 | bad |= dump_tree_aux(node->rb_right, node, depth + 2, '\\'); |
30 | }; | ||
31 | 44 | ||
32 | #ifdef AFS_CACHING_SUPPORT | 45 | return bad; |
33 | static cachefs_match_val_t afs_vnode_cache_match(void *target, | 46 | } |
34 | const void *entry); | ||
35 | static void afs_vnode_cache_update(void *source, void *entry); | ||
36 | 47 | ||
37 | struct cachefs_index_def afs_vnode_cache_index_def = { | 48 | static noinline void dump_tree(const char *name, struct afs_server *server) |
38 | .name = "vnode", | 49 | { |
39 | .data_size = sizeof(struct afs_cache_vnode), | 50 | kenter("%s", name); |
40 | .keys[0] = { CACHEFS_INDEX_KEYS_BIN, 4 }, | 51 | if (dump_tree_aux(server->cb_promises.rb_node, NULL, 0, '-')) |
41 | .match = afs_vnode_cache_match, | 52 | BUG(); |
42 | .update = afs_vnode_cache_update, | 53 | } |
43 | }; | ||
44 | #endif | 54 | #endif |
45 | 55 | ||
46 | /* | 56 | /* |
47 | * handle a callback timing out | 57 | * insert a vnode into the backing server's vnode tree |
48 | * TODO: retain a ref to vnode struct for an outstanding callback timeout | ||
49 | */ | 58 | */ |
50 | static void afs_vnode_cb_timed_out(struct afs_timer *timer) | 59 | static void afs_install_vnode(struct afs_vnode *vnode, |
60 | struct afs_server *server) | ||
51 | { | 61 | { |
52 | struct afs_server *oldserver; | 62 | struct afs_server *old_server = vnode->server; |
53 | struct afs_vnode *vnode; | 63 | struct afs_vnode *xvnode; |
64 | struct rb_node *parent, **p; | ||
54 | 65 | ||
55 | vnode = list_entry(timer, struct afs_vnode, cb_timeout); | 66 | _enter("%p,%p", vnode, server); |
56 | 67 | ||
57 | _enter("%p", vnode); | 68 | if (old_server) { |
69 | spin_lock(&old_server->fs_lock); | ||
70 | rb_erase(&vnode->server_rb, &old_server->fs_vnodes); | ||
71 | spin_unlock(&old_server->fs_lock); | ||
72 | } | ||
58 | 73 | ||
59 | /* set the changed flag in the vnode and release the server */ | 74 | afs_get_server(server); |
60 | spin_lock(&vnode->lock); | 75 | vnode->server = server; |
76 | afs_put_server(old_server); | ||
77 | |||
78 | /* insert into the server's vnode tree in FID order */ | ||
79 | spin_lock(&server->fs_lock); | ||
80 | |||
81 | parent = NULL; | ||
82 | p = &server->fs_vnodes.rb_node; | ||
83 | while (*p) { | ||
84 | parent = *p; | ||
85 | xvnode = rb_entry(parent, struct afs_vnode, server_rb); | ||
86 | if (vnode->fid.vid < xvnode->fid.vid) | ||
87 | p = &(*p)->rb_left; | ||
88 | else if (vnode->fid.vid > xvnode->fid.vid) | ||
89 | p = &(*p)->rb_right; | ||
90 | else if (vnode->fid.vnode < xvnode->fid.vnode) | ||
91 | p = &(*p)->rb_left; | ||
92 | else if (vnode->fid.vnode > xvnode->fid.vnode) | ||
93 | p = &(*p)->rb_right; | ||
94 | else if (vnode->fid.unique < xvnode->fid.unique) | ||
95 | p = &(*p)->rb_left; | ||
96 | else if (vnode->fid.unique > xvnode->fid.unique) | ||
97 | p = &(*p)->rb_right; | ||
98 | else | ||
99 | BUG(); /* can't happen unless afs_iget() malfunctions */ | ||
100 | } | ||
61 | 101 | ||
62 | oldserver = xchg(&vnode->cb_server, NULL); | 102 | rb_link_node(&vnode->server_rb, parent, p); |
63 | if (oldserver) { | 103 | rb_insert_color(&vnode->server_rb, &server->fs_vnodes); |
64 | vnode->flags |= AFS_VNODE_CHANGED; | ||
65 | 104 | ||
66 | spin_lock(&afs_cb_hash_lock); | 105 | spin_unlock(&server->fs_lock); |
67 | list_del_init(&vnode->cb_hash_link); | 106 | _leave(""); |
68 | spin_unlock(&afs_cb_hash_lock); | 107 | } |
69 | 108 | ||
70 | spin_lock(&oldserver->cb_lock); | 109 | /* |
71 | list_del_init(&vnode->cb_link); | 110 | * insert a vnode into the promising server's update/expiration tree |
72 | spin_unlock(&oldserver->cb_lock); | 111 | * - caller must hold vnode->lock |
112 | */ | ||
113 | static void afs_vnode_note_promise(struct afs_vnode *vnode, | ||
114 | struct afs_server *server) | ||
115 | { | ||
116 | struct afs_server *old_server; | ||
117 | struct afs_vnode *xvnode; | ||
118 | struct rb_node *parent, **p; | ||
119 | |||
120 | _enter("%p,%p", vnode, server); | ||
121 | |||
122 | ASSERT(server != NULL); | ||
123 | |||
124 | old_server = vnode->server; | ||
125 | if (vnode->cb_promised) { | ||
126 | if (server == old_server && | ||
127 | vnode->cb_expires == vnode->cb_expires_at) { | ||
128 | _leave(" [no change]"); | ||
129 | return; | ||
130 | } | ||
131 | |||
132 | spin_lock(&old_server->cb_lock); | ||
133 | if (vnode->cb_promised) { | ||
134 | _debug("delete"); | ||
135 | rb_erase(&vnode->cb_promise, &old_server->cb_promises); | ||
136 | vnode->cb_promised = false; | ||
137 | } | ||
138 | spin_unlock(&old_server->cb_lock); | ||
73 | } | 139 | } |
74 | 140 | ||
75 | spin_unlock(&vnode->lock); | 141 | if (vnode->server != server) |
142 | afs_install_vnode(vnode, server); | ||
143 | |||
144 | vnode->cb_expires_at = vnode->cb_expires; | ||
145 | _debug("PROMISE on %p {%lu}", | ||
146 | vnode, (unsigned long) vnode->cb_expires_at); | ||
147 | |||
148 | /* abuse an RB-tree to hold the expiration order (we may have multiple | ||
149 | * items with the same expiration time) */ | ||
150 | spin_lock(&server->cb_lock); | ||
151 | |||
152 | parent = NULL; | ||
153 | p = &server->cb_promises.rb_node; | ||
154 | while (*p) { | ||
155 | parent = *p; | ||
156 | xvnode = rb_entry(parent, struct afs_vnode, cb_promise); | ||
157 | if (vnode->cb_expires_at < xvnode->cb_expires_at) | ||
158 | p = &(*p)->rb_left; | ||
159 | else | ||
160 | p = &(*p)->rb_right; | ||
161 | } | ||
76 | 162 | ||
77 | afs_put_server(oldserver); | 163 | rb_link_node(&vnode->cb_promise, parent, p); |
164 | rb_insert_color(&vnode->cb_promise, &server->cb_promises); | ||
165 | vnode->cb_promised = true; | ||
78 | 166 | ||
167 | spin_unlock(&server->cb_lock); | ||
79 | _leave(""); | 168 | _leave(""); |
80 | } | 169 | } |
81 | 170 | ||
82 | /* | 171 | /* |
172 | * handle remote file deletion by discarding the callback promise | ||
173 | */ | ||
174 | static void afs_vnode_deleted_remotely(struct afs_vnode *vnode) | ||
175 | { | ||
176 | struct afs_server *server; | ||
177 | |||
178 | set_bit(AFS_VNODE_DELETED, &vnode->flags); | ||
179 | |||
180 | server = vnode->server; | ||
181 | if (vnode->cb_promised) { | ||
182 | spin_lock(&server->cb_lock); | ||
183 | if (vnode->cb_promised) { | ||
184 | rb_erase(&vnode->cb_promise, &server->cb_promises); | ||
185 | vnode->cb_promised = false; | ||
186 | } | ||
187 | spin_unlock(&server->cb_lock); | ||
188 | } | ||
189 | |||
190 | afs_put_server(server); | ||
191 | } | ||
192 | |||
193 | /* | ||
83 | * finish off updating the recorded status of a file | 194 | * finish off updating the recorded status of a file |
84 | * - starts callback expiry timer | 195 | * - starts callback expiry timer |
85 | * - adds to server's callback list | 196 | * - adds to server's callback list |
@@ -94,43 +205,19 @@ static void afs_vnode_finalise_status_update(struct afs_vnode *vnode, | |||
94 | 205 | ||
95 | spin_lock(&vnode->lock); | 206 | spin_lock(&vnode->lock); |
96 | 207 | ||
97 | vnode->flags &= ~AFS_VNODE_CHANGED; | 208 | clear_bit(AFS_VNODE_CB_BROKEN, &vnode->flags); |
98 | |||
99 | if (ret == 0) { | ||
100 | /* adjust the callback timeout appropriately */ | ||
101 | afs_kafstimod_add_timer(&vnode->cb_timeout, | ||
102 | vnode->cb_expiry * HZ); | ||
103 | |||
104 | spin_lock(&afs_cb_hash_lock); | ||
105 | list_move_tail(&vnode->cb_hash_link, | ||
106 | &afs_cb_hash(server, &vnode->fid)); | ||
107 | spin_unlock(&afs_cb_hash_lock); | ||
108 | |||
109 | /* swap ref to old callback server with that for new callback | ||
110 | * server */ | ||
111 | oldserver = xchg(&vnode->cb_server, server); | ||
112 | if (oldserver != server) { | ||
113 | if (oldserver) { | ||
114 | spin_lock(&oldserver->cb_lock); | ||
115 | list_del_init(&vnode->cb_link); | ||
116 | spin_unlock(&oldserver->cb_lock); | ||
117 | } | ||
118 | |||
119 | afs_get_server(server); | ||
120 | spin_lock(&server->cb_lock); | ||
121 | list_add_tail(&vnode->cb_link, &server->cb_promises); | ||
122 | spin_unlock(&server->cb_lock); | ||
123 | } else { | ||
124 | /* same server */ | ||
125 | oldserver = NULL; | ||
126 | } | ||
127 | } else if (ret == -ENOENT) { | ||
128 | /* the file was deleted - clear the callback timeout */ | ||
129 | oldserver = xchg(&vnode->cb_server, NULL); | ||
130 | afs_kafstimod_del_timer(&vnode->cb_timeout); | ||
131 | 209 | ||
210 | switch (ret) { | ||
211 | case 0: | ||
212 | afs_vnode_note_promise(vnode, server); | ||
213 | break; | ||
214 | case -ENOENT: | ||
215 | /* the file was deleted on the server */ | ||
132 | _debug("got NOENT from server - marking file deleted"); | 216 | _debug("got NOENT from server - marking file deleted"); |
133 | vnode->flags |= AFS_VNODE_DELETED; | 217 | afs_vnode_deleted_remotely(vnode); |
218 | break; | ||
219 | default: | ||
220 | break; | ||
134 | } | 221 | } |
135 | 222 | ||
136 | vnode->update_cnt--; | 223 | vnode->update_cnt--; |
@@ -162,19 +249,21 @@ int afs_vnode_fetch_status(struct afs_vnode *vnode) | |||
162 | vnode->volume->vlocation->vldb.name, | 249 | vnode->volume->vlocation->vldb.name, |
163 | vnode->fid.vid, vnode->fid.vnode, vnode->fid.unique); | 250 | vnode->fid.vid, vnode->fid.vnode, vnode->fid.unique); |
164 | 251 | ||
165 | if (!(vnode->flags & AFS_VNODE_CHANGED) && vnode->cb_server) { | 252 | if (!test_bit(AFS_VNODE_CB_BROKEN, &vnode->flags) && |
253 | vnode->cb_promised) { | ||
166 | _leave(" [unchanged]"); | 254 | _leave(" [unchanged]"); |
167 | return 0; | 255 | return 0; |
168 | } | 256 | } |
169 | 257 | ||
170 | if (vnode->flags & AFS_VNODE_DELETED) { | 258 | if (test_bit(AFS_VNODE_DELETED, &vnode->flags)) { |
171 | _leave(" [deleted]"); | 259 | _leave(" [deleted]"); |
172 | return -ENOENT; | 260 | return -ENOENT; |
173 | } | 261 | } |
174 | 262 | ||
175 | spin_lock(&vnode->lock); | 263 | spin_lock(&vnode->lock); |
176 | 264 | ||
177 | if (!(vnode->flags & AFS_VNODE_CHANGED)) { | 265 | if (!test_bit(AFS_VNODE_CB_BROKEN, &vnode->flags) && |
266 | vnode->cb_promised) { | ||
178 | spin_unlock(&vnode->lock); | 267 | spin_unlock(&vnode->lock); |
179 | _leave(" [unchanged]"); | 268 | _leave(" [unchanged]"); |
180 | return 0; | 269 | return 0; |
@@ -183,17 +272,18 @@ int afs_vnode_fetch_status(struct afs_vnode *vnode) | |||
183 | if (vnode->update_cnt > 0) { | 272 | if (vnode->update_cnt > 0) { |
184 | /* someone else started a fetch */ | 273 | /* someone else started a fetch */ |
185 | set_current_state(TASK_UNINTERRUPTIBLE); | 274 | set_current_state(TASK_UNINTERRUPTIBLE); |
275 | ASSERT(myself.func != NULL); | ||
186 | add_wait_queue(&vnode->update_waitq, &myself); | 276 | add_wait_queue(&vnode->update_waitq, &myself); |
187 | 277 | ||
188 | /* wait for the status to be updated */ | 278 | /* wait for the status to be updated */ |
189 | for (;;) { | 279 | for (;;) { |
190 | if (!(vnode->flags & AFS_VNODE_CHANGED)) | 280 | if (!test_bit(AFS_VNODE_CB_BROKEN, &vnode->flags)) |
191 | break; | 281 | break; |
192 | if (vnode->flags & AFS_VNODE_DELETED) | 282 | if (test_bit(AFS_VNODE_DELETED, &vnode->flags)) |
193 | break; | 283 | break; |
194 | 284 | ||
195 | /* it got updated and invalidated all before we saw | 285 | /* check to see if it got updated and invalidated all |
196 | * it */ | 286 | * before we saw it */ |
197 | if (vnode->update_cnt == 0) { | 287 | if (vnode->update_cnt == 0) { |
198 | remove_wait_queue(&vnode->update_waitq, | 288 | remove_wait_queue(&vnode->update_waitq, |
199 | &myself); | 289 | &myself); |
@@ -213,7 +303,8 @@ int afs_vnode_fetch_status(struct afs_vnode *vnode) | |||
213 | spin_unlock(&vnode->lock); | 303 | spin_unlock(&vnode->lock); |
214 | set_current_state(TASK_RUNNING); | 304 | set_current_state(TASK_RUNNING); |
215 | 305 | ||
216 | return vnode->flags & AFS_VNODE_DELETED ? -ENOENT : 0; | 306 | return test_bit(AFS_VNODE_DELETED, &vnode->flags) ? |
307 | -ENOENT : 0; | ||
217 | } | 308 | } |
218 | 309 | ||
219 | get_anyway: | 310 | get_anyway: |
@@ -226,15 +317,17 @@ get_anyway: | |||
226 | * vnode */ | 317 | * vnode */ |
227 | do { | 318 | do { |
228 | /* pick a server to query */ | 319 | /* pick a server to query */ |
229 | ret = afs_volume_pick_fileserver(vnode->volume, &server); | 320 | server = afs_volume_pick_fileserver(vnode); |
230 | if (ret<0) | 321 | if (IS_ERR(server)) |
231 | return ret; | 322 | return PTR_ERR(server); |
232 | 323 | ||
233 | _debug("USING SERVER: %08x\n", ntohl(server->addr.s_addr)); | 324 | _debug("USING SERVER: %p{%08x}", |
325 | server, ntohl(server->addr.s_addr)); | ||
234 | 326 | ||
235 | ret = afs_rxfs_fetch_file_status(server, vnode, NULL); | 327 | ret = afs_fs_fetch_file_status(server, vnode, NULL, |
328 | &afs_sync_call); | ||
236 | 329 | ||
237 | } while (!afs_volume_release_fileserver(vnode->volume, server, ret)); | 330 | } while (!afs_volume_release_fileserver(vnode, server, ret)); |
238 | 331 | ||
239 | /* adjust the flags */ | 332 | /* adjust the flags */ |
240 | afs_vnode_finalise_status_update(vnode, server, ret); | 333 | afs_vnode_finalise_status_update(vnode, server, ret); |
@@ -247,8 +340,8 @@ get_anyway: | |||
247 | * fetch file data from the volume | 340 | * fetch file data from the volume |
248 | * - TODO implement caching and server failover | 341 | * - TODO implement caching and server failover |
249 | */ | 342 | */ |
250 | int afs_vnode_fetch_data(struct afs_vnode *vnode, | 343 | int afs_vnode_fetch_data(struct afs_vnode *vnode, off_t offset, size_t length, |
251 | struct afs_rxfs_fetch_descriptor *desc) | 344 | struct page *page) |
252 | { | 345 | { |
253 | struct afs_server *server; | 346 | struct afs_server *server; |
254 | int ret; | 347 | int ret; |
@@ -268,15 +361,16 @@ int afs_vnode_fetch_data(struct afs_vnode *vnode, | |||
268 | * vnode */ | 361 | * vnode */ |
269 | do { | 362 | do { |
270 | /* pick a server to query */ | 363 | /* pick a server to query */ |
271 | ret = afs_volume_pick_fileserver(vnode->volume, &server); | 364 | server = afs_volume_pick_fileserver(vnode); |
272 | if (ret < 0) | 365 | if (IS_ERR(server)) |
273 | return ret; | 366 | return PTR_ERR(server); |
274 | 367 | ||
275 | _debug("USING SERVER: %08x\n", ntohl(server->addr.s_addr)); | 368 | _debug("USING SERVER: %08x\n", ntohl(server->addr.s_addr)); |
276 | 369 | ||
277 | ret = afs_rxfs_fetch_file_data(server, vnode, desc, NULL); | 370 | ret = afs_fs_fetch_data(server, vnode, offset, length, page, |
371 | NULL, &afs_sync_call); | ||
278 | 372 | ||
279 | } while (!afs_volume_release_fileserver(vnode->volume, server, ret)); | 373 | } while (!afs_volume_release_fileserver(vnode, server, ret)); |
280 | 374 | ||
281 | /* adjust the flags */ | 375 | /* adjust the flags */ |
282 | afs_vnode_finalise_status_update(vnode, server, ret); | 376 | afs_vnode_finalise_status_update(vnode, server, ret); |
@@ -284,99 +378,3 @@ int afs_vnode_fetch_data(struct afs_vnode *vnode, | |||
284 | _leave(" = %d", ret); | 378 | _leave(" = %d", ret); |
285 | return ret; | 379 | return ret; |
286 | } | 380 | } |
287 | |||
288 | /* | ||
289 | * break any outstanding callback on a vnode | ||
290 | * - only relevent to server that issued it | ||
291 | */ | ||
292 | int afs_vnode_give_up_callback(struct afs_vnode *vnode) | ||
293 | { | ||
294 | struct afs_server *server; | ||
295 | int ret; | ||
296 | |||
297 | _enter("%s,{%u,%u,%u}", | ||
298 | vnode->volume->vlocation->vldb.name, | ||
299 | vnode->fid.vid, | ||
300 | vnode->fid.vnode, | ||
301 | vnode->fid.unique); | ||
302 | |||
303 | spin_lock(&afs_cb_hash_lock); | ||
304 | list_del_init(&vnode->cb_hash_link); | ||
305 | spin_unlock(&afs_cb_hash_lock); | ||
306 | |||
307 | /* set the changed flag in the vnode and release the server */ | ||
308 | spin_lock(&vnode->lock); | ||
309 | |||
310 | afs_kafstimod_del_timer(&vnode->cb_timeout); | ||
311 | |||
312 | server = xchg(&vnode->cb_server, NULL); | ||
313 | if (server) { | ||
314 | vnode->flags |= AFS_VNODE_CHANGED; | ||
315 | |||
316 | spin_lock(&server->cb_lock); | ||
317 | list_del_init(&vnode->cb_link); | ||
318 | spin_unlock(&server->cb_lock); | ||
319 | } | ||
320 | |||
321 | spin_unlock(&vnode->lock); | ||
322 | |||
323 | ret = 0; | ||
324 | if (server) { | ||
325 | ret = afs_rxfs_give_up_callback(server, vnode); | ||
326 | afs_put_server(server); | ||
327 | } | ||
328 | |||
329 | _leave(" = %d", ret); | ||
330 | return ret; | ||
331 | } | ||
332 | |||
333 | /* | ||
334 | * match a vnode record stored in the cache | ||
335 | */ | ||
336 | #ifdef AFS_CACHING_SUPPORT | ||
337 | static cachefs_match_val_t afs_vnode_cache_match(void *target, | ||
338 | const void *entry) | ||
339 | { | ||
340 | const struct afs_cache_vnode *cvnode = entry; | ||
341 | struct afs_vnode *vnode = target; | ||
342 | |||
343 | _enter("{%x,%x,%Lx},{%x,%x,%Lx}", | ||
344 | vnode->fid.vnode, | ||
345 | vnode->fid.unique, | ||
346 | vnode->status.version, | ||
347 | cvnode->vnode_id, | ||
348 | cvnode->vnode_unique, | ||
349 | cvnode->data_version); | ||
350 | |||
351 | if (vnode->fid.vnode != cvnode->vnode_id) { | ||
352 | _leave(" = FAILED"); | ||
353 | return CACHEFS_MATCH_FAILED; | ||
354 | } | ||
355 | |||
356 | if (vnode->fid.unique != cvnode->vnode_unique || | ||
357 | vnode->status.version != cvnode->data_version) { | ||
358 | _leave(" = DELETE"); | ||
359 | return CACHEFS_MATCH_SUCCESS_DELETE; | ||
360 | } | ||
361 | |||
362 | _leave(" = SUCCESS"); | ||
363 | return CACHEFS_MATCH_SUCCESS; | ||
364 | } | ||
365 | #endif | ||
366 | |||
367 | /* | ||
368 | * update a vnode record stored in the cache | ||
369 | */ | ||
370 | #ifdef AFS_CACHING_SUPPORT | ||
371 | static void afs_vnode_cache_update(void *source, void *entry) | ||
372 | { | ||
373 | struct afs_cache_vnode *cvnode = entry; | ||
374 | struct afs_vnode *vnode = source; | ||
375 | |||
376 | _enter(""); | ||
377 | |||
378 | cvnode->vnode_id = vnode->fid.vnode; | ||
379 | cvnode->vnode_unique = vnode->fid.unique; | ||
380 | cvnode->data_version = vnode->status.version; | ||
381 | } | ||
382 | #endif | ||