[haiku-commits] r37601 - haiku/trunk/src/tests/system/kernel/file_corruption/fs

  • From: ingo_weinhold@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Mon, 19 Jul 2010 17:31:08 +0200 (CEST)

Author: bonefish
Date: 2010-07-19 17:31:08 +0200 (Mon, 19 Jul 2010)
New Revision: 37601
Changeset: http://dev.haiku-os.org/changeset/37601

Added:
   haiku/trunk/src/tests/system/kernel/file_corruption/fs/Notifications.cpp
   haiku/trunk/src/tests/system/kernel/file_corruption/fs/Notifications.h
Modified:
   haiku/trunk/src/tests/system/kernel/file_corruption/fs/File.cpp
   haiku/trunk/src/tests/system/kernel/file_corruption/fs/File.h
   haiku/trunk/src/tests/system/kernel/file_corruption/fs/Jamfile
   haiku/trunk/src/tests/system/kernel/file_corruption/fs/Node.cpp
   haiku/trunk/src/tests/system/kernel/file_corruption/fs/Node.h
   haiku/trunk/src/tests/system/kernel/file_corruption/fs/Transaction.cpp
   haiku/trunk/src/tests/system/kernel/file_corruption/fs/Transaction.h
   haiku/trunk/src/tests/system/kernel/file_corruption/fs/checksumfs.cpp
Log:
Added node monitoring support.


Modified: haiku/trunk/src/tests/system/kernel/file_corruption/fs/File.cpp
===================================================================
--- haiku/trunk/src/tests/system/kernel/file_corruption/fs/File.cpp     
2010-07-19 15:24:36 UTC (rev 37600)
+++ haiku/trunk/src/tests/system/kernel/file_corruption/fs/File.cpp     
2010-07-19 15:31:08 UTC (rev 37601)
@@ -169,8 +169,11 @@
 
 
 status_t
-File::Write(off_t pos, const void* buffer, size_t size, size_t& _bytesWritten)
+File::Write(off_t pos, const void* buffer, size_t size, size_t& _bytesWritten,
+       bool& _sizeChanged)
 {
+       _sizeChanged = false;
+
        if (size == 0) {
                _bytesWritten = 0;
                return B_OK;
@@ -208,6 +211,8 @@
                error = transaction.Commit();
                if (error != B_OK)
                        RETURN_ERROR(error);
+
+               _sizeChanged = true;
        }
 
        // now the file has the right size -- do the write

Modified: haiku/trunk/src/tests/system/kernel/file_corruption/fs/File.h
===================================================================
--- haiku/trunk/src/tests/system/kernel/file_corruption/fs/File.h       
2010-07-19 15:24:36 UTC (rev 37600)
+++ haiku/trunk/src/tests/system/kernel/file_corruption/fs/File.h       
2010-07-19 15:31:08 UTC (rev 37601)
@@ -28,7 +28,8 @@
        virtual status_t                        Read(off_t pos, void* buffer, 
size_t size,
                                                                        size_t& 
_bytesRead);
        virtual status_t                        Write(off_t pos, const void* 
buffer,
-                                                                       size_t 
size, size_t& _bytesWritten);
+                                                                       size_t 
size, size_t& _bytesWritten,
+                                                                       bool& 
_sizeChanged);
        virtual status_t                        Sync();
 
        virtual void                            RevertNodeData(const 
checksumfs_node& nodeData);

Modified: haiku/trunk/src/tests/system/kernel/file_corruption/fs/Jamfile
===================================================================
--- haiku/trunk/src/tests/system/kernel/file_corruption/fs/Jamfile      
2010-07-19 15:24:36 UTC (rev 37600)
+++ haiku/trunk/src/tests/system/kernel/file_corruption/fs/Jamfile      
2010-07-19 15:31:08 UTC (rev 37601)
@@ -22,6 +22,7 @@
        Directory.cpp
        File.cpp
        Node.cpp
+       Notifications.cpp
        SuperBlock.cpp
        SymLink.cpp
        Transaction.cpp

Modified: haiku/trunk/src/tests/system/kernel/file_corruption/fs/Node.cpp
===================================================================
--- haiku/trunk/src/tests/system/kernel/file_corruption/fs/Node.cpp     
2010-07-19 15:24:36 UTC (rev 37600)
+++ haiku/trunk/src/tests/system/kernel/file_corruption/fs/Node.cpp     
2010-07-19 15:31:08 UTC (rev 37601)
@@ -99,7 +99,8 @@
 
 
 status_t
