[haiku-commits] r35491 - haiku/trunk/src/add-ons/kernel/file_systems/bfs

  • From: axeld@xxxxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Tue, 16 Feb 2010 12:30:15 +0100 (CET)

Author: axeld
Date: 2010-02-16 12:30:15 +0100 (Tue, 16 Feb 2010)
New Revision: 35491
Changeset: http://dev.haiku-os.org/changeset/35491/haiku

Modified:
   haiku/trunk/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp
   haiku/trunk/src/add-ons/kernel/file_systems/bfs/Inode.cpp
   haiku/trunk/src/add-ons/kernel/file_systems/bfs/Inode.h
   haiku/trunk/src/add-ons/kernel/file_systems/bfs/Journal.cpp
   haiku/trunk/src/add-ons/kernel/file_systems/bfs/Journal.h
   haiku/trunk/src/add-ons/kernel/file_systems/bfs/Volume.h
   haiku/trunk/src/add-ons/kernel/file_systems/bfs/bfs.h
Log:
* Replaced the specialized inode in transaction mechanism with a generic one.
  That costs 12 more bytes per inode on 32 bit platforms, though.


Modified: haiku/trunk/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp
===================================================================
--- haiku/trunk/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp  
2010-02-16 08:34:55 UTC (rev 35490)
+++ haiku/trunk/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp  
2010-02-16 11:30:15 UTC (rev 35491)
@@ -3,6 +3,7 @@
  * This file may be used under the terms of the MIT License.
  */
 
+
 //! block bitmap handling and allocation policies
 
 

Modified: haiku/trunk/src/add-ons/kernel/file_systems/bfs/Inode.cpp
===================================================================
--- haiku/trunk/src/add-ons/kernel/file_systems/bfs/Inode.cpp   2010-02-16 
08:34:55 UTC (rev 35490)
+++ haiku/trunk/src/add-ons/kernel/file_systems/bfs/Inode.cpp   2010-02-16 
11:30:15 UTC (rev 35491)
@@ -3,9 +3,10 @@
  * This file may be used under the terms of the MIT License.
  */
 
-//! inode access functions
 
+//! Inode access functions
 
+
 #include "Debug.h"
 #include "Inode.h"
 #include "BPlusTree.h"
@@ -175,7 +176,7 @@
                        fInode->Node().flags &= 
~HOST_ENDIAN_TO_BFS_INT32(INODE_IN_USE);
                                // this unblocks any pending bfs_read_vnode() 
calls
                        fInode->Free(*fTransaction);
-                       fTransaction->RemoveInode(fInode);
+                       fTransaction->RemoveListener(fInode);
 
                        remove_vnode(volume->FSVolume(), fInode->ID());
                } else
@@ -291,7 +292,7 @@
 
 
 status_t
