aboutsummaryrefslogtreecommitdiffstats
path: root/fs/afs/callback.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/afs/callback.c')
-rw-r--r--fs/afs/callback.c36
1 files changed, 32 insertions, 4 deletions
diff --git a/fs/afs/callback.c b/fs/afs/callback.c
index e674bebbb8b1..639399f0ab6f 100644
--- a/fs/afs/callback.c
+++ b/fs/afs/callback.c
@@ -44,7 +44,8 @@ void afs_init_callback_state(struct afs_server *server)
44 while (!RB_EMPTY_ROOT(&server->cb_promises)) { 44 while (!RB_EMPTY_ROOT(&server->cb_promises)) {
45 vnode = rb_entry(server->cb_promises.rb_node, 45 vnode = rb_entry(server->cb_promises.rb_node,
46 struct afs_vnode, cb_promise); 46 struct afs_vnode, cb_promise);
47 printk("\nUNPROMISE on %p\n", vnode); 47 _debug("UNPROMISE { vid=%x vn=%u uq=%u}",
48 vnode->fid.vid, vnode->fid.vnode, vnode->fid.unique);
48 rb_erase(&vnode->cb_promise, &server->cb_promises); 49 rb_erase(&vnode->cb_promise, &server->cb_promises);
49 vnode->cb_promised = false; 50 vnode->cb_promised = false;
50 } 51 }
@@ -68,7 +69,7 @@ void afs_broken_callback_work(struct work_struct *work)
68 69
69 /* we're only interested in dealing with a broken callback on *this* 70 /* we're only interested in dealing with a broken callback on *this*
70 * vnode and only if no-one else has dealt with it yet */ 71 * vnode and only if no-one else has dealt with it yet */
71 if (!mutex_trylock(&vnode->cb_broken_lock)) 72 if (!mutex_trylock(&vnode->validate_lock))
72 return; /* someone else is dealing with it */ 73 return; /* someone else is dealing with it */
73 74
74 if (test_bit(AFS_VNODE_CB_BROKEN, &vnode->flags)) { 75 if (test_bit(AFS_VNODE_CB_BROKEN, &vnode->flags)) {
@@ -84,13 +85,14 @@ void afs_broken_callback_work(struct work_struct *work)
84 /* if the vnode's data version number changed then its contents 85 /* if the vnode's data version number changed then its contents
85 * are different */ 86 * are different */
86 if (test_and_clear_bit(AFS_VNODE_ZAP_DATA, &vnode->flags)) { 87 if (test_and_clear_bit(AFS_VNODE_ZAP_DATA, &vnode->flags)) {
87 _debug("zap data"); 88 _debug("zap data {%x:%u}",
89 vnode->fid.vid, vnode->fid.vnode);
88 invalidate_remote_inode(&vnode->vfs_inode); 90 invalidate_remote_inode(&vnode->vfs_inode);
89 } 91 }
90 } 92 }
91 93
92out: 94out:
93 mutex_unlock(&vnode->cb_broken_lock); 95 mutex_unlock(&vnode->validate_lock);
94 96
95 /* avoid the potential race whereby the mutex_trylock() in this 97 /* avoid the potential race whereby the mutex_trylock() in this
96 * function happens again between the clear_bit() and the 98 * function happens again between the clear_bit() and the
@@ -252,6 +254,32 @@ static void afs_do_give_up_callback(struct afs_server *server,
252} 254}
253 255
254/* 256/*
257 * discard the callback on a deleted item
258 */
259void afs_discard_callback_on_delete(struct afs_vnode *vnode)
260{
261 struct afs_server *server = vnode->server;
262
263 _enter("%d", vnode->cb_promised);
264
265 if (!vnode->cb_promised) {
266 _leave(" [not promised]");
267 return;
268 }
269
270 ASSERT(server != NULL);
271
272 spin_lock(&server->cb_lock);
273 if (vnode->cb_promised) {
274 ASSERT(server->cb_promises.rb_node != NULL);
275 rb_erase(&vnode->cb_promise, &server->cb_promises);
276 vnode->cb_promised = false;
277 }
278 spin_unlock(&server->cb_lock);
279 _leave("");
280}
281
282/*
255 * give up the callback registered for a vnode on the file server when the 283 * give up the callback registered for a vnode on the file server when the
256 * inode is being cleared 284 * inode is being cleared
257 */ 285 */