-Node::Write(off_t pos, const void* buffer, size_t size, size_t& _bytesWritten)
+Node::Write(off_t pos, const void* buffer, size_t size, size_t& _bytesWritten,
+       bool& _sizeChanged)
 {
        RETURN_ERROR(B_BAD_VALUE);
 }

Modified: haiku/trunk/src/tests/system/kernel/file_corruption/fs/Node.h
===================================================================
--- haiku/trunk/src/tests/system/kernel/file_corruption/fs/Node.h       
2010-07-19 15:24:36 UTC (rev 37600)
+++ haiku/trunk/src/tests/system/kernel/file_corruption/fs/Node.h       
2010-07-19 15:31:08 UTC (rev 37601)
@@ -42,7 +42,8 @@
        virtual status_t                        Read(off_t pos, void* buffer, 
size_t size,
                                                                        size_t& 
_bytesRead);
        virtual status_t                        Write(off_t pos, const void* 
buffer,
-                                                                       size_t 
size, size_t& _bytesWritten);
+                                                                       size_t 
size, size_t& _bytesWritten,
+                                                                       bool& 
_sizeChanged);
        virtual status_t                        Sync();
 
        inline  const checksumfs_node& NodeData() const { return fNode; }

Added: haiku/trunk/src/tests/system/kernel/file_corruption/fs/Notifications.cpp
===================================================================
--- haiku/trunk/src/tests/system/kernel/file_corruption/fs/Notifications.cpp    
                        (rev 0)
+++ haiku/trunk/src/tests/system/kernel/file_corruption/fs/Notifications.cpp    
2010-07-19 15:31:08 UTC (rev 37601)
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2010, Ingo Weinhold, ingo_weinhold@xxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
+
+
+#include "Notifications.h"
+
+#include "Directory.h"
+#include "Volume.h"
+
+
+// #pragma mark - EntryCreatedNotification
+
+
+EntryCreatedNotification::EntryCreatedNotification(Directory* directory,
+       const char* name, Node* node)
+       :
+       fDirectory(directory),
+       fName(name),
+       fNode(node)
+{
+}
+
+
+void
+EntryCreatedNotification::NotifyPostCommit() const
+{
+       notify_entry_created(fDirectory->GetVolume()->ID(),
+               fDirectory->BlockIndex(), fName, fNode->BlockIndex());
+}
+
+
+// #pragma mark - EntryRemovedNotification
+
+
+EntryRemovedNotification::EntryRemovedNotification(Directory* directory,
+       const char* name, Node* node)
+       :
+       fDirectory(directory),
+       fName(name),
+       fNode(node)
+{
+}
+
+
+void
+EntryRemovedNotification::NotifyPostCommit() const
+{
+       notify_entry_removed(fDirectory->GetVolume()->ID(),
+               fDirectory->BlockIndex(), fName, fNode->BlockIndex());
+}
+
+
+// #pragma mark - EntryMovedNotification
+
+
+EntryMovedNotification::EntryMovedNotification(Directory* fromDirectory,
+       const char* fromName, Directory* toDirectory, const char* toName,
+       Node* node)
+       :
+       fFromDirectory(fromDirectory),
+       fFromName(fromName),
+       fToDirectory(toDirectory),
+       fToName(toName),
+       fNode(node)
+{
+}
+
+
+void
+EntryMovedNotification::NotifyPostCommit() const
+{
+       notify_entry_moved(fFromDirectory->GetVolume()->ID(),
+               fFromDirectory->BlockIndex(), fFromName, 
fToDirectory->BlockIndex(),
+               fToName, fNode->BlockIndex());
+}
+
+
+// #pragma mark - StatChangedNotification
+
+
+StatChangedNotification::StatChangedNotification(Node* node, uint32 statFields)
+       :
+       fNode(node),
+       fStatFields(statFields)
+{
+}
+
+
+void
+StatChangedNotification::NotifyPostCommit() const
+{
+       notify_stat_changed(fNode->GetVolume()->ID(), fNode->BlockIndex(),
+               fStatFields);
+}
+
+
+// #pragma mark - AttributeChangedNotification
+
+
+AttributeChangedNotification::AttributeChangedNotification(Node* node,
+       const char* attribute, int32 cause)
+       :
+       fNode(node),
+       fAttribute(attribute),
+       fCause(cause)
+{
+}
+
+
+void
+AttributeChangedNotification::NotifyPostCommit() const
+{
+       notify_attribute_changed(fNode->GetVolume()->ID(), fNode->BlockIndex(),
+               fAttribute, fCause);
+}