-bfs_inode::InitCheck(Volume* volume)
+bfs_inode::InitCheck(Volume* volume) const
 {
        if (Magic1() != INODE_MAGIC1
                || !(Flags() & INODE_IN_USE)
@@ -403,7 +404,7 @@
 
 
 status_t
-Inode::InitCheck(bool checkNode)
+Inode::InitCheck(bool checkNode) const
 {
        // test inode magic and flags
        if (checkNode) {
@@ -437,6 +438,33 @@
 }
 
 
+/*!    Adds this inode to the specified transaction. This means that the inode 
will
+       be write locked until the transaction ended.
+       To ensure that the inode will stay valid until that point, an extra 
reference
+       is acquired to it as long as this transaction stays active.
+*/
+void
+Inode::WriteLockInTransaction(Transaction& transaction)
+{
+       // These flags can only change while holding the transaction lock
+       if ((Flags() & INODE_IN_TRANSACTION) != 0)
+               return;
+
+       // We share the same list link with the removed list, so we have to 
remove
+       // the inode from that list here (and add it back when we no longer 
need it)
+       if ((Flags() & INODE_DELETED) != 0)
+               fVolume->RemovedInodes().Remove(this);
+
+       if (!fVolume->IsInitializing())
+               acquire_vnode(fVolume->FSVolume(), ID());
+
+       rw_lock_write_lock(&Lock());
+       Node().flags |= HOST_ENDIAN_TO_BFS_INT32(INODE_IN_TRANSACTION);
+
+       transaction.AddListener(this);
+}
+
+
 status_t
 Inode::WriteBack(Transaction& transaction)
 {
@@ -2379,6 +2407,35 @@
 }
 
 
+//     #pragma mark - TransactionListener implementation
+
+
+void
+Inode::TransactionDone(bool success)
+{
+       if (!success) {
+               // revert any changes made to the cached bfs_inode
+               UpdateNodeFromDisk();
+       }
+}
+
+
+void
+Inode::RemovedFromTransaction()
+{
+       Node().flags &= ~HOST_ENDIAN_TO_BFS_INT32(INODE_IN_TRANSACTION);
+
+       // See AddInode() why we do this here
+       if ((Flags() & INODE_DELETED) != 0)
+               fVolume->RemovedInodes().Add(this);
+
+       rw_lock_write_unlock(&Lock());
+
+       if (!fVolume->IsInitializing())
+               put_vnode(fVolume->FSVolume(), ID());
+}
+
+
 //     #pragma mark - creation/deletion
 
 

Modified: haiku/trunk/src/add-ons/kernel/file_systems/bfs/Inode.h
===================================================================
--- haiku/trunk/src/add-ons/kernel/file_systems/bfs/Inode.h     2010-02-16 
08:34:55 UTC (rev 35490)
+++ haiku/trunk/src/add-ons/kernel/file_systems/bfs/Inode.h     2010-02-16 
11:30:15 UTC (rev 35491)
@@ -23,241 +23,245 @@
 class Transaction;
 
 
-class Inode {
+class Inode : public TransactionListener {
        typedef DoublyLinkedListLink<Inode> Link;
 
 public:
-                                                       Inode(Volume* volume, 
ino_t id);
-                                                       Inode(Volume* volume, 
Transaction& transaction,
-                                                               ino_t id, 
mode_t mode, block_run& run);
-                                                       ~Inode();
+                                                               Inode(Volume* 
volume, ino_t id);
+                                                               Inode(Volume* 
volume, Transaction& transaction,
+                                                                       ino_t 
id, mode_t mode, block_run& run);
+                                                               ~Inode();
 
-                       ino_t                   ID() const { return fID; }
-                       off_t                   BlockNumber() const
-                                                               { return 
fVolume->VnodeToBlock(fID); }
+                       status_t                        InitCheck(bool 
checkNode = true) const;
 
-                       rw_lock&                Lock() { return fLock; }
-                       ReadLocker              ReadLock() { return 
ReadLocker(fLock); }
-                       void                    
WriteLockInTransaction(Transaction& transaction)
-                                                               { 
transaction.AddInode(this); }
+                       ino_t                           ID() const { return 
fID; }
+                       off_t                           BlockNumber() const
+                                                                       { 
return fVolume->VnodeToBlock(fID); }
 
-                       recursive_lock& SmallDataLock() { return 
fSmallDataLock; }
+                       rw_lock&                        Lock() { return fLock; }
+                       ReadLocker                      ReadLock() { return 
ReadLocker(fLock); }
+                       void                            
WriteLockInTransaction(Transaction& transaction);
 
-                       status_t                WriteBack(Transaction& 
transaction);
-                       void                    UpdateNodeFromDisk();
+                       recursive_lock&         SmallDataLock() { return 
fSmallDataLock; }
 
-                       bool                    IsContainer() const
-                                                               { return 
S_ISDIR(Mode()); }
-                       bool                    IsDirectory() const
-                                                               { return 
is_directory(Mode()); }
-                       bool                    IsIndex() const
-                                                               { return 
is_index(Mode()); }
+                       status_t                        WriteBack(Transaction& 
transaction);
+                       void                            UpdateNodeFromDisk();
 
-                       bool                    IsAttributeDirectory() const
-                                                               { return 
(Mode() & S_EXTENDED_TYPES)
-                                                                       == 
S_ATTR_DIR; }
-                       bool                    IsAttribute() const
-                                                               { return 
(Mode() & S_EXTENDED_TYPES)
-                                                                       == 
S_ATTR; }
-                       bool                    IsFile() const
-                                                               { return (Mode()
-                                                                       & 
(S_IFMT | S_EXTENDED_TYPES)) == S_FILE; }
-                       bool                    IsRegularNode() const
-                                                               { return 
(Mode() & S_EXTENDED_TYPES) == 0; }
-                                                               // a regular 
node in the standard namespace
-                                                               // (i.e. not an 
index or attribute)
-                       bool                    IsSymLink() const { return 
S_ISLNK(Mode()); }
-                       bool                    IsLongSymLink() const
-                                                               { return 
(Flags() & INODE_LONG_SYMLINK) != 0; }
+                       bool                            IsContainer() const
+                                                                       { 
return S_ISDIR(Mode()); }
+                       bool                            IsDirectory() const
+                                                                       { 
return is_directory(Mode()); }
+                       bool                            IsIndex() const
+                                                                       { 
return is_index(Mode()); }
 
-                       bool                    HasUserAccessableStream() const 
{ return IsFile(); }
-                                                               // currently 
only files can be accessed with
-                                                               // 
bfs_read()/bfs_write()
-                       bool                    NeedsFileCache() const
-                                                               { return 
IsFile() || IsAttribute()
-                                                                       || 
IsLongSymLink(); }
+                       bool                            IsAttributeDirectory() 
const
+                                                                       { 
return (Mode() & S_EXTENDED_TYPES)
+                                                                               
== S_ATTR_DIR; }
+                       bool                            IsAttribute() const
+                                                                       { 
return (Mode() & S_EXTENDED_TYPES)
+                                                                               
== S_ATTR; }
+                       bool                            IsFile() const
+                                                                       { 
return (Mode() & (S_IFMT
+                                                                               
        | S_EXTENDED_TYPES)) == S_FILE; }
+                       bool                            IsRegularNode() const
+                                                                       { 
return (Mode() & S_EXTENDED_TYPES) == 0; }
+                                                                       // a 
regular node in the standard namespace
+                                                                       // 
(i.e. not an index or attribute)
+                       bool                            IsSymLink() const { 
return S_ISLNK(Mode()); }
+                       bool                            IsLongSymLink() const
+                                                                       { 
return (Flags() & INODE_LONG_SYMLINK)
+                                                                               
!= 0; }
 
-                       bool                    IsDeleted() const
-                                                               { return 
(Flags() & INODE_DELETED) != 0; }
+                       bool                            
HasUserAccessableStream() const
+                                                                       { 
return IsFile(); }
+                                                                       // 
currently only files can be accessed with
+                                                                       // 
bfs_read()/bfs_write()
+                       bool                            NeedsFileCache() const
+                                                                       { 
return IsFile() || IsAttribute()
+                                                                               
|| IsLongSymLink(); }
 
-                       mode_t                  Mode() const { return 
fNode.Mode(); }
-                       uint32                  Type() const { return 
fNode.Type(); }
-                       int32                   Flags() const { return 
fNode.Flags(); }
+                       bool                            IsDeleted() const
+                                                                       { 
return (Flags() & INODE_DELETED) != 0; }
 
-                       off_t                   Size() const { return 
fNode.data.Size(); }
-                       off_t                   AllocatedSize() const;
-                       off_t                   LastModified() const
-                                                               { return 
fNode.LastModifiedTime(); }
+                       mode_t                          Mode() const { return 
fNode.Mode(); }
+                       uint32                          Type() const { return 
fNode.Type(); }
+                       int32                           Flags() const { return 
fNode.Flags(); }
 
-                       const block_run& BlockRun() const
-                                                               { return 
fNode.inode_num; }
-                       block_run&              Parent() { return fNode.parent; 
}
-                       block_run&              Attributes() { return 
fNode.attributes; }
+                       off_t                           Size() const { return 
fNode.data.Size(); }
+                       off_t                           AllocatedSize() const;
+                       off_t                           LastModified() const
+                                                                       { 
return fNode.LastModifiedTime(); }
 
-                       Volume*                 GetVolume() const { return 
fVolume; }
+                       const block_run&        BlockRun() const
+                                                                       { 
return fNode.inode_num; }
+                       block_run&                      Parent() { return 
fNode.parent; }
+                       block_run&                      Attributes() { return 
fNode.attributes; }
 
-                       status_t                InitCheck(bool checkNode = 
true);
+                       Volume*                         GetVolume() const { 
return fVolume; }
 
-                       status_t                CheckPermissions(int 
accessMode) const;
+                       status_t                        CheckPermissions(int 
accessMode) const;
 
                        // small_data access methods
-                       small_data*             FindSmallData(const bfs_inode* 
node,
-                                                               const char* 
name) const;
-                       const char*             Name(const bfs_inode* node) 
const;
-                       status_t                GetName(char* buffer,
-                                                               size_t 
bufferSize = B_FILE_NAME_LENGTH) const;
-                       status_t                SetName(Transaction& 
transaction, const char* name);
+                       small_data*                     FindSmallData(const 
bfs_inode* node,
+                                                                       const 
char* name) const;
+                       const char*                     Name(const bfs_inode* 
node) const;
+                       status_t                        GetName(char* buffer, 
size_t bufferSize
+                                                                               
= B_FILE_NAME_LENGTH) const;
+                       status_t                        SetName(Transaction& 
transaction,
+                                                                       const 
char* name);
 
                        // high-level attribute methods
-                       status_t                ReadAttribute(const char* name, 
int32 type,
-                                                               off_t pos, 
uint8* buffer, size_t* _length);
-                       status_t                WriteAttribute(Transaction& 
transaction,
-                                                               const char* 
name, int32 type, off_t pos,
-                                                               const uint8* 
buffer, size_t* _length,
-                                                               bool* _created);
-                       status_t                RemoveAttribute(Transaction& 
transaction,
-                                                               const char* 
name);
+                       status_t                        ReadAttribute(const 
char* name, int32 type,
+                                                                       off_t 
pos, uint8* buffer, size_t* _length);
+                       status_t                        
WriteAttribute(Transaction& transaction,
+                                                                       const 
char* name, int32 type, off_t pos,
+                                                                       const 
uint8* buffer, size_t* _length,
+                                                                       bool* 
_created);
+                       status_t                        
RemoveAttribute(Transaction& transaction,
+                                                                       const 
char* name);
 
                        // attribute methods
-                       status_t                GetAttribute(const char* name, 
Inode** attribute);
-                       void                    ReleaseAttribute(Inode* 
attribute);
-                       status_t                CreateAttribute(Transaction& 
transaction,
-                                                               const char* 
name, uint32 type,
-                                                               Inode** 
attribute);
+                       status_t                        GetAttribute(const 
char* name,
+                                                                       Inode** 
_attribute);
+                       void                            ReleaseAttribute(Inode* 
attribute);
+                       status_t                        
CreateAttribute(Transaction& transaction,
+                                                                       const 
char* name, uint32 type,
+                                                                       Inode** 
attribute);
 
                        // for directories only:
-                       BPlusTree*              Tree() const { return fTree; }
-                       bool                    IsEmpty();
-                       status_t                
ContainerContentsChanged(Transaction& transaction);
+                       BPlusTree*                      Tree() const { return 
fTree; }
+                       bool                            IsEmpty();
+                       status_t                        
ContainerContentsChanged(
+                                                                       
Transaction& transaction);
 
                        // manipulating the data stream
-                       status_t                FindBlockRun(off_t pos, 
block_run& run,
-                                                               off_t& offset);
+                       status_t                        FindBlockRun(off_t pos, 
block_run& run,
+                                                                       off_t& 
offset);
 
-                       status_t                ReadAt(off_t pos, uint8* 
buffer, size_t* length);
-                       status_t                WriteAt(Transaction& 
transaction, off_t pos,
-                                                               const uint8* 
buffer, size_t* length);
-                       status_t                FillGapWithZeros(off_t oldSize, 
off_t newSize);
+                       status_t                        ReadAt(off_t pos, 
uint8* buffer, size_t* length);
+                       status_t                        WriteAt(Transaction& 
transaction, off_t pos,
+                                                                       const 
uint8* buffer, size_t* length);
+                       status_t                        FillGapWithZeros(off_t 
oldSize, off_t newSize);
 
-                       status_t                SetFileSize(Transaction& 
transaction, off_t size);
-                       status_t                Append(Transaction& 
transaction, off_t bytes);
-                       status_t                TrimPreallocation(Transaction& 
transaction);
-                       bool                    NeedsTrimming() const;
+                       status_t                        
SetFileSize(Transaction& transaction,
+                                                                       off_t 
size);
+                       status_t                        Append(Transaction& 
transaction, off_t bytes);
+                       status_t                        
TrimPreallocation(Transaction& transaction);
+                       bool                            NeedsTrimming() const;
 
-                       status_t                Free(Transaction& transaction);
-                       status_t                Sync();
+                       status_t                        Free(Transaction& 
transaction);
+                       status_t                        Sync();
 
-                       bfs_inode&              Node() { return fNode; }
-                       const bfs_inode& Node() const { return fNode; }
+                       bfs_inode&                      Node() { return fNode; }
+                       const bfs_inode&        Node() const { return fNode; }
 
                        // create/remove inodes
-                       status_t                Remove(Transaction& 
transaction, const char* name,
-                                                               ino_t* _id = 
NULL, bool isDirectory = false,
-                                                               bool force = 
false);
-       static  status_t                Create(Transaction& transaction, Inode* 
parent,
-                                                               const char* 
name, int32 mode, int openMode,
-                                                               uint32 type, 
bool* _created = NULL,
-                                                               ino_t* _id = 
NULL, Inode** _inode = NULL,
-                                                               fs_vnode_ops* 
vnodeOps = NULL,
-                                                               uint32 
publishFlags = 0);
+                       status_t                        Remove(Transaction& 
transaction,
+                                                                       const 
char* name, ino_t* _id = NULL,
+                                                                       bool 
isDirectory = false,
+                                                                       bool 
force = false);
+       static  status_t                        Create(Transaction& 
transaction, Inode* parent,
+                                                                       const 
char* name, int32 mode, int openMode,
+                                                                       uint32 
type, bool* _created = NULL,
+                                                                       ino_t* 
_id = NULL, Inode** _inode = NULL,
+                                                                       
fs_vnode_ops* vnodeOps = NULL,
+                                                                       uint32 
publishFlags = 0);
 
                        // index maintaining helper
-                       void                    UpdateOldSize() { fOldSize = 
Size(); }
-                       void                    UpdateOldLastModified()
-                                                               { 
fOldLastModified
-                                                                       = 
Node().LastModifiedTime(); }
-                       off_t                   OldSize() { return fOldSize; }
-                       off_t                   OldLastModified() { return 
fOldLastModified; }
+                       void                            UpdateOldSize() { 
fOldSize = Size(); }
+                       void                            UpdateOldLastModified()
+                                                                       { 
fOldLastModified
+                                                                               
= Node().LastModifiedTime(); }
+                       off_t                           OldSize() { return 
fOldSize; }
+                       off_t                           OldLastModified() { 
return fOldLastModified; }
 
-                       bool                    InNameIndex() const;
-                       bool                    InSizeIndex() const;
-                       bool                    InLastModifiedIndex() const;
+                       bool                            InNameIndex() const;
+                       bool                            InSizeIndex() const;
+                       bool                            InLastModifiedIndex() 
const;
 
                        // file cache
-                       void*                   FileCache() const { return 
fCache; }
-                       void                    SetFileCache(void* cache) { 
fCache = cache; }
-                       void*                   Map() const { return fMap; }
-                       void                    SetMap(void* map) { fMap = map; 
}
+                       void*                           FileCache() const { 
return fCache; }
+                       void                            SetFileCache(void* 
cache) { fCache = cache; }
+                       void*                           Map() const { return 
fMap; }
+                       void                            SetMap(void* map) { 
fMap = map; }
 
 #if _KERNEL_MODE && KDEBUG
-                       void                    AssertReadLocked()
-                                                               { 
ASSERT_READ_LOCKED_RW_LOCK(&fLock); }
-                       void                    AssertWriteLocked()
-                                                               { 
ASSERT_WRITE_LOCKED_RW_LOCK(&fLock); }
+                       void                            AssertReadLocked()
+                                                                       { 
ASSERT_READ_LOCKED_RW_LOCK(&fLock); }
+                       void                            AssertWriteLocked()
+                                                                       { 
ASSERT_WRITE_LOCKED_RW_LOCK(&fLock); }
 #endif
 
-#ifdef B_HAIKU_64_BIT
-                       Link*                   GetDoublyLinkedListLink()
-                                                               { return 
&fListLink; }
-                       const Link*             GetDoublyLinkedListLink() const
-                                                               { return 
&fListLink; }
-#else
-                       Link*                   GetDoublyLinkedListLink()
-                                                               { return 
(Link*)&fNode.pad[0]; }
-                       const Link*             GetDoublyLinkedListLink() const
-                                                               { return 
(Link*)&fNode.pad[0]; }
-#endif
+                       Link*                           
GetDoublyLinkedListLink()
+                                                                       { 
return (Link*)TransactionListener
+                                                                               
::GetDoublyLinkedListLink(); }
+                       const Link*                     
GetDoublyLinkedListLink() const
+                                                                       { 
return (Link*)TransactionListener
+                                                                               
::GetDoublyLinkedListLink(); }
 
+protected:
+       virtual void                            TransactionDone(bool success);
+       virtual void                            RemovedFromTransaction();
+
 private:
-                                                       Inode(const Inode& 
other);
-                                                       Inode& operator=(const 
Inode& other);
-                                                               // no 
implementation
+                                                               Inode(const 
Inode& other);
+                                                               Inode& 
operator=(const Inode& other);
+                                                                       // no 
implementation
 
        friend class AttributeIterator;
        friend class InodeAllocator;
 
                        // small_data access methods
-                       status_t                
_MakeSpaceForSmallData(Transaction& transaction,
-                                                               bfs_inode* 
node, const char* name,
-                                                               int32 length);
-                       status_t                _RemoveSmallData(Transaction& 
transaction,
-                                                               NodeGetter& 
node, const char* name);
-                       status_t                _AddSmallData(Transaction& 
transaction,
-                                                               NodeGetter& 
node, const char* name, uint32 type,
-                                                               off_t pos, 
const uint8* data, size_t length,
-                                                               bool force = 
false);
-                       status_t                _GetNextSmallData(bfs_inode* 
node,
-                                                               small_data** 
_smallData) const;
-                       status_t                _RemoveSmallData(bfs_inode* 
node, small_data* item,
-                                                               int32 index);
-                       status_t                _RemoveAttribute(Transaction& 
transaction,
-                                                               const char* 
name, bool hasIndex, Index* index);
+                       status_t                        
_MakeSpaceForSmallData(Transaction& transaction,
+                                                                       
bfs_inode* node, const char* name,
+                                                                       int32 
length);
+                       status_t                        
_RemoveSmallData(Transaction& transaction,
+                                                                       
NodeGetter& node, const char* name);
+                       status_t                        
_AddSmallData(Transaction& transaction,
+                                                                       
NodeGetter& node, const char* name,
+                                                                       uint32 
type, off_t pos, const uint8* data,
+                                                                       size_t 
length, bool force = false);
+                       status_t                        
_GetNextSmallData(bfs_inode* node,
+                                                                       
small_data** _smallData) const;
+                       status_t                        
_RemoveSmallData(bfs_inode* node,
+                                                                       
small_data* item, int32 index);
+                       status_t                        
_RemoveAttribute(Transaction& transaction,
+                                                                       const 
char* name, bool hasIndex,
+                                                                       Index* 
index);
 
-                       void                    _AddIterator(AttributeIterator* 
iterator);
-                       void                    
_RemoveIterator(AttributeIterator* iterator);
+                       void                            
_AddIterator(AttributeIterator* iterator);
+                       void                            
_RemoveIterator(AttributeIterator* iterator);
 
-                       size_t                  _DoubleIndirectBlockLength() 
const;
-                       status_t                
_FreeStaticStreamArray(Transaction& transaction,
-                                                               int32 level, 
block_run run, off_t size,
-                                                               off_t offset, 
off_t& max);
-                       status_t                _FreeStreamArray(Transaction& 
transaction,
-                                                               block_run* 
array, uint32 arrayLength,
-                                                               off_t size, 
off_t& offset, off_t& max);
-                       status_t                
_AllocateBlockArray(Transaction& transaction,
-                                                               block_run& run, 
size_t length,
-                                                               bool 
variableSize = false);
-                       status_t                _GrowStream(Transaction& 
transaction, off_t size);
-                       status_t                _ShrinkStream(Transaction& 
transaction, off_t size);
+                       size_t                          
_DoubleIndirectBlockLength() const;
+                       status_t                        
_FreeStaticStreamArray(Transaction& transaction,
+                                                                       int32 
level, block_run run, off_t size,
+                                                                       off_t 
offset, off_t& max);
+                       status_t                        
_FreeStreamArray(Transaction& transaction,
+                                                                       
block_run* array, uint32 arrayLength,
+                                                                       off_t 
size, off_t& offset, off_t& max);
+                       status_t                        
_AllocateBlockArray(Transaction& transaction,
+                                                                       
block_run& run, size_t length,
+                                                                       bool 
variableSize = false);
+                       status_t                        
_GrowStream(Transaction& transaction,
+                                                                       off_t 
size);
+                       status_t                        
_ShrinkStream(Transaction& transaction,
+                                                                       off_t 
size);
 
 private:
-                       rw_lock                 fLock;
-                       Volume*                 fVolume;
-                       ino_t                   fID;
-                       BPlusTree*              fTree;
-                       Inode*                  fAttributes;
-                       void*                   fCache;
-                       void*                   fMap;
-                       bfs_inode               fNode;
+                       rw_lock                         fLock;
+                       Volume*                         fVolume;
+                       ino_t                           fID;
+                       BPlusTree*                      fTree;
+                       Inode*                          fAttributes;
+                       void*                           fCache;
+                       void*                           fMap;
+                       bfs_inode                       fNode;
 
-                       off_t                   fOldSize;
-                       off_t                   fOldLastModified;
+                       off_t                           fOldSize;
+                       off_t                           fOldLastModified;
                                // we need those values to ensure we will remove
                                // the correct keys from the indices
 
-#ifdef B_HAIKU_64_BIT
-                       Link                    fListLink;
-#endif
-
                        mutable recursive_lock fSmallDataLock;
                        SinglyLinkedList<AttributeIterator> fIterators;
 };

Modified: haiku/trunk/src/add-ons/kernel/file_systems/bfs/Journal.cpp
===================================================================
--- haiku/trunk/src/add-ons/kernel/file_systems/bfs/Journal.cpp 2010-02-16 
08:34:55 UTC (rev 35490)
+++ haiku/trunk/src/add-ons/kernel/file_systems/bfs/Journal.cpp 2010-02-16 
11:30:15 UTC (rev 35491)
@@ -1,8 +1,9 @@
 /*
- * Copyright 2001-2009, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx
+ * Copyright 2001-2010, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx
  * This file may be used under the terms of the MIT License.
  */
 
+
 //! Transaction and logging
 
 
@@ -1005,7 +1006,7 @@
                        // closed.
                        bool separateSubTransactions = fSeparateSubTransactions;
                        fSeparateSubTransactions = true;
-                       owner->UnlockInodes(success);
+                       owner->NotifyListeners(success);
                        fSeparateSubTransactions = separateSubTransactions;
 
                        fOwner = owner->Parent();
@@ -1018,7 +1019,7 @@
                        && recursive_lock_get_recursion(&fLock) == 1)
                        fSeparateSubTransactions = false;
        } else
