aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2007-05-11 01:22:20 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-11 11:29:32 -0400
commit0f300ca9284caabdd2c07c7f91b90f1f530f614e (patch)
tree12c64af9cbaeafbe47e63872a750badb623a7e81 /fs
parent9d577b6a31a53a19d3b0fe414d645a61ef201846 (diff)
AFS: fix a couple of problems with unlinking AFS files
Fix a couple of problems with unlinking AFS files. (1) The parent directory wasn't being updated properly between unlink() and the following lookup(). It seems that, for some reason, invalidate_remote_inode() wasn't discarding the directory contents correctly, so this patch calls invalidate_inode_pages2() instead on non-regular files. (2) afs_vnode_deleted_remotely() should handle vnodes that don't have a source server recorded without oopsing. Signed-off-by: David Howells <dhowells@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/afs/file.c2
-rw-r--r--fs/afs/inode.c10
-rw-r--r--fs/afs/super.c3
-rw-r--r--fs/afs/vnode.c33
4 files changed, 31 insertions, 17 deletions
diff --git a/fs/afs/file.c b/fs/afs/file.c
index 3e25795e5a42..9c0e721d9fc2 100644
--- a/fs/afs/file.c
+++ b/fs/afs/file.c
@@ -236,7 +236,7 @@ static void afs_invalidatepage(struct page *page, unsigned long offset)
236{ 236{
237 int ret = 1; 237 int ret = 1;
238 238
239 kenter("{%lu},%lu", page->index, offset); 239 _enter("{%lu},%lu", page->index, offset);
240 240
241 BUG_ON(!PageLocked(page)); 241 BUG_ON(!PageLocked(page));
242 242
diff --git a/fs/afs/inode.c b/fs/afs/inode.c
index 515a5d12d8fb..47f5fed7195d 100644
--- a/fs/afs/inode.c
+++ b/fs/afs/inode.c
@@ -209,11 +209,15 @@ bad_inode:
209 */ 209 */
210void afs_zap_data(struct afs_vnode *vnode) 210void afs_zap_data(struct afs_vnode *vnode)
211{ 211{
212 _enter("zap data {%x:%u}", vnode->fid.vid, vnode->fid.vnode); 212 _enter("{%x:%u}", vnode->fid.vid, vnode->fid.vnode);
213 213
214 /* nuke all the non-dirty pages that aren't locked, mapped or being 214 /* nuke all the non-dirty pages that aren't locked, mapped or being
215 * written back */ 215 * written back in a regular file and completely discard the pages in a
216 invalidate_remote_inode(&vnode->vfs_inode); 216 * directory or symlink */
217 if (S_ISREG(vnode->vfs_inode.i_mode))
218 invalidate_remote_inode(&vnode->vfs_inode);
219 else
220 invalidate_inode_pages2(vnode->vfs_inode.i_mapping);
217} 221}
218 222
219/* 223/*
diff --git a/fs/afs/super.c b/fs/afs/super.c
index d24be334b608..422f532b9b62 100644
--- a/fs/afs/super.c
+++ b/fs/afs/super.c
@@ -488,6 +488,7 @@ static struct inode *afs_alloc_inode(struct super_block *sb)
488 vnode->flags = 1 << AFS_VNODE_UNSET; 488 vnode->flags = 1 << AFS_VNODE_UNSET;
489 vnode->cb_promised = false; 489 vnode->cb_promised = false;
490 490
491 _leave(" = %p", &vnode->vfs_inode);
491 return &vnode->vfs_inode; 492 return &vnode->vfs_inode;
492} 493}
493 494
@@ -498,7 +499,7 @@ static void afs_destroy_inode(struct inode *inode)
498{ 499{
499 struct afs_vnode *vnode = AFS_FS_I(inode); 500 struct afs_vnode *vnode = AFS_FS_I(inode);
500 501
501 _enter("{%lu}", inode->i_ino); 502 _enter("%p{%x:%u}", inode, vnode->fid.vid, vnode->fid.vnode);
502 503
503 _debug("DESTROY INODE %p", inode); 504 _debug("DESTROY INODE %p", inode);
504 505
diff --git a/fs/afs/vnode.c b/fs/afs/vnode.c
index ec814660209f..bea8bd9e7b2a 100644
--- a/fs/afs/vnode.c
+++ b/fs/afs/vnode.c
@@ -175,24 +175,33 @@ static void afs_vnode_deleted_remotely(struct afs_vnode *vnode)
175{ 175{
176 struct afs_server *server; 176 struct afs_server *server;
177 177
178 _enter("{%p}", vnode->server);
179
178 set_bit(AFS_VNODE_DELETED, &vnode->flags); 180 set_bit(AFS_VNODE_DELETED, &vnode->flags);
179 181
180 server = vnode->server; 182 server = vnode->server;
181 if (vnode->cb_promised) { 183 if (server) {
182 spin_lock(&server->cb_lock);
183 if (vnode->cb_promised) { 184 if (vnode->cb_promised) {
184 rb_erase(&vnode->cb_promise, &server->cb_promises); 185 spin_lock(&server->cb_lock);
185 vnode->cb_promised = false; 186 if (vnode->cb_promised) {
187 rb_erase(&vnode->cb_promise,
188 &server->cb_promises);
189 vnode->cb_promised = false;
190 }
191 spin_unlock(&server->cb_lock);
186 } 192 }
187 spin_unlock(&server->cb_lock);
188 }
189 193
190 spin_lock(&vnode->server->fs_lock); 194 spin_lock(&server->fs_lock);
191 rb_erase(&vnode->server_rb, &vnode->server->fs_vnodes); 195 rb_erase(&vnode->server_rb, &server->fs_vnodes);
192 spin_unlock(&vnode->server->fs_lock); 196 spin_unlock(&server->fs_lock);
193 197
194 vnode->server = NULL; 198 vnode->server = NULL;
195 afs_put_server(server); 199 afs_put_server(server);
200 } else {
201 ASSERT(!vnode->cb_promised);
202 }
203
204 _leave("");
196} 205}
197 206
198/* 207/*
@@ -225,7 +234,7 @@ void afs_vnode_finalise_status_update(struct afs_vnode *vnode,
225 */ 234 */
226static void afs_vnode_status_update_failed(struct afs_vnode *vnode, int ret) 235static void afs_vnode_status_update_failed(struct afs_vnode *vnode, int ret)
227{ 236{
228 _enter("%p,%d", vnode, ret); 237 _enter("{%x:%u},%d", vnode->fid.vid, vnode->fid.vnode, ret);
229 238
230 spin_lock(&vnode->lock); 239 spin_lock(&vnode->lock);
231 240