Added: haiku/trunk/src/tests/system/kernel/file_corruption/fs/Notifications.h
===================================================================
--- haiku/trunk/src/tests/system/kernel/file_corruption/fs/Notifications.h      
                        (rev 0)
+++ haiku/trunk/src/tests/system/kernel/file_corruption/fs/Notifications.h      
2010-07-19 15:31:08 UTC (rev 37601)
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2010, Ingo Weinhold, ingo_weinhold@xxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef NOTIFICATIONS_H
+#define NOTIFICATIONS_H
+
+
+#include "Transaction.h"
+
+
+class Directory;
+
+
+class EntryCreatedNotification : public PostCommitNotification {
+public:
+                                                               
EntryCreatedNotification(Directory* directory,
+                                                                       const 
char* name, Node* node);
+
+       virtual void                            NotifyPostCommit() const;
+
+private:
+                       Directory*                      fDirectory;
+                       const char*                     fName;
+                       Node*                           fNode;
+};
+
+
+class EntryRemovedNotification : public PostCommitNotification {
+public:
+                                                               
EntryRemovedNotification(Directory* directory,
+                                                                       const 
char* name, Node* node);
+
+       virtual void                            NotifyPostCommit() const;
+
+private:
+                       Directory*                      fDirectory;
+                       const char*                     fName;
+                       Node*                           fNode;
+};
+
+
+class EntryMovedNotification : public PostCommitNotification {
+public:
+                                                               
EntryMovedNotification(Directory* fromDirectory,
+                                                                       const 
char* fromName,
+                                                                       
Directory* toDirectory, const char* toName,
+                                                                       Node* 
node);
+
+       virtual void                            NotifyPostCommit() const;
+
+private:
+                       Directory*                      fFromDirectory;
+                       const char*                     fFromName;
+                       Directory*                      fToDirectory;
+                       const char*                     fToName;
+                       Node*                           fNode;
+};
+
+
+class StatChangedNotification : public PostCommitNotification {
+public:
+                                                               
StatChangedNotification(Node* node,
+                                                                       uint32 
statFields);
+
+       virtual void                            NotifyPostCommit() const;
+
+private:
+                       Node*                           fNode;
+                       uint32                          fStatFields;
+};
+
+
+class AttributeChangedNotification : public PostCommitNotification {
+public:
+                                                               
AttributeChangedNotification(Node* node,
+                                                                       const 
char* attribute, int32 cause);
+
+       virtual void                            NotifyPostCommit() const;
+
+private:
+                       Node*                           fNode;
+                       const char*                     fAttribute;
+                       int32                           fCause;
+};
+
+
+#endif // NOTIFICATIONS_H

Modified: haiku/trunk/src/tests/system/kernel/file_corruption/fs/Transaction.cpp
===================================================================
--- haiku/trunk/src/tests/system/kernel/file_corruption/fs/Transaction.cpp      
2010-07-19 15:24:36 UTC (rev 37600)
+++ haiku/trunk/src/tests/system/kernel/file_corruption/fs/Transaction.cpp      
2010-07-19 15:31:08 UTC (rev 37601)
@@ -71,7 +71,7 @@
 
 
 status_t
-Transaction::Commit()
+Transaction::Commit(const PostCommitNotification* notification)
 {
        ASSERT(fID >= 0);
 
@@ -93,6 +93,10 @@
                return error;
        }
 
+       // send notifications
+       if (notification != NULL)
+               notification->NotifyPostCommit();
+
        // clean up
        _DeleteNodeInfosAndUnlock(false);
 
@@ -206,3 +210,12 @@
                delete info;
        }
 }
+
+
+
+// #pragma mark - PostCommitNotification
+
+
+PostCommitNotification::~PostCommitNotification()
+{
+}