-               owner->MoveInodesTo(fOwner);
+               owner->MoveListenersTo(fOwner);
 
        recursive_lock_unlock(&fLock);
        return B_OK;
@@ -1077,6 +1078,7 @@
 
 #ifdef BFS_DEBUGGER_COMMANDS
 
+
 void
 Journal::Dump()
 {
@@ -1121,9 +1123,23 @@
        return 0;
 }
 
+
 #endif // BFS_DEBUGGER_COMMANDS
 
 
+//     #pragma mark - TransactionListener
+
+
+TransactionListener::TransactionListener()
+{
+}
+
+
+TransactionListener::~TransactionListener()
+{
+}
+
+
 //     #pragma mark - Transaction
 
 
@@ -1143,74 +1159,33 @@
 }
 
 
-/*!    Adds an inode to this transaction. This means that the inode will be 
write
-       locked until the transaction ended.
-       To ensure that the inode will stay valid until that point, an extra 
reference
-       is acquired to it as long as this transaction stays active.
-*/
 void
-Transaction::AddInode(Inode* inode)
+Transaction::AddListener(TransactionListener* listener)
 {
        if (fJournal == NULL)
                panic("Transaction is not running!");
 
-       // These flags can only change while holding the transaction lock
-       if ((inode->Flags() & INODE_IN_TRANSACTION) != 0)
-               return;
-
-       // We share the same list link with the removed list, so we have to 
remove
-       // the inode from that list here (and add it back when we no longer 
need it)
-       if ((inode->Flags() & INODE_DELETED) != 0)
-               GetVolume()->RemovedInodes().Remove(inode);
-
-       if (!GetVolume()->IsInitializing())
-               acquire_vnode(GetVolume()->FSVolume(), inode->ID());
-
-       rw_lock_write_lock(&inode->Lock());
-       fLockedInodes.Add(inode);
-       inode->Node().flags |= HOST_ENDIAN_TO_BFS_INT32(INODE_IN_TRANSACTION);
+       fListeners.Add(listener);
 }
 
 
 void
