Writing to attributes was deadlock prone; the BFS volume lock was acquired with

the BFS Journal lock held.
Since our get_vnode() is no longer unsafe (unlike Be's version of it), we can
get rid of the UNSAFE_GET_VNODE stuff, which also solves this bug.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19916 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2007-01-23 17:09:21 +00:00
parent 3a630146d2
commit fc317af25e
4 changed files with 4 additions and 42 deletions
@@ -1,6 +1,6 @@
/* BlockAllocator - block bitmap handling and allocation policies /* BlockAllocator - block bitmap handling and allocation policies
* *
* Copyright 2001-2006, Axel Dörfler, [email protected]. * Copyright 2001-2007, Axel Dörfler, [email protected].
* This file may be used under the terms of the MIT License. * This file may be used under the terms of the MIT License.
*/ */
@@ -935,9 +935,6 @@ BlockAllocator::CheckNextNode(check_control *control)
// get iterator for the next directory // get iterator for the next directory
#ifdef UNSAFE_GET_VNODE
RecursiveLocker locker(fVolume->Lock());
#endif
Vnode vnode(fVolume, cookie->current); Vnode vnode(fVolume, cookie->current);
Inode *inode; Inode *inode;
if (vnode.Get(&inode) < B_OK) { if (vnode.Get(&inode) < B_OK) {
@@ -1039,9 +1036,6 @@ BlockAllocator::CheckNextNode(check_control *control)
// if we are allowed to fix errors, we should remove the file // if we are allowed to fix errors, we should remove the file
if (control->flags & BFS_REMOVE_WRONG_TYPES if (control->flags & BFS_REMOVE_WRONG_TYPES
&& control->flags & BFS_FIX_BITMAP_ERRORS) { && control->flags & BFS_FIX_BITMAP_ERRORS) {
#ifdef UNSAFE_GET_VNODE
RecursiveLocker locker(fVolume->Lock());
#endif
// it's safe to start a transaction, because Inode::Remove() // it's safe to start a transaction, because Inode::Remove()
// won't touch the block bitmap (which we hold the lock for) // won't touch the block bitmap (which we hold the lock for)
// if we set the INODE_DONT_FREE_SPACE flag - since we fix // if we set the INODE_DONT_FREE_SPACE flag - since we fix
+1 -4
View File
@@ -1,6 +1,6 @@
/* Inode - inode access functions /* Inode - inode access functions
* *
* Copyright 2001-2006, Axel Dörfler, [email protected]. * Copyright 2001-2007, Axel Dörfler, [email protected].
* This file may be used under the terms of the MIT License. * This file may be used under the terms of the MIT License.
*/ */
#ifndef INODE_H #ifndef INODE_H
@@ -250,9 +250,6 @@ class Vnode {
status_t Get(Inode **_inode) status_t Get(Inode **_inode)
{ {
// should we check inode against NULL here? it should not be necessary // should we check inode against NULL here? it should not be necessary
#ifdef UNSAFE_GET_VNODE
RecursiveLocker locker(fVolume->Lock());
#endif
return get_vnode(fVolume->ID(), fID, (void **)_inode); return get_vnode(fVolume->ID(), fID, (void **)_inode);
} }
+1 -2
View File
@@ -3,7 +3,7 @@ SubDir HAIKU_TOP src add-ons kernel file_systems bfs ;
# save original optimization level # save original optimization level
oldOPTIM = $(OPTIM) ; oldOPTIM = $(OPTIM) ;
# R5 support is currently disabled! # R5 support has been removed!
# #
# Have a look in src/tests/add-ons/kernel/file_systems/bfs/r5/ # Have a look in src/tests/add-ons/kernel/file_systems/bfs/r5/
# for an R5 compatible version. # for an R5 compatible version.
@@ -13,7 +13,6 @@ oldOPTIM = $(OPTIM) ;
# set some additional defines # set some additional defines
{ {
local defines = local defines =
UNSAFE_GET_VNODE
#BFS_BIG_ENDIAN_ONLY #BFS_BIG_ENDIAN_ONLY
; ;
@@ -1,6 +1,6 @@
/* kernel_interface - file system interface to Haiku's vnode layer /* kernel_interface - file system interface to Haiku's vnode layer
* *
* Copyright 2001-2006, Axel Dörfler, [email protected]. * Copyright 2001-2007, Axel Dörfler, [email protected].
* This file may be used under the terms of the MIT License. * This file may be used under the terms of the MIT License.
*/ */
@@ -693,10 +693,6 @@ bfs_write_stat(void *_ns, void *_node, const struct stat *stat, uint32 mask)
if (status < B_OK) if (status < B_OK)
RETURN_ERROR(status); RETURN_ERROR(status);
#ifdef UNSAFE_GET_VNODE
RecursiveLocker locker(volume->Lock());
#endif
WriteLocked locked(inode->Lock()); WriteLocked locked(inode->Lock());
if (locked.IsLocked() < B_OK) if (locked.IsLocked() < B_OK)
RETURN_ERROR(B_ERROR); RETURN_ERROR(B_ERROR);
@@ -793,9 +789,6 @@ bfs_create(void *_ns, void *_directory, const char *name, int openMode, int mode
cookie->last_size = 0; cookie->last_size = 0;
cookie->last_notification = system_time(); cookie->last_notification = system_time();
#ifdef UNSAFE_GET_VNODE
RecursiveLocker locker(volume->Lock());
#endif
Transaction transaction(volume, directory->BlockNumber()); Transaction transaction(volume, directory->BlockNumber());
status_t status = Inode::Create(transaction, directory, name, S_FILE | (mode & S_IUMSK), status_t status = Inode::Create(transaction, directory, name, S_FILE | (mode & S_IUMSK),
@@ -834,9 +827,6 @@ bfs_create_symlink(void *_ns, void *_directory, const char *name, const char *pa
if (status < B_OK) if (status < B_OK)
RETURN_ERROR(status); RETURN_ERROR(status);
#ifdef UNSAFE_GET_VNODE
RecursiveLocker locker(volume->Lock());
#endif
Transaction transaction(volume, directory->BlockNumber()); Transaction transaction(volume, directory->BlockNumber());
Inode *link; Inode *link;
@@ -904,9 +894,6 @@ bfs_unlink(void *_ns, void *_directory, const char *name)
if (status < B_OK) if (status < B_OK)
return status; return status;
#ifdef UNSAFE_GET_VNODE
RecursiveLocker locker(volume->Lock());
#endif
Transaction transaction(volume, directory->BlockNumber()); Transaction transaction(volume, directory->BlockNumber());
off_t id; off_t id;
@@ -1274,9 +1261,6 @@ bfs_free_cookie(void *_ns, void *_node, void *_cookie)
&& (needsTrimming && (needsTrimming
|| inode->OldLastModified() != inode->LastModified() || inode->OldLastModified() != inode->LastModified()
|| inode->OldSize() != inode->Size())) { || inode->OldSize() != inode->Size())) {
#ifdef UNSAFE_GET_VNODE
RecursiveLocker locker(volume->Lock());
#endif
ReadLocked locked(inode->Lock()); ReadLocked locked(inode->Lock());
// trim the preallocated blocks and update the size, // trim the preallocated blocks and update the size,
@@ -1406,9 +1390,6 @@ bfs_create_dir(void *_ns, void *_directory, const char *name, int mode, vnode_id
if (status < B_OK) if (status < B_OK)
RETURN_ERROR(status); RETURN_ERROR(status);
#ifdef UNSAFE_GET_VNODE
RecursiveLocker locker(volume->Lock());
#endif
Transaction transaction(volume, directory->BlockNumber()); Transaction transaction(volume, directory->BlockNumber());
// Inode::Create() locks the inode if we pass the "id" parameter, but we // Inode::Create() locks the inode if we pass the "id" parameter, but we
@@ -1438,9 +1419,6 @@ bfs_remove_dir(void *_ns, void *_directory, const char *name)
Volume *volume = (Volume *)_ns; Volume *volume = (Volume *)_ns;
Inode *directory = (Inode *)_directory; Inode *directory = (Inode *)_directory;
#ifdef UNSAFE_GET_VNODE
RecursiveLocker locker(volume->Lock());
#endif
Transaction transaction(volume, directory->BlockNumber()); Transaction transaction(volume, directory->BlockNumber());
off_t id; off_t id;
@@ -1882,9 +1860,6 @@ bfs_create_index(fs_volume _fs, const char *name, uint32 type, uint32 flags)
if (geteuid() != 0) if (geteuid() != 0)
return B_NOT_ALLOWED; return B_NOT_ALLOWED;
#ifdef UNSAFE_GET_VNODE
RecursiveLocker locker(volume->Lock());
#endif
Transaction transaction(volume, volume->Indices()); Transaction transaction(volume, volume->Indices());
Index index(volume); Index index(volume);
@@ -1917,9 +1892,6 @@ bfs_remove_index(void *_ns, const char *name)
if ((indices = volume->IndicesNode()) == NULL) if ((indices = volume->IndicesNode()) == NULL)
return B_ENTRY_NOT_FOUND; return B_ENTRY_NOT_FOUND;
#ifdef UNSAFE_GET_VNODE
RecursiveLocker locker(volume->Lock());
#endif
Transaction transaction(volume, volume->Indices()); Transaction transaction(volume, volume->Indices());
status_t status = indices->Remove(transaction, name); status_t status = indices->Remove(transaction, name);