Modified: haiku/trunk/src/tests/system/kernel/file_corruption/fs/Transaction.h
===================================================================
--- haiku/trunk/src/tests/system/kernel/file_corruption/fs/Transaction.h        
2010-07-19 15:24:36 UTC (rev 37600)
+++ haiku/trunk/src/tests/system/kernel/file_corruption/fs/Transaction.h        
2010-07-19 15:31:08 UTC (rev 37601)
@@ -13,6 +13,7 @@
 #include "Node.h"
 
 
+class PostCommitNotification;
 class Volume;
 
 
@@ -32,7 +33,11 @@
 
                        status_t                        Start();
                        status_t                        StartAndAddNode(Node* 
node, uint32 flags = 0);
-                       status_t                        Commit();
+                       status_t                        Commit(
+                                                                       const 
PostCommitNotification* notification
+                                                                               
= NULL);
+       inline  status_t                        Commit(
+                                                                       const 
PostCommitNotification& notification);
                        void                            Abort();
 
                        status_t                        AddNode(Node* node, 
uint32 flags = 0);
@@ -62,4 +67,22 @@
 };
 
 
+status_t
+Transaction::Commit(const PostCommitNotification& notification)
+{
+       return Commit(&notification);
+}
+
+
+// #pragma mark -
+
+
+class PostCommitNotification {
+public:
+       virtual                                         
~PostCommitNotification();
+
+       virtual void                            NotifyPostCommit() const = 0;
+};
+
+
 #endif // TRANSACTION_H

Modified: haiku/trunk/src/tests/system/kernel/file_corruption/fs/checksumfs.cpp
===================================================================
--- haiku/trunk/src/tests/system/kernel/file_corruption/fs/checksumfs.cpp       
2010-07-19 15:24:36 UTC (rev 37600)
+++ haiku/trunk/src/tests/system/kernel/file_corruption/fs/checksumfs.cpp       
2010-07-19 15:31:08 UTC (rev 37601)
@@ -19,12 +19,14 @@
 #include <AutoLocker.h>
 
 #include <debug.h>
+#include <util/AutoLock.h>
 
 #include "checksumfs.h"
 #include "checksumfs_private.h"
 #include "DebugSupport.h"
 #include "Directory.h"
 #include "File.h"
+#include "Notifications.h"
 #include "SuperBlock.h"
 #include "SymLink.h"
 #include "Transaction.h"
@@ -35,18 +37,100 @@
        B_CURRENT_FS_API_VERSION;
 static const char* const kCheckSumFSShortName  = "checksumfs";
 
+static const bigtime_t kModifiedInterimUpdateInterval = 500000;
+       // wait at least 0.5s between interim modified updates
 
+
 // #pragma mark -
 
 
 struct FileCookie {
-       int     openMode;
+       mutex           lock;
+       int                     openMode;
+       bigtime_t       lastModifiedUpdate;
+       bool            modifiedNeedsUpdate;
+       bool            sizeChangedSinceUpdate;
+       bool            modifiedNeedsFinalUpdate;
+       bool            finalSizeChanged;
 
+
        FileCookie(int openMode)
                :
-               openMode(openMode)
+               openMode(openMode),
+               lastModifiedUpdate(0),
+               modifiedNeedsUpdate(false),
+               sizeChangedSinceUpdate(false),
+               modifiedNeedsFinalUpdate(false),
+               finalSizeChanged(false)
        {
+               mutex_init(&lock, "checksumfs file cookie");
        }
+
+       ~FileCookie()
+       {
+               mutex_destroy(&lock);
+       }
+
+       status_t UpdateModifiedIfNecessary(Node* node, bool finalUpdate)
+       {
+               MutexLocker locker(lock);
+
+               return _UpdateModifiedIfNecessary(node, finalUpdate);
+       }
+
+       status_t FileModified(Node* node, bool sizeChanged)
+       {
+               MutexLocker locker(lock);
+
+               modifiedNeedsUpdate = true;
+               modifiedNeedsFinalUpdate = true;
+               sizeChangedSinceUpdate |= sizeChanged;
+               finalSizeChanged |= sizeChanged;
+
+               return _UpdateModifiedIfNecessary(node, false);
+       }
+
+private:
+       status_t _UpdateModifiedIfNecessary(Node* node, bool finalUpdate)
+       {
+               uint32 statFlags = B_STAT_MODIFICATION_TIME | 
B_STAT_CHANGE_TIME;
+
+               if (finalUpdate) {
+                       if (!modifiedNeedsFinalUpdate)
+                               return B_OK;
+                       if (finalSizeChanged)
+                               statFlags |= B_STAT_SIZE;
+               } else {
+                       if (!modifiedNeedsUpdate)
+                               return B_OK;
+
+                       if (system_time()
+                                       < lastModifiedUpdate + 
kModifiedInterimUpdateInterval) {
+                               // not enough time passed -- postpone update
+                               return B_OK;
+                       }
+
+                       statFlags |= B_STAT_INTERIM_UPDATE
+                               | (sizeChangedSinceUpdate ? B_STAT_SIZE : 0);
+               }
+
+               // do the update -- start a transaction, lock the node, and 
update
+               Transaction transaction(node->GetVolume());
+               status_t error = transaction.StartAndAddNode(node);
+               if (error != B_OK)
+                       return error;
+
+               node->Touched(NODE_MODIFIED);
+
+               error = transaction.Commit(StatChangedNotification(node, 
statFlags));
+               if (error != B_OK)
+                       return error;
+
+               modifiedNeedsUpdate = false;
+               lastModifiedUpdate = system_time();
+
+               return B_OK;
+       }
 };
 
 