-Transaction::RemoveInode(Inode* inode)
+Transaction::RemoveListener(TransactionListener* listener)
 {
        if (fJournal == NULL)
                panic("Transaction is not running!");
 
-       inode->Node().flags &= ~HOST_ENDIAN_TO_BFS_INT32(INODE_IN_TRANSACTION);
-       fLockedInodes.Remove(inode);
-       rw_lock_write_unlock(&inode->Lock());
-
-       // See AddInode() why we do this here
-       if ((inode->Flags() & INODE_DELETED) != 0)
-               GetVolume()->RemovedInodes().Add(inode);
-
-       if (!GetVolume()->IsInitializing())
-               put_vnode(GetVolume()->FSVolume(), inode->ID());
+       fListeners.Remove(listener);
+       listener->RemovedFromTransaction();
 }
 
 
 void
-Transaction::UnlockInodes(bool success)
+Transaction::NotifyListeners(bool success)
 {
-       while (Inode* inode = fLockedInodes.RemoveHead()) {
-               if (success) {
-                       inode->Node().flags
-                               &= 
~HOST_ENDIAN_TO_BFS_INT32(INODE_IN_TRANSACTION);
-               } else {
-                       // revert any changes made to the cached bfs_inode
-                       inode->UpdateNodeFromDisk();
-               }
-
-               rw_lock_write_unlock(&inode->Lock());
-
-               // See AddInode() why we do this here
-               if ((inode->Flags() & INODE_DELETED) != 0)
-                       GetVolume()->RemovedInodes().Add(inode);
-
-               if (!GetVolume()->IsInitializing())
-                       put_vnode(GetVolume()->FSVolume(), inode->ID());
+       while (TransactionListener* listener = fListeners.RemoveHead()) {
+               listener->TransactionDone(success);
+               listener->RemovedFromTransaction();
        }
 }
 
@@ -1219,9 +1194,9 @@
        sure they will still be reverted in case the transaction is aborted.
 */
 void
-Transaction::MoveInodesTo(Transaction* transaction)
+Transaction::MoveListenersTo(Transaction* transaction)
 {
-       while (Inode* inode = fLockedInodes.RemoveHead()) {
-               transaction->fLockedInodes.Add(inode);
+       while (TransactionListener* listener = fListeners.RemoveHead()) {
+               transaction->fListeners.Add(listener);
        }
 }

Modified: haiku/trunk/src/add-ons/kernel/file_systems/bfs/Journal.h
===================================================================
--- haiku/trunk/src/add-ons/kernel/file_systems/bfs/Journal.h   2010-02-16 
08:34:55 UTC (rev 35490)
+++ haiku/trunk/src/add-ons/kernel/file_systems/bfs/Journal.h   2010-02-16 
11:30:15 UTC (rev 35491)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2009, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx
+ * Copyright 2001-2010, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx
  * This file may be used under the terms of the MIT License.
  */
 #ifndef JOURNAL_H
@@ -86,6 +86,19 @@
 }
 
 
+class TransactionListener
+       : public DoublyLinkedListLinkImpl<TransactionListener> {
+public:
+                                                               
TransactionListener();
+       virtual                                         ~TransactionListener();
+
+       virtual void                            TransactionDone(bool success) = 
0;
+       virtual void                            RemovedFromTransaction() = 0;
+};
+
+typedef DoublyLinkedList<TransactionListener> TransactionListeners;
+
+
 class Transaction {
 public:
        Transaction(Volume* volume, off_t refBlock)
@@ -176,11 +189,11 @@
        int32 ID() const
                { return fJournal->TransactionID(); }
 
-       void AddInode(Inode* inode);
-       void RemoveInode(Inode* inode);
+       void AddListener(TransactionListener* listener);
+       void RemoveListener(TransactionListener* listener);
 
-       void UnlockInodes(bool success);
-       void MoveInodesTo(Transaction* transaction);
+       void NotifyListeners(bool success);
+       void MoveListenersTo(Transaction* transaction);
 
        void SetParent(Transaction* parent)
                { fParent = parent; }
@@ -192,13 +205,15 @@
        Transaction& operator=(const Transaction& other);
                // no implementation
 
-       Journal*                fJournal;
-       InodeList               fLockedInodes;
-       Transaction*    fParent;
+       Journal*                                fJournal;
+       TransactionListeners    fListeners;
+       Transaction*                    fParent;
 };
 
+
 #ifdef BFS_DEBUGGER_COMMANDS
 int dump_journal(int argc, char** argv);
 #endif
 
+
 #endif // JOURNAL_H

Modified: haiku/trunk/src/add-ons/kernel/file_systems/bfs/Volume.h
===================================================================
--- haiku/trunk/src/add-ons/kernel/file_systems/bfs/Volume.h    2010-02-16 
08:34:55 UTC (rev 35490)
+++ haiku/trunk/src/add-ons/kernel/file_systems/bfs/Volume.h    2010-02-16 
11:30:15 UTC (rev 35491)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2009, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx
+ * Copyright 2001-2010, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx
  * This file may be used under the terms of the MIT License.
  */
 #ifndef VOLUME_H
@@ -11,10 +11,12 @@
 #include "bfs.h"
 #include "BlockAllocator.h"
 
+
 class Journal;
 class Inode;
 class Query;
 
+
 enum volume_flags {
        VOLUME_READ_ONLY        = 0x0001
 };
@@ -25,6 +27,7 @@
 
 typedef DoublyLinkedList<Inode> InodeList;
 
+
 class Volume {
 public:
                                                        Volume(fs_volume* 
volume);

Modified: haiku/trunk/src/add-ons/kernel/file_systems/bfs/bfs.h
===================================================================
--- haiku/trunk/src/add-ons/kernel/file_systems/bfs/bfs.h       2010-02-16 
08:34:55 UTC (rev 35490)
+++ haiku/trunk/src/add-ons/kernel/file_systems/bfs/bfs.h       2010-02-16 
11:30:15 UTC (rev 35491)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2009, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx
+ * Copyright 2001-2010, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx
  * Parts of this code is based on work previously done by Marcus Overhagen.
  *
  * This file may be used under the terms of the MIT License.
@@ -7,6 +7,7 @@
 #ifndef BFS_H
 #define BFS_H
 
+
 //!    BFS definitions and helper functions
 
 
@@ -144,20 +145,25 @@
 struct bfs_inode;
 
 struct small_data {
-       uint32          type;
-       uint16          name_size;
-       uint16          data_size;
-       char            name[0];        // name_size long, followed by data
+                       uint32                          type;
+                       uint16                          name_size;
+                       uint16                          data_size;
+                       char                            name[0];        // 
name_size long, followed by data
 
-       uint32 Type() const { return BFS_ENDIAN_TO_HOST_INT32(type); }
-       uint16 NameSize() const { return BFS_ENDIAN_TO_HOST_INT16(name_size); }
-       uint16 DataSize() const { return BFS_ENDIAN_TO_HOST_INT16(data_size); }
+                       uint32                          Type() const
+                                                                       { 
return BFS_ENDIAN_TO_HOST_INT32(type); }
+                       uint16                          NameSize() const
+                                                                       { 
return BFS_ENDIAN_TO_HOST_INT16(
+                                                                               
name_size); }
+                       uint16                          DataSize() const
+                                                                       { 
return BFS_ENDIAN_TO_HOST_INT16(
+                                                                               
data_size); }
 
-       inline char             *Name() const;
-       inline uint8    *Data() const;
-       inline uint32   Size() const;
-       inline small_data *Next() const;
-       inline bool             IsLast(const bfs_inode *inode) const;
+       inline  char*                           Name() const;
+       inline  uint8*                          Data() const;
+       inline  uint32                          Size() const;
+       inline  small_data*                     Next() const;
+       inline  bool                            IsLast(const bfs_inode* inode) 
const;
 } _PACKED;
 
 // the file name is part of the small_data structure
@@ -222,7 +228,7 @@
                { return BFS_ENDIAN_TO_HOST_INT64(status_change_time); }
        small_data* SmallDataStart() { return small_data_start; }
 
-       status_t InitCheck(Volume *volume);
+       status_t InitCheck(Volume* volume) const;
                // defined in Inode.cpp
 
        static int64 ToInode(bigtime_t time)


Other related posts:

  • » [haiku-commits] r35491 - haiku/trunk/src/add-ons/kernel/file_systems/bfs - axeld