@@ -308,7 +392,8 @@
        }
 
        // commit the transaction
-       return transaction.Commit();
+       return transaction.Commit(EntryRemovedNotification(directory, name,
+               childNode));
 }
 
 
@@ -723,7 +808,8 @@
        directory->Touched(NODE_MODIFIED);
 
        // commit the transaction
-       return transaction.Commit();
+       return transaction.Commit(EntryCreatedNotification(directory, name,
+               newSymLink));
 }
 
 
@@ -773,7 +859,7 @@
        directory->Touched(NODE_MODIFIED);
 
        // commit the transaction
-       return transaction.Commit();
+       return transaction.Commit(EntryCreatedNotification(directory, name, 
node));
 }
 
 
@@ -896,7 +982,8 @@
        toDirectory->Touched(NODE_MODIFIED);
 
        // commit the transaction
-       return transaction.Commit();
+       return transaction.Commit(EntryMovedNotification(fromDirectory, 
fromName,
+               toDirectory, toName, node));
 }
 
 
@@ -1027,7 +1114,7 @@
                node->Touched(NODE_ACCESSED);
 
        // commit the transaction
-       return transaction.Commit();
+       return transaction.Commit(StatChangedNotification(node, statMask));
 }
 
 
@@ -1231,7 +1318,8 @@
        transaction.KeepNode(newFile);
 
        // commit the transaction
-       error = transaction.Commit();
+       error = transaction.Commit(EntryCreatedNotification(directory, name,
+               newFile));
        if (error != B_OK) {
                volume->RemoveNode(newFile);
                delete newFile;
@@ -1281,6 +1369,10 @@
 checksumfs_free_cookie(fs_volume* fsVolume, fs_vnode* vnode, void* _cookie)
 {
        FileCookie* cookie = (FileCookie*)_cookie;
+       Node* node = (Node*)vnode->private_node;
+
+       cookie->UpdateModifiedIfNecessary(node, true);
+
        delete cookie;
        return B_OK;
 }
@@ -1330,8 +1422,16 @@
                        // special value handled by Write()
        }
 
-       RETURN_ERROR(node->Write(pos, buffer, *_length, *_length));
-// TODO: Modification time update!
+       bool sizeChanged;
+       status_t error = node->Write(pos, buffer, *_length, *_length, 
sizeChanged);
+       if (error != B_OK)
+               RETURN_ERROR(error);
+
+       // update the modification time and send out a notification from time to
+       // time
+       cookie->FileModified(node, sizeChanged);
+
+       return B_OK;
 }
 
 
@@ -1384,7 +1484,8 @@
        directory->Touched(NODE_MODIFIED);
 
        // commit the transaction
-       return transaction.Commit();
+       return transaction.Commit(EntryCreatedNotification(directory, name,
+               newDirectory));
 }
 
 


Other related posts:

  • » [haiku-commits] r37601 - haiku/trunk/src/tests/system/kernel/file_corruption/fs - ingo_weinhold